Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ The `DockviewApi` (available via the `onReady` event) provides:
- `removeGroup(group)` — Remove a group
- `getPanel(id)` — Get panel by ID
- `getGroup(id)` — Get group by ID
- `moveToNext()` / `moveToPrevious()` — Navigate between panels
- `activateNext()` / `activatePrevious()` — Navigate between panels (formerly `moveToNext` / `moveToPrevious`, now deprecated aliases)
- `addFloatingGroup(panel, options)` — Create a floating group
- `addEdgeGroup(options)` — Pin a group to a layout edge
- `createTabGroup(options)` — Create a tab group for visual organization
Expand Down
34 changes: 34 additions & 0 deletions packages/dockview-core/src/__tests__/api/component.api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,39 @@ describe('component.api', () => {
expect(f).toHaveBeenCalledTimes(1);
}
});

test('activateNext / activatePrevious delegate to the component', () => {
const activateNext = jest.fn();
const activatePrevious = jest.fn();
const component: Partial<DockviewComponent> = {
activateNext,
activatePrevious,
};
const cut = new DockviewApi(<DockviewComponent>component);

cut.activateNext({ includePanel: true });
expect(activateNext).toHaveBeenCalledWith({ includePanel: true });

cut.activatePrevious();
expect(activatePrevious).toHaveBeenCalledTimes(1);
});

test('deprecated moveToNext / moveToPrevious alias activateNext / activatePrevious', () => {
const activateNext = jest.fn();
const activatePrevious = jest.fn();
const component: Partial<DockviewComponent> = {
activateNext,
activatePrevious,
};
const cut = new DockviewApi(<DockviewComponent>component);

cut.moveToNext({ includePanel: true });
expect(activateNext).toHaveBeenCalledWith({ includePanel: true });

cut.moveToPrevious({ includePanel: false });
expect(activatePrevious).toHaveBeenCalledWith({
includePanel: false,
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -958,23 +958,23 @@ describe('dockviewComponent', () => {
expect(dockview.activeGroup!.model.activePanel).toBe(panel3);
expect(dockview.activeGroup!.model.indexOf(panel3!)).toBe(1);

dockview.moveToPrevious({ includePanel: true });
dockview.activatePrevious({ includePanel: true });
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup!.model.activePanel).toBe(panel1);

dockview.moveToNext({ includePanel: true });
dockview.activateNext({ includePanel: true });
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup!.model.activePanel).toBe(panel3);

dockview.moveToPrevious({ includePanel: false });
dockview.activatePrevious({ includePanel: false });
expect(dockview.activeGroup).toBe(group1);
expect(dockview.activeGroup!.model.activePanel).toBe(panel4);

dockview.moveToPrevious({ includePanel: true });
dockview.activatePrevious({ includePanel: true });
expect(dockview.activeGroup).toBe(group1);
expect(dockview.activeGroup!.model.activePanel).toBe(panel2);

dockview.moveToNext({ includePanel: false });
dockview.activateNext({ includePanel: false });
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup!.model.activePanel).toBe(panel3);
});
Expand Down
30 changes: 26 additions & 4 deletions packages/dockview-core/src/api/component.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1122,17 +1122,39 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
}

/**
* Move the focus progmatically to the next panel or group.
* Activate the next panel or group, moving focus programmatically. Pass
* `{ includePanel: true }` to step through the panels of the active group
* before advancing to the next group.
*/
activateNext(options?: MovementOptions): void {
this.component.activateNext(options);
}

/**
* Activate the previous panel or group, moving focus programmatically. Pass
* `{ includePanel: true }` to step through the panels of the active group
* before advancing to the previous group.
*/
activatePrevious(options?: MovementOptions): void {
this.component.activatePrevious(options);
}

/**
* @deprecated Use {@link DockviewApi.activateNext} instead. Renamed because
* this advances the active panel/group (focus), it does not relocate a
* panel. Removal planned for a future major release.
*/
moveToNext(options?: MovementOptions): void {
this.component.moveToNext(options);
this.activateNext(options);
}

/**
* Move the focus progmatically to the previous panel or group.
* @deprecated Use {@link DockviewApi.activatePrevious} instead. Renamed
* because this advances the active panel/group (focus), it does not
* relocate a panel. Removal planned for a future major release.
*/
moveToPrevious(options?: MovementOptions): void {
this.component.moveToPrevious(options);
this.activatePrevious(options);
}

maximizeGroup(panel: IDockviewPanel): void {
Expand Down
8 changes: 4 additions & 4 deletions packages/dockview-core/src/dockview/dockviewComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,8 +425,8 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
direction: GroupNavigationDirection
): DockviewGroupPanel | undefined;
// events
moveToNext(options?: MovementOptions): void;
moveToPrevious(options?: MovementOptions): void;
activateNext(options?: MovementOptions): void;
activatePrevious(options?: MovementOptions): void;
setActivePanel(panel: IDockviewPanel): void;
focus(): void;
toJSON(): SerializedDockview;
Expand Down Expand Up @@ -3006,7 +3006,7 @@ export class DockviewComponent
this.doSetGroupAndPanelActive(panel.group);
}

