@oscarpalmer/oui 0.25.0 → 0.26.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 (40) hide show
  1. package/dist/js/embedded-CHK82Uh5.d.mts +76 -0
  2. package/dist/js/{embedded-84gxpReS.d.mts → embedded-ai6cqURc.d.mts} +21 -17
  3. package/dist/js/floatable/embedded.d.mts +2 -2
  4. package/dist/js/floatable/embedded.mjs +27 -16
  5. package/dist/js/floatable/standalone.d.mts +2 -2
  6. package/dist/js/floatable/standalone.mjs +2 -2
  7. package/dist/js/focus-trap/embedded.d.mts +2 -2
  8. package/dist/js/focus-trap/embedded.mjs +157 -79
  9. package/dist/js/focus-trap/standalone.d.mts +2 -1
  10. package/dist/js/focus-trap/standalone.mjs +3 -3
  11. package/dist/js/index.d.mts +3 -2
  12. package/dist/js/index.mjs +4 -2
  13. package/dist/js/internal/draggable.d.mts +2 -2
  14. package/dist/js/internal/draggable.mjs +2 -2
  15. package/dist/js/{movable-BKFgoaOl.d.mts → movable-dNqBctx3.d.mts} +16 -16
  16. package/dist/js/movable.d.mts +2 -2
  17. package/dist/js/movable.mjs +4 -4
  18. package/dist/js/popover.d.mts +3 -3
  19. package/dist/js/popover.mjs +9 -9
  20. package/dist/js/sortable.d.mts +2 -2
  21. package/dist/js/sortable.mjs +4 -4
  22. package/dist/js/splitter.mjs +48 -47
  23. package/dist/js/toolbar.d.mts +1 -0
  24. package/dist/js/toolbar.mjs +107 -0
  25. package/dist/js/tooltip.d.mts +1 -1
  26. package/dist/js/tooltip.mjs +7 -7
  27. package/package.json +13 -1
  28. package/src/js/floatable/embedded.ts +65 -44
  29. package/src/js/floatable/standalone.ts +1 -1
  30. package/src/js/focus-trap/embedded.ts +219 -93
  31. package/src/js/focus-trap/standalone.ts +4 -2
  32. package/src/js/index.ts +1 -0
  33. package/src/js/internal/draggable.ts +20 -20
  34. package/src/js/movable.ts +17 -17
  35. package/src/js/popover.ts +18 -18
  36. package/src/js/sortable.ts +26 -26
  37. package/src/js/splitter.ts +98 -96
  38. package/src/js/toolbar.ts +214 -0
  39. package/src/js/tooltip.ts +14 -10
  40. package/dist/js/embedded-BpwzMSEF.d.mts +0 -26
@@ -0,0 +1,76 @@
1
+ //#region src/js/focus-trap/embedded.d.ts
2
+ declare class OuiFocusTrap {
3
+ #private;
4
+ /**
5
+ * Is focused maintained within the _FocusTrap_ when clicking outside of it?
6
+ */
7
+ get contain(): boolean;
8
+ /**
9
+ * Should focus be maintained within the _FocusTrap_ when clicking outside of it?
10
+ */
11
+ set contain(value: boolean);
12
+ /**
13
+ * Is the _FocusTrap_ disabled?
14
+ */
15
+ get disabled(): boolean;
16
+ /**
17
+ * Should the _FocusTrap_ be disabled?
18
+ */
19
+ set disabled(value: boolean);
20
+ /**
21
+ * Is focus allowed to escape when pressing _Escape_ within the _FocusTrap_?
22
+ */
23
+ get noescape(): boolean;
24
+ /**
25
+ * Should the _FocusTrap_ allow focus to escape when pressing _Escape_?
26
+ */
27
+ set noescape(value: boolean);
28
+ constructor(state: OuiFocusTrapState);
29
+ /**
30
+ * Destroys the _FocusTrap_
31
+ */
32
+ destroy(): void;
33
+ /**
34
+ * Disables the _FocusTrap_
35
+ */
36
+ disable(): void;
37
+ /**
38
+ * Enables the _FocusTrap_
39
+ */
40
+ enable(): void;
41
+ /**
42
+ * Focuses the _FocusTrap_
43
+ *
44
+ * @param last When `true`, focuses the last focusable element within the _FocusTrap_ instead of the first
45
+ */
46
+ focus(last: boolean): void;
47
+ }
48
+ type OuiFocusTrapOptions = {
49
+ /**
50
+ * Should focus be maintained within the _FocusTrap_ when clicking outside of it?
51
+ */
52
+ contain?: boolean;
53
+ /**
54
+ * Should the _FocusTrap_ allow focus to escape when pressing _Escape_?
55
+ */
56
+ noescape?: boolean;
57
+ };
58
+ type OuiFocusTrapState = {
59
+ disabled: boolean;
60
+ element: HTMLElement;
61
+ options: Required<OuiFocusTrapOptions>;
62
+ };
63
+ /**
64
+ * Creates _(or retrieves)_ a _FocusTrap_ for an element
65
+ *
66
+ * @param element Element to trap focus within
67
+ * @param options _FocusTrap_ options
68
+ * @returns _FocusTrap_ instance
69
+ */
70
+ declare function createFocusTrap(element: HTMLElement, options?: OuiFocusTrapOptions): OuiFocusTrap;
71
+ declare function removeFocusTrap(element: HTMLElement): void;
72
+ declare const ATTRIBUTE_FOCUSTRAP = "oui-focus-trap";
73
+ declare const ATTRIBUTE_FOCUSTRAP_CONTAIN = "oui-focus-trap-contain";
74
+ declare const ATTRIBUTE_FOCUSTRAP_NOESCAPE = "oui-focus-trap-noescape";
75
+ //#endregion
76
+ export { createFocusTrap as a, OuiFocusTrap as i, ATTRIBUTE_FOCUSTRAP_CONTAIN as n, removeFocusTrap as o, ATTRIBUTE_FOCUSTRAP_NOESCAPE as r, ATTRIBUTE_FOCUSTRAP as t };
@@ -1,12 +1,26 @@
1
1
  import { RemovableEventListener } from "@oscarpalmer/toretto/models";
