@fabric-msft/fabric-web 5.0.0 → 5.0.1

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 (230) hide show
  1. package/CHANGELOG.json +180 -0
  2. package/CHANGELOG.md +56 -1
  3. package/dist/dts/components/accordion-menu/accordion-menu.d.ts +1 -1
  4. package/dist/dts/components/accordion-menu/accordion-menu.d.ts.map +1 -1
  5. package/dist/dts/components/accordion-menu-panel/accordion-menu-panel.d.ts +2 -2
  6. package/dist/dts/components/accordion-menu-panel/accordion-menu-panel.d.ts.map +1 -1
  7. package/dist/dts/components/component-register.d.ts +67 -0
  8. package/dist/dts/components/component-register.d.ts.map +1 -0
  9. package/dist/dts/components/field/field.d.ts +32 -1
  10. package/dist/dts/components/field/field.d.ts.map +1 -1
  11. package/dist/dts/components/filter-pill/filter-pill.d.ts +1 -1
  12. package/dist/dts/components/filter-pill/filter-pill.d.ts.map +1 -1
  13. package/dist/dts/components/listbox/listbox.d.ts +1 -1
  14. package/dist/dts/components/listbox/listbox.d.ts.map +1 -1
  15. package/dist/dts/components/menu/menu.d.ts +71 -83
  16. package/dist/dts/components/menu/menu.d.ts.map +1 -1
  17. package/dist/dts/components/menu/menu.positioning.d.ts +26 -67
  18. package/dist/dts/components/menu/menu.positioning.d.ts.map +1 -1
  19. package/dist/dts/components/menu/menu.styles.d.ts.map +1 -1
  20. package/dist/dts/components/menu-item/menu-item.d.ts +4 -4
  21. package/dist/dts/components/menu-item/menu-item.d.ts.map +1 -1
  22. package/dist/dts/components/menu-list/menu-list.d.ts +1 -1
  23. package/dist/dts/components/menu-list/menu-list.d.ts.map +1 -1
  24. package/dist/dts/components/option-group/option-group.d.ts +1 -1
  25. package/dist/dts/components/option-group/option-group.d.ts.map +1 -1
  26. package/dist/dts/components/popover/popover.d.ts +48 -69
  27. package/dist/dts/components/popover/popover.d.ts.map +1 -1
  28. package/dist/dts/components/popover/popover.definition.d.ts +1 -1
  29. package/dist/dts/components/popover/popover.definition.d.ts.map +1 -1
  30. package/dist/dts/components/popover/popover.options.d.ts +2 -2
  31. package/dist/dts/components/popover/popover.options.d.ts.map +1 -1
  32. package/dist/dts/components/popover/popover.positioning.d.ts +92 -0
  33. package/dist/dts/components/popover/popover.positioning.d.ts.map +1 -0
  34. package/dist/dts/components/popover/popover.styles.d.ts.map +1 -1
  35. package/dist/dts/components/search-box/search-box.d.ts +1 -1
  36. package/dist/dts/components/search-box/search-box.d.ts.map +1 -1
  37. package/dist/dts/components/search-box/search-box.options.d.ts.map +1 -1
  38. package/dist/dts/components/table/table.d.ts +1 -1
  39. package/dist/dts/components/table/table.d.ts.map +1 -1
  40. package/dist/dts/components/text-input/text-input.base.d.ts +3 -3
  41. package/dist/dts/components/text-input/text-input.base.d.ts.map +1 -1
  42. package/dist/dts/components/text-input/text-input.d.ts.map +1 -1
  43. package/dist/dts/components/tooltip/tooltip.d.ts +5 -0
  44. package/dist/dts/components/tooltip/tooltip.d.ts.map +1 -1
  45. package/dist/dts/components/tooltip/tooltip.template.d.ts +13 -0
  46. package/dist/dts/components/tooltip/tooltip.template.d.ts.map +1 -0
  47. package/dist/dts/components/tree/tree.d.ts +16 -0
  48. package/dist/dts/components/tree/tree.d.ts.map +1 -1
  49. package/dist/dts/components/tree-item/index.d.ts +2 -1
  50. package/dist/dts/components/tree-item/index.d.ts.map +1 -1
  51. package/dist/dts/components/tree-item/tree-item.definition.d.ts.map +1 -1
  52. package/dist/dts/components/tree-item/tree-item.styles.d.ts +2 -0
  53. package/dist/dts/components/tree-item/tree-item.styles.d.ts.map +1 -0
  54. package/dist/dts/components/tree-item/tree-item.template.d.ts +4 -0
  55. package/dist/dts/components/tree-item/tree-item.template.d.ts.map +1 -0
  56. package/dist/dts/components/wizard/wizard.d.ts +1 -1
  57. package/dist/dts/components/wizard/wizard.d.ts.map +1 -1
  58. package/dist/dts/components/wizard-step/wizard-step.d.ts +1 -1
  59. package/dist/dts/components/wizard-step/wizard-step.d.ts.map +1 -1
  60. package/dist/dts/index.d.ts +3 -2
  61. package/dist/dts/index.d.ts.map +1 -1
  62. package/dist/dts/util/accessibility-utilities.d.ts +23 -0
  63. package/dist/dts/util/accessibility-utilities.d.ts.map +1 -0
  64. package/dist/dts/util/attribute-utilities.d.ts +9 -0
  65. package/dist/dts/util/attribute-utilities.d.ts.map +1 -0
  66. package/dist/dts/util/debounce.d.ts.map +1 -0
  67. package/dist/dts/util/debug.d.ts +32 -0
  68. package/dist/dts/util/debug.d.ts.map +1 -0
  69. package/dist/dts/util/direction.d.ts +193 -0
  70. package/dist/dts/util/direction.d.ts.map +1 -1
  71. package/dist/dts/util/dom.d.ts +2 -0
  72. package/dist/dts/util/dom.d.ts.map +1 -0
  73. package/dist/dts/util/element-internal-mocks.d.ts +67 -0
  74. package/dist/dts/util/element-internal-mocks.d.ts.map +1 -0
  75. package/dist/dts/util/focus-management.d.ts +132 -0
  76. package/dist/dts/util/focus-management.d.ts.map +1 -0
  77. package/dist/dts/util/hash-utilities.d.ts +8 -0
  78. package/dist/dts/util/hash-utilities.d.ts.map +1 -0
  79. package/dist/dts/util/index.d.ts +13 -6
  80. package/dist/dts/util/index.d.ts.map +1 -1
  81. package/dist/dts/util/positioning/flexible-position-strategy.d.ts +87 -0
  82. package/dist/dts/util/positioning/flexible-position-strategy.d.ts.map +1 -0
  83. package/dist/dts/util/positioning/index.d.ts +9 -0
  84. package/dist/dts/util/positioning/index.d.ts.map +1 -0
  85. package/dist/dts/util/positioning/position-calculator.d.ts +46 -0
  86. package/dist/dts/util/positioning/position-calculator.d.ts.map +1 -0
  87. package/dist/dts/util/positioning/types.d.ts +181 -0
  88. package/dist/dts/util/positioning/types.d.ts.map +1 -0
  89. package/dist/esm/components/accordion-menu/accordion-menu.js +1 -1
  90. package/dist/esm/components/accordion-menu/accordion-menu.js.map +1 -1
  91. package/dist/esm/components/accordion-menu/accordion-menu.styles.js +1 -1
  92. package/dist/esm/components/accordion-menu-panel/accordion-menu-panel.js +2 -2
  93. package/dist/esm/components/accordion-menu-panel/accordion-menu-panel.js.map +1 -1
  94. package/dist/esm/components/accordion-menu-panel/accordion-menu-panel.styles.js +1 -1
  95. package/dist/esm/components/card/card.styles.js +1 -1
  96. package/dist/esm/components/card-footer/card-footer.styles.js +1 -1
  97. package/dist/esm/components/card-header/card-header.styles.js +1 -1
  98. package/dist/esm/components/card-preview/card-preview.styles.js +1 -1
  99. package/dist/esm/components/carousel/carousel.js +1 -1
  100. package/dist/esm/components/carousel/carousel.js.map +1 -1
  101. package/dist/esm/components/carousel/carousel.styles.js +1 -1
  102. package/dist/esm/components/component-register.js +67 -0
  103. package/dist/esm/components/component-register.js.map +1 -0
  104. package/dist/esm/components/compound-button/compound-button.options.js +1 -1
  105. package/dist/esm/components/field/field.js +68 -1
  106. package/dist/esm/components/field/field.js.map +1 -1
  107. package/dist/esm/components/filter-pill/filter-pill.js +1 -1
  108. package/dist/esm/components/filter-pill/filter-pill.js.map +1 -1
  109. package/dist/esm/components/filter-pill/filter-pill.options.js +1 -1
  110. package/dist/esm/components/filter-pill/filter-pill.styles.js +3 -2
  111. package/dist/esm/components/listbox/listbox.js +1 -1
  112. package/dist/esm/components/listbox/listbox.js.map +1 -1
  113. package/dist/esm/components/loading-button/loading-button.js.map +1 -1
  114. package/dist/esm/components/menu/menu.js +158 -230
  115. package/dist/esm/components/menu/menu.js.map +1 -1
  116. package/dist/esm/components/menu/menu.options.js +1 -1
  117. package/dist/esm/components/menu/menu.options.js.map +1 -1
  118. package/dist/esm/components/menu/menu.positioning.js +98 -201
  119. package/dist/esm/components/menu/menu.positioning.js.map +1 -1
  120. package/dist/esm/components/menu/menu.styles.js +2 -2
  121. package/dist/esm/components/menu/menu.styles.js.map +1 -1
  122. package/dist/esm/components/menu-item/menu-item.js +4 -4
  123. package/dist/esm/components/menu-item/menu-item.js.map +1 -1
  124. package/dist/esm/components/menu-item/menu-item.styles.js +1 -1
  125. package/dist/esm/components/menu-list/menu-list.js +1 -1
  126. package/dist/esm/components/menu-list/menu-list.js.map +1 -1
  127. package/dist/esm/components/menu-list/menu-list.styles.js +1 -1
  128. package/dist/esm/components/multi-view/multi-view.styles.js +1 -1
  129. package/dist/esm/components/multi-view-controller/multi-view-controller.styles.js +1 -1
  130. package/dist/esm/components/multi-view-group/multi-view-group.styles.js +1 -1
  131. package/dist/esm/components/option-group/option-group.js +1 -1
  132. package/dist/esm/components/option-group/option-group.js.map +1 -1
  133. package/dist/esm/components/popover/define.js +2 -2
  134. package/dist/esm/components/popover/define.js.map +1 -1
  135. package/dist/esm/components/popover/popover.definition.js.map +1 -1
  136. package/dist/esm/components/popover/popover.js +82 -122
  137. package/dist/esm/components/popover/popover.js.map +1 -1
  138. package/dist/esm/components/popover/popover.options.js +2 -2
  139. package/dist/esm/components/popover/popover.options.js.map +1 -1
  140. package/dist/esm/components/popover/popover.positioning.js +314 -0
  141. package/dist/esm/components/popover/popover.positioning.js.map +1 -0
  142. package/dist/esm/components/popover/popover.styles.js +14 -18
  143. package/dist/esm/components/popover/popover.styles.js.map +1 -1
  144. package/dist/esm/components/search-box/search-box.js +1 -1
  145. package/dist/esm/components/search-box/search-box.js.map +1 -1
  146. package/dist/esm/components/search-box/search-box.options.js +1 -1
  147. package/dist/esm/components/search-box/search-box.options.js.map +1 -1
  148. package/dist/esm/components/simple-table/simple-table.styles.js +2 -1
  149. package/dist/esm/components/table/table.js +1 -1
  150. package/dist/esm/components/table/table.js.map +1 -1
  151. package/dist/esm/components/table/table.styles.js +1 -1
  152. package/dist/esm/components/table-cell/table-cell.styles.js +1 -1
  153. package/dist/esm/components/tag/tag.styles.js +1 -1
  154. package/dist/esm/components/teaching-bubble/teaching-bubble.styles.js +1 -1
  155. package/dist/esm/components/text-input/text-input.base.js +3 -3
  156. package/dist/esm/components/text-input/text-input.base.js.map +1 -1
  157. package/dist/esm/components/text-input/text-input.js +1 -0
  158. package/dist/esm/components/text-input/text-input.js.map +1 -1
  159. package/dist/esm/components/text-input/text-input.styles.js +1 -1
  160. package/dist/esm/components/tooltip/tooltip.js +23 -0
  161. package/dist/esm/components/tooltip/tooltip.js.map +1 -1
  162. package/dist/esm/components/tooltip/tooltip.template.js +16 -0
  163. package/dist/esm/components/tooltip/tooltip.template.js.map +1 -0
  164. package/dist/esm/components/tree/tree.js +38 -1
  165. package/dist/esm/components/tree/tree.js.map +1 -1
  166. package/dist/esm/components/tree-item/index.js +2 -1
  167. package/dist/esm/components/tree-item/index.js.map +1 -1
  168. package/dist/esm/components/tree-item/tree-item.definition.js +4 -3
  169. package/dist/esm/components/tree-item/tree-item.definition.js.map +1 -1
  170. package/dist/esm/components/tree-item/tree-item.styles.js +9 -0
  171. package/dist/esm/components/tree-item/tree-item.styles.js.map +1 -0
  172. package/dist/esm/components/tree-item/tree-item.template.js +6 -0
  173. package/dist/esm/components/tree-item/tree-item.template.js.map +1 -0
  174. package/dist/esm/components/wizard/wizard.js +3 -3
  175. package/dist/esm/components/wizard/wizard.js.map +1 -1
  176. package/dist/esm/components/wizard/wizard.styles.js +1 -1
  177. package/dist/esm/components/wizard-panel/wizard-panel.styles.js +1 -1
  178. package/dist/esm/components/wizard-step/wizard-step.js +1 -1
  179. package/dist/esm/components/wizard-step/wizard-step.js.map +1 -1
  180. package/dist/esm/components/wizard-step/wizard-step.styles.js +1 -1
  181. package/dist/esm/index.js +17 -7
  182. package/dist/esm/index.js.map +1 -1
  183. package/dist/esm/util/accessibility-utilities.js +40 -0
  184. package/dist/esm/util/accessibility-utilities.js.map +1 -0
  185. package/dist/esm/util/attribute-utilities.js +12 -0
  186. package/dist/esm/util/attribute-utilities.js.map +1 -0
  187. package/dist/esm/util/debounce.js.map +1 -0
  188. package/dist/esm/util/debug.js +74 -0
  189. package/dist/esm/util/debug.js.map +1 -0
  190. package/dist/esm/util/direction.js +240 -8
  191. package/dist/esm/util/direction.js.map +1 -1
  192. package/dist/esm/util/dom.js +3 -0
  193. package/dist/esm/util/dom.js.map +1 -0
  194. package/dist/esm/util/element-internal-mocks.js +114 -0
  195. package/dist/esm/util/element-internal-mocks.js.map +1 -0
  196. package/dist/esm/util/focus-management.js +247 -0
  197. package/dist/esm/util/focus-management.js.map +1 -0
  198. package/dist/esm/util/hash-utilities.js +12 -0
  199. package/dist/esm/util/hash-utilities.js.map +1 -0
  200. package/dist/esm/util/index.js +13 -6
  201. package/dist/esm/util/index.js.map +1 -1
  202. package/dist/esm/util/positioning/flexible-position-strategy.js +232 -0
  203. package/dist/esm/util/positioning/flexible-position-strategy.js.map +1 -0
  204. package/dist/esm/util/positioning/index.js +10 -0
  205. package/dist/esm/util/positioning/index.js.map +1 -0
  206. package/dist/esm/util/positioning/position-calculator.js +196 -0
  207. package/dist/esm/util/positioning/position-calculator.js.map +1 -0
  208. package/dist/esm/util/positioning/types.js +30 -0
  209. package/dist/esm/util/positioning/types.js.map +1 -0
  210. package/dist/index.d.ts +697 -223
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +2365 -1215
  213. package/dist/index.js.map +1 -1
  214. package/dist/index.min.js +109 -110
  215. package/dist/index.min.js.map +1 -1
  216. package/package.json +6 -8
  217. package/dist/component-utilities.js +0 -43
  218. package/dist/dts/components/popover/positioning.d.ts +0 -51
  219. package/dist/dts/components/popover/positioning.d.ts.map +0 -1
  220. package/dist/dts/util/positioning.d.ts +0 -129
  221. package/dist/dts/util/positioning.d.ts.map +0 -1
  222. package/dist/dts/utils/debounce.d.ts.map +0 -1
  223. package/dist/esm/component-utilities.js +0 -13
  224. package/dist/esm/components/popover/positioning.js +0 -189
  225. package/dist/esm/components/popover/positioning.js.map +0 -1
  226. package/dist/esm/util/positioning.js +0 -130
  227. package/dist/esm/util/positioning.js.map +0 -1
  228. package/dist/esm/utils/debounce.js.map +0 -1
  229. /package/dist/dts/{utils → util}/debounce.d.ts +0 -0
  230. /package/dist/esm/{utils → util}/debounce.js +0 -0
