@oscarpalmer/oui 0.38.0 → 0.40.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 (264) hide show
  1. package/README.md +1 -1
  2. package/dist/css/badge.css +11 -8
  3. package/dist/css/button.css +106 -14
  4. package/dist/css/color-picker.css +555 -73
  5. package/dist/css/color.css +86 -86
  6. package/dist/css/combobox.css +98 -4
  7. package/dist/css/content.css +7 -6
  8. package/dist/css/floatable.css +1 -3
  9. package/dist/css/form.css +99 -6
  10. package/dist/css/icon.css +99 -0
  11. package/dist/css/listbox.css +3 -0
  12. package/dist/css/message.css +4 -3
  13. package/dist/css/mixins/button.mixins.css +1 -0
  14. package/dist/css/reset.css +1 -1
  15. package/dist/css/tabs.css +95 -3
  16. package/dist/css/typography.css +90 -0
  17. package/dist/js/color-picker/color-picker.constants.d.mts +2 -0
  18. package/dist/js/color-picker/color-picker.constants.mjs +60 -0
  19. package/dist/js/color-picker/color-picker.dom.d.mts +8 -0
  20. package/dist/js/color-picker/color-picker.dom.mjs +191 -0
  21. package/dist/js/color-picker/color-picker.event.d.mts +9 -0
  22. package/dist/js/color-picker/color-picker.event.mjs +2 -0
  23. package/dist/js/color-picker/color-picker.form.d.mts +5 -0
  24. package/dist/js/color-picker/color-picker.form.mjs +27 -0
  25. package/dist/js/color-picker/color-picker.misc.d.mts +2 -0
  26. package/dist/js/color-picker/color-picker.misc.mjs +2 -0
  27. package/dist/js/color-picker/color-picker.model.d.mts +2 -0
  28. package/dist/js/color-picker/color-picker.model.mjs +24 -0
  29. package/dist/js/color-picker/color-picker.output.d.mts +8 -0
  30. package/dist/js/color-picker/color-picker.output.mjs +235 -0
  31. package/dist/js/color-picker/color-picker.state.d.mts +8 -0
  32. package/dist/js/color-picker/color-picker.state.mjs +2 -0
  33. package/dist/js/{color-picker.d.mts → color-picker/index.d.mts} +10 -43
  34. package/dist/js/color-picker/index.mjs +305 -0
  35. package/dist/js/color-picker.constants-D1mxw_Le.d.mts +179 -0
  36. package/dist/js/color-picker.event-Cksj5TvS.mjs +500 -0
  37. package/dist/js/color-picker.misc-CtsXGrOe.d.mts +27 -0
  38. package/dist/js/combobox/combobox.constants.d.mts +2 -0
  39. package/dist/js/combobox/{constants.combobox.mjs → combobox.constants.mjs} +21 -21
  40. package/dist/js/combobox/combobox.dom.d.mts +26 -0
  41. package/dist/js/combobox/{dom.combobox.mjs → combobox.dom.mjs} +44 -37
  42. package/dist/js/combobox/combobox.event.d.mts +22 -0
  43. package/dist/js/combobox/{event.combobox.mjs → combobox.event.mjs} +1 -1
  44. package/dist/js/combobox/combobox.misc.d.mts +2 -0
  45. package/dist/js/combobox/{misc.combobox.mjs → combobox.misc.mjs} +1 -1
  46. package/dist/js/combobox/combobox.model.d.mts +2 -0
  47. package/dist/js/combobox/combobox.state.d.mts +10 -0
  48. package/dist/js/combobox/combobox.state.mjs +2 -0
  49. package/dist/js/combobox/index.d.mts +163 -2
  50. package/dist/js/combobox/index.mjs +53 -52
  51. package/dist/js/combobox.constants-DZVkMP5g.d.mts +19 -0
  52. package/dist/js/combobox.misc-C1tPZZDi.d.mts +22 -0
  53. package/dist/js/{combobox/models.combobox.d.mts → combobox.model-oDV06XCN.d.mts} +6 -6
  54. package/dist/js/{state.combobox-Qm3FWzYW.mjs → combobox.state-BfJ3Hxg8.mjs} +96 -82
  55. package/dist/js/constants.listbox-C5Ap6Ag_.d.mts +9 -0
  56. package/dist/js/dialog/dialog.model.d.mts +2 -0
  57. package/dist/js/dialog/dialog.model.mjs +11 -0
  58. package/dist/js/dialog/index.d.mts +12 -0
  59. package/dist/js/dialog/index.mjs +123 -0
  60. package/dist/js/dialog.model-DX2mndMh.d.mts +45 -0
  61. package/dist/js/floatable/floatable.embedded.d.mts +2 -2
  62. package/dist/js/floatable/floatable.embedded.mjs +64 -92
  63. package/dist/js/floatable/floatable.model.d.mts +2 -0
  64. package/dist/js/floatable/floatable.model.mjs +23 -0
  65. package/dist/js/floatable/floatable.standalone.d.mts +2 -1
  66. package/dist/js/floatable.embedded-MeTyXjFn.d.mts +17 -0
  67. package/dist/js/floatable.model-DXsQgoU7.d.mts +62 -0
  68. package/dist/js/focus-trap/focus-trap.embedded.d.mts +2 -2
  69. package/dist/js/focus-trap/focus-trap.embedded.mjs +112 -134
  70. package/dist/js/focus-trap/focus-trap.model.d.mts +2 -0
  71. package/dist/js/focus-trap/focus-trap.model.mjs +15 -0
  72. package/dist/js/focus-trap/focus-trap.standalone.d.mts +2 -1
  73. package/dist/js/focus-trap.embedded-DIU05m1z.d.mts +13 -0
  74. package/dist/js/{focus-trap.embedded-DR8NpZfr.d.mts → focus-trap.model-BeX6UYlw.d.mts} +16 -18
  75. package/dist/js/index.d.mts +26 -14
  76. package/dist/js/index.mjs +18 -15
  77. package/dist/js/internal/attributable.d.mts +2 -3
  78. package/dist/js/internal/attributable.mjs +3 -2
  79. package/dist/js/internal/draggable/draggable.model.d.mts +2 -0
  80. package/dist/js/internal/draggable/draggable.model.mjs +37 -0
  81. package/dist/js/internal/draggable/index.d.mts +13 -0
  82. package/dist/js/internal/{draggable.mjs → draggable/index.mjs} +83 -114
  83. package/dist/js/internal/listbox/listbox.constants.d.mts +7 -10
  84. package/dist/js/internal/listbox/listbox.constants.mjs +15 -16
  85. package/dist/js/internal/listbox/listbox.data.d.mts +9 -10
  86. package/dist/js/internal/listbox/listbox.data.mjs +1 -1
  87. package/dist/js/internal/listbox/listbox.dom.d.mts +19 -20
  88. package/dist/js/internal/listbox/listbox.dom.mjs +1 -1
  89. package/dist/js/internal/listbox/listbox.event.d.mts +3 -4
  90. package/dist/js/internal/listbox/listbox.event.mjs +23 -20
  91. package/dist/js/internal/listbox/listbox.form.d.mts +4 -5
  92. package/dist/js/internal/listbox/listbox.form.mjs +15 -12
  93. package/dist/js/internal/listbox/listbox.misc.d.mts +10 -11
  94. package/dist/js/internal/listbox/listbox.misc.mjs +1 -1
  95. package/dist/js/internal/listbox/listbox.model.d.mts +2 -2
  96. package/dist/js/internal/listbox/listbox.state.d.mts +5 -6
  97. package/dist/js/internal/listbox/listbox.state.mjs +19 -20
  98. package/dist/js/internal/misc.d.mts +5 -4
  99. package/dist/js/internal/misc.mjs +7 -1
  100. package/dist/js/internal/navigable/index.d.mts +6 -0
  101. package/dist/js/internal/navigable/index.mjs +125 -0
  102. package/dist/js/internal/navigable/navigable.model.d.mts +2 -0
  103. package/dist/js/internal/navigable/navigable.model.mjs +18 -0
  104. package/dist/js/l10n/index.d.mts +9 -0
  105. package/dist/js/{l10n.mjs → l10n/index.mjs} +50 -23
  106. package/dist/js/l10n/l10n.model.d.mts +2 -0
  107. package/dist/js/l10n/l10n.model.mjs +9 -0
  108. package/dist/js/l10n.model-D6a9frgl.d.mts +26 -0
  109. package/dist/js/listbox/constants.listbox.d.mts +2 -2
  110. package/dist/js/listbox/constants.listbox.mjs +10 -14
  111. package/dist/js/listbox/event.listbox.d.mts +6 -7
  112. package/dist/js/listbox/event.listbox.mjs +47 -1
  113. package/dist/js/listbox/index.d.mts +8 -6
  114. package/dist/js/listbox/index.mjs +47 -49
  115. package/dist/js/listbox/misc.listbox.d.mts +1 -1
  116. package/dist/js/listbox/misc.listbox.mjs +1 -1
  117. package/dist/js/listbox/state.listbox.d.mts +8 -10
  118. package/dist/js/listbox/state.listbox.mjs +2 -2
  119. package/dist/js/{listbox.data-C7CRa5Ya.mjs → listbox.data-BQyZGKgr.mjs} +83 -66
  120. package/dist/js/{listbox.model-CRReGOmu.d.mts → listbox.model-CuBOj4qe.d.mts} +15 -11
  121. package/dist/js/menu/index.mjs +167 -0
  122. package/dist/js/menu/menu.model.d.mts +33 -0
  123. package/dist/js/menu/menu.model.mjs +15 -0
  124. package/dist/js/{misc.listbox-Cyz2CRDy.mjs → misc.listbox-CjfBUbHD.mjs} +27 -69
  125. package/dist/js/{misc.listbox-gnoJhrTr.d.mts → misc.listbox-CtoGvXQo.d.mts} +2 -2
  126. package/dist/js/movable/movable.embedded.d.mts +2 -2
  127. package/dist/js/movable/movable.embedded.mjs +60 -72
  128. package/dist/js/movable/movable.model.d.mts +2 -0
  129. package/dist/js/movable/movable.model.mjs +12 -0
  130. package/dist/js/movable/movable.standalone.d.mts +2 -1
  131. package/dist/js/movable.embedded-DoyXLegc.d.mts +11 -0
  132. package/dist/js/movable.model-BHaK_mKw.d.mts +186 -0
  133. package/dist/js/navigable.model-BPOM8DZk.d.mts +44 -0
  134. package/dist/js/popover/index.d.mts +12 -0
  135. package/dist/js/{popover.mjs → popover/index.mjs} +40 -50
  136. package/dist/js/popover/popover.model.d.mts +2 -0
  137. package/dist/js/popover/popover.model.mjs +12 -0
  138. package/dist/js/popover.model-ubKNG612.d.mts +38 -0
  139. package/dist/js/resizable/resizable.embedded.d.mts +2 -2
  140. package/dist/js/resizable/resizable.embedded.mjs +44 -59
  141. package/dist/js/resizable/resizable.model.d.mts +2 -0
  142. package/dist/js/resizable/resizable.model.mjs +21 -0
  143. package/dist/js/resizable/resizable.standalone.d.mts +2 -1
  144. package/dist/js/resizable.embedded-Bf1qBUdt.d.mts +11 -0
  145. package/dist/js/resizable.model-BwzJcTVJ.d.mts +46 -0
  146. package/dist/js/sortable/sortable.embedded.d.mts +2 -2
  147. package/dist/js/sortable/sortable.embedded.mjs +69 -82
  148. package/dist/js/sortable/sortable.model.d.mts +2 -0
  149. package/dist/js/sortable/sortable.model.mjs +24 -0
  150. package/dist/js/sortable/sortable.standalone.d.mts +2 -1
  151. package/dist/js/sortable.embedded-DzBKAwSG.d.mts +11 -0
  152. package/dist/js/{splitter.d.mts → splitter/index.d.mts} +8 -7
  153. package/dist/js/splitter/index.mjs +284 -0
  154. package/dist/js/splitter/splitter.model.d.mts +2 -0
  155. package/dist/js/splitter/splitter.model.mjs +37 -0
  156. package/dist/js/splitter.model-DOLNjLVS.d.mts +57 -0
  157. package/dist/js/{tabs.d.mts → tabs/index.d.mts} +7 -8
  158. package/dist/js/{tabs.mjs → tabs/index.mjs} +58 -58
  159. package/dist/js/tabs/tabs.model.d.mts +2 -0
  160. package/dist/js/tabs/tabs.model.mjs +18 -0
  161. package/dist/js/tabs.model-DRBX_JtI.d.mts +40 -0
  162. package/dist/js/toolbar/index.mjs +27 -0
  163. package/dist/js/toolbar/toolbar.model.d.mts +11 -0
  164. package/dist/js/toolbar/toolbar.model.mjs +7 -0
  165. package/dist/js/tooltip/index.d.mts +19 -0
  166. package/dist/js/{tooltip.mjs → tooltip/index.mjs} +60 -85
  167. package/dist/js/tooltip/tooltip.model.d.mts +2 -0
  168. package/dist/js/tooltip/tooltip.model.mjs +15 -0
  169. package/dist/js/tooltip.model-DRkY_BsL.d.mts +37 -0
  170. package/package.json +43 -37
  171. package/dist/js/color-picker.mjs +0 -924
  172. package/dist/js/combobox/constants.combobox.d.mts +0 -2
  173. package/dist/js/combobox/dom.combobox.d.mts +0 -27
  174. package/dist/js/combobox/event.combobox.d.mts +0 -23
  175. package/dist/js/combobox/misc.combobox.d.mts +0 -2
  176. package/dist/js/combobox/state.combobox.d.mts +0 -12
  177. package/dist/js/combobox/state.combobox.mjs +0 -2
  178. package/dist/js/constants.combobox-DmRAMC64.d.mts +0 -26
  179. package/dist/js/constants.listbox-DRsXUxd3.d.mts +0 -14
  180. package/dist/js/dialog.d.mts +0 -47
  181. package/dist/js/dialog.mjs +0 -131
  182. package/dist/js/draggable-a6w0J1OD.d.mts +0 -154
  183. package/dist/js/floatable.embedded-Bct4U5Dm.d.mts +0 -69
  184. package/dist/js/index-DJdFlTLm.d.mts +0 -177
  185. package/dist/js/internal/draggable.d.mts +0 -2
  186. package/dist/js/internal/navigable.d.mts +0 -37
  187. package/dist/js/internal/navigable.mjs +0 -135
  188. package/dist/js/l10n-Bn-7RcwR.d.mts +0 -20
  189. package/dist/js/l10n.d.mts +0 -2
  190. package/dist/js/menu.mjs +0 -172
  191. package/dist/js/popover.d.mts +0 -38
  192. package/dist/js/resizable.embedded-3qoR0Bjm.d.mts +0 -34
  193. package/dist/js/splitter.mjs +0 -322
  194. package/dist/js/toolbar.mjs +0 -31
  195. package/dist/js/tooltip.d.mts +0 -45
  196. package/src/css/a11y.scss +0 -13
  197. package/src/css/badge.scss +0 -62
  198. package/src/css/button.scss +0 -50
  199. package/src/css/color-picker.scss +0 -344
  200. package/src/css/color.scss +0 -113
  201. package/src/css/combobox.scss +0 -255
  202. package/src/css/content.scss +0 -181
  203. package/src/css/flex.scss +0 -107
  204. package/src/css/floatable.scss +0 -155
  205. package/src/css/form.scss +0 -575
  206. package/src/css/listbox.scss +0 -121
  207. package/src/css/message.scss +0 -74
  208. package/src/css/mixins/badge.mixins.scss +0 -53
  209. package/src/css/mixins/button.mixins.scss +0 -112
  210. package/src/css/mixins/input.mixins.scss +0 -114
  211. package/src/css/mixins/message.mixins.scss +0 -41
  212. package/src/css/mixins/misc.mixins.scss +0 -48
  213. package/src/css/mixins/shadow.mixins.scss +0 -57
  214. package/src/css/reset.scss +0 -392
  215. package/src/css/splitter.scss +0 -89
  216. package/src/css/table.scss +0 -107
  217. package/src/css/tabs.scss +0 -74
  218. package/src/js/color-picker.ts +0 -1653
  219. package/src/js/combobox/constants.combobox.ts +0 -83
  220. package/src/js/combobox/dom.combobox.ts +0 -411
  221. package/src/js/combobox/event.combobox.ts +0 -365
  222. package/src/js/combobox/index.ts +0 -382
  223. package/src/js/combobox/misc.combobox.ts +0 -104
  224. package/src/js/combobox/models.combobox.ts +0 -54
  225. package/src/js/combobox/state.combobox.ts +0 -246
  226. package/src/js/dialog.ts +0 -255
  227. package/src/js/floatable/floatable.embedded.ts +0 -336
  228. package/src/js/floatable/floatable.standalone.ts +0 -6
  229. package/src/js/focus-trap/focus-trap.embedded.ts +0 -411
  230. package/src/js/focus-trap/focus-trap.standalone.ts +0 -1
  231. package/src/js/index.ts +0 -16
  232. package/src/js/internal/attributable.ts +0 -73
  233. package/src/js/internal/draggable.ts +0 -657
  234. package/src/js/internal/listbox/listbox.constants.ts +0 -25
  235. package/src/js/internal/listbox/listbox.data.ts +0 -287
  236. package/src/js/internal/listbox/listbox.dom.ts +0 -446
  237. package/src/js/internal/listbox/listbox.event.ts +0 -129
  238. package/src/js/internal/listbox/listbox.form.ts +0 -125
  239. package/src/js/internal/listbox/listbox.misc.ts +0 -135
  240. package/src/js/internal/listbox/listbox.model.ts +0 -169
  241. package/src/js/internal/listbox/listbox.state.ts +0 -82
  242. package/src/js/internal/misc.ts +0 -27
  243. package/src/js/internal/navigable.ts +0 -317
  244. package/src/js/l10n.ts +0 -192
  245. package/src/js/listbox/constants.listbox.ts +0 -61
  246. package/src/js/listbox/event.listbox.ts +0 -106
  247. package/src/js/listbox/index.ts +0 -364
  248. package/src/js/listbox/misc.listbox.ts +0 -70
  249. package/src/js/listbox/state.listbox.ts +0 -194
  250. package/src/js/menu.ts +0 -348
  251. package/src/js/movable/movable.embedded.ts +0 -318
  252. package/src/js/movable/movable.standalone.ts +0 -2
  253. package/src/js/popover.ts +0 -229
  254. package/src/js/resizable/resizable.embedded.ts +0 -413
  255. package/src/js/resizable/resizable.standalone.ts +0 -5
  256. package/src/js/sortable/sortable.embedded.ts +0 -527
  257. package/src/js/sortable/sortable.standalone.ts +0 -2
  258. package/src/js/splitter.ts +0 -583
  259. package/src/js/tabs.ts +0 -441
  260. package/src/js/toolbar.ts +0 -63
  261. package/src/js/tooltip.ts +0 -367
  262. /package/dist/js/combobox/{models.combobox.mjs → combobox.model.mjs} +0 -0
  263. /package/dist/js/{menu.d.mts → menu/index.d.mts} +0 -0
  264. /package/dist/js/{toolbar.d.mts → toolbar/index.d.mts} +0 -0
