@oscarpalmer/oui 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/css/floatable.css +9 -0
  2. package/dist/js/dialog.d.mts +3 -1
  3. package/dist/js/dialog.mjs +35 -19
  4. package/dist/js/{draggable-zszaW1qS.d.mts → draggable-fIYXd8eO.d.mts} +3 -3
  5. package/dist/js/floatable/floatable.embedded.d.mts +2 -2
  6. package/dist/js/floatable/floatable.embedded.mjs +17 -16
  7. package/dist/js/floatable/floatable.standalone.d.mts +1 -1
  8. package/dist/js/{floatable.embedded-YxGwzgbE.d.mts → floatable.embedded-DUR8bQBK.d.mts} +1 -2
  9. package/dist/js/focus-trap/focus-trap.embedded.mjs +6 -5
  10. package/dist/js/index.d.mts +4 -3
  11. package/dist/js/index.mjs +6 -2
  12. package/dist/js/internal/attributable.mjs +3 -4
  13. package/dist/js/internal/draggable.d.mts +1 -1
  14. package/dist/js/internal/draggable.mjs +12 -9
  15. package/dist/js/internal/navigable.d.mts +32 -0
  16. package/dist/js/internal/navigable.mjs +107 -0
  17. package/dist/js/menu.d.mts +1 -0
  18. package/dist/js/menu.mjs +168 -0
  19. package/dist/js/movable/movable.embedded.d.mts +1 -1
  20. package/dist/js/movable/movable.embedded.mjs +8 -13
  21. package/dist/js/movable/movable.standalone.d.mts +1 -1
  22. package/dist/js/popover.d.mts +1 -1
  23. package/dist/js/popover.mjs +27 -12
  24. package/dist/js/resizable/resizable.embedded.d.mts +2 -0
  25. package/dist/js/resizable/resizable.embedded.mjs +191 -0
  26. package/dist/js/resizable/resizable.standalone.d.mts +2 -0
  27. package/dist/js/resizable/resizable.standalone.mjs +2 -0
  28. package/dist/js/resizable.embedded-CXrUVPzR.d.mts +35 -0
  29. package/dist/js/sortable/sortable.embedded.d.mts +1 -1
  30. package/dist/js/sortable/sortable.embedded.mjs +15 -13
  31. package/dist/js/sortable/sortable.standalone.d.mts +1 -1
  32. package/dist/js/splitter.mjs +30 -26
  33. package/dist/js/toolbar.mjs +12 -88
  34. package/dist/js/tooltip.d.mts +1 -1
  35. package/dist/js/tooltip.mjs +12 -17
  36. package/package.json +11 -3
  37. package/src/css/floatable.scss +9 -0
  38. package/src/css/form.scss +6 -6
  39. package/src/js/dialog.ts +50 -24
  40. package/src/js/floatable/floatable.embedded.ts +19 -18
  41. package/src/js/focus-trap/focus-trap.embedded.ts +6 -5
  42. package/src/js/index.ts +3 -1
  43. package/src/js/internal/attributable.ts +3 -5
  44. package/src/js/internal/draggable.ts +13 -10
  45. package/src/js/internal/navigable.ts +247 -0
  46. package/src/js/menu.ts +345 -0
  47. package/src/js/movable/movable.embedded.ts +10 -13
  48. package/src/js/popover.ts +41 -15
  49. package/src/js/resizable/resizable.embedded.ts +390 -0
  50. package/src/js/resizable/resizable.standalone.ts +5 -0
  51. package/src/js/sortable/sortable.embedded.ts +17 -22
  52. package/src/js/splitter.ts +41 -36
  53. package/src/js/toolbar.ts +27 -178
  54. package/src/js/tooltip.ts +18 -30
@@ -1,7 +1,10 @@
1
1
  import {isPlainObject} from '@oscarpalmer/atoms/is';
2
+ import {getAria} from '@oscarpalmer/toretto/aria';
3
+ import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
2
4
  import {on} from '@oscarpalmer/toretto/event';
3
5
  import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
4
6
  import type {RemovableEventListener} from '@oscarpalmer/toretto/models';
7
+ import {setStyle, setStyles} from '@oscarpalmer/toretto/style';
5
8
 
