Skip to content

Commit 9184867

Browse files
committed
feat(splitter): implement keyboard navigation
1 parent da506d4 commit 9184867

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

src/components/splitter/splitter-bar.ts

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import { html, LitElement, nothing } from 'lit';
33
import { type StyleInfo, styleMap } from 'lit/directives/style-map.js';
44
import { splitterContext } from '../common/context.js';
55
import { addInternalsController } from '../common/controllers/internals.js';
6+
import {
7+
addKeybindings,
8+
arrowDown,
9+
arrowLeft,
10+
arrowRight,
11+
arrowUp,
12+
ctrlKey,
13+
} from '../common/controllers/key-bindings.js';
614
import { createMutationController } from '../common/controllers/mutation-observer.js';
715
import { registerComponent } from '../common/definitions/register.js';
816
import type { Constructor } from '../common/mixins/constructor.js';
@@ -106,14 +114,10 @@ export default class IgcSplitterBarComponent extends EventEmitterMixin<
106114
);
107115
},
108116
start: () => {
109-
if (
110-
!this._siblingPanes[0]?.resizable ||
111-
!this._siblingPanes[1]?.resizable ||
112-
this._siblingPanes[0].collapsed
113-
) {
117+
if (this._resizeDisallowed) {
114118
return false;
115119
}
116-
this.emitEvent('igcMovingStart', { detail: this._siblingPanes[0] });
120+
this.emitEvent('igcMovingStart', { detail: this._siblingPanes[0]! });
117121
return true;
118122
},
119123
resize: ({ state }) => {
@@ -133,6 +137,16 @@ export default class IgcSplitterBarComponent extends EventEmitterMixin<
133137
},
134138
cancel: () => {},
135139
});
140+
141+
addKeybindings(this)
142+
.set(arrowUp, this.resizePanes)
143+
.set(arrowDown, this.resizePanes)
144+
.set(arrowLeft, this.resizePanes)
145+
.set(arrowRight, this.resizePanes)
146+
.set([ctrlKey, arrowUp], () => this._handleExpanderClick(true))
147+
.set([ctrlKey, arrowDown], () => this._handleExpanderClick(false))
148+
.set([ctrlKey, arrowLeft], () => this._handleExpanderClick(true))
149+
.set([ctrlKey, arrowRight], () => this._handleExpanderClick(false));
136150
//addThemingController(this, all);
137151
}
138152

@@ -143,6 +157,34 @@ export default class IgcSplitterBarComponent extends EventEmitterMixin<
143157
});
144158
}
145159

160+
private resizePanes(event: KeyboardEvent) {
161+
if (this._resizeDisallowed) {
162+
return false;
163+
}
164+
if (
165+
(event.key === arrowUp || event.key === arrowDown) &&
166+
this._orientation === 'horizontal'
167+
) {
168+
return false;
169+
}
170+
if (
171+
(event.key === arrowLeft || event.key === arrowRight) &&
172+
this._orientation === 'vertical'
173+
) {
174+
return false;
175+
}
176+
let delta = 0;
177+
if (event.key === arrowUp || event.key === arrowLeft) {
178+
delta = -10;
179+
} else {
180+
delta = 10;
181+
}
182+
this.emitEvent('igcMovingStart', { detail: this._siblingPanes[0]! });
183+
this.emitEvent('igcMoving', { detail: delta });
184+
this.emitEvent('igcMovingEnd', { detail: delta });
185+
return true;
186+
}
187+
146188
private _createSiblingPaneMutationController(pane: IgcSplitterPaneComponent) {
147189
createMutationController(pane, {
148190
callback: () => {
@@ -167,19 +209,19 @@ export default class IgcSplitterBarComponent extends EventEmitterMixin<
167209
this.requestUpdate();
168210
}
169211

170-
private _handleExpanderClick(start: boolean, event: PointerEvent) {
212+
private _handleExpanderClick(start: boolean, event?: PointerEvent) {
171213
// Prevent resize controller from starting
172-
event.stopPropagation();
214+
event?.stopPropagation();
173215

174216
const prevSibling = this._siblingPanes[0]!;
175217
const nextSibling = this._siblingPanes[1]!;
176218
let target: IgcSplitterPaneComponent;
177219
if (start) {
178-
// if next is clicked when prev pane is hidden, show prev pane, else hide next pane.
179-
target = prevSibling.collapsed ? prevSibling : nextSibling;
180-
} else {
181220
// if prev is clicked when next pane is hidden, show next pane, else hide prev pane.
182221
target = nextSibling.collapsed ? nextSibling : prevSibling;
222+
} else {
223+
// if next is clicked when prev pane is hidden, show prev pane, else hide next pane.
224+
target = prevSibling.collapsed ? prevSibling : nextSibling;
183225
}
184226
target.toggle();
185227
}
@@ -211,6 +253,7 @@ export default class IgcSplitterBarComponent extends EventEmitterMixin<
211253
<div
212254
part=${partMap(this._resolvePartNames())}
213255
style=${styleMap(this._internalStyles)}
256+
tabindex="0"
214257
>
215258
${this._renderBarControls()}
216259
</div>

0 commit comments

Comments
 (0)