2
2
 
3
3
  //#region src/js/floatable/embedded.d.ts
4
+ type CreateOuiFloatableOptions = {
5
+ /**
6
+ * Open the _OuiFloatable_ when created? _(defaults to `true`)_
7
+ */
8
+ open?: boolean;
9
+ /**
10
+ * Position of the _OuiFloatable_ _(defaults to `below`)_
11
+ */
12
+ position?: OuiFloatablePosition;
13
+ };
4
14
  declare class OuiFloatable {
5
15
  #private;
6
16
  /**
7
- * Is the _Floatable_ open?
17
+ * Is the _OuiFloatable_ open?
8
18
  */
9
19
  get open(): boolean;
20
+ /**
21
+ * Open or close the _OuiFloatable_
22
+ */
23
+ set open(value: boolean);
10
24
  constructor(state: OuiFloatableState, standalone: boolean);
11
25
  /**
12
26
  * Destroy the _OuiFloatable_, removing it from the DOM and cleaning up references
@@ -37,28 +51,18 @@ type OuiFloatableState = {
37
51
  content: HTMLElement;
38
52
  options: OuiFloatableOptions;
39
53
  };
40
- type GetOuiFloatableOptions = {
41
- /**
42
- * Open the _OuiFloatable_ when created? _(defaults to `true`)_
43
- */
44
- open?: boolean;
45
- /**
46
- * Position of the _OuiFloatable_ _(defaults to `below`)_
47
- */
48
- position?: OuiFloatablePosition;
49
- };
50
- declare function createFloatable(anchor: HTMLElement, content: HTMLElement, options: OuiFloatableOptions, standalone: boolean): OuiFloatable;
54
+ declare function createEmbeddedFloatable(anchor: HTMLElement, content: HTMLElement, options: OuiFloatableOptions): OuiFloatable;
51
55
  /**
52
- * Create a _Floatable_ for an anchor and content element
56
+ * Create a _OuiFloatable_ for an anchor and content element
53
57
  *
54
58
  * @param anchor Anchor element
55
59
  * @param content Content element
56
- * @param options _Floatable_ options
57
- * @returns _Floatable_ instance
60
+ * @param options _OuiFloatable_ options
61
+ * @returns _OuiFloatable_ instance
58
62
  */
59
- declare function getFloatable(anchor: HTMLElement | SVGElement, content: HTMLElement | SVGElement, options?: GetOuiFloatableOptions): OuiFloatable;
63
+ declare function createFloatable(anchor: HTMLElement, content: HTMLElement, options?: CreateOuiFloatableOptions): OuiFloatable;
60
64
  declare function getOnBeforeToggleListener(element: HTMLElement): RemovableEventListener;
61
65
  declare function removeFloatable(content: HTMLElement): void;
62
66
  declare const ATTRIBUTE_FLOATABLE = "oui-floatable";
63
67
  //#endregion
