@ixfx/components 0.5.19 → 0.6.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 (198) hide show
  1. package/bundle/index.d.ts +462 -210
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +8027 -6493
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.js +3 -3
  6. package/dist/ac-token-DVbmHmky.d.ts +107 -0
  7. package/dist/ac-token-DVbmHmky.d.ts.map +1 -0
  8. package/dist/ac-token.d.ts +2 -0
  9. package/dist/ac-token.js +646 -0
  10. package/dist/ac-token.js.map +1 -0
  11. package/dist/{button-CphdEaZd.js → button-Bn0BuLpO.js} +2 -3
  12. package/dist/{button-CphdEaZd.js.map → button-Bn0BuLpO.js.map} +1 -1
  13. package/dist/button.d.ts +1 -1
  14. package/dist/button.d.ts.map +1 -1
  15. package/dist/button.js +1 -1
  16. package/dist/checkbox.js +1 -1
  17. package/dist/{colour-picker-37NyVenk.js → colour-picker-0stHB90J.js} +18 -8
  18. package/dist/colour-picker-0stHB90J.js.map +1 -0
  19. package/dist/colour-picker.d.ts +1 -1
  20. package/dist/colour-picker.js +1 -1
  21. package/dist/crumbs.d.ts +2 -2
  22. package/dist/crumbs.js +1152 -1
  23. package/dist/crumbs.js.map +1 -0
  24. package/dist/data-controller-DOlmqNKb.js +171 -0
  25. package/dist/data-controller-DOlmqNKb.js.map +1 -0
  26. package/dist/data-display.js +1 -1
  27. package/dist/data-grid-BeAkORz2.d.ts +215 -0
  28. package/dist/data-grid-BeAkORz2.d.ts.map +1 -0
  29. package/dist/data-grid.d.ts +2 -0
  30. package/dist/data-grid.js +1225 -0
  31. package/dist/data-grid.js.map +1 -0
  32. package/dist/data-provider-BAn_-oR1.d.ts +61 -0
  33. package/dist/data-provider-BAn_-oR1.d.ts.map +1 -0
  34. package/dist/{defaults-BkWCPJFL.js → defaults-BCiDhZbF.js} +20 -3
  35. package/dist/defaults-BCiDhZbF.js.map +1 -0
  36. package/dist/drag-ghost-DtSDvjri.js +85 -0
  37. package/dist/drag-ghost-DtSDvjri.js.map +1 -0
  38. package/dist/editable-label.js +1 -1
  39. package/dist/{incr-search-2pz21xtR.js → element-search-Y8SRfPGM.js} +2 -133
  40. package/dist/element-search-Y8SRfPGM.js.map +1 -0
  41. package/dist/fallbacks-DEE1nCTt.js +406 -0
  42. package/dist/fallbacks-DEE1nCTt.js.map +1 -0
  43. package/dist/form-CsXJX15p.js +64 -0
  44. package/dist/form-CsXJX15p.js.map +1 -0
  45. package/dist/form.d.ts +15 -0
  46. package/dist/form.d.ts.map +1 -0
  47. package/dist/form.js +2 -0
  48. package/dist/grouped-item-lister-CNLMgdIr.d.ts +121 -0
  49. package/dist/grouped-item-lister-CNLMgdIr.d.ts.map +1 -0
  50. package/dist/grouped-item-lister.d.ts +2 -0
  51. package/dist/grouped-item-lister.js +177 -0
  52. package/dist/grouped-item-lister.js.map +1 -0
  53. package/dist/{icon-DG9Lm3LT.js → icons-Bm2ByQ3s.js} +6 -3
  54. package/dist/icons-Bm2ByQ3s.js.map +1 -0
  55. package/dist/icons.js +2 -8
  56. package/dist/incr-search-vCzuao-2.js +137 -0
  57. package/dist/incr-search-vCzuao-2.js.map +1 -0
  58. package/dist/incr-search.d.ts +1 -1
  59. package/dist/incr-search.js +2 -1
  60. package/dist/{index-BKAlRgbq.d.ts → index-BOUaDIW-.d.ts} +4 -1
  61. package/dist/index-BOUaDIW-.d.ts.map +1 -0
  62. package/dist/{index-D9u_Q7-b.d.ts → index-Cu5i8zZY.d.ts} +3 -3
  63. package/dist/{index-D9u_Q7-b.d.ts.map → index-Cu5i8zZY.d.ts.map} +1 -1
  64. package/dist/{index-DkhBGHgF.d.ts → index-ovq_GTdl.d.ts} +2 -2
  65. package/dist/{index-DkhBGHgF.d.ts.map → index-ovq_GTdl.d.ts.map} +1 -1
  66. package/dist/index.d.ts +54 -572
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +1898 -4253
  69. package/dist/index.js.map +1 -1
  70. package/dist/labelled-radial-input.d.ts +1 -1
  71. package/dist/labelled-radial-input.js +1 -2
  72. package/dist/labelled-radial-input.js.map +1 -1
  73. package/dist/led.d.ts +0 -1
  74. package/dist/led.d.ts.map +1 -1
  75. package/dist/led.js +2 -4
  76. package/dist/led.js.map +1 -1
  77. package/dist/menu-DIfU70AA.js +1609 -0
  78. package/dist/menu-DIfU70AA.js.map +1 -0
  79. package/dist/menu-item-BG5w7fi4.d.ts.map +1 -1
  80. package/dist/menu.d.ts +1 -1
  81. package/dist/menu.js +1 -2
  82. package/dist/miller.d.ts +3 -3
  83. package/dist/miller.js +3 -3
  84. package/dist/narrowed-text.d.ts.map +1 -1
  85. package/dist/narrowed-text.js +4 -4
  86. package/dist/narrowed-text.js.map +1 -1
  87. package/dist/notification-pill-DyZydXoZ.d.ts +68 -0
  88. package/dist/notification-pill-DyZydXoZ.d.ts.map +1 -0
  89. package/dist/notifier.d.ts +2 -0
  90. package/dist/notifier.js +146 -0
  91. package/dist/notifier.js.map +1 -0
  92. package/dist/panel.js +1 -2
  93. package/dist/panel.js.map +1 -1
  94. package/dist/plots.js +1 -1
  95. package/dist/polar-pad.d.ts +1 -1
  96. package/dist/polar-pad.js +1 -1
  97. package/dist/{radial-input-BhZeyyP-.d.ts → radial-input-DXMN55Nz.d.ts} +2 -2
  98. package/dist/{radial-input-BhZeyyP-.d.ts.map → radial-input-DXMN55Nz.d.ts.map} +1 -1
  99. package/dist/{radial-input-CVxGH-Cp.js → radial-input-Dk8Wydp5.js} +4 -4
  100. package/dist/radial-input-Dk8Wydp5.js.map +1 -0
  101. package/dist/radial-input.d.ts +1 -1
  102. package/dist/radial-input.js +1 -1
  103. package/dist/range-input.d.ts +1 -1
  104. package/dist/range-input.js +1 -1
  105. package/dist/range.d.ts +1 -1
  106. package/dist/range.js +1 -1
  107. package/dist/scroll-fade-CAs1EabA.js +70 -0
  108. package/dist/scroll-fade-CAs1EabA.js.map +1 -0
  109. package/dist/select-horiz.d.ts +50 -0
  110. package/dist/select-horiz.d.ts.map +1 -0
  111. package/dist/select-horiz.js +263 -0
  112. package/dist/select-horiz.js.map +1 -0
  113. package/dist/{slider-input-CzmSVgm7.js → slider-input-CT4gcF-o.js} +2 -2
  114. package/dist/{slider-input-CzmSVgm7.js.map → slider-input-CT4gcF-o.js.map} +1 -1
  115. package/dist/{slider-input-TidGhvXt.d.ts → slider-input-XppH3vcy.d.ts} +2 -2
  116. package/dist/{slider-input-TidGhvXt.d.ts.map → slider-input-XppH3vcy.d.ts.map} +1 -1
  117. package/dist/slider-input.d.ts +1 -1
  118. package/dist/slider-input.js +1 -1
  119. package/dist/snackbar.d.ts +58 -0
  120. package/dist/snackbar.d.ts.map +1 -0
  121. package/dist/snackbar.js +265 -0
  122. package/dist/snackbar.js.map +1 -0
  123. package/dist/split-layout.js +1 -1
  124. package/dist/swipe.d.ts +1 -1
  125. package/dist/swipe.js +1 -1
  126. package/dist/tabs.js +533 -1
  127. package/dist/tabs.js.map +1 -0
  128. package/dist/{tickled-controller-BF2Ea0DE.d.ts → tickled-controller-BtevrRLV.d.ts} +8 -6
  129. package/dist/tickled-controller-BtevrRLV.d.ts.map +1 -0
  130. package/dist/{tickled-styles-fNDdqf6l.js → tickled-controller-DkAU-0qL.js} +19 -105
  131. package/dist/tickled-controller-DkAU-0qL.js.map +1 -0
  132. package/dist/tickled-styles-BrAHEj1q.js +89 -0
  133. package/dist/tickled-styles-BrAHEj1q.js.map +1 -0
  134. package/dist/transitory-label.d.ts +30 -0
  135. package/dist/transitory-label.d.ts.map +1 -0
  136. package/dist/transitory-label.js +249 -0
  137. package/dist/transitory-label.js.map +1 -0
  138. package/dist/{tree-BtiiDX1a.js → tree-BO6BXI2b.js} +4 -4
  139. package/dist/{tree-BtiiDX1a.js.map → tree-BO6BXI2b.js.map} +1 -1
  140. package/dist/{tree-component-DQ9vzdy5.d.ts → tree-component-BvV4muxx.d.ts} +2 -2
  141. package/dist/{tree-component-DQ9vzdy5.d.ts.map → tree-component-BvV4muxx.d.ts.map} +1 -1
  142. package/dist/tree.d.ts +3 -3
  143. package/dist/tree.js +1 -1
  144. package/dist/{types-DO3gt5vg.d.ts → types-Bc23SI94.d.ts} +3 -61
  145. package/dist/types-Bc23SI94.d.ts.map +1 -0
  146. package/dist/types-DlVNJez_.d.ts +41 -0
  147. package/dist/types-DlVNJez_.d.ts.map +1 -0
  148. package/dist/vertical-list.d.ts +122 -0
  149. package/dist/vertical-list.d.ts.map +1 -0
  150. package/dist/vertical-list.js +737 -0
  151. package/dist/vertical-list.js.map +1 -0
  152. package/dist/wheel-nudge-BlSCe_hD.js.map +1 -1
  153. package/dist/{wheel-nudge-DgMTRYlh.d.ts → wheel-nudge-DGrNzWuE.d.ts} +3 -3
  154. package/dist/wheel-nudge-DGrNzWuE.d.ts.map +1 -0
  155. package/dist/{xy-axis-CxHC8z5E.js → xy-axis-B6yMjckW.js} +3 -109
  156. package/dist/xy-axis-B6yMjckW.js.map +1 -0
  157. package/dist/xy-pad.d.ts +1 -1
  158. package/dist/xy-pad.js +1 -1
  159. package/docs-user/README.md +3 -2
  160. package/docs-user/ac-token.md +7 -1
  161. package/docs-user/colour-picker.md +8 -4
  162. package/docs-user/data-grid.md +248 -0
  163. package/docs-user/index.json +217 -0
  164. package/docs-user/llms.txt +57 -0
  165. package/docs-user/menu.md +11 -8
  166. package/docs-user/rating.md +102 -0
  167. package/llms.txt +57 -0
  168. package/package.json +21 -11
  169. package/dist/colour-picker-37NyVenk.js.map +0 -1
  170. package/dist/crumb-navigation-BrB0r14u.js +0 -1220
  171. package/dist/crumb-navigation-BrB0r14u.js.map +0 -1
  172. package/dist/defaults-BkWCPJFL.js.map +0 -1
  173. package/dist/fallbacks-DPgPEqo8.js +0 -218
  174. package/dist/fallbacks-DPgPEqo8.js.map +0 -1
  175. package/dist/icon-DG9Lm3LT.js.map +0 -1
  176. package/dist/icons.js.map +0 -1
  177. package/dist/incr-search-2pz21xtR.js.map +0 -1
  178. package/dist/index-BKAlRgbq.d.ts.map +0 -1
  179. package/dist/interaction-D6efrBLo.js +0 -1
  180. package/dist/menu-CdwSe_XN.js +0 -825
  181. package/dist/menu-CdwSe_XN.js.map +0 -1
  182. package/dist/menu-item-CrmUwIoJ.js +0 -782
  183. package/dist/menu-item-CrmUwIoJ.js.map +0 -1
  184. package/dist/radial-input-CVxGH-Cp.js.map +0 -1
  185. package/dist/registry-CkW7q09Q.js +0 -21
  186. package/dist/registry-CkW7q09Q.js.map +0 -1
  187. package/dist/selecthorizontal.d.ts +0 -15
  188. package/dist/selecthorizontal.d.ts.map +0 -1
  189. package/dist/selecthorizontal.js +0 -43
  190. package/dist/selecthorizontal.js.map +0 -1
  191. package/dist/tab-list-mAoD6L0e.js +0 -615
  192. package/dist/tab-list-mAoD6L0e.js.map +0 -1
  193. package/dist/tickled-controller-BF2Ea0DE.d.ts.map +0 -1
  194. package/dist/tickled-styles-fNDdqf6l.js.map +0 -1
  195. package/dist/types-DO3gt5vg.d.ts.map +0 -1
  196. package/dist/wheel-nudge-DgMTRYlh.d.ts.map +0 -1
  197. package/dist/xy-axis-CxHC8z5E.js.map +0 -1
  198. package/docs-user/selecthorizontal.md +0 -32