package/src/js/menu.ts DELETED
@@ -1,348 +0,0 @@
1
- import {setAria, setRole} from '@oscarpalmer/toretto/aria';
2
- import {setAttribute, setAttributes} from '@oscarpalmer/toretto/attribute';
3
- import {on} from '@oscarpalmer/toretto/event';
4
- import {findAncestor} from '@oscarpalmer/toretto/find';
5
- import {createEmbeddedFloatable, getOnBeforeToggleListener} from './floatable/floatable.embedded';
6
- import type {OuiFloatable} from './floatable/floatable.standalone';
7
- import {attributable} from './internal/attributable';
8
- import {
9
- NAVIGABLE_KEYS_HORIZONTAL,
10
- NAVIGABLE_KEYS_VERTICAL,
11
- type OuiNavigable,
12
- type OuiNavigableOptions,
13
- getNavigable,
14
- updateNavigableFocus,
15
- } from './internal/navigable';
16
-
17
- // #region Types
18
-
19
- type OuiBasicMenu = {
20
- destroy(): void;
21
- };
22
-
23
- type OuiBasicMenuOptions = Pick<OuiNavigableOptions, 'role' | 'selector' | 'vertical'>;
24
-
25
- class OuiMenu {
26
- content: HTMLElement;
27
-
28
- element: HTMLElement;
29
-
30
- floatable: OuiFloatable;
31
-
32
- navigable: OuiNavigable;
33
-
34
- toggle: HTMLElement;
35
-
36
- get open(): boolean {
37
- return this.floatable.open;
38
- }
39
-
40
- constructor(element: HTMLElement, navigable: OuiNavigable) {
41
- this.element = element;
42
- this.navigable = navigable;
43
-
44
- this.content = navigable.element;
45
-
46
- this.toggle = element.querySelector(SELECTOR_MENU_TOGGLE)!;
47
-
48
- this.floatable = createEmbeddedFloatable(this.toggle, this.content, {
49
- attribute: ATTRIBUTE_MENU_POSITION,
50
- position:
51
- findAncestor(element.parentElement!, SELECTOR_MENU_CONTENT) == null
52
- ? 'below-start'
53
- : 'end-top',
54
- reusable: false,
55
- });
56
-
57
- this.navigable.listeners.push(
58
- getOnBeforeToggleListener(this.content),
59
- on(this.content, 'click', event => {
60
- event.stopPropagation();
61
-
62
- const toggle = findAncestor(event, SELECTOR_MENU_TOGGLE);
63
-
64
- if (toggle != null) {
65
- return;
66
- }
67
-
68
- const elements = document.querySelectorAll(SELECTOR_MENU_CONTENT);
69
-
70
- for (const element of elements) {
71
- menus.get(element as HTMLElement)?.floatable.hide();
72
- }
73
-
74
- const menu = menus.get(elements[0] as HTMLElement);
75
-
76
- if (menu != null && event.pointerId === -1) {
77
- updateNavigableFocus(menu.navigable, true);
78
- }
79
- }),
80
- on(this.content, 'toggle', event => {
81
- const expanded = event.newState === 'open';
82
-
83
- if (expanded) {
84
- this.floatable?.update();
85
-
86
- updateNavigableFocus(this.navigable, true);
87
- } else {
88
- }
89
-
90
- setAria(this.toggle, 'expanded', expanded);
91
- }),
92
- );
93
-
94
- this.floatable.update();
95
-
96
- initializeMenu(this);
97
-
98
- updateNavigableFocus(this.navigable, false);
99
- }
100
-
101
- destroy(): void {
102
- this.floatable.destroy();
103
- this.navigable.destroy();
104
-
105
- this.floatable = undefined as never;
106
- this.navigable = undefined as never;
107
- }
108
- }
109
-
110
- class OuiMenubar {
111
- element: HTMLElement;
112
-
113
- navigable: OuiNavigable;
114
-
115
- constructor(element: HTMLElement, navigable: OuiNavigable) {
116
- this.element = element;
117
- this.navigable = navigable;
118
-
119
- updateNavigableFocus(this.navigable, false);
120
- }
121
-
122
- destroy(): void {
123
- this.navigable.destroy();
124
-
125
- this.navigable = undefined as never;
126
- }
127
- }
128
-
129
- // #endregion
130
-
131
- // #region Functions
132
-
133
- function addInstance<Instance>(
134
- instances: WeakMap<HTMLElement, Instance>,
135
- ctor: new (element: HTMLElement, navigable: OuiNavigable) => Instance,
136
- element: HTMLElement,
137
- content: HTMLElement,
138
- options: OuiBasicMenuOptions,
139
- ): void {
140
- if (!instances.has(content)) {
141
- instances.set(
142
- content,
143
- new ctor(
144
- element,
145
- getNavigable(content, {
146
- ...options,
147
- onDeactivate,
148
- onPreventNavigation,
149
- onShouldActivate,
150
- onShouldDeactivate,
151
- }),
152
- ),
153
- );
154
- }
155
- }
156
-
157
- function addMenu(element: HTMLElement): void {
158
- const content = element.querySelector(SELECTOR_MENU_CONTENT);
159
- const toggle = element.querySelector(SELECTOR_MENU_TOGGLE);
160
-
161
- if (content != null && toggle != null) {
162
- addInstance(menus, OuiMenu, element, content as never, {
163
- selector: SELECTOR_MENU_ITEM,
164
- vertical: true,
165
- });
166
- }
167
- }
168
-
169
- function addMenubar(element: HTMLElement): void {
170
- addInstance(menubars, OuiMenubar, element, element, {
171
- role: 'menubar',
172
- selector: SELECTOR_MENUBAR_ITEM,
173
- vertical: false,
174
- });
175
- }
176
-
177
- function getId(element: HTMLElement, value?: string): string {
178
- let {id} = element;
179
-
180
- if (id == null || id.trim().length === 0) {
181
- id = value == null ? `oui_menu_${++index}` : `${value}_toggle`;
182
-
183
- element.id = id;
184
- }
185
-
186
- return id;
187
- }
188
-
189
- function initializeMenu(menu: OuiMenu): void {
190
- const id = getId(menu.content);
191
-
192
- setAttribute(menu.toggle, 'popovertarget', id);
193
-
194
- setAria(menu.toggle, {
195
- controls: id,
196
- expanded: 'false',
197
- haspopup: 'menu',
198
- });
199
-
200
- setAttributes(menu.content, {
201
- popover: '',
202
- tabindex: '-1',
203
- });
204
-
205
- setRole(menu.content, 'menu');
206
- }
207
-
208
- function onDeactivate(_: KeyboardEvent, navigable: OuiNavigable): void {
209
- const menu = menus.get(navigable.element);
210
-
211
- if (menu == null) {
212
- return;
213
- }
214
-
215
- menu.floatable.hide();
216
-
217
- const element = findAncestor(menu.element.parentElement!, SELECTORS) as HTMLElement | null;
218
-
219
- if (element == null) {
220
- return;
221
- }
222
-
223
- const instance = menubars.get(element) ?? menus.get(element);
224
-
225
- if (instance != null) {
226
- updateNavigableFocus(instance.navigable, true);
227
- }
228
- }
229
-
230
- function onPreventNavigation(_: KeyboardEvent, navigable: OuiNavigable): boolean {
231
- const instance = menubars.get(navigable.element) ?? menus.get(navigable.element);
232
-
233
- return findAncestor(instance?.element.parentElement!, SELECTORS) != null;
234
- }
235
-
236
- function onShouldActivate(event: KeyboardEvent, navigable: OuiNavigable): boolean {
237
- let activate = false;
238
-
239
- if (menubars.has(navigable.element)) {
240
- activate =
241
- navigable.orientation === 'horizontal'
242
- ? NAVIGABLE_KEYS_VERTICAL.has(event.key)
243
- : NAVIGABLE_KEYS_HORIZONTAL.has(event.key);
244
- } else if (menus.has(navigable.element)) {
245
- activate =
246
- navigable.orientation === 'horizontal'
247
- ? NAVIGABLE_KEYS_VERTICAL.has(event.key)
248
- : event.key === 'ArrowRight';
249
- }
250
-
251
- if (activate) {
252
- const target =
253
- event.target instanceof HTMLElement && event.target.matches(SELECTOR_MENU_TOGGLE)
254
- ? event.target
255
- : undefined;
256
-
257
- if (target == null) {
258
- activate = false;
259
- } else {
260
- target.click();
261
- }
262
- }
263
-
264
- return activate;
265
- }
266
-
267
- function onShouldDeactivate(event: KeyboardEvent, navigable: OuiNavigable): boolean | undefined {
268
- if (menubars.has(navigable.element)) {
269
- return;
270
- }
271
-
272
- const menu = menus.get(navigable.element);
273
-
274
- if (menu == null) {
275
- return;
276
- }
277
-
278
- const horizontal = navigable.orientation === 'horizontal';
279
-
280
- const altKey = horizontal ? 'ArrowDown' : 'ArrowRight';
281
- const baseKey = horizontal ? 'ArrowUp' : 'ArrowLeft';
282
-
283
- if (event.key === baseKey) {
284
- return findAncestor(menu.element.parentElement!, SELECTOR_MENU_CONTENT) != null;
285
- }
286
-
287
- if (
288
- event.key === altKey &&
289
- event.target instanceof HTMLElement &&
290
- !event.target.hasAttribute('popovertarget')
291
- ) {
292
- return false;
293
- }
294
- }
295
-
296
- function removeInstance<Instance extends OuiBasicMenu>(
297
- instances: WeakMap<HTMLElement, Instance>,
298
- element: HTMLElement,
299
- ): void {
300
- instances.get(element)?.destroy();
301
-
302
- instances.delete(element);
303
- }
304
-
305
- function removeMenu(element: HTMLElement): void {
306
- removeInstance(menus, element);
307
- }
308
-
309
- function removeMenubar(element: HTMLElement): void {
310
- removeInstance(menubars, element);
311
- }
312
-
313
- // #endregion
314
-
315
- // #region Variables
316
-
317
- const ATTRIBUTE_MENU = 'oui-menu';
318
-
319
- const ATTRIBUTE_MENU_POSITION = 'oui-menu-position';
320
-
321
- const ATTRIBUTE_MENUBAR = 'oui-menubar';
322
-
323
- const SELECTOR_MENUBAR = `[${ATTRIBUTE_MENUBAR}]`;
324
-
325
- const SELECTOR_MENUBAR_ITEM = `:scope > [${ATTRIBUTE_MENUBAR}-item], :scope > * > [${ATTRIBUTE_MENUBAR}-item]`;
326
-
327
- const SELECTOR_MENU_CONTENT = `[${ATTRIBUTE_MENU}-content]`;
328
-
329
- const SELECTOR_MENU_ITEM = `:scope > [${ATTRIBUTE_MENU}-item], :scope > * > [${ATTRIBUTE_MENU}-item]`;
330
-
331
- const SELECTOR_MENU_TOGGLE = `[${ATTRIBUTE_MENU}-toggle]`;
332
-
333
- const SELECTORS = `${SELECTOR_MENUBAR}, ${SELECTOR_MENU_CONTENT}`;
334
-
335
- const menubars = new WeakMap<HTMLElement, OuiMenubar>();
336
-
337
- const menus = new WeakMap<HTMLElement, OuiMenu>();
338
-
339
- let index = 0;
340
-
341
- // #endregion
342
-
343
- // #region Initialization
344
-
345
- attributable(ATTRIBUTE_MENU, addMenu, removeMenu);
346
- attributable(ATTRIBUTE_MENUBAR, addMenubar, removeMenubar);
347
-
348
- // #endregion
@@ -1,318 +0,0 @@
1
- import type {EventPosition, PlainObject} from '@oscarpalmer/atoms/models';
2
- import {setAttribute} from '@oscarpalmer/toretto/attribute';
3
- import {dispatch, getEventPosition, on} from '@oscarpalmer/toretto/event';
4
- import {isHTMLOrSVGElement} from '@oscarpalmer/toretto/is';
5
- import {getStyles, setStyle, setStyles} from '@oscarpalmer/toretto/style';
6
- import {attributable} from '../internal/attributable';
7
- import {
8
- addDraggable,
9
- getDraggableStates,
10
- OuiDraggable,
11
- removeDraggable,
12
- type CreateOuiDraggableOptions,
13
- type OuiDraggableBound,
14
- type OuiDraggableGlobals,
15
- type OuiDraggableItem,
16
- type OuiDraggableState,
17
- type OuiDragMovePosition,
18
- } from '../internal/draggable';
19
-
20
- // #region Types
21
-
22
- export class OuiMovable extends OuiDraggable<OuiMovableState> {
23
- #element: HTMLElement;
24
-
25
- #style: OuiMovableStyle;
26
-
27
- constructor(element: HTMLElement, options?: CreateOuiDraggableOptions) {
28
- const style = getStyles(element, ['inset', 'position']);
29
-
30
- super(
31
- 'movable',
32
- 'move',
33
- ATTRIBUTE_MOVABLE,
34
- element,
35
- {
36
- container: {
37
- attribute: ATTRIBUTE_CONTAINER,
38
- map: CONTAINERS,
39
- onDestroy: destroyContainer,
40
- onInitialize: initializeContainer,
41
- },
42
- direction: {
43
- attribute: ATTRIBUTE_DIRECTION,
44
- onAfter: afterDirection,
45
- },
46
- drag: {
47
- onBegin,
48
- onCancel,
49
- onEnd,
50
- onMove,
51
- },
52
- input: options,
53
- position: {
54
- getOffset: getOffsetPosition,
55
- getOriginal: getOriginalPosition,
56
- },
57
- getDragged() {
58
- return element;
59
- },
60
- getOrigin() {
61
- return element;
62
- },
63
- },
64
- {
65
- style,
66
- hasHandles: element.querySelector(SELECTOR_HANDLE) != null,
67
- moved: false,
68
- },
69
- );
70
-
71
- this.#element = element;
72
-
73
- this.#style = style;
74
- }
75
-
76
- /**
77
- * Destroys the _Movable_
78
- */
79
- override destroy(): void {
80
- MOVED.delete(this);
81
-
82
- setStyles(this.#element, this.#style);
83
-
84
- this.#element = undefined as never;
85
- this.#style = undefined as never;
86
-
87
- super.destroy();
88
- }
89
- }
90
-
91
- type OuiMovableState = {
92
- hasHandles?: boolean;
93
- moved: boolean;
94
- offset?: Partial<EventPosition>;
95
- style: OuiMovableStyle;
96
- };
97
-
98
- type OuiMovableStyle = {
99
- inset: string | undefined;
100
- position: string | undefined;
101
- };
102
-
103
- // #endregion
104
-
105
- // #region Functions
106
-
107
- function afterDirection(item: OuiDraggableItem): void {
108
- const container = item.state.container?.getBoundingClientRect();
109
-
110
- if (container != null) {
111
- setOffset(item.state as OuiDraggableState & OuiMovableState, container);
112
- }
113
- }
114
-
115
- /**
116
- * Creates _(or retrieves)_ a _OuiMovable_ instance for an element
117
- *
118
- * @param element Element to make movable
119
- * @returns _OuiMovable_ instance
120
- */
121
- export function createMovable(
122
- element: HTMLElement,
123
- options?: CreateOuiDraggableOptions,
124
- ): OuiMovable {
125
- if (!isHTMLOrSVGElement(element)) {
126
- throw new TypeError(MESSAGE);
127
- }
128
-
129
- return addMovable(element, options) as OuiMovable;
130
- }
131
-
132
- function destroyContainer(_: unknown, container: HTMLElement, empty: boolean): void {
133
- if (empty) {
134
- resizer.unobserve(container);
135
- }
136
- }
137
-
138
- function getOffsetPosition(
139
- globals: OuiDraggableGlobals,
140
- _: OuiDraggableItem,
141
- __: HTMLElement,
142
- position: EventPosition,
143
- ): EventPosition {
144
- return {
145
- x: position.x - (globals.element?.rectangle.left ?? 0),
146
- y: position.y - (globals.element?.rectangle.top ?? 0),
147
- };
148
- }
149
-
150
- function getOriginalPosition(globals: OuiDraggableGlobals): EventPosition {
151
- return {
152
- x: globals.element?.rectangle.left ?? 0,
153
- y: globals.element?.rectangle.top ?? 0,
154
- };
155
- }
156
-
157
- function initializeContainer(item: OuiDraggableItem): void {
158
- resizer.observe(item.state.container!);
159
- }
160
-
161
- function onBegin(): void {}
162
-
163
- function onCancel(globals: OuiDraggableGlobals, item: OuiDraggableItem): void {
164
- const {element, moved, style} = item.state as OuiDraggableState & OuiMovableState;
165
-
166
- const {x, y} = globals.original ?? {x: 0, y: 0};
167
-
168
- if (moved) {
169
- setStyle(element, 'inset', `${y}px auto auto ${x}px`);
170
- } else {
171
- setStyles(element, style);
172
- }
173
-
174
- element.removeAttribute(ATTRIBUTE_MOVING);
175
- }
176
-
177
- function onEnd(
178
- event: MouseEvent | TouchEvent,
179
- globals: OuiDraggableGlobals,
180
- item: OuiDraggableItem,
181
- reset: () => void,
182
- ): void {
183
- const movable = item.instance as OuiMovable;
184
- const state = item.state as OuiDraggableState & OuiMovableState;
185
-
186
- state.element.removeAttribute(ATTRIBUTE_MOVING);
187
-
188
- if (!state.moved) {
189
- state.moved = true;
190
-
191
- if (state.container != null) {
192
- MOVED.add(movable);
193
- }
194
- }
195
-
196
- const container = state.container?.getBoundingClientRect();
197
-
198
- if (container != null) {
199
- setOffset(state, container);
200
- }
201
-
202
- if (
203
- dispatch(state.element, 'oui:movable:end', {
204
- detail: {
205
- from: {...globals.original},
206
- to: getEventPosition(event),
207
- },
208
- }).defaultPrevented
209
- ) {
210
- onCancel(globals, item);
211
- }
212
-
213
- reset();
214
- }
215
-
216
- function onMove(
217
- _: MouseEvent | TouchEvent,
218
- globals: OuiDraggableGlobals,
219
- __: OuiDraggableItem,
220
- position: OuiDragMovePosition,
221
- ): PlainObject | undefined {
222
- setAttribute(globals.element?.node as never, ATTRIBUTE_MOVING, '');
223
-
224
- return {
225
- from: {...globals.original},
226
- to: {...position.calculated},
227
- };
228
- }
229
-
230
- function onResize(entries: ResizeObserverEntry[]): void {
231
- const {length} = entries;
232
-
233
- for (let index = 0; index < length; index += 1) {
234
- const entry = entries[index];
235
- const set = CONTAINERS.get(entry.target as HTMLElement);
236
-
237
- if (set == null) {
238
- continue;
239
- }
240
-
241
- for (const movable of set) {
242
- reposition(movable);
243
- }
244
- }
245
- }
246
-
247
- function onScroll(): void {
248
- for (const moved of MOVED) {
249
- reposition(moved);
250
- }
251
- }
252
-
253
- function reposition(movable: OuiMovable): void {
254
- const state = getDraggableStates(movable.element)?.movable as OuiDraggableState & OuiMovableState;
255
-
256
- if (state == null || !state.moved || state.container == null) {
257
- return;
258
- }
259
-
260
- const container = state.container.getBoundingClientRect();
261
-
262
- const x = container.left + (state.offset?.x ?? 0);
263
- const y = container.top + (state.offset?.y ?? 0);
264
-
265
- setStyle(state.element, 'inset', `${y}px auto auto ${x}px`);
266
- }
267
-
268
- function setOffset(state: OuiDraggableState & OuiMovableState, container: DOMRect): void {
269
- state.offset = {};
270
-
271
- const element = state.element.getBoundingClientRect();
272
-
273
- state.offset.y = element.top - container.top;
274
- state.offset.x = element.left - container.left;
275
- }
276
-
277
- // #endregion
278
-
279
- // #region Variables
280
-
281
- export const ATTRIBUTE_MOVABLE = 'oui-movable';
282
-
283
- const ATTRIBUTE_CONTAINER = `${ATTRIBUTE_MOVABLE}-container`;
284
-
285
- const ATTRIBUTE_DIRECTION = `${ATTRIBUTE_MOVABLE}-direction`;
286
-
287
- export const ATTRIBUTE_MOVABLE_HANDLE = `${ATTRIBUTE_MOVABLE}-handle`;
288
-
289
- const ATTRIBUTE_MOVING = `${ATTRIBUTE_MOVABLE}-moving`;
290
-
291
- const CONTAINERS = new Map<HTMLElement, Set<OuiMovable>>();
292
-
293
- const MESSAGE = 'The element must be an instance of HTMLElement or SVGElement';
294
-
295
- const MOVED = new Set<OuiMovable>();
296
-
297
- const SELECTOR_HANDLE = `[${ATTRIBUTE_MOVABLE_HANDLE}]`;
298
-
299
- const bound: OuiDraggableBound = {
300
- constructor: OuiMovable,
301
- property: 'movable',
302
- };
303
-
304
- const resizer = new ResizeObserver(onResize);
305
-
306
- const addMovable = addDraggable.bind(bound);
307
-
308
- const removeMovable = removeDraggable.bind(bound);
309
-
310
- // #endregion
311
-
312
- // #region Initialization
313
-
314
- on(document, 'scroll', onScroll);
315
-
316
- attributable(ATTRIBUTE_MOVABLE, addMovable, removeMovable);
317
-
318
- // #endregion
@@ -1,2 +0,0 @@
1
- export type {CreateOuiDraggableOptions as CreateOuiMovableOptions} from '../internal/draggable';
2
- export {createMovable, type OuiMovable} from './movable.embedded';