64
- export { createFloatable as a, removeFloatable as c, OuiFloatablePosition as i, OuiFloatable as n, getFloatable as o, OuiFloatableOptions as r, getOnBeforeToggleListener as s, ATTRIBUTE_FLOATABLE as t };
68
+ export { createEmbeddedFloatable as a, removeFloatable as c, OuiFloatablePosition as i, OuiFloatable as n, createFloatable as o, OuiFloatableOptions as r, getOnBeforeToggleListener as s, ATTRIBUTE_FLOATABLE as t };
@@ -1,2 +1,2 @@
1
- import { a as createFloatable, c as removeFloatable, i as OuiFloatablePosition, n as OuiFloatable, o as getFloatable, r as OuiFloatableOptions, s as getOnBeforeToggleListener, t as ATTRIBUTE_FLOATABLE } from "../embedded-84gxpReS.mjs";
2
- export { ATTRIBUTE_FLOATABLE, OuiFloatable, OuiFloatableOptions, OuiFloatablePosition, createFloatable, getFloatable, getOnBeforeToggleListener, removeFloatable };
1
+ import { a as createEmbeddedFloatable, c as removeFloatable, i as OuiFloatablePosition, n as OuiFloatable, o as createFloatable, r as OuiFloatableOptions, s as getOnBeforeToggleListener, t as ATTRIBUTE_FLOATABLE } from "../embedded-ai6cqURc.mjs";
2
+ export { ATTRIBUTE_FLOATABLE, OuiFloatable, OuiFloatableOptions, OuiFloatablePosition, createEmbeddedFloatable, createFloatable, getOnBeforeToggleListener, removeFloatable };
@@ -6,11 +6,18 @@ var OuiFloatable = class {
6
6
  #destroyed = false;
7
7
  #state;
8
8
  /**
9
- * Is the _Floatable_ open?
9
+ * Is the _OuiFloatable_ open?
10
10
  */
11
11
  get open() {
12
12
  return this.#state.content.checkVisibility();
13
13
  }
14
+ /**
15
+ * Open or close the _OuiFloatable_
16
+ */
17
+ set open(value) {
18
+ if (value === true) this.show();
19
+ else if (value === false) this.hide();
20
+ }
14
21
  constructor(state, standalone) {
15
22
  this.#state = state;
16
23
  const { anchor, content } = state;
@@ -53,36 +60,39 @@ var OuiFloatable = class {
53
60
  if (!this.#destroyed) setPosition(this.#state, position);
54
61
  }
55
62
  };
56
- function createFloatable(anchor, content, options, standalone) {
57
- if (!isHTMLOrSVGElement(anchor) || !isHTMLOrSVGElement(content)) throw new TypeError("Anchor and content must be an HTMLElement or SVGElement.");
58
- let floatable = instances.get(content);
59
- if (floatable == null) {
60
- floatable = new OuiFloatable(getState(anchor, content, options), standalone);
61
- instances.set(content, floatable);
62
- }
63
- return floatable;
64
- }
65
63
  function getAnchorName(anchor) {
66
64
  let { anchorName } = anchor.style;
67
65
  if (anchorName.length > 0) return anchorName;
68
66
  index += 1;
69
67
  return `--oui-floatable-anchor-${index}`;
70
68
  }
69
+ function createEmbeddedFloatable(anchor, content, options) {
70
+ return createInstance(anchor, content, options, false);
71
+ }
71
72
  /**
72
- * Create a _Floatable_ for an anchor and content element
73
+ * Create a _OuiFloatable_ for an anchor and content element
73
74
  *
74
75
  * @param anchor Anchor element
75
76
  * @param content Content element
76
- * @param options _Floatable_ options
77
- * @returns _Floatable_ instance
77
+ * @param options _OuiFloatable_ options
78
+ * @returns _OuiFloatable_ instance
78
79
  */
79
- function getFloatable(anchor, content, options) {
80
+ function createFloatable(anchor, content, options) {
80
81
  const { open, position } = getOptions(options);
81
- const floatable = createFloatable(anchor, content, { position }, true);
82
+ const floatable = createInstance(anchor, content, { position }, true);
82
83
  floatable?.update(position);
83
84
  if (open) floatable?.show();
84
85
  return floatable;
85
86
  }
87
+ function createInstance(anchor, content, options, standalone) {
88
+ if (!isHTMLOrSVGElement(anchor) || !isHTMLOrSVGElement(content)) throw new TypeError(MESSAGE);
89
+ let floatable = instances.get(content);
90
+ if (floatable == null) {
91
+ floatable = new OuiFloatable(getState(anchor, content, options), standalone);
92
+ instances.set(content, floatable);
93
+ }
94
+ return floatable;
95
+ }
86
96
  function getOnBeforeToggleListener(element) {
87
97
  return on(element, EVENT_BEFORE, (event) => {
88
98
  const { newState, source } = event;
@@ -137,10 +147,11 @@ const ARIA_DISABLED = "aria-disabled";
137
147
  const ATTRIBUTE_FLOATABLE = "oui-floatable";
138
148
  const ATTRIBUTE_POSITION = "oui-position";
139
149
  const EVENT_BEFORE = "beforetoggle";
150
+ const MESSAGE = "Anchor and content must be an HTMLElement or SVGElement";
140
151
  const POSITIONS = Object.fromEntries(Object.entries(AREAS).map(([position, area]) => [area, position]));
141
152
  const STATE_OPEN = "open";
142
153
  const TRUE = "true";
143
154
  const instances = /* @__PURE__ */ new WeakMap();
144
155
  let index = 0;
145
156
  //#endregion
146
- export { ATTRIBUTE_FLOATABLE, OuiFloatable, createFloatable, getFloatable, getOnBeforeToggleListener, removeFloatable };
157
+ export { ATTRIBUTE_FLOATABLE, OuiFloatable, createEmbeddedFloatable, createFloatable, getOnBeforeToggleListener, removeFloatable };
@@ -1,2 +1,2 @@
1
- import { i as OuiFloatablePosition, n as OuiFloatable, o as getFloatable } from "../embedded-84gxpReS.mjs";
2
- export { type OuiFloatable, type OuiFloatablePosition, getFloatable };
1
+ import { i as OuiFloatablePosition, n as OuiFloatable, o as createFloatable } from "../embedded-ai6cqURc.mjs";
2
+ export { type OuiFloatable, type OuiFloatablePosition, createFloatable };
@@ -1,2 +1,2 @@
1
- import { getFloatable } from "./embedded.mjs";
2
- export { getFloatable };
1
+ import { createFloatable } from "./embedded.mjs";
2
+ export { createFloatable };
@@ -1,2 +1,2 @@
1
- import { a as createFocusTrap, i as FocusTrap, n as FOCUS_TRAP_NOESCAPE, o as removeFocusTrap, r as FOCUS_TRAP_SELECTOR, t as FOCUS_TRAP_CONTAIN } from "../embedded-BpwzMSEF.mjs";
2
- export { FOCUS_TRAP_CONTAIN, FOCUS_TRAP_NOESCAPE, FOCUS_TRAP_SELECTOR, FocusTrap, createFocusTrap, removeFocusTrap };
1
+ import { a as createFocusTrap, i as OuiFocusTrap, n as ATTRIBUTE_FOCUSTRAP_CONTAIN, o as removeFocusTrap, r as ATTRIBUTE_FOCUSTRAP_NOESCAPE, t as ATTRIBUTE_FOCUSTRAP } from "../embedded-CHK82Uh5.mjs";
2
+ export { ATTRIBUTE_FOCUSTRAP, ATTRIBUTE_FOCUSTRAP_CONTAIN, ATTRIBUTE_FOCUSTRAP_NOESCAPE, OuiFocusTrap, createFocusTrap, removeFocusTrap };
@@ -1,67 +1,144 @@
1
1
  import { on } from "@oscarpalmer/toretto/event";
2
+ import { isPlainObject } from "@oscarpalmer/atoms/is";
3
+ import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
2
4
  import { clamp } from "@oscarpalmer/atoms/number";
3
5
  import { findAncestor } from "@oscarpalmer/toretto/find";
4
6
  import { getFocusable } from "@oscarpalmer/toretto/focusable";
5
7
  //#region src/js/focus-trap/embedded.ts
6
- var FocusTrap = class {
7
- disabled = false;
8
- connected = true;
9
- element;
10
- embedded;
8
+ var OuiFocusTrap = class {
9
+ #destroyed = false;
10
+ #tabIndex;
11
+ #state;
12
+ /**
13
+ * Is focused maintained within the _FocusTrap_ when clicking outside of it?
14
+ */
11
15
  get contain() {
12
- return this.element.hasAttribute(FOCUS_TRAP_CONTAIN);
13
- }
16
+ return this.#state.element.hasAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN);
17
+ }
18
+ /**
19
+ * Should focus be maintained within the _FocusTrap_ when clicking outside of it?
20
+ */
21
+ set contain(value) {
22
+ if (value === true) this.#state.element.setAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN, "");
23
+ else if (value === false) this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN);
24
+ }
25
+ /**
26
+ * Is the _FocusTrap_ disabled?
27
+ */
28
+ get disabled() {
29
+ return this.#state.disabled;
30
+ }
31
+ /**
32
+ * Should the _FocusTrap_ be disabled?
33
+ */
34
+ set disabled(value) {
35
+ if (value === true) this.disable();
36
+ else if (value === false) this.enable();
37
+ }
38
+ /**
39
+ * Is focus allowed to escape when pressing _Escape_ within the _FocusTrap_?
40
+ */
14
41
  get noescape() {
15
- return this.element.hasAttribute(FOCUS_TRAP_NOESCAPE);
16
- }
17
- constructor(element, options) {
18
- this.element = element;
19
- this.embedded = options != null;
20
- element.setAttribute("tabindex", "-1");
21
- if (options != null) element.setAttribute(FOCUS_TRAP_SELECTOR, "");
22
- if (options?.noescape) element.setAttribute(FOCUS_TRAP_NOESCAPE, "");
23
- }
24
- connect() {
25
- setConnected(this, true);
26
- }
42
+ return this.#state.element.hasAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE);
43
+ }
44
+ /**
45
+ * Should the _FocusTrap_ allow focus to escape when pressing _Escape_?
46
+ */
47
+ set noescape(value) {
48
+ if (value === true) this.#state.element.setAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE, "");
49
+ else if (value === false) this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE);
50
+ }
51
+ constructor(state) {
52
+ this.#state = state;
53
+ this.#tabIndex = state.element.tabIndex;
54
+ state.element.tabIndex = -1;
55
+ state.element.setAttribute(ATTRIBUTE_FOCUSTRAP, "");
56
+ this.contain = state.options.contain;
57
+ this.noescape = state.options.noescape;
58
+ states.set(this, state);
59
+ }
60
+ /**
61
+ * Destroys the _FocusTrap_
62
+ */
27
63
  destroy() {
28
- this.element = void 0;
29
- }
64
+ if (this.#destroyed) return;
65
+ this.#destroyed = true;
66
+ disabled.delete(this);
67
+ instances.delete(this.#state.element);
68
+ states.delete(this);
69
+ this.#state.element.tabIndex = this.#tabIndex;
70
+ this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP);
71
+ this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN);
72
+ this.#state.element.removeAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE);
73
+ this.#state.element = void 0;
74
+ }
75
+ /**
76
+ * Disables the _FocusTrap_
77
+ */
30
78
  disable() {
31
- if (!(this.disabled || this.noescape)) setDisabled(this, true);
32
- }
33
- disconnect() {
34
- setConnected(this, false);
79
+ if (!this.#destroyed && !(this.disabled || this.#state.options.noescape)) setDisabled(this, this.#state, true);
35
80
  }
81
+ /**
82
+ * Enables the _FocusTrap_
83
+ */
36
84
  enable() {
37
- if (this.disabled) setDisabled(this, false);
85
+ if (!this.#destroyed && this.disabled) setDisabled(this, this.#state, false);
38
86
  }
87
+ /**
88
+ * Focuses the _FocusTrap_
89
+ *
90
+ * @param last When `true`, focuses the last focusable element within the _FocusTrap_ instead of the first
91
+ */
39
92
  focus(last) {
40
- tabToTrap(this, getFocusable(this.element), this.element, last ? -1 : 0);
93
+ if (!this.#destroyed && !this.disabled) tabToTrap(this, getFocusable(this.#state.element), this.#state.element, last ? -1 : 0);
41
94
  }
42
95
  };
96
+ /**
97
+ * Creates _(or retrieves)_ a _FocusTrap_ for an element
98
+ *
99
+ * @param element Element to trap focus within
100
+ * @param options _FocusTrap_ options
101
+ * @returns _FocusTrap_ instance
102
+ */
43
103
  function createFocusTrap(element, options) {
44
- let focusTrap = FOCUSTRAPS_ALL.get(element);
45
- if (focusTrap == null) {
46
- focusTrap = new FocusTrap(element, options);
47
- FOCUSTRAPS_ALL.set(element, focusTrap);
104
+ if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE);
105
+ let instance = instances.get(element);
106
+ if (instance == null) {
107
+ instance = new OuiFocusTrap(getState(element, options));
108
+ instances.set(element, instance);
48
109
  }
49
- return focusTrap;
110
+ return instance;
111
+ }
112
+ function getOptions(element, input) {
113
+ const options = isPlainObject(input) ? input : {};
114
+ return {
115
+ contain: typeof options.contain === "boolean" ? options.contain : element.hasAttribute(ATTRIBUTE_FOCUSTRAP_CONTAIN),
116
+ noescape: typeof options.noescape === "boolean" ? options.noescape : element.hasAttribute(ATTRIBUTE_FOCUSTRAP_NOESCAPE)
117
+ };
118
+ }
119
+ function getState(element, options) {
120
+ return {
121
+ element,
122
+ disabled: false,
123
+ options: getOptions(element, options)
124
+ };
50
125
  }
51
126
  function onEscape(event) {
52
- let element = findAncestor(event, ATTRIBUTE_SELECTOR);
53
- let focusTrap = FOCUSTRAPS_ALL.get(element);
54
- if (element == null || focusTrap == null) return;
55
- while (focusTrap.disabled) {
56
- element = findAncestor(focusTrap.element.parentElement, ATTRIBUTE_SELECTOR);
57
- focusTrap = FOCUSTRAPS_ALL.get(element);
58
- if (element == null || focusTrap == null) return;
59
- if (!focusTrap.disabled) break;
60
- }
61
- focusTrap?.disable();
127
+ let element = findAncestor(event, SELECTOR);
128
+ let instance = instances.get(element);
129
+ let state = states.get(instance);
130
+ if (element == null || instance == null || state == null) return;
131
+ while (state.disabled) {
132
+ element = findAncestor(state.element.parentElement, SELECTOR);
133
+ instance = instances.get(element);
134
+ state = states.get(instance);
135
+ if (element == null || instance == null || state == null) return;
136
+ if (!state.disabled) break;
137
+ }
138
+ instance?.disable();
62
139
  }
63
140
  function onFocusIn(event) {
64
- lastTarget = FOCUSTRAPS_ALL.get(findAncestor(event, ATTRIBUTE_SELECTOR)) == null ? void 0 : event.target;
141
+ lastTarget = instances.get(findAncestor(event, SELECTOR)) == null ? void 0 : event.target;
65
142
  }
66
143
  function onKeydown(event) {
67
144
  switch (event.key) {
@@ -75,82 +152,83 @@ function onKeydown(event) {
75
152
  }
76
153
  }
77
154
  function onPointerdown(event) {
78
- const lastFocusTrap = findAncestor(lastTarget, ATTRIBUTE_SELECTOR);
79
- const nextFocusTrap = findAncestor(event, ATTRIBUTE_SELECTOR);
80
- if (lastFocusTrap != null && nextFocusTrap !== lastFocusTrap) {
81
- if (FOCUSTRAPS_ALL.get(lastFocusTrap)?.contain ?? false) {
155
+ const last = findAncestor(lastTarget, SELECTOR);
156
+ const next = findAncestor(event, SELECTOR);
157
+ if (last != null && next !== last) {
158
+ if (states.get(instances.get(last))?.options.contain ?? false) {
82
159
  event.preventDefault();
83
160
  lastTarget?.focus();
84
161
  }
85
162
  }
86
- if (FOCUSTRAPS_DISABLED.size === 0) return;
87
- for (const focusTrap of FOCUSTRAPS_DISABLED) if (focusTrap.element !== nextFocusTrap) focusTrap.enable();
163
+ if (disabled.size === 0) return;
164
+ for (const focusTrap of disabled) {
165
+ const state = states.get(focusTrap);
166
+ if (state != null && state.element !== next) focusTrap.enable();
167
+ }
88
168
  }
89
169
  function onTab(event) {
90
- const element = findAncestor(event, ATTRIBUTE_SELECTOR);
91
- const focusTrap = FOCUSTRAPS_ALL.get(element);
92
- if (focusTrap == null) return;
93
- if (!focusTrap.disabled) event.preventDefault();
170
+ const element = findAncestor(event, SELECTOR);
171
+ const instance = instances.get(element);
172
+ if (instance == null) return;
173
+ if (!instance.disabled) event.preventDefault();
94
174
  const elements = getFocusable(element);
95
175
  const index = elements.indexOf(event.target);
96
- if (index === -1 || elements.length === 0) tabToTrap(focusTrap, elements, element);
97
- else tabToElement(focusTrap, elements, index, event.shiftKey ? -1 : 1);
176
+ if (index === -1 || elements.length === 0) tabToTrap(instance, elements, element);
177
+ else tabToElement(instance, elements, index, event.shiftKey ? -1 : 1);
98
178
  }
99
179
  function removeFocusTrap(element) {
100
- FOCUSTRAPS_ALL.get(element)?.destroy();
101
- FOCUSTRAPS_ALL.delete(element);
102
- }
103
- function setConnected(focusTrap, value) {
104
- if (!focusTrap.embedded || focusTrap.connected === value) return;
105
- focusTrap.connected = value;
180
+ instances.get(element)?.destroy();
181
+ instances.delete(element);
106
182
  }
107
- function setDisabled(focusTrap, value) {
108
- focusTrap.disabled = value;
109
- if (value) FOCUSTRAPS_DISABLED.add(focusTrap);
110
- else FOCUSTRAPS_DISABLED.delete(focusTrap);
183
+ function setDisabled(focusTrap, state, value) {
184
+ state.disabled = value;
185
+ if (value) disabled.add(focusTrap);
186
+ else disabled.delete(focusTrap);
111
187
  }
112
- function tabToElement(focusTrap, elements, index, modifier) {
188
+ function tabToElement(instance, elements, index, modifier) {
113
189
  const { length } = elements;
114
190
  const next = clamp(index + modifier, 0, length - 1, true);
115
- if (focusTrap.disabled) {
191
+ if (instance.disabled) {
116
192
  if (index === length - 1 && next === 0 || index === 0 && next === length - 1) {
117
193
  lastTarget = void 0;
118
- focusTrap.enable();
194
+ instance.enable();
119
195
  }
120
196
  return;
121
197
  }
122
198
  const element = elements[next];
123
- const elementFocusTrap = FOCUSTRAPS_ALL.get(element);
199
+ const elementFocusTrap = instances.get(element);
124
200
  if (elementFocusTrap != null) elementFocusTrap.focus(modifier === -1);
125
201
  else {
126
202
  elements[next].focus();
127
203
  lastTarget = elements[next];
128
204
  }
129
205
  }
130
- function tabToTrap(focusTrap, elements, element, index) {
131
- if (focusTrap.disabled) {
206
+ function tabToTrap(instance, elements, element, index) {
207
+ if (instance.disabled) {
132
208
  lastTarget = void 0;
133
- focusTrap.enable();
209
+ instance.enable();
134
210
  } else {
135
211
  const next = elements.length === 0 ? element : elements.at(index ?? 0);
136
212
  next.focus();
137
213
  lastTarget = next;
138
214
  }
139
215
  }
140
- const FOCUS_TRAP_SELECTOR = "oui-focus-trap";
141
- const ATTRIBUTE_SELECTOR = `[${FOCUS_TRAP_SELECTOR}]`;
216
+ const ATTRIBUTE_FOCUSTRAP = "oui-focus-trap";
217
+ const ATTRIBUTE_FOCUSTRAP_CONTAIN = `${ATTRIBUTE_FOCUSTRAP}-contain`;
218
+ const ATTRIBUTE_FOCUSTRAP_NOESCAPE = `${ATTRIBUTE_FOCUSTRAP}-noescape`;
142
219
  const EVENT_OPTIONS = {
143
220
  capture: true,
144
221
  passive: false
145
222
  };
146
- const FOCUS_TRAP_CONTAIN = `${FOCUS_TRAP_SELECTOR}-contain`;
147
- const FOCUS_TRAP_NOESCAPE = `${FOCUS_TRAP_SELECTOR}-noescape`;
148
- const FOCUSTRAPS_ALL = /* @__PURE__ */ new WeakMap();
149
- const FOCUSTRAPS_DISABLED = /* @__PURE__ */ new Set();
223
+ const MESSAGE = "Element must be an HTMLElement or SVGElement";
224
+ const SELECTOR = `[${ATTRIBUTE_FOCUSTRAP}]`;
225
+ const disabled = /* @__PURE__ */ new Set();
226
+ const instances = /* @__PURE__ */ new WeakMap();
227
+ const states = /* @__PURE__ */ new WeakMap();
150
228
  let lastTarget;
151
229
  on(document, "focusin", onFocusIn, EVENT_OPTIONS);
152
230
  on(document, "keydown", onKeydown, EVENT_OPTIONS);
153
231
  on(document, "mousedown", onPointerdown, EVENT_OPTIONS);
154
232
  on(document, "touchstart", onPointerdown, EVENT_OPTIONS);
155
233
  //#endregion
156
- export { FOCUS_TRAP_CONTAIN, FOCUS_TRAP_NOESCAPE, FOCUS_TRAP_SELECTOR, FocusTrap, createFocusTrap, removeFocusTrap };
234
+ export { ATTRIBUTE_FOCUSTRAP, ATTRIBUTE_FOCUSTRAP_CONTAIN, ATTRIBUTE_FOCUSTRAP_NOESCAPE, OuiFocusTrap, createFocusTrap, removeFocusTrap };
@@ -1 +1,2 @@
1
- export { };
1
+ import { a as createFocusTrap, i as OuiFocusTrap } from "../embedded-CHK82Uh5.mjs";
2
+ export { type OuiFocusTrap, createFocusTrap };
@@ -1,6 +1,6 @@
1
1
  import { attributable } from "../internal/attributable.mjs";
2
- import { FOCUS_TRAP_SELECTOR, createFocusTrap, removeFocusTrap } from "./embedded.mjs";
2
+ import { ATTRIBUTE_FOCUSTRAP, createFocusTrap, removeFocusTrap } from "./embedded.mjs";
3
3
  //#region src/js/focus-trap/standalone.ts
4
- attributable(FOCUS_TRAP_SELECTOR, createFocusTrap, removeFocusTrap);
4
+ attributable(ATTRIBUTE_FOCUSTRAP, createFocusTrap, removeFocusTrap);
5
5
  //#endregion
6
- export {};
6
+ export { createFocusTrap };
@@ -1,6 +1,7 @@
1
1
  import { OuiDialog, getDialog } from "./dialog.mjs";
2
- import { i as OuiFloatablePosition, n as OuiFloatable, o as getFloatable } from "./embedded-84gxpReS.mjs";
2
+ import { i as OuiFloatablePosition, n as OuiFloatable, o as createFloatable } from "./embedded-ai6cqURc.mjs";
3
+ import { a as createFocusTrap, i as OuiFocusTrap } from "./embedded-CHK82Uh5.mjs";
3
4
  import { OuiPopover, getPopover } from "./popover.mjs";
4
5
  import { OuiSplitterElement } from "./splitter.mjs";
5
6
  import { OuiTooltip, getTooltip, setTooltipDelay } from "./tooltip.mjs";
6
- export { type OuiDialog, type OuiFloatable, type OuiFloatablePosition, type OuiPopover, OuiSplitterElement, type OuiTooltip, getDialog, getFloatable, getPopover, getTooltip, setTooltipDelay };
7
+ export { type OuiDialog, type OuiFloatable, type OuiFloatablePosition, type OuiFocusTrap, type OuiPopover, OuiSplitterElement, type OuiTooltip, createFloatable, createFocusTrap, getDialog, getPopover, getTooltip, setTooltipDelay };
package/dist/js/index.mjs CHANGED
@@ -1,10 +1,12 @@
1
- import { getFloatable } from "./floatable/embedded.mjs";
1
+ import { createFloatable } from "./floatable/embedded.mjs";
2
2
  import { getDialog } from "./dialog.mjs";
3
3
  import "./movable.mjs";
4
4
  import "./sortable.mjs";
5
+ import "./toolbar.mjs";
5
6
  import "./floatable/standalone.mjs";
7
+ import { createFocusTrap } from "./focus-trap/embedded.mjs";
6
8
  import "./focus-trap/standalone.mjs";
7
9
  import { getPopover } from "./popover.mjs";
8
10
  import { OuiSplitterElement } from "./splitter.mjs";
9
11
  import { getTooltip, setTooltipDelay } from "./tooltip.mjs";
10
- export { OuiSplitterElement, getDialog, getFloatable, getPopover, getTooltip, setTooltipDelay };
12
+ export { OuiSplitterElement, createFloatable, createFocusTrap, getDialog, getPopover, getTooltip, setTooltipDelay };
@@ -1,2 +1,2 @@
1
- import { a as DraggableState, i as DraggableBound, n as DragMovePosition, o as addDraggable, r as Draggable, s as removeDraggable } from "../movable-BKFgoaOl.mjs";
2
- export { DragMovePosition, Draggable, DraggableBound, DraggableState, addDraggable, removeDraggable };
1
+ import { a as OuiDraggable, i as DraggableState, n as DragMovePosition, o as addDraggable, r as DraggableBound, s as removeDraggable } from "../movable-dNqBctx3.mjs";
2
+ export { DragMovePosition, DraggableBound, DraggableState, OuiDraggable, addDraggable, removeDraggable };
@@ -4,7 +4,7 @@ import { findAncestor } from "@oscarpalmer/toretto/find";
4
4
  import { toggleStyles } from "@oscarpalmer/toretto/style";
5
5
  import supportsTouch from "@oscarpalmer/toretto/touch";
6
6
  //#region src/js/internal/draggable.ts
7
- var Draggable = class {
7
+ var OuiDraggable = class {
8
8
  prefix;
9
9
  element;
10
10
  options;
@@ -212,4 +212,4 @@ on(document, "pointerup", onPointerup);
212
212
  on(document, "touchcancel", onPointerup, { passive: false });
213
213
  on(document, "touchstart", onPointerdown, { passive: false });
214
214
  //#endregion
215
- export { Draggable, addDraggable, removeDraggable };
215
+ export { OuiDraggable, addDraggable, removeDraggable };