@@ -0,0 +1,247 @@
1
+ import { keyHome, keyEnd, keyArrowUp, keyArrowRight, keyArrowLeft, keyArrowDown } from '@microsoft/fast-web-utilities';
2
+
3
+ /**
4
+ * Default disabled check: matches disabled, aria-disabled="true", or inert attributes.
5
+ */
6
+ const defaultIsDisabled = el => el.matches('[disabled], [aria-disabled="true"], [inert]');
7
+ /**
8
+ * Creates a roving focus controller for managing keyboard navigation
9
+ * across a list of elements using the roving tabindex pattern.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const controller = createRovingFocusController({
14
+ * items: () => this.slottedPills ?? [],
15
+ * orientation: "vertical",
16
+ * enableHomeEnd: true,
17
+ * wrap: true
18
+ * });
19
+ *
20
+ * // In connectedCallback or setup:
21
+ * controller.applyTabindex();
22
+ *
23
+ * // In keydown handler:
24
+ * if (controller.handleKeydown(event)) return;
25
+ * // ...handle other keys like Escape
26
+ * ```
27
+ *
28
+ * @public
29
+ */
30
+ function createRovingFocusController(options) {
31
+ const {
32
+ items,
33
+ isDisabled = defaultIsDisabled,
34
+ orientation = "vertical",
35
+ enableHomeEnd = true,
36
+ wrap = true,
37
+ preventDefault = true,
38
+ focusItem,
39
+ onFocusChange,
40
+ isRtl
41
+ } = options;
42
+ /**
43
+ * Find the currently active item (the one with tabindex="0").
44
+ */
45
+ const findActiveItem = () => {
46
+ var _a;
47
+ const allItems = items();
48
+ return (_a = allItems.find(el => el.getAttribute("tabindex") === "0")) !== null && _a !== void 0 ? _a : null;
49
+ };
50
+ /**
51
+ * Set tabindex on all items, making the specified element active.
52
+ * Disabled items are always set to -1 regardless of activeEl.
53
+ */
54
+ const setActive = (activeEl, allItems) => {
55
+ const list = allItems !== null && allItems !== void 0 ? allItems : items();
56
+ for (const el of list) {
57
+ const shouldBeActive = el === activeEl && !isDisabled(el);
58
+ el.tabIndex = shouldBeActive ? 0 : -1;
59
+ el.setAttribute("tabindex", shouldBeActive ? "0" : "-1");
60
+ }
61
+ };
62
+ /**
63
+ * Focus an element using custom focusItem or default focus().
64
+ */
65
+ const doFocus = el => {
66
+ if (focusItem) {
67
+ focusItem(el);
68
+ } else {
69
+ el.focus();
70
+ }
71
+ };
72
+ /**
73
+ * Activate an item: set tabindex, optionally focus, and fire callback.
74
+ * Centralizes the repeated setActive + doFocus + onFocusChange pattern.
75
+ */
76
+ const activate = (el, enabledIndex, shouldFocus, allItems) => {
77
+ setActive(el, allItems);
78
+ if (shouldFocus) doFocus(el);
79
+ if (enabledIndex !== null) onFocusChange === null || onFocusChange === void 0 ? void 0 : onFocusChange(el, enabledIndex);
80
+ };
81
+ /**
82
+ * Apply roving tabindex. Preserves current active if still valid;
83
+ * otherwise falls back to first enabled.
84
+ */
85
+ const applyTabindex = () => {
86
+ const allItems = items();
87
+ if (allItems.length === 0) return;
88
+ const enabled = allItems.filter(el => !isDisabled(el));
89
+ if (enabled.length === 0) {
90
+ // No enabled items - all get -1
91
+ setActive(null, allItems);
92
+ return;
93
+ }
94
+ // Try to preserve current active if still valid and enabled
95
+ const currentActive = findActiveItem();
96
+ if (currentActive && enabled.includes(currentActive)) {
97
+ // Current active is still valid - keep it
98
+ setActive(currentActive, allItems);
99
+ return;
100
+ }
101
+ // Fall back to first enabled
102
+ setActive(enabled[0], allItems);
103
+ };
104
+ /**
105
+ * Move focus by delta, with optional wrapping.
106
+ * Uses tabindex=0 to determine current position (Shadow DOM safe).
107
+ */
108
+ const move = delta => {
109
+ const allItems = items();
110
+ const enabled = allItems.filter(el => !isDisabled(el));
111
+ if (enabled.length === 0) return false;
112
+ // Single item: nowhere to move
113
+ if (enabled.length === 1) return false;
114
+ // Find current index via tabindex=0 (not document.activeElement - Shadow DOM safe)
115
+ const currentActive = findActiveItem();
116
+ let currentIndex = currentActive ? enabled.indexOf(currentActive) : -1;
117
+ if (currentIndex === -1) currentIndex = 0;
118
+ // Calculate next index
119
+ let nextIndex = currentIndex + delta;
120
+ if (wrap) {
121
+ nextIndex = (nextIndex + enabled.length) % enabled.length;
122
+ } else {
123
+ // Clamp to bounds
124
+ if (nextIndex < 0 || nextIndex >= enabled.length) {
125
+ return false; // At boundary, can't move
126
+ }
127
+ }
128
+ const nextEl = enabled[nextIndex];
129
+ activate(nextEl, nextIndex, true, allItems);
130
+ return true;
131
+ };
132
+ /**
133
+ * Focus first enabled item.
134
+ */
135
+ const focusFirst = () => {
136
+ const allItems = items();
137
+ const enabled = allItems.filter(el => !isDisabled(el));
138
+ if (enabled.length === 0) return false;
139
+ activate(enabled[0], 0, true, allItems);
140
+ return true;
141
+ };
142
+ /**
143
+ * Focus last enabled item.
144
+ */
145
+ const focusLast = () => {
146
+ const allItems = items();
147
+ const enabled = allItems.filter(el => !isDisabled(el));
148
+ if (enabled.length === 0) return false;
149
+ const lastIndex = enabled.length - 1;
150
+ activate(enabled[lastIndex], lastIndex, true, allItems);
151
+ return true;
152
+ };
153
+ /**
154
+ * Focus specific item.
155
+ */
156
+ const focus = item => {
157
+ const allItems = items();
158
+ if (!allItems.includes(item)) return false;
159
+ if (isDisabled(item)) return false;
160
+ const enabled = allItems.filter(el => !isDisabled(el));
161
+ const index = enabled.indexOf(item);
162
+ activate(item, index !== -1 ? index : null, true, allItems);
163
+ return true;
164
+ };
165
+ /**
166
+ * Sync tabindex to target without focusing (for click/focusin handlers).
167
+ * Fires onFocusChange to maintain consistency with other activation methods.
168
+ */
169
+ const sync = target => {
170
+ if (!target || !(target instanceof HTMLElement)) return false;
171
+ const allItems = items();
172
+ // Find the closest managed item (target might be a child of a managed item)
173
+ const item = allItems.find(el => el === target || el.contains(target));
174
+ if (!item) return false;
175
+ if (isDisabled(item)) return false;
176
+ const enabled = allItems.filter(el => !isDisabled(el));
177
+ const index = enabled.indexOf(item);
178
+ // Use activate with shouldFocus=false to avoid refocus jump
179
+ activate(item, index !== -1 ? index : null, false, allItems);
180
+ return true;
181
+ };
182
+ /**
183
+ * Check if a key matches the navigation direction.
184
+ * Respects RTL mode for horizontal navigation.
185
+ */
186
+ const isNavigationKey = (key, direction) => {
187
+ const rtl = isRtl();
188
+ if (direction === "prev") {
189
+ if (orientation === "vertical" || orientation === "both") {
190
+ if (key === keyArrowUp) return true;
191
+ }
192
+ if (orientation === "horizontal" || orientation === "both") {
193
+ // In RTL, ArrowRight goes to previous
194
+ if (rtl ? key === keyArrowRight : key === keyArrowLeft) return true;
195
+ }
196
+ } else {
197
+ if (orientation === "vertical" || orientation === "both") {
198
+ if (key === keyArrowDown) return true;
199
+ }
200
+ if (orientation === "horizontal" || orientation === "both") {
201
+ // In RTL, ArrowLeft goes to next
202
+ if (rtl ? key === keyArrowLeft : key === keyArrowRight) return true;
203
+ }
204
+ }
205
+ return false;
206
+ };
207
+ /**
208
+ * Handle keydown event.
209
+ */
210
+ const handleKeydown = event => {
211
+ const {
212
+ key
213
+ } = event;
214
+ let handled = false;
215
+ if (isNavigationKey(key, "prev")) {
216
+ handled = move(-1);
217
+ } else if (isNavigationKey(key, "next")) {
218
+ handled = move(1);
219
+ } else if (enableHomeEnd && key === keyHome) {
220
+ handled = focusFirst();
221
+ } else if (enableHomeEnd && key === keyEnd) {
222
+ handled = focusLast();
223
+ }
224
+ if (handled && preventDefault) {
225
+ event.preventDefault();
226
+ }
227
+ return handled;
228
+ };
229
+ /**
230
+ * Cleanup (no-op for now, kept for lifecycle symmetry).
231
+ */
232
+ const destroy = () => {
233
+ // No listeners to clean up - component handles that
234
+ };
235
+ return {
236
+ applyTabindex,
237
+ move,
238
+ focusFirst,
239
+ focusLast,
240
+ focus,
241
+ sync,
242
+ handleKeydown,
243
+ destroy
244
+ };
245
+ }
246
+
247
+ export { createRovingFocusController };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-management.js","sourceRoot":"","sources":["../../../../../../src/util/focus-management.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,OAAO,EACP,MAAM,EACP,MAAM,+BAA+B,CAAC;AA8HvC;;GAEG;AACH,MAAM,iBAAiB,GAAG,CAAC,EAAe,EAAW,EAAE,CACrD,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,2BAA2B,CACzC,OAA2B;IAE3B,MAAM,EACJ,KAAK,EACL,UAAU,GAAG,iBAAiB,EAC9B,WAAW,GAAG,UAAU,EACxB,aAAa,GAAG,IAAI,EACpB,IAAI,GAAG,IAAI,EACX,cAAc,GAAG,IAAI,EACrB,SAAS,EACT,aAAa,EACb,KAAK,EACN,GAAG,OAAO,CAAC;IAEZ;;OAEG;IACH,MAAM,cAAc,GAAG,GAAuB,EAAE;;QAC9C,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,OAAO,MAAA,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,mCAAI,IAAI,CAAC;IAC5E,CAAC,CAAC;IAEF;;;OAGG;IACH,MAAM,SAAS,GAAG,CAChB,QAA4B,EAC5B,QAAwB,EAClB,EAAE;QACR,MAAM,IAAI,GAAG,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,KAAK,EAAE,CAAC;QACjC,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;YACtB,MAAM,cAAc,GAAG,EAAE,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC1D,EAAE,CAAC,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,OAAO,GAAG,CAAC,EAAe,EAAQ,EAAE;QACxC,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC;IAEF;;;OAGG;IACH,MAAM,QAAQ,GAAG,CACf,EAAe,EACf,YAA2B,EAC3B,WAAoB,EACpB,QAAwB,EAClB,EAAE;QACR,SAAS,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACxB,IAAI,WAAW;YAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,YAAY,KAAK,IAAI;YAAE,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF;;;OAGG;IACH,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAElC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,gCAAgC;YAChC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,4DAA4D;QAC5D,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC;QACvC,IAAI,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACrD,0CAA0C;YAC1C,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,6BAA6B;QAC7B,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC;IAEF;;;OAGG;IACH,MAAM,IAAI,GAAG,CAAC,KAAa,EAAW,EAAE;QACtC,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAEvC,+BAA+B;QAC/B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAEvC,mFAAmF;QACnF,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC;QACvC,IAAI,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,IAAI,YAAY,KAAK,CAAC,CAAC;YAAE,YAAY,GAAG,CAAC,CAAC;QAE1C,uBAAuB;QACvB,IAAI,SAAS,GAAG,YAAY,GAAG,KAAK,CAAC;QAErC,IAAI,IAAI,EAAE,CAAC;YACT,SAAS,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,kBAAkB;YAClB,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACjD,OAAO,KAAK,CAAC,CAAC,0BAA0B;YAC1C,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,UAAU,GAAG,GAAY,EAAE;QAC/B,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAEvC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,SAAS,GAAG,GAAY,EAAE;QAC9B,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAEvC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACrC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,KAAK,GAAG,CAAC,IAAiB,EAAW,EAAE;QAC3C,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAEnC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEpC,QAAQ,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF;;;OAGG;IACH,MAAM,IAAI,GAAG,CAAC,MAA0B,EAAW,EAAE;QACnD,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,YAAY,WAAW,CAAC;YAAE,OAAO,KAAK,CAAC;QAE9D,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC;QACzB,4EAA4E;QAC5E,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,MAAM,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAEzE,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QAEnC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEpC,4DAA4D;QAC5D,QAAQ,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF;;;OAGG;IACH,MAAM,eAAe,GAAG,CACtB,GAAW,EACX,SAA0B,EACjB,EAAE;QACX,MAAM,GAAG,GAAG,KAAK,EAAE,CAAC;QACpB,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,IAAI,WAAW,KAAK,UAAU,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;gBACzD,IAAI,GAAG,KAAK,UAAU;oBAAE,OAAO,IAAI,CAAC;YACtC,CAAC;YACD,IAAI,WAAW,KAAK,YAAY,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;gBAC3D,sCAAsC;gBACtC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG,KAAK,YAAY;oBAAE,OAAO,IAAI,CAAC;YACtE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,WAAW,KAAK,UAAU,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;gBACzD,IAAI,GAAG,KAAK,YAAY;oBAAE,OAAO,IAAI,CAAC;YACxC,CAAC;YACD,IAAI,WAAW,KAAK,YAAY,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;gBAC3D,iCAAiC;gBACjC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,aAAa;oBAAE,OAAO,IAAI,CAAC;YACtE,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAW,EAAE;QACtD,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACtB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,IAAI,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;YACjC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;YACxC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,aAAa,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YAC5C,OAAO,GAAG,UAAU,EAAE,CAAC;QACzB,CAAC;aAAM,IAAI,aAAa,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YAC3C,OAAO,GAAG,SAAS,EAAE,CAAC;QACxB,CAAC;QAED,IAAI,OAAO,IAAI,cAAc,EAAE,CAAC;YAC9B,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF;;OAEG;IACH,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,oDAAoD;IACtD,CAAC,CAAC;IAEF,OAAO;QACL,aAAa;QACb,IAAI;QACJ,UAAU;QACV,SAAS;QACT,KAAK;QACL,IAAI;QACJ,aAAa;QACb,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Creates a unique ID string using a prefix and counter as salt for the random hex.
3
+ * @param prefix - The prefix string for the ID
4
+ * @param counter - Optional. A counter value used as salt for additional uniqueness
5
+ * @returns A unique ID string in the format `{prefix}{counter}-{randomHex}`
6
+ */
7
+ function createUniqueId(prefix, counter = 0) {
8
+ const randomHex = Math.round((Math.random() + counter) * 0x10000).toString(16).slice(0, 8);
9
+ return `${prefix}${counter}-${randomHex}`;
10
+ }
11
+
12
+ export { createUniqueId };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-utilities.js","sourceRoot":"","sources":["../../../../../../src/util/hash-utilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,UAAkB,CAAC;IAChE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC;SAC9D,QAAQ,CAAC,EAAE,CAAC;SACZ,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACf,OAAO,GAAG,MAAM,GAAG,OAAO,IAAI,SAAS,EAAE,CAAC;AAC5C,CAAC"}
@@ -1,11 +1,18 @@
1
+ export * from "./accessibility-utilities.js";
2
+ export * from "./apply-mixins.js";
3
+ export * from "./attribute-utilities.js";
4
+ export * from "./debounce.js";
5
+ export * from "./debug.js";
1
6
  export * from "./descendants.js";