moveToNext(options: MovementOptions = {}): void {
activateNext(options: MovementOptions = {}): void {
if (!options.group) {
if (!this.activeGroup) {
return;
Expand All @@ -3029,7 +3029,7 @@ export class DockviewComponent
this.doSetGroupAndPanelActive(next);
}

moveToPrevious(options: MovementOptions = {}): void {
activatePrevious(options: MovementOptions = {}): void {
if (!options.group) {
if (!this.activeGroup) {
return;
Expand Down
4 changes: 2 additions & 2 deletions packages/dockview-core/src/gridview/baseComponentGridview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
this.doRemoveGroup(group);
}

public moveToNext(options?: MovementOptions2): void {
public activateNext(options?: MovementOptions2): void {
options ??= {};
if (!options.group) {
if (!this.activeGroup) {
Expand All @@ -351,7 +351,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
this.doSetGroupActive(next as T);
}

public moveToPrevious(options?: MovementOptions2): void {
public activatePrevious(options?: MovementOptions2): void {
options ??= {};
if (!options.group) {
if (!this.activeGroup) {
Expand Down
19 changes: 13 additions & 6 deletions packages/docs/docs/advanced/focus-navigation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,23 @@ enterprise feature covered in [Keyboard Navigation](/docs/advanced/keyboard).

## Programmatic focus navigation

The two core methods are `moveToNext` and `moveToPrevious`:
The two core methods are `activateNext` and `activatePrevious`:

```ts
// Move focus to the next panel or group
api.moveToNext({ includePanel: true });
api.activateNext({ includePanel: true });

// Move focus to the previous panel or group
api.moveToPrevious({ includePanel: true });
api.activatePrevious({ includePanel: true });
```

:::info Renamed in v8
These methods were previously called `moveToNext` / `moveToPrevious`. The old
names still work as deprecated aliases but will be removed in a future major
release — the new names make it clear they advance the active panel/group
(focus) rather than relocating a panel.
:::

Both accept an optional `options` object:

| Option | Type | Description |
Expand All @@ -31,15 +38,15 @@ Both accept an optional `options` object:

```ts
// Cycle only through groups (not individual panels within them)
api.moveToNext();
api.activateNext();

// Cycle through all panels across all groups
api.moveToNext({ includePanel: true });
api.activateNext({ includePanel: true });
```

## Spatial navigation

`moveToNext` / `moveToPrevious` cycle through groups in list order. To navigate by _visual_ direction instead, `adjacentGroupInDirection` returns the nearest grid group to the left, right, above, or below a given group (by comparing their centre points). Floating and popout groups are ignored, and it returns `undefined` when there is no group in that direction.
`activateNext` / `activatePrevious` cycle through groups in list order. To navigate by _visual_ direction instead, `adjacentGroupInDirection` returns the nearest grid group to the left, right, above, or below a given group (by comparing their centre points). Floating and popout groups are ignored, and it returns `undefined` when there is no group in that direction.

```ts
const left = api.adjacentGroupInDirection(api.activeGroup, 'left');
Expand Down
6 changes: 3 additions & 3 deletions packages/docs/docs/advanced/keyboard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ between groups, and even docking a panel into a new position, all without a
mouse. This page covers the built-in keymap and keyboard docking. For the
accessibility semantics that back it (ARIA roles, screen-reader announcements,
focus indicators), see [Accessibility](/docs/advanced/accessibility); for the
free programmatic focus APIs (`moveToNext`, `adjacentGroupInDirection`, …), see
programmatic focus APIs (`activateNext`, `adjacentGroupInDirection`, …), see
[Focus Navigation](/docs/advanced/focus-navigation).

## Enabling the keymap
Expand Down Expand Up @@ -82,7 +82,7 @@ to match, case-insensitively — e.g. `'ctrl+]'`, `'shift+f6'`, `'ctrl+tab'`.
| Move focus to the group in a direction | `Ctrl+Shift+←/→/↑/↓` | `focusGroup{Left,Right,Up,Down}` |

`F6` / `Shift+F6` cycle the groups in list order. `Ctrl+Shift+Arrows` jump to
the visually adjacent group instead — the same geometry used by the free
the visually adjacent group instead — the same geometry used by the
[`adjacentGroupInDirection`](/docs/advanced/focus-navigation) API, so mouse and
keyboard agree on what "the group to the left" is. Once focus lands on the tab
strip (via `Ctrl+Shift+\` or `F6`),
Expand Down Expand Up @@ -118,7 +118,7 @@ within a popped-out group and the drop preview, announcements, and resulting
focus all stay in that window.
:::

For the free programmatic focus APIs (`moveToNext`, `moveToPrevious`,
For the programmatic focus APIs (`activateNext`, `activatePrevious`,
`adjacentGroupInDirection`, …) that let you build your own keyboard handlers
without the enterprise keymap, see
[Focus Navigation](/docs/advanced/focus-navigation).
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/docs/overview/features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ The guiding rule: capabilities that other free layout managers already offer (fl
| Panel lifecycle events | Per-panel `onDidVisibilityChange`, `onDidFocusChange`, `onDidActiveChange`, `onDidDimensionsChange` | <span className="feature-check">✓</span> | <span className="feature-check">✓</span> |
| Runtime option updates | Change behaviour at runtime via `api.updateOptions()` | <span className="feature-check">✓</span> | <span className="feature-check">✓</span> |
| Comprehensive events | Events for every interaction — see [Events](/docs/core/events) | <span className="feature-check">✓</span> | <span className="feature-check">✓</span> |
| Keyboard navigation | `moveToNext` / `moveToPrevious` to cycle through panels | <span className="feature-check">✓</span> | <span className="feature-check">✓</span> |
| Keyboard navigation | `activateNext` / `activatePrevious` to cycle through panels | <span className="feature-check">✓</span> | <span className="feature-check">✓</span> |

### Accessibility

Expand Down
Loading
Loading