6
9
  // #region Types
7
10
 
@@ -45,13 +48,15 @@ export class OuiFloatable {
45
48
  const {anchor, content} = state;
46
49
 
47
50
  if (standalone) {
48
- content.setAttribute(ATTRIBUTE_FLOATABLE, '');
51
+ setAttribute(content, ATTRIBUTE_FLOATABLE, '');
49
52
 
50
53
  content.popover = 'manual';
54
+ } else {
55
+ content.popover ??= 'auto';
51
56
  }
52
57
 
53
- anchor.style.anchorName = state.name;
54
- content.style.positionAnchor = state.name;
58
+ setStyle(anchor, 'anchorName', state.name);
59
+ setStyle(content, 'positionAnchor', state.name);
55
60
  }
56
61
 
57
62
  /**
@@ -211,11 +216,11 @@ function createInstance(
211
216
  export function getOnBeforeToggleListener(element: HTMLElement): RemovableEventListener {
212
217
  return on(
213
218
  element,
214
- EVENT_BEFORE,
219
+ 'beforetoggle',
215
220
  event => {
216
221
  const {newState, source} = event;
217
222
 
218
- if (newState === FLOATABLE_STATE_OPEN && source?.getAttribute(ARIA_DISABLED) === TRUE) {
223
+ if (newState === 'open' && source != null && getAria(source, 'disabled') === 'true') {
219
224
  event.preventDefault();
220
225
  }
221
226
  },
@@ -248,9 +253,11 @@ function getPosition(
248
253
  return options.position;
249
254
  }
250
255
 
251
- const attribute = anchor.getAttribute(options.attribute) ?? '';
256
+ const attribute = getAttribute(anchor, options.attribute);
252
257
 
253
- return attribute in AREAS ? (attribute as OuiFloatablePosition) : options.position;
258
+ return attribute != null && attribute in AREAS
259
+ ? (attribute as OuiFloatablePosition)
260
+ : options.position;
254
261
  }
255
262
 
256
263
  function getState(
@@ -281,10 +288,12 @@ function setPosition(state: OuiFloatableState, override?: OuiFloatablePosition):
281
288
 
282
289
  const area = AREAS[position];
283
290
 
284
- state.content.style.positionAnchor = state.name;
285
- state.content.style.positionArea = area;
291
+ setAttribute(state.content, ATTRIBUTE_POSITION, POSITIONS[area]);
286
292
 
287
- state.content.setAttribute(ATTRIBUTE_POSITION, POSITIONS[area]);
293
+ setStyles(state.content, {
294
+ positionAnchor: state.name,
295
+ positionArea: area,
296
+ });
288
297
  }
289
298
 
290
299
  // #endregion
@@ -306,24 +315,16 @@ const AREAS: Record<OuiFloatablePosition, string> = {
306
315
  'start-top': 'span-end start',
307
316
  };
308
317
 
309
- const ARIA_DISABLED = 'aria-disabled';
310
-
311
318
  export const ATTRIBUTE_FLOATABLE = 'oui-floatable';
312
319
 
313
320
  const ATTRIBUTE_POSITION = 'oui-position';
314
321
 
315
- const EVENT_BEFORE = 'beforetoggle';
316
-
317
- export const FLOATABLE_STATE_OPEN = 'open';
318
-
319
322
  const MESSAGE = 'Anchor and content must be an HTMLElement or SVGElement';
320
323
 
321
324
  const POSITIONS = Object.fromEntries(
322
325
  Object.entries(AREAS).map(([position, area]) => [area, position]),
323
326
  ) as Record<string, OuiFloatablePosition>;
324
327
 
325
- const TRUE = 'true';
326
-
327
328
  const instances = new WeakMap<HTMLElement, OuiFloatable>();
328
329
 
329
330
  let index = 0;
@@ -1,5 +1,6 @@
1
1
  import {isPlainObject} from '@oscarpalmer/atoms/is';
2
2
  import {clamp} from '@oscarpalmer/atoms/number';
3
+ import {setAttribute} from '@oscarpalmer/toretto/attribute';
3
4
  import {on} from '@oscarpalmer/toretto/event';
4
5
  import {findAncestor} from '@oscarpalmer/toretto/find';
5
6
  import {getFocusable} from '@oscarpalmer/toretto/focusable';
@@ -26,9 +27,9 @@ export class OuiFocusTrap {
26
27
  */