2
7
  export * from "./direction.js";
3
- export * from "./typings.js";
4
- export * from "./template-helpers.js";
5
- export * from "./match-media-stylesheet-behaviors.js";
8
+ export * from "./dom.js";
9
+ export * from "./element-internal-mocks.js";
6
10
  export * from "./element-internals.js";
7
- export * from "./apply-mixins.js";
8
- export * from "./whitespace-filter.js";
11
+ export * from "./focus-management.js";
12
+ export * from "./hash-utilities.js";
13
+ export * from "./match-media-stylesheet-behaviors.js";
9
14
  export * from "./support.js";
10
- export * from "./positioning.js";
15
+ export * from "./template-helpers.js";
16
+ export * from "./typings.js";
17
+ export * from "./whitespace-filter.js";
11
18
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/util/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/util/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uCAAuC,CAAC;AACtD,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,232 @@
1
+ import { getBoundaryBounds, getViewportBounds, getEffectiveBoundary, getOriginPoint, getOverlayPoint, getOverlayFit, applyPositionStyles } from './position-calculator.js';
2
+
3
+ /**
4
+ * Flexible position strategy - main positioning engine.
5
+ * Orchestrates position calculation, fallback selection, and style application.
6
+ * Inspired by Angular CDK's FlexibleConnectedPositionStrategy.
7
+ */
8
+ /**
9
+ * Flexible position strategy implementation.
10
+ * Main entry point for positioning overlays with fallback logic.
11
+ */
12
+ class FlexiblePositionStrategy {
13
+ constructor(config) {
14
+ var _a, _b, _c, _d;
15
+ this.origin = config.origin;
16
+ this.overlay = config.overlay;
17
+ this.positions = config.positions;
18
+ this.boundaryElement = (_a = config.boundaryElement) !== null && _a !== void 0 ? _a : null;
19
+ this.offsetParent = (_b = config.offsetParent) !== null && _b !== void 0 ? _b : null;
20
+ this.viewportMargin = (_c = config.viewportMargin) !== null && _c !== void 0 ? _c : 0;
21
+ this.resize = (_d = config.resize) !== null && _d !== void 0 ? _d : false;
22
+ this.resizeMinHeight = config.resizeMinHeight;
23
+ }
24
+ /**
25
+ * Get the effective boundary (custom boundary or viewport).
26
+ */
27
+ getBoundary() {
28
+ const rawBoundary = this.boundaryElement ? getBoundaryBounds(this.boundaryElement) : getViewportBounds();
29
+ return getEffectiveBoundary(rawBoundary, this.viewportMargin);
30
+ }
31
+ /**
32
+ * Returns the configured candidate positions.
33
+ */
34
+ getCandidates() {
35
+ return [...this.positions];
36
+ }
37
+ /**
38
+ * Evaluate a single position against the current boundary.
39
+ * Returns the computed PositionResult without applying any styles.
40
+ */
41
+ evaluatePosition(position) {
42
+ const originRect = this.origin.getBoundingClientRect();
43
+ const overlayRect = this.overlay.getBoundingClientRect();
44
+ const boundary = this.getBoundary();
45
+ const originPoint = getOriginPoint(originRect, position);
46
+ const overlayPoint = getOverlayPoint(originPoint, overlayRect, position);
47
+ const fit = getOverlayFit(overlayPoint, overlayRect, boundary);
48
+ return {
49
+ position,
50
+ originPoint,
51
+ overlayPoint,
52
+ fit
53
+ };
54
+ }
55
+ /**
56
+ * Selects the best position from the candidates list.
57
+ *
58
+ * 1. First candidate that fits completely wins immediately.
59
+ * 2. If nothing fits and resize is enabled, picks the one with most
60
+ * available space (best candidate for resize).
61
+ * 3. Otherwise picks the position with the most visible area.
62
+ */
63
+ selectBestPosition() {
64
+ const candidates = this.getCandidates();
65
+ let bestResult = this.evaluatePosition(candidates[0]);
66
+ let bestArea = bestResult.fit.visibleArea;
67
+ if (bestResult.fit.isCompletelyWithinViewport) {
68
+ return bestResult;
69
+ }
70
+ for (let i = 1; i < candidates.length; i++) {
71
+ const result = this.evaluatePosition(candidates[i]);
72
+ if (result.fit.isCompletelyWithinViewport) {
73
+ return result;
74
+ }
75
+ if (result.fit.visibleArea > bestArea) {
76
+ bestResult = result;
77
+ bestArea = result.fit.visibleArea;
78
+ }
79
+ }
80
+ // Nothing fits. If resize is enabled, prefer the candidate with most room.
81
+ if (this.resize && candidates.length > 1) {
82
+ let bestSpace = this.getAvailableSpace(candidates[0]);
83
+ let bestSpaceCandidate = candidates[0];
84
+ for (let i = 1; i < candidates.length; i++) {
85
+ const space = this.getAvailableSpace(candidates[i]);
86
+ if (space > bestSpace) {
87
+ bestSpace = space;
88
+ bestSpaceCandidate = candidates[i];
89
+ }
90
+ }
91
+ if (bestSpaceCandidate !== bestResult.position) {
92
+ return this.evaluatePosition(bestSpaceCandidate);
93
+ }
94
+ }
95
+ return bestResult;
96
+ }
97
+ /**
98
+ * Apply position result to the overlay element.
99
+ */
100
+ applyPositionResult(result) {
101
+ applyPositionStyles(this.overlay, result.overlayPoint, result.position, this.offsetParent);
102
+ }
103
+ /**
104
+ * Get the available space for the overlay in a given position.
105
+ * Measures the distance from the anchor edge to the boundary edge in the
106
+ * relevant direction based on the position's connection points.
107
+ *
108
+ * @param position - The connected position to measure space for.
109
+ * @returns Available space in pixels.
110
+ */
111
+ getAvailableSpace(position) {
112
+ var _a;
113
+ const originRect = this.origin.getBoundingClientRect();
114
+ const boundary = this.getBoundary();
115
+ // Determine direction based on the connection points.
116
+ // "above" style: overlayY === bottom, originY === top → space above anchor
117
+ // "below" style: overlayY === top, originY === bottom → space below anchor
118
+ if (position.overlayY === "bottom" && position.originY === "top") {
119
+ // Overlay sits above the anchor
120
+ return Math.max(0, originRect.top - boundary.top);
121
+ }
122
+ if (position.overlayY === "top" && position.originY === "bottom") {
123
+ // Overlay sits below the anchor
124
+ return Math.max(0, boundary.bottom - originRect.bottom);
125
+ }
126
+ // Horizontal cases (start/end)
127
+ if (position.overlayX === "end" && position.originX === "start") {
128
+ return Math.max(0, originRect.left - boundary.left);
129
+ }
130
+ if (position.overlayX === "start" && position.originX === "end") {
131
+ return Math.max(0, boundary.right - originRect.right);
132
+ }
133
+ // Fallback: return full boundary height
134
+ return Math.max(0, ((_a = boundary.height) !== null && _a !== void 0 ? _a : boundary.bottom - boundary.top) || 0);
135
+ }
136
+ /**
137
+ * Applies a resize constraint to the overlay element if it
138
+ * does not fit in the available space for the given position.
139
+ *
140
+ * @param position - The connected position to measure available space for.
141
+ * @returns Whether a constraint was applied and the max-height value.
142
+ */
143
+ tryResize(position) {
144
+ if (!this.resize) {
145
+ return {
146
+ resized: false,
147
+ maxHeight: null
148
+ };
149
+ }
150
+ const overlayHeight = this.overlay.getBoundingClientRect().height;
151
+ const available = this.getAvailableSpace(position);
152
+ if (overlayHeight <= available) {
153
+ return {
154
+ resized: false,
155
+ maxHeight: null
156
+ };
157
+ }
158
+ if (this.resizeMinHeight !== undefined && available < this.resizeMinHeight) {
159
+ return {
160
+ resized: false,
161
+ maxHeight: null
162
+ };
163
+ }
164
+ this.overlay.style.maxHeight = `${available}px`;
165
+ this.overlay.style.overflow = "auto";
166
+ return {
167
+ resized: true,
168
+ maxHeight: available
169
+ };
170
+ }
171
+ /**
172
+ * High-level reposition entry point.
173
+ *
174
+ * 1. Clears any previous resize constraint so the overlay is evaluated
175
+ * at its natural size.
176
+ * 2. Selects the best position from the positions array.
177
+ * 3. Applies a resize constraint if the overlay still overflows.
178
+ * 4. Applies the final position.
179
+ *
180
+ * The component controls flip vs auto behavior by choosing which
181
+ * positions to provide:
182
+ * - Flip: `[original, opposite]`
183
+ * - Auto: `[original, ...allOtherCandidates]`
184
+ *
185
+ * @returns A {@link RepositionResult} describing what happened, or `null`
186
+ * if no positions or resize are provided.
187
+ */
188
+ reposition() {
189
+ const candidates = this.getCandidates();
190
+ if (candidates.length === 0 && !this.resize) {
191
+ return null;
192
+ }
193
+ // Clear any previous resize constraint to evaluate natural size
194
+ this.clearResize();
195
+ // Step 1: Select the best position (evaluated at natural overlay size)
196
+ let positionResult = this.selectBestPosition();
197
+ // Step 2: Apply resize constraint if enabled
198
+ let resized = false;
199
+ let maxHeight = null;
200
+ if (this.resize) {
201
+ ({
202
+ resized,
203
+ maxHeight
204
+ } = this.tryResize(positionResult.position));
205
+ if (resized) {
206
+ // Re-evaluate the overlay point now that the element has been resized.
207
+ // The post-resize dimensions are smaller, so any position that depends
208
+ // on overlay height (e.g. "above" where overlayY === "bottom") would
209
+ // produce a stale — and incorrect — overlayPoint if we skipped this.
210
+ positionResult = this.evaluatePosition(positionResult.position);
211
+ }
212
+ }
213
+ // Step 3: Apply the selected position
214
+ this.applyPositionResult(positionResult);
215
+ return {
216
+ resized,
217
+ maxHeight,
218
+ positionResult
219
+ };
220
+ }
221
+ /**
222
+ * Clear any resize constraint applied to the overlay element.
223
+ */
224
+ clearResize() {
225
+ if (this.resize) {
226
+ this.overlay.style.maxHeight = "";
227
+ this.overlay.style.overflow = "";
228
+ }
229
+ }
230
+ }
231
+
232
+ export { FlexiblePositionStrategy };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flexible-position-strategy.js","sourceRoot":"","sources":["../../../../../../../src/util/positioning/flexible-position-strategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Positioning utilities - Angular CDK-inspired positioning engine.
3
+ * @packageDocumentation
4
+ */
5
+ export { HorizontalConnectionPositions, VerticalConnectionPositions, CollisionEdges, RepositionModes, DEFAULT_ROOT_MARGIN } from "./types.js";
6
+ // Position Calculator
7
+ export { getViewportBounds, getBoundaryBounds, getEffectiveBoundary, getOriginPoint, getOverlayPoint, getOverlayFit, applyPositionStyles } from "./position-calculator.js";
8
+ // Flexible Position Strategy
9
+ export { FlexiblePositionStrategy } from "./flexible-position-strategy.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../src/util/positioning/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAqBH,OAAO,EACL,6BAA6B,EAC7B,2BAA2B,EAC3B,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,sBAAsB;AACtB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,aAAa,EACb,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAElC,6BAA6B;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC"}