@@ -0,0 +1,1609 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
+ import { t as TickledController } from "./tickled-controller-DkAU-0qL.js";
3
+ import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
4
+ import { t as themeFallbacks } from "./fallbacks-DEE1nCTt.js";
5
+ import { t as popupSurfaceStyles } from "./popup-D80sj2QC.js";
6
+ import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
7
+ import { LitElement, css, html, nothing } from "lit";
8
+ import { property, query, state } from "lit/decorators.js";
9
+ //#region src/menu/menu-container.ts
10
+ let MenuContainer = class MenuContainer extends LitElement {
11
+ constructor(..._args) {
12
+ super(..._args);
13
+ this.tickled = new TickledController(this, {
14
+ getItems: () => {
15
+ return this._getMenuItems().map((item, i) => ({
16
+ id: i,
17
+ enabled: !item.hasAttribute(`disabled`)
18
+ }));
19
+ },
20
+ onTickle: (index) => {
21
+ const items = this._getMenuItems();
22
+ if (index !== void 0) {
23
+ const item = items[index];
24
+ item.tabIndex = 0;
25
+ item.focus({ preventScroll: true });
26
+ }
27
+ },
28
+ onStateChange: () => {
29
+ this._syncTickledClasses();
30
+ }
31
+ });
32
+ this._handleMouseOver = (e) => {
33
+ const items = this._getMenuItems();
34
+ const path = e.composedPath();
35
+ const hoveredIndex = items.findIndex((item) => path.includes(item));
36
+ if (hoveredIndex !== -1) {
37
+ const item = items[hoveredIndex];
38
+ const itemPathIndex = path.indexOf(item);
39
+ if (!path.slice(0, itemPathIndex).some((node) => node instanceof Element && node.tagName === `IXFX-MENU-CONTAINER`)) this.tickled.handlePointerEnter(hoveredIndex);
40
+ e.stopPropagation();
41
+ }
42
+ };
43
+ this._handleKeydown = (e) => {
44
+ const items = this._getMenuItems();
45
+ if (items.length === 0) return;
46
+ switch (e.key) {
47
+ case `ArrowDown`:
48
+ e.preventDefault();
49
+ e.stopPropagation();
50
+ this._focusNext(items, 1);
51
+ break;
52
+ case `ArrowUp`:
53
+ e.preventDefault();
54
+ e.stopPropagation();
55
+ this._focusNext(items, -1);
56
+ break;
57
+ case `Home`:
58
+ e.preventDefault();
59
+ e.stopPropagation();
60
+ this._focusItem(items, 0);
61
+ break;
62
+ case `End`:
63
+ e.preventDefault();
64
+ e.stopPropagation();
65
+ this._focusItem(items, items.length - 1);
66
+ break;
67
+ case `Enter`:
68
+ case ` `:
69
+ e.preventDefault();
70
+ e.stopPropagation();
71
+ this._activateFocusedItem(items);
72
+ }
73
+ };
74
+ }
75
+ static {
76
+ this.styles = [
77
+ popupSurfaceStyles,
78
+ themeFallbacks,
79
+ tickledStyles,
80
+ css`
81
+ :host {
82
+ display: block;
83
+ }
84
+
85
+ .popover {
86
+ padding: var(--space-xs) 0;
87
+ min-width: 160px;
88
+ }
89
+
90
+ :host {
91
+ opacity: 1;
92
+ transform: translateY(0) scale(1);
93
+ transition: opacity 0.12s ease-out, transform 0.12s ease-out,
94
+ display 0.12s allow-discrete, overlay 0.12s allow-discrete;
95
+ }
96
+
97
+ @starting-style :host {
98
+ opacity: 0;
99
+ transform: translateY(-4px) scale(0.97);
100
+ }
101
+
102
+ ::slotted(menu-separator) {
103
+ display: block;
104
+ margin: var(--space-xs) 0;
105
+ }
106
+ `
107
+ ];
108
+ }
109
+ _updateIconSections() {
110
+ const slot = this.shadowRoot?.querySelector(`slot`);
111
+ if (!slot) return;
112
+ const assigned = slot.assignedElements({ flatten: true });
113
+ const sections = [];
114
+ let section = [];
115
+ for (const el of assigned) if (el.tagName === `IXFX-MENU-SEPARATOR` || el.tagName === `IXFX-MENU-HEADER`) {
116
+ if (section.length > 0) {
117
+ sections.push(section);
118
+ section = [];
119
+ }
120
+ } else section.push(el);
121
+ if (section.length > 0) sections.push(section);
122
+ this._propagateContext();
123
+ for (const sec of sections) {
124
+ const hasIcon = sec.some((el) => {
125
+ if (el.tagName === `IXFX-MENU-RADIO-GROUP`) return [...el.children].some((ri) => ri.hasAttribute(`icon-name`));
126
+ return el.hasAttribute(`icon-name`);
127
+ });
128
+ for (const el of sec) if (el.tagName === `IXFX-MENU-RADIO-GROUP`) for (const ri of el.children) if (hasIcon) ri.setAttribute(`data-icon-section`, ``);
129
+ else ri.removeAttribute(`data-icon-section`);
130
+ else if (hasIcon) el.setAttribute(`data-icon-section`, ``);
131
+ else el.removeAttribute(`data-icon-section`);
132
+ }
133
+ this.performUpdate();
134
+ }
135
+ _propagateContext() {
136
+ const slot = this.shadowRoot?.querySelector(`slot`);
137
+ if (!slot) return;
138
+ for (const el of slot.assignedElements({ flatten: true })) {
139
+ if (`registry` in el) el.registry = this.registry;
140
+ if (`keyboardManager` in el) el.keyboardManager = this.keyboardManager;
141
+ }
142
+ }
143
+ updated(changedProperties) {
144
+ if (changedProperties.has(`registry`) || changedProperties.has(`keyboardManager`)) this._propagateContext();
145
+ }
146
+ /**
147
+ * Sync data-input-mode to :host so CSS variables cascade to slotted items
148
+ */
149
+ willUpdate(changed) {
150
+ super.willUpdate(changed);
151
+ this.setAttribute(`data-input-mode`, this.tickled.inputMode);
152
+ }
153
+ render() {
154
+ return html`
155
+ <div
156
+ class="popover popup-surface"
157
+ role="menu"
158
+ @keydown=${this._handleKeydown}
159
+ @mouseover=${this._handleMouseOver}
160
+ >
161
+ <slot @slotchange=${this._updateIconSections}></slot>
162
+ </div>
163
+ `;
164
+ }
165
+ _getMenuItems() {
166
+ const slot = this.shadowRoot?.querySelector(`slot`);
167
+ if (!slot) return [];
168
+ const skipTags = [`IXFX-MENU-SEPARATOR`, `IXFX-MENU-HEADER`];
169
+ const result = [];
170
+ for (const el of slot.assignedElements({ flatten: true })) {
171
+ if (skipTags.includes(el.tagName)) continue;
172
+ if (el.hasAttribute(`disabled`)) continue;
173
+ const role = el.getAttribute(`role`);
174
+ if (role === `none` || role === `presentation`) continue;
175
+ if (el.tagName === `IXFX-MENU-RADIO-GROUP`) {
176
+ const groupSlot = el.shadowRoot?.querySelector(`slot`);
177
+ for (const radioItem of groupSlot?.assignedElements({ flatten: true }) ?? []) if (!radioItem.hasAttribute(`disabled`)) result.push(radioItem);
178
+ } else result.push(el);
179
+ }
180
+ return result;
181
+ }
182
+ /**
183
+ * Sync .tickled class on slotted items to match controller state
184
+ * This is called via onStateChange whenever the tickled state changes
185
+ */
186
+ _syncTickledClasses() {
187
+ const items = this._getMenuItems();
188
+ items.forEach((item, i) => {
189
+ if (this.tickled.isTickled(i)) {
190
+ item.classList.add(`tickled`);
191
+ item.tabIndex = 0;
192
+ const innerItem = item.shadowRoot?.querySelector(`.item`);
193
+ if (innerItem) {
194
+ innerItem.style.background = `rgba(0, 0, 0, 0.06)`;
195
+ innerItem.style.borderColor = `var(--accent)`;
196
+ innerItem.style.color = `inherit`;
197
+ }
198
+ } else {
199
+ item.classList.remove(`tickled`);
200
+ item.tabIndex = -1;
201
+ const innerItem = item.shadowRoot?.querySelector(`.item`);
202
+ if (innerItem) {
203
+ innerItem.style.background = ``;
204
+ innerItem.style.borderColor = ``;
205
+ innerItem.style.color = ``;
206
+ }
207
+ }
208
+ });
209
+ if (this.tickled.inputMode === `keyboard` && this.tickled.tickledId !== void 0) items[this.tickled.tickledId]?.focus();
210
+ }
211
+ focusFirst() {
212
+ this.tickled.handleKeyboardNavigation(`first`);
213
+ }
214
+ _focusNext(items, direction) {
215
+ if (items.length === 0) return;
216
+ this.tickled.handleKeyboardNavigation(direction > 0 ? `next` : `previous`);
217
+ }
218
+ _focusItem(items, index) {
219
+ if (items.length === 0) return;
220
+ const clampedIndex = Math.max(0, Math.min(index, items.length - 1));
221
+ this.tickled.handleKeyboardNavigation(clampedIndex);
222
+ }
223
+ _activateFocusedItem(items) {
224
+ const tickledIndex = this.tickled.tickledId;
225
+ if (tickledIndex === void 0) return;
226
+ const item = items[tickledIndex];
227
+ if (!item) return;
228
+ const tagName = item.tagName;
229
+ if (tagName === `IXFX-MENU-SUB-TRIGGER`) return;
230
+ if (tagName === `IXFX-MENU-CHECK-ITEM`) {
231
+ const checkItem = item;
232
+ checkItem.checked = !checkItem.checked;
233
+ checkItem.dispatchEvent(new CustomEvent(`command`, {
234
+ detail: {
235
+ command: checkItem.command,
236
+ checked: checkItem.checked
237
+ },
238
+ bubbles: true,
239
+ composed: true
240
+ }));
241
+ return;
242
+ }
243
+ if (tagName === `IXFX-MENU-RADIO-ITEM`) {
244
+ item.dispatchEvent(new CustomEvent(`radio-select`, {
245
+ detail: { value: item.value },
246
+ bubbles: true,
247
+ composed: true
248
+ }));
249
+ return;
250
+ }
251
+ if (tagName === `IXFX-MENU-ITEM`) {
252
+ const command = item.command;
253
+ if (command) item.dispatchEvent(new CustomEvent(`command`, {
254
+ detail: { command },
255
+ bubbles: true,
256
+ composed: true
257
+ }));
258
+ return;
259
+ }
260
+ item.click();
261
+ }
262
+ };
263
+ __decorate([property({
264
+ type: String,
265
+ attribute: `anchor`
266
+ })], MenuContainer.prototype, "anchor", void 0);
267
+ __decorate([property({ attribute: false })], MenuContainer.prototype, "registry", void 0);
268
+ __decorate([property({ attribute: false })], MenuContainer.prototype, "keyboardManager", void 0);
269
+ __decorate([query(`.popover`)], MenuContainer.prototype, "_popover", void 0);
270
+ MenuContainer = __decorate([safeCustomElement(`ixfx-menu-container`)], MenuContainer);
271
+ //#endregion
272
+ //#region src/menu/menu-trigger.ts
273
+ var _MenuTrigger;
274
+ let MenuTrigger = class MenuTrigger extends LitElement {
275
+ static {
276
+ _MenuTrigger = this;
277
+ }
278
+ constructor(..._args) {
279
+ super(..._args);
280
+ this.mode = `trigger`;
281
+ this.label = `⋮`;
282
+ this.placement = `bottom-start`;
283
+ this.tabStop = true;
284
+ this._isOpen = false;
285
+ this._hasMenu = false;
286
+ this._hasTriggerSlot = false;
287
+ this._anchorName = `--mt-${_MenuTrigger._count++}`;
288
+ this._clickListener = this._handleClickOutside.bind(this);
289
+ this._handlePopoverToggle = (e) => {
290
+ if (e.newState === `closed`) {
291
+ this._isOpen = false;
292
+ document.removeEventListener(`click`, this._clickListener);
293
+ this.dispatchEvent(new CustomEvent(`menu-trigger-close`, {
294
+ bubbles: true,
295
+ composed: true
296
+ }));
297
+ }
298
+ };
299
+ this._handleKeydown = (e) => {
300
+ if (!this._isOpen) return;
301
+ if (e.key === `Escape`) {
302
+ e.preventDefault();
303
+ e.stopPropagation();
304
+ this._closeMenu();
305
+ this._triggerBtn?.focus();
306
+ } else if (e.key === `Tab`) {
307
+ this._closeMenu();
308
+ this._triggerBtn?.focus();
309
+ }
310
+ };
311
+ }
312
+ static {
313
+ this._count = 0;
314
+ }
315
+ connectedCallback() {
316
+ super.connectedCallback();
317
+ document.addEventListener(`keydown`, this._handleKeydown);
318
+ this.addEventListener(`command`, this._handleCommand);
319
+ this.addEventListener(`radio-change`, this._handleRadioChange);
320
+ }
321
+ disconnectedCallback() {
322
+ super.disconnectedCallback();
323
+ document.removeEventListener(`keydown`, this._handleKeydown);
324
+ this.removeEventListener(`command`, this._handleCommand);
325
+ this.removeEventListener(`radio-change`, this._handleRadioChange);
326
+ document.removeEventListener(`click`, this._clickListener);
327
+ }
328
+ firstUpdated() {
329
+ this.style.setProperty(`--anchor-name`, this._anchorName);
330
+ this._popup.addEventListener(`toggle`, this._handlePopoverToggle);
331
+ this.updateComplete.then(() => {
332
+ const slot = this.shadowRoot?.querySelector(`slot[name="menu"]`);
333
+ if (slot) {
334
+ if (slot.assignedElements({ flatten: true }).length > 0) {
335
+ this._hasMenu = true;
336
+ this._propagateContext();
337
+ }
338
+ }
339
+ this._updatePosition();
340
+ });
341
+ }
342
+ updated(changedProperties) {
343
+ if (changedProperties.has(`registry`) || changedProperties.has(`keyboardManager`)) this._propagateContext();
344
+ }
345
+ _updatePosition() {
346
+ const pos = {
347
+ "bottom-start": { insetArea: `block-end span-inline-start` },
348
+ "bottom-end": { insetArea: `block-end span-inline-end` },
349
+ "right-start": { insetArea: `inline-end span-block-start` }
350
+ }[this.placement];
351
+ this._popup.style.insetArea = pos.insetArea;
352
+ this._popup.style.positionAnchor = this._anchorName;
353
+ const fb = {
354
+ "bottom-start": {
355
+ top: `anchor(bottom)`,
356
+ left: `anchor(left)`,
357
+ right: `auto`
358
+ },
359
+ "bottom-end": {
360
+ top: `anchor(bottom)`,
361
+ left: `auto`,
362
+ right: `anchor(left)`
363
+ },
364
+ "right-start": {
365
+ top: `anchor(top)`,
366
+ left: `anchor(right)`,
367
+ right: `auto`
368
+ }
369
+ }[this.placement];
370
+ this._popup.style.top = fb.top;
371
+ this._popup.style.left = fb.left;
372
+ this._popup.style.right = fb.right;
373
+ }
374
+ _propagateContext() {
375
+ const items = (this.shadowRoot?.querySelector(`slot[name="menu"]`))?.assignedElements({ flatten: true }) ?? [];
376
+ for (const el of items) {
377
+ if (`registry` in el) el.registry = this.registry;
378
+ if (`keyboardManager` in el) el.keyboardManager = this.keyboardManager;
379
+ }
380
+ }
381
+ _handleSlotChange(e) {
382
+ const assigned = e.target.assignedElements({ flatten: true });
383
+ this._hasMenu = assigned.length > 0;
384
+ this._propagateContext();
385
+ }
386
+ _handleTriggerSlotChange(e) {
387
+ const slot = e.target;
388
+ this._hasTriggerSlot = slot.assignedElements({ flatten: true }).length > 0;
389
+ }
390
+ get isOpen() {
391
+ return this._isOpen;
392
+ }
393
+ openMenu() {
394
+ this._openMenu();
395
+ }
396
+ closeMenu() {
397
+ this._closeMenu();
398
+ }
399
+ focusTrigger() {
400
+ this._triggerBtn?.focus();
401
+ }
402
+ _openMenu() {
403
+ if (this._isOpen || !this._popup?.popover) return;
404
+ try {
405
+ this._popup.showPopover({ source: this });
406
+ this._isOpen = true;
407
+ document.addEventListener(`click`, this._clickListener);
408
+ this.dispatchEvent(new CustomEvent(`menu-trigger-open`, {
409
+ bubbles: true,
410
+ composed: true
411
+ }));
412
+ requestAnimationFrame(() => {
413
+ this._getMenuContainer()?.focusFirst();
414
+ });
415
+ } catch (err) {
416
+ console.warn(`showPopover failed:`, err);
417
+ }
418
+ }
419
+ _closeMenu() {
420
+ if (!this._isOpen) return;
421
+ if (this._popup?.popover) try {
422
+ this._popup.hidePopover();
423
+ } catch {}
424
+ this._isOpen = false;
425
+ document.removeEventListener(`click`, this._clickListener);
426
+ }
427
+ _handleTriggerClick(e) {
428
+ e.stopPropagation();
429
+ if (this._isOpen) {
430
+ this._closeMenu();
431
+ this._triggerBtn?.focus();
432
+ } else this._openMenu();
433
+ }
434
+ _handleClickOutside(e) {
435
+ if (!this.contains(e.target)) {
436
+ if (this._popup?.popover && this._popup.hasAttribute(`open`)) try {
437
+ this._popup.hidePopover();
438
+ } catch {}
439
+ }
440
+ }
441
+ _getMenuContainer() {
442
+ return ((this.shadowRoot?.querySelector(`slot[name="menu"]`))?.assignedElements({ flatten: true }) ?? []).find((el) => el.tagName === `IXFX-MENU-CONTAINER`) ?? null;
443
+ }
444
+ _handleCommand(e) {
445
+ if (this._popup?.popover) try {
446
+ this._popup.hidePopover();
447
+ } catch {}
448
+ this.dispatchEvent(new CustomEvent(`menu-command`, {
449
+ detail: e.detail,
450
+ bubbles: true,
451
+ composed: true
452
+ }));
453
+ }
454
+ _handleRadioChange(e) {
455
+ if (this._popup?.popover) try {
456
+ this._popup.hidePopover();
457
+ } catch {}
458
+ this.dispatchEvent(new CustomEvent(`menu-command`, {
459
+ detail: {
460
+ command: e.detail.name,
461
+ value: e.detail.value
462
+ },
463
+ bubbles: true,
464
+ composed: true
465
+ }));
466
+ }
467
+ _handleContextMenu(e) {
468
+ if (this.mode !== `context`) return;
469
+ e.preventDefault();
470
+ this._popup.style.top = `${e.clientY}px`;
471
+ this._popup.style.left = `${e.clientX}px`;
472
+ this._popup.style.position = `fixed`;
473
+ this._popup.style.positionAnchor = `none`;
474
+ if (this._popup?.popover) try {
475
+ this._popup.showPopover();
476
+ } catch {}
477
+ }
478
+ static {
479
+ this.styles = [
480
+ themeFallbacks,
481
+ popupSurfaceStyles,
482
+ css`
483
+ :host {
484
+ display: inline-block;
485
+ position: relative;
486
+ --ixfx-button-padding: var(--ixfx-button-padding, var(--space-s) var(--space-m));
487
+ }
488
+
489
+ .trigger-area {
490
+ anchor-name: var(--anchor-name);
491
+ display: inline-flex;
492
+ align-items: stretch;
493
+ }
494
+
495
+ .trigger-btn {
496
+ background: none;
497
+ border: none;
498
+ color: var(--surface-3-text);
499
+ cursor: pointer;
500
+ padding: var(--ixfx-button-padding);
501
+ font-family: var(--font-family, inherit);
502
+ font-size: var(--text-m);
503
+ font-weight: 600;
504
+ border-radius: var(--radius-s);
505
+ opacity: 0.6;
506
+ transition: opacity var(--transition), background var(--transition);
507
+ }
508
+
509
+ .trigger-btn:hover {
510
+ background: var(--_trigger-hover-bg, var(--surface-4));
511
+ color: var(--surface-3-text);
512
+ opacity: var(--_trigger-hover-opacity, 1);
513
+ }
514
+
515
+ .trigger-btn:focus-visible {
516
+ background: var(--surface-4);
517
+ color: var(--surface-3-text);
518
+ outline: none;
519
+ opacity: 1;
520
+ }
521
+
522
+ .popup {
523
+ position: fixed;
524
+ position-anchor: var(--anchor-name);
525
+ inset: auto;
526
+ margin: 8px;
527
+ padding: 0;
528
+ border: none;
529
+ background: transparent;
530
+ z-index: 100;
531
+ max-height: min(60vh, 400px);
532
+ max-width: min(90vw, 320px);
533
+ overflow: auto;
534
+ overscroll-behavior: contain;
535
+ position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
536
+ }
537
+
538
+ .popup[popover] {
539
+ opacity: 1;
540
+ transform: translateY(0) scale(1);
541
+ transition: opacity 0.12s ease-out, transform 0.12s ease-out,
542
+ display 0.12s allow-discrete, overlay 0.12s allow-discrete;
543
+ }
544
+
545
+ @starting-style .popup {
546
+ opacity: 0;
547
+ transform: translateY(-4px) scale(0.97);
548
+ }
549
+ `
550
+ ];
551
+ }
552
+ render() {
553
+ const showButton = this.mode !== `dropdown` && this._hasMenu && !this._hasTriggerSlot;
554
+ return html`
555
+ <div
556
+ class="trigger-area"
557
+ @click=${this._handleTriggerClick}
558
+ @contextmenu=${this._handleContextMenu}
559
+ >
560
+ ${showButton ? html`<button class="trigger-btn" part="base" tabindex=${this.tabStop ? `0` : `-1`}>${this.label}</button>` : null}
561
+ <slot name="trigger" @slotchange=${this._handleTriggerSlotChange}></slot>
562
+ </div>
563
+ <div
564
+ class="popup popup-surface"
565
+ popover="auto"
566
+ @click=${(e) => e.stopPropagation()}
567
+ >
568
+ <slot name="menu" @slotchange=${this._handleSlotChange}></slot>
569
+ </div>
570
+ `;
571
+ }
572
+ };
573
+ __decorate([property({ type: String })], MenuTrigger.prototype, "mode", void 0);
574
+ __decorate([property({ type: String })], MenuTrigger.prototype, "label", void 0);
575
+ __decorate([property({ attribute: false })], MenuTrigger.prototype, "registry", void 0);
576
+ __decorate([property({ attribute: false })], MenuTrigger.prototype, "keyboardManager", void 0);
577
+ __decorate([property({ type: String })], MenuTrigger.prototype, "placement", void 0);
578
+ __decorate([property({
579
+ type: Boolean,
580
+ attribute: `tab-stop`
581
+ })], MenuTrigger.prototype, "tabStop", void 0);
582
+ __decorate([state()], MenuTrigger.prototype, "_isOpen", void 0);
583
+ __decorate([state()], MenuTrigger.prototype, "_hasMenu", void 0);
584
+ __decorate([state()], MenuTrigger.prototype, "_hasTriggerSlot", void 0);
585
+ __decorate([query(`.trigger-btn`)], MenuTrigger.prototype, "_triggerBtn", void 0);
586
+ __decorate([query(`.popup`)], MenuTrigger.prototype, "_popup", void 0);
587
+ MenuTrigger = _MenuTrigger = __decorate([safeCustomElement(`ixfx-menu-trigger`)], MenuTrigger);
588
+ //#endregion
589
+ //#region src/menu/menu-item.ts
590
+ let MenuItem = class MenuItem extends LitElement {
591
+ constructor(..._args) {
592
+ super(..._args);
593
+ this.command = ``;
594
+ this.commandArgs = ``;
595
+ this.label = ``;
596
+ this.disabled = false;
597
+ this.iconName = ``;
598
+ this._hasChildren = false;
599
+ this._hoverTimeout = null;
600
+ }
601
+ disconnectedCallback() {
602
+ super.disconnectedCallback();
603
+ if (this._hoverTimeout) clearTimeout(this._hoverTimeout);
604
+ }
605
+ _handleSlotChange() {
606
+ const assigned = this._slot?.assignedElements() ?? [];
607
+ this._hasChildren = assigned.length > 0;
608
+ }
609
+ _handleMouseEnter() {
610
+ if (this.disabled || !this._hasChildren || !this.submenuPopover) return;
611
+ if (this._hoverTimeout) clearTimeout(this._hoverTimeout);
612
+ this._hoverTimeout = window.setTimeout(() => {
613
+ this._showSubmenu();
614
+ }, 150);
615
+ }
616
+ _handleMouseLeave() {
617
+ if (this._hoverTimeout) {
618
+ clearTimeout(this._hoverTimeout);
619
+ this._hoverTimeout = null;
620
+ }
621
+ this._hideSubmenu();
622
+ }
623
+ _showSubmenu() {
624
+ if (!this.submenuPopover?.popover) return;
625
+ try {
626
+ this.submenuPopover.showPopover();
627
+ } catch (err) {
628
+ console.warn(`showPopover failed:`, err);
629
+ }
630
+ }
631
+ _hideSubmenu() {
632
+ if (!this.submenuPopover?.popover) return;
633
+ try {
634
+ this.submenuPopover.hidePopover();
635
+ } catch (err) {
636
+ console.warn(`hidePopover failed:`, err);
637
+ }
638
+ }
639
+ handleClick() {
640
+ if (this.disabled) return;
641
+ this.dispatchEvent(new CustomEvent(`command`, {
642
+ detail: {
643
+ command: this.command,
644
+ args: this.commandArgs
645
+ },
646
+ bubbles: true,
647
+ composed: true
648
+ }));
649
+ }
650
+ _resolvedLabel() {
651
+ if (this.label) return this.label;
652
+ if (this.registry && this.command) return this.registry.get(this.command)?.label ?? ``;
653
+ return ``;
654
+ }
655
+ _resolvedIcon() {
656
+ if (this.iconName) return this.iconName;
657
+ if (this.registry && this.command) return this.registry.get(this.command)?.icon ?? null;
658
+ return null;
659
+ }
660
+ willUpdate(changedProperties) {
661
+ super.willUpdate(changedProperties);
662
+ const resolvedIcon = this._resolvedIcon();
663
+ if (resolvedIcon && !this.iconName) this.setAttribute(`data-icon-section`, ``);
664
+ else if (!resolvedIcon && !this.iconName) this.removeAttribute(`data-icon-section`);
665
+ }
666
+ updated(changedProperties) {
667
+ super.updated(changedProperties);
668
+ }
669
+ _getShortcut() {
670
+ if (!this.keyboardManager || !this.command) return null;
671
+ const binding = (this.keyboardManager.getBindings?.() ?? []).find((b) => b.commandId === this.command);
672
+ if (!binding) return null;
673
+ const mods = Array.from(binding.modifiers ?? [], (m) => ({
674
+ ctrl: `⌃`,
675
+ shift: `⇧`,
676
+ alt: `⌥`,
677
+ meta: `⌘`
678
+ })[m] ?? m);
679
+ const key = binding.key?.length === 1 ? binding.key.toUpperCase() : binding.key;
680
+ return [...mods, key].join(``);
681
+ }
682
+ static {
683
+ this.styles = [
684
+ themeFallbacks,
685
+ tickledItemStyles,
686
+ css`
687
+ :host {
688
+ display: block;
689
+ }
690
+
691
+ .item {
692
+ display: flex !important;
693
+ align-items: center;
694
+ padding: 6px var(--space-m);
695
+ font-size: var(--text-m);
696
+ background: var(--item-bg, transparent);
697
+ border: var(--item-border, 1px solid transparent);
698
+ color: var(--item-text, inherit);
699
+ }
700
+
701
+ :host(.tickled) .item {
702
+ background: var(--item-bg-tickled);
703
+ border: var(--item-border-tickled);
704
+ color: var(--item-text-tickled);
705
+ }
706
+
707
+ :host(:focus) {
708
+ outline: none;
709
+ }
710
+
711
+ .item.disabled {
712
+ opacity: var(--disabled-opacity);
713
+ cursor: default;
714
+ }
715
+
716
+ .item.disabled:hover {
717
+ background: transparent;
718
+ }
719
+
720
+ .icon-slot {
721
+ width: 0;
722
+ overflow: hidden;
723
+ flex-shrink: 0;
724
+ display: inline-flex;
725
+ align-items: center;
726
+ justify-content: center;
727
+ }
728
+
729
+ :host([icon-name]) .icon-slot,
730
+ :host([data-icon-section]) .icon-slot {
731
+ width: 1em;
732
+ height: 1em;
733
+ margin-right: var(--space-s);
734
+ }
735
+
736
+ .label {
737
+ flex: 1;
738
+ }
739
+
740
+ .shortcut {
741
+ margin-left: auto;
742
+ color: var(--surface-muted-text);
743
+ font-size: var(--text-s);
744
+ }
745
+
746
+ .arrow {
747
+ color: var(--surface-muted-text);
748
+ margin-left: var(--space-m);
749
+ }
750
+ `
751
+ ];
752
+ }
753
+ render() {
754
+ const shortcut = this._getShortcut();
755
+ const resolvedIcon = this._resolvedIcon();
756
+ return html`
757
+ <div
758
+ class="item ${this.disabled ? `disabled` : ``}"
759
+ @click=${this.handleClick}
760
+ @mouseenter=${this._handleMouseEnter}
761
+ @mouseleave=${this._handleMouseLeave}
762
+ tabindex="${this.disabled ? -1 : 0}"
763
+ role="menuitem"
764
+ aria-haspopup="${this._hasChildren ? `true` : `false`}"
765
+ aria-expanded="${this.submenuPopover?.matches(`:popover-open`) ?? false}"
766
+ >
767
+ <span class="icon-slot">${resolvedIcon ? html`<ixfx-icon name="${resolvedIcon}"></ixfx-icon>` : null}</span>
768
+ <span class="label"><slot></slot>${this._resolvedLabel()}</span>
769
+ ${shortcut ? html`<span class="shortcut">${shortcut}</span>` : null}
770
+ ${this._hasChildren ? html`<span class="arrow"><ixfx-icon name="chevron-right"></ixfx-icon></span>` : null}
771
+ </div>
772
+ <slot @slotchange=${this._handleSlotChange}></slot>
773
+ `;
774
+ }
775
+ };
776
+ __decorate([property({ type: String })], MenuItem.prototype, "command", void 0);
777
+ __decorate([property({
778
+ type: String,
779
+ attribute: `command-args`
780
+ })], MenuItem.prototype, "commandArgs", void 0);
781
+ __decorate([property({ type: String })], MenuItem.prototype, "label", void 0);
782
+ __decorate([property({ type: Boolean })], MenuItem.prototype, "disabled", void 0);
783
+ __decorate([property({
784
+ type: String,
785
+ attribute: `icon-name`
786
+ })], MenuItem.prototype, "iconName", void 0);
787
+ __decorate([property({ attribute: false })], MenuItem.prototype, "registry", void 0);
788
+ __decorate([property({ attribute: false })], MenuItem.prototype, "keyboardManager", void 0);
789
+ __decorate([property({ attribute: false })], MenuItem.prototype, "submenuPopover", void 0);
790
+ __decorate([state()], MenuItem.prototype, "_hasChildren", void 0);
791
+ __decorate([query(`slot`)], MenuItem.prototype, "_slot", void 0);
792
+ MenuItem = __decorate([safeCustomElement(`ixfx-menu-item`)], MenuItem);
793
+ //#endregion
794
+ //#region src/menu/menu-bar.ts
795
+ let MenuBar = class MenuBar extends LitElement {
796
+ constructor(..._args) {
797
+ super(..._args);
798
+ this._openTrigger = null;
799
+ this._inputMode = `mouse`;
800
+ this._handlePointerMove = () => {
801
+ this._setInputMode(`mouse`);
802
+ };
803
+ this._handleTriggerOpen = (e) => {
804
+ this._openTrigger = e.target;
805
+ };
806
+ this._handleTriggerClose = (e) => {
807
+ if (e.target === this._openTrigger) this._openTrigger = null;
808
+ };
809
+ this._handleFocusIn = (e) => {
810
+ const trigger = this._getTriggers().find((t) => t === e.target);
811
+ if (!trigger || !this._openTrigger || trigger === this._openTrigger) return;
812
+ this._openTrigger.closeMenu();
813
+ trigger.openMenu();
814
+ };
815
+ this._handleKeydown = (e) => {
816
+ if (e.key !== `ArrowLeft` && e.key !== `ArrowRight`) return;
817
+ const triggers = this._getTriggers();
818
+ if (triggers.length === 0) return;
819
+ const current = this._openTrigger ?? triggers.find((t) => t === e.target);
820
+ if (!current) return;
821
+ const idx = triggers.indexOf(current);
822
+ if (idx === -1) return;
823
+ e.preventDefault();
824
+ e.stopPropagation();
825
+ this._setInputMode(`keyboard`);
826
+ const next = triggers[(idx + (e.key === `ArrowRight` ? 1 : -1) + triggers.length) % triggers.length];
827
+ if (this._openTrigger) {
828
+ this._openTrigger.closeMenu();
829
+ next.openMenu();
830
+ } else next.focusTrigger();
831
+ };
832
+ }
833
+ connectedCallback() {
834
+ super.connectedCallback();
835
+ this.addEventListener(`menu-trigger-open`, this._handleTriggerOpen);
836
+ this.addEventListener(`menu-trigger-close`, this._handleTriggerClose);
837
+ this.addEventListener(`focusin`, this._handleFocusIn);
838
+ this.addEventListener(`keydown`, this._handleKeydown);
839
+ this.addEventListener(`pointermove`, this._handlePointerMove);
840
+ }
841
+ disconnectedCallback() {
842
+ super.disconnectedCallback();
843
+ this.removeEventListener(`menu-trigger-open`, this._handleTriggerOpen);
844
+ this.removeEventListener(`menu-trigger-close`, this._handleTriggerClose);
845
+ this.removeEventListener(`focusin`, this._handleFocusIn);
846
+ this.removeEventListener(`keydown`, this._handleKeydown);
847
+ this.removeEventListener(`pointermove`, this._handlePointerMove);
848
+ }
849
+ _setInputMode(mode) {
850
+ if (this._inputMode === mode) return;
851
+ this._inputMode = mode;
852
+ this.setAttribute(`data-input-mode`, mode);
853
+ }
854
+ _getTriggers() {
855
+ return [...this.children].filter((el) => el.tagName === `IXFX-MENU-TRIGGER`);
856
+ }
857
+ static {
858
+ this.styles = css`
859
+ :host {
860
+ display: flex;
861
+ align-items: center;
862
+ }
863
+
864
+ /* Keyboard mode: suppress hover highlight on trigger buttons */
865
+ :host([data-input-mode="keyboard"]) {
866
+ --_trigger-hover-bg: transparent;
867
+ --_trigger-hover-opacity: 0.6;
868
+ }
869
+ `;
870
+ }
871
+ render() {
872
+ return html`<slot role="menubar"></slot>`;
873
+ }
874
+ };
875
+ MenuBar = __decorate([safeCustomElement(`ixfx-menu-bar`)], MenuBar);
876
+ //#endregion
877
+ //#region src/menu/menu-check-item.ts
878
+ let MenuCheckItem = class MenuCheckItem extends LitElement {
879
+ constructor(..._args) {
880
+ super(..._args);
881
+ this.command = ``;
882
+ this.commandArgs = ``;
883
+ this.label = ``;
884
+ this.checked = false;
885
+ this.disabled = false;
886
+ this.iconName = ``;
887
+ }
888
+ handleClick() {
889
+ if (this.disabled) return;
890
+ this.checked = !this.checked;
891
+ this.dispatchEvent(new CustomEvent(`command`, {
892
+ detail: {
893
+ command: this.command,
894
+ checked: this.checked,
895
+ args: this.commandArgs
896
+ },
897
+ bubbles: true,
898
+ composed: true
899
+ }));
900
+ }
901
+ _resolvedLabel() {
902
+ if (this.label) return this.label;
903
+ if (this.registry && this.command) return this.registry.get(this.command)?.label ?? ``;
904
+ return ``;
905
+ }
906
+ _resolvedIcon() {
907
+ if (this.iconName) return this.iconName;
908
+ if (this.registry && this.command) return this.registry.get(this.command)?.icon ?? null;
909
+ return null;
910
+ }
911
+ willUpdate(changedProperties) {
912
+ super.willUpdate(changedProperties);
913
+ const resolvedIcon = this._resolvedIcon();
914
+ if (resolvedIcon && !this.iconName) this.setAttribute(`data-icon-section`, ``);
915
+ else if (!resolvedIcon && !this.iconName) this.removeAttribute(`data-icon-section`);
916
+ }
917
+ updated(changedProperties) {
918
+ super.updated(changedProperties);
919
+ }
920
+ _getShortcut() {
921
+ if (!this.keyboardManager || !this.command) return null;
922
+ const binding = (this.keyboardManager.getBindings?.() ?? []).find((b) => b.commandId === this.command);
923
+ if (!binding) return null;
924
+ const mods = Array.from(binding.modifiers ?? [], (m) => ({
925
+ ctrl: `⌃`,
926
+ shift: `⇧`,
927
+ alt: `⌥`,
928
+ meta: `⌘`
929
+ })[m] ?? m);
930
+ const key = binding.key?.length === 1 ? binding.key.toUpperCase() : binding.key;
931
+ return [...mods, key].join(``);
932
+ }
933
+ static {
934
+ this.styles = [
935
+ themeFallbacks,
936
+ tickledItemStyles,
937
+ css`
938
+ :host {
939
+ display: block;
940
+ }
941
+
942
+ .item {
943
+ display: flex;
944
+ padding: 6px var(--space-m);
945
+ font-size: var(--text-m);
946
+ }
947
+
948
+ :host(:focus) {
949
+ outline: none;
950
+ }
951
+
952
+ .item.disabled {
953
+ opacity: var(--disabled-opacity);
954
+ cursor: default;
955
+ }
956
+
957
+ .item.disabled:hover {
958
+ background: transparent;
959
+ }
960
+
961
+ .check {
962
+ width: 16px;
963
+ margin-right: var(--space-s);
964
+ font-size: var(--text-m);
965
+ color: var(--accent);
966
+ }
967
+
968
+ .icon-slot {
969
+ width: 0;
970
+ overflow: hidden;
971
+ flex-shrink: 0;
972
+ display: inline-flex;
973
+ align-items: center;
974
+ justify-content: center;
975
+ }
976
+
977
+ :host([icon-name]) .icon-slot,
978
+ :host([data-icon-section]) .icon-slot {
979
+ width: 1em;
980
+ height: 1em;
981
+ margin-right: var(--space-s);
982
+ }
983
+
984
+ .label {
985
+ flex: 1;
986
+ }
987
+
988
+ .shortcut {
989
+ margin-left: var(--space-l);
990
+ color: var(--surface-muted-text);
991
+ font-size: var(--text-s);
992
+ }
993
+ `
994
+ ];
995
+ }
996
+ render() {
997
+ const shortcut = this._getShortcut();
998
+ const resolvedIcon = this._resolvedIcon();
999
+ return html`
1000
+ <div
1001
+ class="item ${this.disabled ? `disabled` : ``}"
1002
+ @click=${this.handleClick}
1003
+ tabindex="${this.disabled ? -1 : 0}"
1004
+ role="menuitemcheckbox"
1005
+ aria-checked="${this.checked}"
1006
+ >
1007
+ <span class="check">${this.checked ? `✓` : ``}</span>
1008
+ <span class="icon-slot">${resolvedIcon ? html`<ixfx-icon name="${resolvedIcon}"></ixfx-icon>` : null}</span>
1009
+ <span class="label">${this._resolvedLabel()}</span>
1010
+ ${shortcut ? html`<span class="shortcut">${shortcut}</span>` : null}
1011
+ </div>
1012
+ `;
1013
+ }
1014
+ };
1015
+ __decorate([property({ type: String })], MenuCheckItem.prototype, "command", void 0);
1016
+ __decorate([property({
1017
+ type: String,
1018
+ attribute: `command-args`
1019
+ })], MenuCheckItem.prototype, "commandArgs", void 0);
1020
+ __decorate([property({ type: String })], MenuCheckItem.prototype, "label", void 0);
1021
+ __decorate([property({ type: Boolean })], MenuCheckItem.prototype, "checked", void 0);
1022
+ __decorate([property({ type: Boolean })], MenuCheckItem.prototype, "disabled", void 0);
1023
+ __decorate([property({
1024
+ type: String,
1025
+ attribute: `icon-name`
1026
+ })], MenuCheckItem.prototype, "iconName", void 0);
1027
+ __decorate([property({ attribute: false })], MenuCheckItem.prototype, "registry", void 0);
1028
+ __decorate([property({ attribute: false })], MenuCheckItem.prototype, "keyboardManager", void 0);
1029
+ MenuCheckItem = __decorate([safeCustomElement(`ixfx-menu-check-item`)], MenuCheckItem);
1030
+ //#endregion
1031
+ //#region src/menu/menu-command-controller.ts
1032
+ var MenuCommandController = class {
1033
+ constructor(options) {
1034
+ this.registry = options.registry;
1035
+ this.target = options.target ?? document;
1036
+ this.boundHandler = this.handleCommand.bind(this);
1037
+ }
1038
+ start() {
1039
+ this.target.addEventListener(`command`, this.boundHandler);
1040
+ }
1041
+ stop() {
1042
+ this.target.removeEventListener(`command`, this.boundHandler);
1043
+ }
1044
+ handleCommand(e) {
1045
+ const target = e.target;
1046
+ const command = target?.command;
1047
+ if (!command) return;
1048
+ const args = target?.commandArgs ?? ``;
1049
+ this.registry.invoke(command, { args });
1050
+ }
1051
+ };
1052
+ //#endregion
1053
+ //#region src/menu/menu-sub-trigger.ts
1054
+ var _MenuSubTrigger;
1055
+ let MenuSubTrigger = class MenuSubTrigger extends LitElement {
1056
+ static {
1057
+ _MenuSubTrigger = this;
1058
+ }
1059
+ constructor(..._args) {
1060
+ super(..._args);
1061
+ this.command = ``;
1062
+ this.commandArgs = ``;
1063
+ this.label = ``;
1064
+ this.disabled = false;
1065
+ this.iconName = ``;
1066
+ this._hasSubmenu = false;
1067
+ this._anchorName = `--mst-${_MenuSubTrigger._count++}`;
1068
+ this._hoverTimeout = null;
1069
+ this._hideTimeout = null;
1070
+ }
1071
+ static {
1072
+ this._count = 0;
1073
+ }
1074
+ connectedCallback() {
1075
+ super.connectedCallback();
1076
+ this.addEventListener(`keydown`, this._handleKeydown);
1077
+ }
1078
+ firstUpdated() {
1079
+ this.style.setProperty(`--anchor-name`, this._anchorName);
1080
+ }
1081
+ disconnectedCallback() {
1082
+ super.disconnectedCallback();
1083
+ this.removeEventListener(`keydown`, this._handleKeydown);
1084
+ if (this._hoverTimeout) clearTimeout(this._hoverTimeout);
1085
+ if (this._hideTimeout) clearTimeout(this._hideTimeout);
1086
+ }
1087
+ _propagateContext() {
1088
+ const items = this._slot?.assignedElements({ flatten: true }) ?? [];
1089
+ for (const el of items) {
1090
+ if (`registry` in el) el.registry = this.registry;
1091
+ if (`keyboardManager` in el) el.keyboardManager = this.keyboardManager;
1092
+ }
1093
+ }
1094
+ updated(changedProperties) {
1095
+ if (changedProperties.has(`registry`) || changedProperties.has(`keyboardManager`)) this._propagateContext();
1096
+ }
1097
+ willUpdate(changedProperties) {
1098
+ super.willUpdate(changedProperties);
1099
+ const resolvedIcon = this._resolvedIcon();
1100
+ if (resolvedIcon && !this.iconName) this.setAttribute(`data-icon-section`, ``);
1101
+ else if (!resolvedIcon && !this.iconName) this.removeAttribute(`data-icon-section`);
1102
+ }
1103
+ _resolvedIcon() {
1104
+ if (this.iconName) return this.iconName;
1105
+ if (this.registry && this.command) return this.registry.get(this.command)?.icon ?? null;
1106
+ return null;
1107
+ }
1108
+ _handleSlotChange() {
1109
+ this._hasSubmenu = this._slot?.assignedElements().length > 0;
1110
+ this._propagateContext();
1111
+ }
1112
+ _showSubmenu() {
1113
+ if (!this._submenuPopover?.popover) return;
1114
+ try {
1115
+ this._submenuPopover.showPopover();
1116
+ } catch {}
1117
+ }
1118
+ _hideSubmenu() {
1119
+ if (!this._submenuPopover?.popover) return;
1120
+ try {
1121
+ this._submenuPopover.hidePopover();
1122
+ } catch {}
1123
+ }
1124
+ _cancelHide() {
1125
+ if (this._hideTimeout) {
1126
+ clearTimeout(this._hideTimeout);
1127
+ this._hideTimeout = null;
1128
+ }
1129
+ }
1130
+ _scheduleHide() {
1131
+ this._cancelHide();
1132
+ this._hideTimeout = window.setTimeout(() => {
1133
+ this._hideSubmenu();
1134
+ this._hideTimeout = null;
1135
+ }, 100);
1136
+ }
1137
+ _handleMouseEnter() {
1138
+ if (this.disabled || !this._hasSubmenu) return;
1139
+ this._cancelHide();
1140
+ if (this._hoverTimeout) clearTimeout(this._hoverTimeout);
1141
+ this._hoverTimeout = window.setTimeout(() => {
1142
+ this._showSubmenu();
1143
+ }, 150);
1144
+ }
1145
+ _handleMouseLeave() {
1146
+ if (this._hoverTimeout) {
1147
+ clearTimeout(this._hoverTimeout);
1148
+ this._hoverTimeout = null;
1149
+ }
1150
+ this._scheduleHide();
1151
+ }
1152
+ _handleSubmenuMouseEnter() {
1153
+ this._cancelHide();
1154
+ }
1155
+ _handleSubmenuMouseLeave() {
1156
+ this._scheduleHide();
1157
+ }
1158
+ _handleClick() {
1159
+ if (this.disabled || !this.command) return;
1160
+ this.dispatchEvent(new CustomEvent(`command`, {
1161
+ detail: {
1162
+ command: this.command,
1163
+ args: this.commandArgs
1164
+ },
1165
+ bubbles: true,
1166
+ composed: true
1167
+ }));
1168
+ }
1169
+ _handleKeydown(e) {
1170
+ if (this.disabled) return;
1171
+ switch (e.key) {
1172
+ case `ArrowRight`:
1173
+ case `Enter`:
1174
+ case ` `:
1175
+ e.preventDefault();
1176
+ e.stopPropagation();
1177
+ if (this._hasSubmenu) {
1178
+ this._showSubmenu();
1179
+ requestAnimationFrame(() => {
1180
+ (this._slot?.assignedElements({ flatten: true }).find((el) => el.tagName === `IXFX-MENU-CONTAINER`))?.focusFirst();
1181
+ });
1182
+ }
1183
+ break;
1184
+ case `ArrowLeft`:
1185
+ e.preventDefault();
1186
+ e.stopPropagation();
1187
+ this._hideSubmenu();
1188
+ this._itemEl?.focus();
1189
+ break;
1190
+ case `Escape`:
1191
+ e.preventDefault();
1192
+ e.stopPropagation();
1193
+ this._hideSubmenu();
1194
+ }
1195
+ }
1196
+ static {
1197
+ this.styles = [
1198
+ themeFallbacks,
1199
+ tickledItemStyles,
1200
+ css`
1201
+ :host {
1202
+ display: block;
1203
+ }
1204
+
1205
+ .item {
1206
+ anchor-name: var(--anchor-name);
1207
+ display: flex;
1208
+ padding: 6px var(--space-m);
1209
+ font-size: var(--text-m);
1210
+ }
1211
+
1212
+ .submenu-popover {
1213
+ position: fixed;
1214
+ position-anchor: var(--anchor-name);
1215
+ inset: auto;
1216
+ top: anchor(top);
1217
+ left: anchor(right);
1218
+ margin: 0;
1219
+ padding: 0;
1220
+ border: none;
1221
+ background: transparent;
1222
+ /* UA stylesheet sets overflow:auto on [popover], which clips the box-shadow
1223
+ of the inner ixfx-menu-container child. Override to let the shadow render. */
1224
+ overflow: visible;
1225
+ position-try-fallbacks: flip-inline, flip-block, flip-block flip-inline;
1226
+ }
1227
+
1228
+ :host(:focus) {
1229
+ outline: none;
1230
+ }
1231
+
1232
+ .item.disabled {
1233
+ opacity: var(--disabled-opacity);
1234
+ cursor: default;
1235
+ }
1236
+
1237
+ .item.disabled:hover {
1238
+ background: transparent;
1239
+ }
1240
+
1241
+ .icon-slot {
1242
+ width: 0;
1243
+ overflow: hidden;
1244
+ flex-shrink: 0;
1245
+ display: inline-flex;
1246
+ align-items: center;
1247
+ justify-content: center;
1248
+ }
1249
+
1250
+ :host([icon-name]) .icon-slot,
1251
+ :host([data-icon-section]) .icon-slot {
1252
+ width: 1em;
1253
+ height: 1em;
1254
+ margin-right: var(--space-s);
1255
+ }
1256
+
1257
+ .label {
1258
+ flex: 1;
1259
+ }
1260
+
1261
+ .arrow {
1262
+ color: var(--surface-muted-text);
1263
+ margin-left: var(--space-m);
1264
+ }
1265
+ `
1266
+ ];
1267
+ }
1268
+ render() {
1269
+ const resolvedIcon = this._resolvedIcon();
1270
+ return html`
1271
+ <div
1272
+ class="item ${this.disabled ? `disabled` : ``}"
1273
+ @click=${this._handleClick}
1274
+ @mouseenter=${this._handleMouseEnter}
1275
+ @mouseleave=${this._handleMouseLeave}
1276
+ tabindex="${this.disabled ? -1 : 0}"
1277
+ role="menuitem"
1278
+ aria-haspopup="true"
1279
+ aria-expanded="false"
1280
+ >
1281
+ <span class="icon-slot">${resolvedIcon ? html`<ixfx-icon name="${resolvedIcon}"></ixfx-icon>` : null}</span>
1282
+ <span class="label"><slot></slot>${this.label}</span>
1283
+ <span class="arrow">${this._hasSubmenu ? html`<ixfx-icon name="chevron-right"></ixfx-icon>` : nothing}</span>
1284
+ </div>
1285
+ <div class="submenu-popover" popover="auto"
1286
+ @mouseenter=${this._handleSubmenuMouseEnter}
1287
+ @mouseleave=${this._handleSubmenuMouseLeave}
1288
+ >
1289
+ <slot name="submenu" @slotchange=${this._handleSlotChange}></slot>
1290
+ </div>
1291
+ `;
1292
+ }
1293
+ };
1294
+ __decorate([property({ type: String })], MenuSubTrigger.prototype, "command", void 0);
1295
+ __decorate([property({
1296
+ type: String,
1297
+ attribute: `command-args`
1298
+ })], MenuSubTrigger.prototype, "commandArgs", void 0);
1299
+ __decorate([property({ type: String })], MenuSubTrigger.prototype, "label", void 0);
1300
+ __decorate([property({ type: Boolean })], MenuSubTrigger.prototype, "disabled", void 0);
1301
+ __decorate([property({
1302
+ type: String,
1303
+ attribute: `icon-name`
1304
+ })], MenuSubTrigger.prototype, "iconName", void 0);
1305
+ __decorate([property({ attribute: false })], MenuSubTrigger.prototype, "registry", void 0);
1306
+ __decorate([property({ attribute: false })], MenuSubTrigger.prototype, "keyboardManager", void 0);
1307
+ __decorate([state()], MenuSubTrigger.prototype, "_hasSubmenu", void 0);
1308
+ __decorate([query(`slot[name="submenu"]`)], MenuSubTrigger.prototype, "_slot", void 0);
1309
+ __decorate([query(`.submenu-popover`)], MenuSubTrigger.prototype, "_submenuPopover", void 0);
1310
+ __decorate([query(`.item`)], MenuSubTrigger.prototype, "_itemEl", void 0);
1311
+ MenuSubTrigger = _MenuSubTrigger = __decorate([safeCustomElement(`ixfx-menu-sub-trigger`)], MenuSubTrigger);
1312
+ //#endregion
1313
+ //#region src/menu/menu-separator.ts
1314
+ let MenuSeparator = class MenuSeparator extends LitElement {
1315
+ static {
1316
+ this.styles = [themeFallbacks, css`
1317
+ :host {
1318
+ display: block;
1319
+ margin: var(--space-xs) 0;
1320
+ }
1321
+
1322
+ .separator {
1323
+ height: 1px;
1324
+ background: var(--surface-4);
1325
+ }
1326
+ `];
1327
+ }
1328
+ render() {
1329
+ return html`<div class="separator"></div>`;
1330
+ }
1331
+ };
1332
+ MenuSeparator = __decorate([safeCustomElement(`ixfx-menu-separator`)], MenuSeparator);
1333
+ //#endregion
1334
+ //#region src/menu/menu-header.ts
1335
+ let MenuHeader = class MenuHeader extends LitElement {
1336
+ constructor(..._args) {
1337
+ super(..._args);
1338
+ this.label = ``;
1339
+ }
1340
+ static {
1341
+ this.styles = [themeFallbacks, css`
1342
+ :host {
1343
+ display: block;
1344
+ padding: 6px var(--space-m) var(--space-xs);
1345
+ font-size: var(--text-s);
1346
+ font-weight: var(--font-weight-bold);
1347
+ text-transform: uppercase;
1348
+ color: var(--surface-muted-text);
1349
+ letter-spacing: 0.5px;
1350
+ }
1351
+ `];
1352
+ }
1353
+ render() {
1354
+ return html`<div>${this.label}</div>`;
1355
+ }
1356
+ };
1357
+ __decorate([property({ type: String })], MenuHeader.prototype, "label", void 0);
1358
+ MenuHeader = __decorate([safeCustomElement(`ixfx-menu-header`)], MenuHeader);
1359
+ //#endregion
1360
+ //#region src/menu/menu-from-tree.ts
1361
+ function isLeaf(node) {
1362
+ return node.children === void 0 || node.children.length === 0;
1363
+ }
1364
+ function menuFromTree(nodes, options = {}) {
1365
+ const { onCommand, registry, keyboardManager } = options;
1366
+ return html`${nodes.map((node) => {
1367
+ const label = node.item.label;
1368
+ if (label === `-`) return html`<ixfx-menu-separator></ixfx-menu-separator>`;
1369
+ if (label.startsWith(`# `)) return html`<ixfx-menu-header label="${label.slice(2)}"></ixfx-menu-header>`;
1370
+ if (!isLeaf(node)) {
1371
+ const submenu = menuFromTree(node.children, options);
1372
+ return html`
1373
+ <ixfx-menu-sub-trigger label="${label}">
1374
+ <ixfx-menu-container
1375
+ slot="submenu"
1376
+ .registry=${registry ?? nothing}
1377
+ .keyboardManager=${keyboardManager ?? nothing}
1378
+ >${submenu}</ixfx-menu-container>
1379
+ </ixfx-menu-sub-trigger>
1380
+ `;
1381
+ }
1382
+ return html`
1383
+ <ixfx-menu-item
1384
+ command="${node.item.key}"
1385
+ label="${label}"
1386
+ icon-name="${node.item.icon ?? nothing}"
1387
+ @command=${onCommand ? (e) => onCommand(e.detail) : nothing}
1388
+ ></ixfx-menu-item>
1389
+ `;
1390
+ })}`;
1391
+ }
1392
+ function buildMenuItemEl(node, options) {
1393
+ const { onCommand, registry } = options;
1394
+ const label = node.item.label;
1395
+ const el = document.createElement(`ixfx-menu-item`);
1396
+ el.setAttribute(`command`, node.item.key);
1397
+ el.setAttribute(`label`, label);
1398
+ if (node.item.icon) el.setAttribute(`icon-name`, node.item.icon);
1399
+ if (onCommand) el.addEventListener(`command`, (e) => onCommand(e.detail));
1400
+ if (registry) el.registry = registry;
1401
+ return el;
1402
+ }
1403
+ function buildMenuSeparatorEl() {
1404
+ return document.createElement(`ixfx-menu-separator`);
1405
+ }
1406
+ function buildMenuHeaderEl(label) {
1407
+ const el = document.createElement(`ixfx-menu-header`);
1408
+ el.setAttribute(`label`, label);
1409
+ return el;
1410
+ }
1411
+ function buildMenuSubTriggerEl(node, options) {
1412
+ const { registry, keyboardManager } = options;
1413
+ const el = document.createElement(`ixfx-menu-sub-trigger`);
1414
+ el.setAttribute(`label`, node.item.label);
1415
+ if (registry) el.registry = registry;
1416
+ if (keyboardManager) el.keyboardManager = keyboardManager;
1417
+ const container = document.createElement(`ixfx-menu-container`);
1418
+ container.setAttribute(`slot`, `submenu`);
1419
+ if (registry) container.registry = registry;
1420
+ if (keyboardManager) container.keyboardManager = keyboardManager;
1421
+ const childEls = menuFromTreeToElements(node.children, options);
1422
+ for (const child of childEls) container.appendChild(child);
1423
+ el.appendChild(container);
1424
+ return el;
1425
+ }
1426
+ function menuFromTreeToElements(nodes, options = {}) {
1427
+ return nodes.map((node) => {
1428
+ const label = node.item.label;
1429
+ if (label === `-`) return buildMenuSeparatorEl();
1430
+ if (label.startsWith(`# `)) return buildMenuHeaderEl(label.slice(2));
1431
+ if (!isLeaf(node)) return buildMenuSubTriggerEl(node, options);
1432
+ return buildMenuItemEl(node, options);
1433
+ });
1434
+ }
1435
+ //#endregion
1436
+ //#region src/menu/menu-radio-item.ts
1437
+ let MenuRadioItem = class MenuRadioItem extends LitElement {
1438
+ constructor(..._args) {
1439
+ super(..._args);
1440
+ this.value = ``;
1441
+ this.label = ``;
1442
+ this.disabled = false;
1443
+ this.groupValue = ``;
1444
+ this.iconName = ``;
1445
+ }
1446
+ handleClick() {
1447
+ if (this.disabled) return;
1448
+ this.dispatchEvent(new CustomEvent(`radio-select`, {
1449
+ detail: { value: this.value },
1450
+ bubbles: true,
1451
+ composed: true
1452
+ }));
1453
+ }
1454
+ static {
1455
+ this.styles = [
1456
+ themeFallbacks,
1457
+ tickledItemStyles,
1458
+ css`
1459
+ :host {
1460
+ display: block;
1461
+ }
1462
+
1463
+ .item {
1464
+ display: flex;
1465
+ padding: 6px var(--space-m);
1466
+ font-size: var(--text-m);
1467
+ }
1468
+
1469
+ :host(:focus) {
1470
+ outline: none;
1471
+ }
1472
+
1473
+ .item.disabled {
1474
+ opacity: var(--disabled-opacity);
1475
+ cursor: default;
1476
+ }
1477
+
1478
+ .item.disabled:hover {
1479
+ background: transparent;
1480
+ }
1481
+
1482
+ .radio {
1483
+ width: 16px;
1484
+ margin-right: var(--space-s);
1485
+ font-size: var(--text-m);
1486
+ color: var(--accent);
1487
+ }
1488
+
1489
+ .icon-slot {
1490
+ width: 0;
1491
+ overflow: hidden;
1492
+ flex-shrink: 0;
1493
+ display: inline-flex;
1494
+ align-items: center;
1495
+ justify-content: center;
1496
+ }
1497
+
1498
+ :host([icon-name]) .icon-slot,
1499
+ :host([data-icon-section]) .icon-slot {
1500
+ width: 1em;
1501
+ height: 1em;
1502
+ margin-right: var(--space-s);
1503
+ }
1504
+
1505
+ .label {
1506
+ flex: 1;
1507
+ }
1508
+ `
1509
+ ];
1510
+ }
1511
+ render() {
1512
+ const isSelected = this.groupValue === this.value;
1513
+ return html`
1514
+ <div
1515
+ class="item ${this.disabled ? `disabled` : ``}"
1516
+ @click=${this.handleClick}
1517
+ tabindex="${this.disabled ? -1 : 0}"
1518
+ role="menuitemradio"
1519
+ aria-checked="${isSelected}"
1520
+ >
1521
+ <span class="radio">${isSelected ? `●` : ``}</span>
1522
+ <span class="icon-slot">${this.iconName ? html`<ixfx-icon name="${this.iconName}"></ixfx-icon>` : null}</span>
1523
+ <span class="label">${this.label}</span>
1524
+ </div>
1525
+ `;
1526
+ }
1527
+ };
1528
+ __decorate([property({ type: String })], MenuRadioItem.prototype, "value", void 0);
1529
+ __decorate([property({ type: String })], MenuRadioItem.prototype, "label", void 0);
1530
+ __decorate([property({ type: Boolean })], MenuRadioItem.prototype, "disabled", void 0);
1531
+ __decorate([property({ type: String })], MenuRadioItem.prototype, "groupValue", void 0);
1532
+ __decorate([property({
1533
+ type: String,
1534
+ attribute: `icon-name`
1535
+ })], MenuRadioItem.prototype, "iconName", void 0);
1536
+ MenuRadioItem = __decorate([safeCustomElement(`ixfx-menu-radio-item`)], MenuRadioItem);
1537
+ //#endregion
1538
+ //#region src/menu/menu-radio-group.ts
1539
+ let MenuRadioGroup = class MenuRadioGroup extends LitElement {
1540
+ constructor(..._args) {
1541
+ super(..._args);
1542
+ this.name = ``;
1543
+ this.value = ``;
1544
+ this.slottedElements = [];
1545
+ }
1546
+ handleSlotChange(e) {
1547
+ const slot = e.target;
1548
+ this.slottedElements = slot.assignedElements();
1549
+ this.updateSlottedValues();
1550
+ }
1551
+ updateSlottedValues() {
1552
+ for (const el of this.slottedElements) el.groupValue = this.value;
1553
+ }
1554
+ handleRadioSelect(e) {
1555
+ this.value = e.detail.value;
1556
+ this.dispatchEvent(new CustomEvent(`radio-change`, {
1557
+ detail: {
1558
+ name: this.name,
1559
+ value: this.value
1560
+ },
1561
+ bubbles: true,
1562
+ composed: true
1563
+ }));
1564
+ }
1565
+ updated(changedProperties) {
1566
+ if (changedProperties.has(`value`)) this.updateSlottedValues();
1567
+ }
1568
+ static {
1569
+ this.styles = css`
1570
+ :host {
1571
+ display: block;
1572
+ }
1573
+
1574
+ ::slotted(menu-radio-item) {
1575
+ display: block;
1576
+ }
1577
+ `;
1578
+ }
1579
+ render() {
1580
+ return html`
1581
+ <slot @slotchange=${this.handleSlotChange} @radio-select=${this.handleRadioSelect}></slot>
1582
+ `;
1583
+ }
1584
+ };
1585
+ __decorate([property({ type: String })], MenuRadioGroup.prototype, "name", void 0);
1586
+ __decorate([property({ type: String })], MenuRadioGroup.prototype, "value", void 0);
1587
+ __decorate([state()], MenuRadioGroup.prototype, "slottedElements", void 0);
1588
+ MenuRadioGroup = __decorate([safeCustomElement(`ixfx-menu-radio-group`)], MenuRadioGroup);
1589
+ //#endregion
1590
+ //#region src/menu/index.ts
1591
+ var menu_exports = /* @__PURE__ */ __exportAll({
1592
+ MenuBar: () => MenuBar,
1593
+ MenuCheckItem: () => MenuCheckItem,
1594
+ MenuCommandController: () => MenuCommandController,
1595
+ MenuContainer: () => MenuContainer,
1596
+ MenuHeader: () => MenuHeader,
1597
+ MenuItem: () => MenuItem,
1598
+ MenuRadioGroup: () => MenuRadioGroup,
1599
+ MenuRadioItem: () => MenuRadioItem,
1600
+ MenuSeparator: () => MenuSeparator,
1601
+ MenuSubTrigger: () => MenuSubTrigger,
1602
+ MenuTrigger: () => MenuTrigger,
1603
+ menuFromTree: () => menuFromTree,
1604
+ menuFromTreeToElements: () => menuFromTreeToElements
1605
+ });
1606
+ //#endregion
1607
+ export { menuFromTreeToElements as a, MenuSubTrigger as c, MenuBar as d, MenuItem as f, menuFromTree as i, MenuCommandController as l, MenuContainer as m, MenuRadioGroup as n, MenuHeader as o, MenuTrigger as p, MenuRadioItem as r, MenuSeparator as s, menu_exports as t, MenuCheckItem as u };
1608
+
1609
+ //# sourceMappingURL=menu-DIfU70AA.js.map