27
28
  set contain(value: boolean) {
28
29
  if (value === true) {
29
- this.#state.element.setAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN, '');
30
+ setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_CONTAIN, '');
30
31
  } else if (value === false) {
31
- this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN);
32
+ setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_CONTAIN, undefined);
32
33
  }
33
34
  }
34
35
 
@@ -62,9 +63,9 @@ export class OuiFocusTrap {
62
63
  */
63
64
  set noescape(value: boolean) {
64
65
  if (value === true) {
65
- this.#state.element.setAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE, '');
66
+ setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_NOESCAPE, '');
66
67
  } else if (value === false) {
67
- this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE);
68
+ setAttribute(this.#state.element, ATTRIBUTE_FOCUSTRAP_NOESCAPE, undefined);
68
69
  }
69
70
  }
70
71
 
@@ -74,7 +75,7 @@ export class OuiFocusTrap {
74
75
 
75
76
  state.element.tabIndex = -1;
76
77
 
77
- state.element.setAttribute(ATTRIBUTE_FOCUSTRAP, '');
78
+ setAttribute(state.element, ATTRIBUTE_FOCUSTRAP, '');
78
79
 
79
80
  this.contain = state.options.contain;
80
81
  this.noescape = state.options.noescape;
package/src/js/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import './sortable/sortable.embedded';
1
+ import './menu';
2
2
  import './toolbar';
3
3
 
4
4
  export * from './dialog';
@@ -6,5 +6,7 @@ export * from './floatable/floatable.standalone';
6
6
  export * from './focus-trap/focus-trap.standalone';
7
7
  export * from './movable/movable.standalone';
8
8
  export * from './popover';
9
+ export * from './resizable/resizable.standalone';
10
+ export * from './sortable/sortable.standalone';
9
11
  export * from './splitter';
10
12
  export * from './tooltip';
@@ -1,5 +1,3 @@
1
- import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
2
-
3
1
  export function attributable(
4
2
  attribute: string,
5
3
  add: (element: HTMLElement) => void,
@@ -11,7 +9,7 @@ export function attributable(
11
9
  for (let index = 0; index < length; index += 1) {
12
10
  const entry = entries[index];
13
11
 
14
- if (entry.type === 'attributes' && isHTMLOrSVGElement(entry.target)) {
12
+ if (entry.type === 'attributes' && entry.target instanceof Element) {
15
13
  if (entry.target.hasAttribute(attribute)) {
16
14
  handleAdded(attribute, [entry.target], add);
17
15
  } else {
@@ -41,7 +39,7 @@ function handleAdded(
41
39
  nodes: Node[] | NodeList,
42
40
  add: (element: HTMLElement) => void,
43
41
  ): void {
44
- const elements = [...nodes].filter(isHTMLOrSVGElement) as HTMLElement[];
42
+ const elements = [...nodes].filter(node => node instanceof Element) as HTMLElement[];
45
43
 
46
44
  const {length} = elements;
47
45
 
@@ -59,7 +57,7 @@ function handleAdded(
59
57
  }
60
58
 
61
59
  function handleRemoved(nodes: Node[] | NodeList, remove: (element: HTMLElement) => void): void {
62
- const elements = [...nodes].filter(isHTMLOrSVGElement) as HTMLElement[];
60
+ const elements = [...nodes].filter(node => node instanceof Element) as HTMLElement[];
63
61
 
64
62
  const {length} = elements;
65
63
 
@@ -1,12 +1,13 @@
1
1
  import type {EventPosition, PlainObject} from '@oscarpalmer/atoms/models';
2
2
  import {clamp} from '@oscarpalmer/atoms/number';
3
+ import {getAttribute, setAttribute} from '@oscarpalmer/toretto/attribute';
3
4
  import {getPosition, on} from '@oscarpalmer/toretto/event';
4
5
  import {findAncestor} from '@oscarpalmer/toretto/find';
5
- import {toggleStyles, type StyleToggler} from '@oscarpalmer/toretto/style';
6
+ import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
7
+ import {setStyle, setStyles, toggleStyles, type StyleToggler} from '@oscarpalmer/toretto/style';
6
8
  import supportsTouch from '@oscarpalmer/toretto/touch';
7
9
  import type {OuiMovable} from '../movable/movable.embedded';
8
10
  import type {OuiSortable} from '../sortable/sortable.embedded';
9
- import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
10
11
 
11
12
  // #region Types
12
13
 
@@ -63,7 +64,7 @@ export abstract class OuiDraggable<ExtraState extends PlainObject = PlainObject>
63
64
  setContainer(item);
64
65
  setDirection(item);
65
66
 
66
- element.setAttribute(attribute, '');
67
+ setAttribute(element, attribute, '');
67
68
 
68
69
  let states = globals.states.get(element);
69
70
 
@@ -425,9 +426,11 @@ function onPointerdown(event: MouseEvent | TouchEvent): void {
425
426
 
426
427
  const next = getNextPosition(item, position);
427
428
 
428
- dragged.style.position = 'fixed';
429
- dragged.style.inset = `${next.y}px auto auto ${next.x}px`;
430
- dragged.style.transform = 'translate3d(0, 0, 0)';
429
+ setStyles(dragged, {
430
+ position: 'fixed',
431
+ inset: `${next.y}px auto auto ${next.x}px`,
432
+ transform: 'translate3d(0, 0, 0)',
433
+ });
431
434
 
432
435
  item.state.options.drag.onBegin?.(event, globals, item, element, handle, next);
433
436
 
@@ -450,7 +453,7 @@ function onPointermove(event: MouseEvent | TouchEvent): void {
450
453
  const next = getNextPosition(current, position);
451
454
 
452
455
  if (globals.element != null) {
453
- globals.element.node.style.inset = `${next.y}px auto auto ${next.x}px`;
456
+ setStyle(globals.element.node, 'inset', `${next.y}px auto auto ${next.x}px`);
454
457
  }
455
458
 
456
459
  const detail = current.state.options.drag.onMove(event, globals, current, {
@@ -529,7 +532,7 @@ function setContainer(item: OuiDraggableItem): void {
529
532
  }
530
533
 
531
534
  const selector =
532
- container ?? item.instance.element.getAttribute(item.state.options.container.attribute);
535
+ container ?? getAttribute(item.instance.element, item.state.options.container.attribute);
533
536
 
534
537
  if (typeof selector !== 'string') {
535
538
  return;
@@ -559,7 +562,7 @@ function setContainerElement(item: OuiDraggableItem, element: HTMLElement): void
559
562
  }
560
563
 
561
564
  function setDirection(item: OuiDraggableItem): void {
562
- const direction = item.state.element.getAttribute(item.state.options.direction.attribute);
565
+ const direction = getAttribute(item.state.element, item.state.options.direction.attribute);
563
566
 
564
567
  if (horizontals.has(direction as OuiDraggableDirection)) {
565
568
  item.state.vertical = false;
@@ -650,7 +653,7 @@ on(document, 'keydown', onKeydown);
650
653
  on(document, 'mousedown', onPointerdown);
651
654
  on(document, 'pointermove', onPointermove);
652
655
  on(document, 'pointerup', onPointerup);
653
- on(document, 'touchcancel', onPointerup, {passive: false});
656
+ on(document, 'touchcancel', onPointerup);
654
657
  on(document, 'touchstart', onPointerdown, {passive: false});
655
658
 
656
659
  // #endregion
@@ -0,0 +1,247 @@
1
+ import {clamp} from '@oscarpalmer/atoms/number';
2
+ import {getAria, setRole} from '@oscarpalmer/toretto/aria';
3
+ import {on} from '@oscarpalmer/toretto/event';
4
+ import {findAncestor} from '@oscarpalmer/toretto/find';
5
+ import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
6
+ import type {AriaRole, RemovableEventListener} from '@oscarpalmer/toretto/models';
7
+
8
+ // #region Types
9
+
10
+ export class OuiNavigable {
11
+ active: OuiNavigableActive = {
12
+ index: 0,
13
+ };
14
+
15
+ element: HTMLElement;
16
+
17
+ listeners: RemovableEventListener[];
18
+
19
+ options: OuiNavigableOptions;
20
+
21
+ orientation: OuiNavigableOrientation;
22
+
23
+ constructor(element: HTMLElement, options: OuiNavigableOptions) {
24
+ this.element = element;
25
+ this.options = options;
26
+
27
+ this.listeners = [
28
+ on(element, 'focusin', event => {
29
+ onFocusin(this, event);
30
+ }),
31
+ on(element, 'keydown', event => {
32
+ onKeydown(this, event);
33
+ }),
34
+ ];
35
+
36
+ this.orientation = getOrientation(element, options);
37
+
38
+ if (options.role != null) {
39
+ setRole(element, options.role);
40
+ }
41
+ }
42
+
43
+ destroy(): void {
44
+ const listeners = this.listeners.splice(0);
45
+
46
+ for (const listener of listeners) {
47
+ listener();
48
+ }
49
+
50
+ this.active.element = undefined;
51
+ this.element = undefined as never;
52
+ }
53
+ }
54
+
55
+ type OuiNavigableActive = {
56
+ element?: HTMLElement;
57
+ index: number;
58
+ };
59
+
60
+ export type OuiNavigableOptions = {
61
+ role?: AriaRole;
62
+ selector: string;
63
+ vertical: boolean;
64
+ onDeactivate?: (event: KeyboardEvent, navigable: OuiNavigable) => void;
65
+ onPreventNavigation?: (event: KeyboardEvent, navigable: OuiNavigable) => boolean;
66
+ onShouldActivate?: (event: KeyboardEvent, navigable: OuiNavigable) => boolean;
67
+ onShouldDeactivate?: (event: KeyboardEvent, navigable: OuiNavigable) => boolean | undefined;
68
+ };
69
+
70
+ type OuiNavigableOrientation = 'horizontal' | 'vertical';
71
+
72
+ // #endregion
73
+
74
+ // #region Functions
75
+
76
+ function getItems(container: HTMLElement, selector: string): HTMLElement[] {
77
+ return [...container.querySelectorAll(selector)].filter(isValidItem);
78
+ }
79
+
80
+ export function getNavigable(element: HTMLElement, options: OuiNavigableOptions): OuiNavigable {
81
+ return new OuiNavigable(element, options);
82
+ }
83
+
84
+ function getOrientation(
85
+ element: HTMLElement,
86
+ options: OuiNavigableOptions,
87
+ ): OuiNavigableOrientation {
88
+ const attribute = getAria(element, 'orientation');
89
+
90
+ return ORIENTATIONS.has(attribute as OuiNavigableOrientation)
91
+ ? (attribute as OuiNavigableOrientation)
92
+ : options.vertical
93
+ ? ORIENTATION_VERTICAL
94
+ : ORIENTATION_HORIZONTAL;
95
+ }
96
+
97
+ function isValidItem(element: Element): element is HTMLElement {
98
+ return 'disabled' in element ? element.disabled !== true : true;
99
+ }
100
+
101
+ function onFocusin(navigable: OuiNavigable, event: FocusEvent): void {
102
+ const item = findAncestor(event, navigable.options.selector);
103
+
104
+ if (!isHTMLOrSVGElement(item) || !isValidItem(item)) {
105
+ return;
106
+ }
107
+
108
+ const items = getItems(navigable.element, navigable.options.selector);
109
+ const index = items.indexOf(item);
110
+
111
+ if (index === -1) {
112
+ return;
113
+ }
114
+
115
+ navigable.active.element = item;
116
+ navigable.active.index = index;
117
+
118
+ updateNavigableFocus(navigable, false, items);
119
+ }
120
+
121
+ function onKeydown(navigable: OuiNavigable, event: KeyboardEvent): void {
122
+ const escaped = event.key === 'Escape';
123
+ const stopPropagation = navigable.options.onShouldDeactivate?.(event, navigable);
124
+
125
+ if (escaped || stopPropagation != null) {
126
+ if (escaped || stopPropagation) {
127
+ event.stopPropagation();
128
+ }
129
+
130
+ navigable.options.onDeactivate?.(event, navigable);
131
+
132
+ return;
133
+ }
134
+
135
+ if (!KEYS_ALL.has(event.key)) {
136
+ return;
137
+ }
138
+
139
+ const mustActivate = KEYS_ACTIVATE.has(event.key);
140
+ const shouldActivate = navigable.options.onShouldActivate?.(event, navigable) === true;
141
+
142
+ if (
143
+ mustActivate ||
144
+ shouldActivate ||
145
+ navigable.options.onPreventNavigation?.(event, navigable) === true
146
+ ) {
147
+ event.stopPropagation();
148
+ }
149
+
150
+ if (mustActivate || shouldActivate) {
151
+ return;
152
+ }
153
+
154
+ const items = getItems(navigable.element, navigable.options.selector);
155
+ const {length} = items;
156
+
157
+ if (length === 0) {
158
+ return;
159
+ }
160
+
161
+ let index: number | undefined;
162
+
163
+ if (KEYS_ABSOLUTE.has(event.key)) {
164
+ index = event.key === 'Home' ? 0 : items.length - 1;
165
+ } else {
166
+ const direction = NAVIGABLE_KEYS_HORIZONTAL.has(event.key)
167
+ ? ORIENTATION_HORIZONTAL
168
+ : ORIENTATION_VERTICAL;
169
+
170
+ if (navigable.orientation === direction) {
171
+ if (navigable.active.element instanceof HTMLSelectElement) {
172
+ event.preventDefault();
173
+ }
174
+
175
+ index = clamp(
176
+ navigable.active.index + (KEYS_NEXT.has(event.key) ? 1 : -1),
177
+ 0,
178
+ length - 1,
179
+ true,
180
+ );
181
+ }
182
+ }
183
+
184
+ if (index == null || index === navigable.active.index) {
185
+ return;
186
+ }
187
+
188
+ navigable.active.element = items[index];
189
+ navigable.active.index = index;
190
+
191
+ updateNavigableFocus(navigable, true, items);
192
+ }
193
+
194
+ export function updateNavigableFocus(
195
+ navigable: OuiNavigable,
196
+ focus: boolean,
197
+ items?: HTMLElement[],
198
+ ): void {
199
+ const updated = items ?? getItems(navigable.element, navigable.options.selector);
200
+ const {length} = updated;
201
+
202
+ if (length === 0) {
203
+ return;
204
+ }
205
+
206
+ for (let index = 0; index < length; index += 1) {
207
+ updated[index].tabIndex = index === navigable.active.index ? 0 : -1;
208
+ }
209
+
210
+ navigable.active.element ??= updated[navigable.active.index];
211
+
212
+ if (focus) {
213
+ navigable.active.element?.focus();
214
+ }
215
+ }
216
+
217
+ // #endregion
218
+
219
+ // #region Variables
220
+
221
+ const KEYS_ABSOLUTE = new Set(['End', 'Home']);
222
+
223
+ const KEYS_ACTIVATE = new Set(['Enter', ' ']);
224
+
225
+ export const NAVIGABLE_KEYS_HORIZONTAL = new Set(['ArrowRight', 'ArrowLeft']);
226
+
227
+ export const NAVIGABLE_KEYS_VERTICAL = new Set(['ArrowDown', 'ArrowUp']);
228
+
229
+ const KEYS_ALL = new Set([
230
+ ...KEYS_ABSOLUTE,
231
+ ...KEYS_ACTIVATE,
232
+ ...NAVIGABLE_KEYS_HORIZONTAL,
233
+ ...NAVIGABLE_KEYS_VERTICAL,
234
+ ]);
235
+
236
+ const KEYS_NEXT = new Set(['ArrowDown', 'ArrowRight']);
237
+
238
+ const ORIENTATION_HORIZONTAL: OuiNavigableOrientation = 'horizontal';
239
+
240
+ const ORIENTATION_VERTICAL: OuiNavigableOrientation = 'vertical';
241
+
242
+ const ORIENTATIONS = new Set<OuiNavigableOrientation>([
243
+ ORIENTATION_HORIZONTAL,
244
+ ORIENTATION_VERTICAL,
245
+ ]);
246
+
247
+ // #endregion