@mono-lit/helper 0.0.9 → 0.1.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 (164) hide show
  1. package/dist/accordion-core-DaNyPWRr.js +277 -0
  2. package/dist/alert-core-DWtHbX_-.js +134 -0
  3. package/dist/breadcrumb-list-core-Dh68T8Cf.js +747 -0
  4. package/dist/{mono-button-CLkHg3WW.js → button-core-DerXg84Q.js} +3 -276
  5. package/dist/button-dropdown-core-DKYEOyjy.js +654 -0
  6. package/dist/button-utils-D5-66M02.js +63 -0
  7. package/dist/card-utils-l80qAmrN.js +312 -0
  8. package/dist/chart-core-DV7hD3ZY.js +801 -0
  9. package/dist/checkbox-utils-DKdrhAzF.js +337 -0
  10. package/dist/chip-utils-DpRrd7Zj.js +403 -0
  11. package/dist/{data-source-controller-C6C4ej_M.js → data-source-controller-DS_JLrmS.js} +1 -1
  12. package/dist/{data-source-options-fxT5QIX4.js → data-source-options-DJUNU26C.js} +6 -6
  13. package/dist/{data-source-read-BL266IW0.js → data-source-read-uKJpRAzx.js} +2 -2
  14. package/dist/date-core-CyuSyvvG.js +734 -0
  15. package/dist/drawer-core-DbFWvNln.js +759 -0
  16. package/dist/dropdown-core-BCH1pK14.js +511 -0
  17. package/dist/dropdown-table-core-SfHUJVFq.js +1342 -0
  18. package/dist/export.js +1 -1
  19. package/dist/{field-path-BabiMrrA.js → field-path-DK2VBWHl.js} +1 -1
  20. package/dist/field-tooltip.css_raw-DVblekCl.js +5 -0
  21. package/dist/{field-validation.css_raw-Cx6SGrfP.js → field-validation.css_raw-BU7C6173.js} +1 -170
  22. package/dist/file-upload-core-Cz_dBQMx.js +624 -0
  23. package/dist/filter-builder-core-DyWjbBP7.js +381 -0
  24. package/dist/{filter-builder-B6Y2mmbM.js → filter-builder-vbqIuPhX.js} +1 -1
  25. package/dist/{filter-eval-ChDSaAUH.js → filter-eval-CqeBnMYh.js} +1 -1
  26. package/dist/{filter-odata-Bi27XUpQ.js → filter-odata-GsczYKNC.js} +1 -1
  27. package/dist/{hydration-flush-BaE9gN3C.js → hydration-flush-Volt9X7Q.js} +2 -1071
  28. package/dist/index.js +11 -11
  29. package/dist/{index.node-DTqDBca7.js → index.node-Csy9zrr1.js} +4 -4
  30. package/dist/index.node.js +11 -11
  31. package/dist/input-utils-BglY-k0H.js +1145 -0
  32. package/dist/menu-core-DkAYuCZ2.js +831 -0
  33. package/dist/modal-core-CSBSPN_m.js +844 -0
  34. package/dist/mono-button-DVvZ03P-.js +280 -0
  35. package/dist/{mono-button.shadow-DqZMpcqY.js → mono-button.shadow-BANxMGln.js} +6 -594
  36. package/dist/{mono-data-chart-NKPdAgVq.js → mono-data-chart-ChF4J9RT.js} +6 -6
  37. package/dist/{mono-data-dropdown-B2iRpJuI.js → mono-data-dropdown-Bgj2PDfm.js} +1 -1
  38. package/dist/{mono-data-grid-llJCX9MC.js → mono-data-grid-DJkp96N-.js} +144 -46
  39. package/dist/{mono-event-BPku9HpS.js → mono-event-CAZf0F_k.js} +14 -9
  40. package/dist/{mono-form-controller-BrA10erm.js → mono-form-controller-DxZLvyg6.js} +2 -1
  41. package/dist/mono-table-checkbox-core-BKOMx8R5.js +5288 -0
  42. package/dist/nav-core-B5qU2dzn.js +225 -0
  43. package/dist/{normalize-error-D93O4q8g.js → normalize-error-BEcd1tmS.js} +2 -2
  44. package/dist/nuxt.js +1 -1
  45. package/dist/otp-core-DXg3vFLh.js +758 -0
  46. package/dist/radio-utils-Dk9Tl1jz.js +319 -0
  47. package/dist/rich-text-editor-core-Ddd_QaLn.js +1280 -0
  48. package/dist/select-utils-BgArYHk8.js +2140 -0
  49. package/dist/sidebar-core-CD6txDo3.js +583 -0
  50. package/dist/slider-core-vcWr321-.js +1014 -0
  51. package/dist/src/components/dropdown-table/dropdown-table-core.d.ts +2 -2
  52. package/dist/src/components/dropdown-table/dropdown-table-types.d.ts +1 -1
  53. package/dist/src/components/dropdown-table/index.d.ts +1 -1
  54. package/dist/src/components/dropdown-table/index.shadow.d.ts +1 -1
  55. package/dist/src/components/dropdown-table/mono-data-dropdown.d.ts +1 -1
  56. package/dist/src/components/form/form-types.d.ts +9 -3
  57. package/dist/src/components/input/input-core.d.ts +1 -1
  58. package/dist/src/components/input/input-types.d.ts +1 -1
  59. package/dist/src/components/otp/otp-core.d.ts +1 -1
  60. package/dist/src/components/select/select-core.d.ts +1 -1
  61. package/dist/src/components/select/select-types.d.ts +1 -1
  62. package/dist/src/components/slider/slider-core.d.ts +1 -1
  63. package/dist/src/components/slider/slider-types.d.ts +1 -1
  64. package/dist/src/components/table/filter-suggestion.d.ts +171 -0
  65. package/dist/src/components/table/index.d.ts +5 -4
  66. package/dist/src/components/table/index.shadow.d.ts +5 -4
  67. package/dist/src/components/table/mono-data-grid.d.ts +22 -3
  68. package/dist/src/components/table/mono-table-empty-core.d.ts +37 -0
  69. package/dist/src/components/table/mono-table-search-core.d.ts +22 -3
  70. package/dist/src/components/table/table-types.d.ts +74 -4
  71. package/dist/src/components/tag-input/tag-input-core.d.ts +1 -1
  72. package/dist/src/components/tag-input/tag-input-types.d.ts +1 -1
  73. package/dist/src/components/textarea/textarea-core.d.ts +1 -1
  74. package/dist/src/composables/mono-event.d.ts +7 -1
  75. package/dist/src/entries/index.d.ts +8 -6
  76. package/dist/src/entries/index.node.d.ts +8 -6
  77. package/dist/src/search/index.d.ts +1 -1
  78. package/dist/src/utils/group-count.d.ts +36 -0
  79. package/dist/switch-utils-CTZ4id2V.js +338 -0
  80. package/dist/tabs-core-r5-B8k_N.js +317 -0
  81. package/dist/tag-input-utils-D2JA90DQ.js +3060 -0
  82. package/dist/textarea-utils-VU1KeXm8.js +821 -0
  83. package/dist/ui/accordion.js +2 -274
  84. package/dist/ui/alert.js +2 -131
  85. package/dist/ui/breadcrumb.js +4 -745
  86. package/dist/ui/button-dropdown.js +4 -652
  87. package/dist/ui/button.js +2 -63
  88. package/dist/ui/card.js +2 -310
  89. package/dist/ui/chart.js +4 -800
  90. package/dist/ui/checkbox.js +4 -335
  91. package/dist/ui/chip.js +4 -402
  92. package/dist/ui/date.js +3 -732
  93. package/dist/ui/drawer.js +3 -757
  94. package/dist/ui/dropdown-table.js +5 -1341
  95. package/dist/ui/dropdown.js +4 -509
  96. package/dist/ui/file-upload.js +3 -622
  97. package/dist/ui/filter.js +5 -380
  98. package/dist/ui/form.js +1 -1
  99. package/dist/ui/index.css +118 -1
  100. package/dist/ui/input.js +3 -1141
  101. package/dist/ui/menu.js +4 -828
  102. package/dist/ui/modal.js +4 -843
  103. package/dist/ui/nav.js +4 -223
  104. package/dist/ui/otp.js +4 -756
  105. package/dist/ui/radio.js +4 -317
  106. package/dist/ui/rich-text-editor.js +4 -1278
  107. package/dist/ui/select.js +5 -2138
  108. package/dist/ui/shadow/accordion.js +4 -273
  109. package/dist/ui/shadow/alert.js +4 -130
  110. package/dist/ui/shadow/breadcrumb.js +5 -744
  111. package/dist/ui/shadow/button-dropdown.js +6 -652
  112. package/dist/ui/shadow/button.js +3 -63
  113. package/dist/ui/shadow/card.js +4 -309
  114. package/dist/ui/shadow/chart.js +6 -1576
  115. package/dist/ui/shadow/checkbox.js +4 -334
  116. package/dist/ui/shadow/chip.js +4 -396
  117. package/dist/ui/shadow/date.js +7 -731
  118. package/dist/ui/shadow/drawer.js +4 -756
  119. package/dist/ui/shadow/dropdown-table.js +8 -1762
  120. package/dist/ui/shadow/dropdown.js +4 -508
  121. package/dist/ui/shadow/file-upload.js +4 -620
  122. package/dist/ui/shadow/filter.js +7 -379
  123. package/dist/ui/shadow/input.js +6 -1140
  124. package/dist/ui/shadow/menu.js +5 -828
  125. package/dist/ui/shadow/modal.js +6 -1063
  126. package/dist/ui/shadow/nav.js +5 -223
  127. package/dist/ui/shadow/otp.js +6 -754
  128. package/dist/ui/shadow/radio.js +4 -316
  129. package/dist/ui/shadow/rich-text-editor.js +4 -1276
  130. package/dist/ui/shadow/select.js +6 -2136
  131. package/dist/ui/shadow/sidebar.js +5 -581
  132. package/dist/ui/shadow/slider.js +5 -1010
  133. package/dist/ui/shadow/switch.js +4 -335
  134. package/dist/ui/shadow/table.js +10 -4501
  135. package/dist/ui/shadow/tabs.js +6 -315
  136. package/dist/ui/shadow/tag-input.js +7 -3057
  137. package/dist/ui/shadow/textarea.js +6 -817
  138. package/dist/ui/sidebar.js +3 -581
  139. package/dist/ui/slider.js +4 -1012
  140. package/dist/ui/switch.js +4 -336
  141. package/dist/ui/table.js +9 -4502
  142. package/dist/ui/tabs.js +4 -315
  143. package/dist/ui/tag-input.js +5 -3058
  144. package/dist/ui/textarea.js +4 -819
  145. package/dist/{vite-CivRCJaf.js → vite-CfW7z2wn.js} +21 -14
  146. package/dist/vite.js +1 -1
  147. package/dist/vue.d.ts +3 -2
  148. package/package.json +10 -11
  149. package/dist/chip-strip-bNfLn52Z.js +0 -215
  150. package/dist/data-source-controller-Dx6IQ2CN.js +0 -243
  151. package/dist/data-source-options-BM4r4PRw.js +0 -558
  152. package/dist/data-source-read-HyBCRg1t.js +0 -242
  153. package/dist/excel-BXzr3uI1.js +0 -784
  154. package/dist/export-ixRdCS2y.js +0 -2388
  155. package/dist/field-tooltip-addon-CWCp19mJ.js +0 -702
  156. package/dist/field-tooltip.css_raw-U5UeTa2d.js +0 -269
  157. package/dist/filter-builder-C0T3pMx2.js +0 -208
  158. package/dist/form-control-core-BbiACMtL.js +0 -226
  159. package/dist/icon-ClxnYhBG.js +0 -19
  160. package/dist/import-Dc4eXC02.js +0 -612
  161. package/dist/light-slots-_no0r2Z-.js +0 -246
  162. package/dist/markdown-uGlE_OfJ.js +0 -20191
  163. package/dist/mono-data-grid-e9ZVBlNN.js +0 -4240
  164. package/dist/normalize-error-BmLbgANw.js +0 -1048
@@ -0,0 +1,831 @@
1
+ import { a as defineHybridPropAliases, n as arrayHasChanged, r as booleanStringConverter, t as __decorate } from "./decorate-DbYFpi8R.js";
2
+ import { t as dispatchMonoEvent } from "./mono-event-CAZf0F_k.js";
3
+ import { t as isIconifyClass } from "./icon-BM9N-jOt.js";
4
+ import { a as validateColorProp, i as isThemeColorToken, n as colorClassToken, r as customColorStyle, t as CUSTOM_COLOR_CLASS } from "./color-CEYYtRX-.js";
5
+ import { html, isServer, nothing } from "lit";
6
+ import { property, state } from "lit/decorators.js";
7
+
8
+ //#region src/components/menu/menu-utils.ts
9
+ function isItem(node) {
10
+ return !node.type || node.type === "item";
11
+ }
12
+ function isGroup(node) {
13
+ return node.type === "group";
14
+ }
15
+ function isDivider(node) {
16
+ return node.type === "divider";
17
+ }
18
+ function isSubheader(node) {
19
+ return node.type === "subheader";
20
+ }
21
+ /**
22
+ * Walk the tree and collect the chain (root → leaf) leading to the item with
23
+ * the given id. Returns an empty array if not found.
24
+ */
25
+ function findActivePath(items, id) {
26
+ for (const node of items) {
27
+ if (node.id === id) return [node];
28
+ if (node.items?.length) {
29
+ const sub = findActivePath(node.items, id);
30
+ if (sub.length) return [node, ...sub];
31
+ }
32
+ }
33
+ return [];
34
+ }
35
+ function findItem(items, id) {
36
+ for (const node of items) {
37
+ if (node.id === id) return node;
38
+ if (node.items?.length) {
39
+ const sub = findItem(node.items, id);
40
+ if (sub) return sub;
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Generate a 1–2 character alias from a menu item's title for the icon
47
+ * fallback (used by `renderMenuIcon` when no `item.icon` and no slot icon are
48
+ * provided). Each space-delimited word contributes its first character; output
49
+ * is uppercased and capped at `max` characters.
50
+ *
51
+ * Examples:
52
+ * getMenuAlias('Dashboard') → 'D'
53
+ * getMenuAlias('Post Budget') → 'PB'
54
+ * getMenuAlias('Sales Order Report') → 'SO'
55
+ * getMenuAlias('logbook') → 'L'
56
+ * getMenuAlias('') → ''
57
+ */
58
+ function getMenuAlias(input, max = 2) {
59
+ if (!input || typeof input !== "string") return "";
60
+ const words = input.trim().split(/\s+/).filter(Boolean);
61
+ if (!words.length) return "";
62
+ return words.slice(0, max).map((w) => w.charAt(0)).join("").toUpperCase();
63
+ }
64
+ function collectDefaultOpenGroups(items) {
65
+ const out = [];
66
+ const visit = (list) => {
67
+ for (const node of list) {
68
+ if (isGroup(node) && node.defaultOpen) out.push(node.id);
69
+ if (node.items?.length) visit(node.items);
70
+ }
71
+ };
72
+ visit(items);
73
+ return out;
74
+ }
75
+ function generateMenuRootClasses(props) {
76
+ return [
77
+ "mono-menu",
78
+ props.density,
79
+ colorClassToken(props.color),
80
+ props.nav ? "nav" : "plain",
81
+ props.selectable ? "" : "not-selectable",
82
+ props.disabled ? "disabled" : "",
83
+ props.cssClassName ?? "",
84
+ props.rootExtra ?? ""
85
+ ].filter(Boolean).join(" ");
86
+ }
87
+ function validateMenuProps(props) {
88
+ const errors = [];
89
+ if (props.density && ![
90
+ "compact",
91
+ "comfortable",
92
+ "default"
93
+ ].includes(props.density)) errors.push(`Invalid density: ${String(props.density)}`);
94
+ const colorError = validateColorProp(props.color);
95
+ if (colorError) errors.push(colorError);
96
+ return errors;
97
+ }
98
+ /**
99
+ * The Basecoat styling attributes for the menu ROOT, mirroring the props one
100
+ * for one. A prop at its DEFAULT emits nothing — `:not([mono-density])` is
101
+ * comfortable and `:not([mono-color])` is primary — so the rendered DOM is
102
+ * also the shortest hand-written markup that paints the same (see menu.css).
103
+ * `nav` defaults to TRUE, so `mono-plain` is the attribute that says
104
+ * something. Shared so `<mono-menu>` and a standalone `<mono-menu-list>`
105
+ * cannot drift apart.
106
+ */
107
+ function menuRootAttrs(props) {
108
+ return {
109
+ density: props.density === "comfortable" ? null : props.density,
110
+ color: isThemeColorToken(props.color) || props.color === "surface" ? props.color === "primary" ? null : props.color : CUSTOM_COLOR_CLASS
111
+ };
112
+ }
113
+
114
+ //#endregion
115
+ //#region src/components/menu/menu-render.ts
116
+ function clsFor(base, key, cssClass) {
117
+ const extra = cssClass?.[key];
118
+ return extra ? `${base} ${extra}` : base;
119
+ }
120
+ function renderMenuIcon(item, ctx) {
121
+ const slotNodes = ctx.getSlotIconNodes(item.id);
122
+ if (!!(slotNodes && slotNodes.length)) return html`
123
+ <span
124
+ class=${clsFor("mono-menu-icon", "icon", ctx.cssClass)}
125
+ mono-icon
126
+ aria-hidden="true"
127
+ >
128
+ <span data-mono-slot=${`icon-${item.id}`}></span>
129
+ </span>
130
+ `;
131
+ if (ctx.iconSlot && item.icon && isIconifyClass(item.icon)) return html`
132
+ <span
133
+ class=${clsFor("mono-menu-icon", "icon", ctx.cssClass)}
134
+ mono-icon
135
+ aria-hidden="true"
136
+ >
137
+ <slot name=${`icon-${item.id}`}></slot>
138
+ </span>
139
+ `;
140
+ if (item.icon && isIconifyClass(item.icon)) return html`
141
+ <span
142
+ class=${clsFor("mono-menu-icon", "icon", ctx.cssClass)}
143
+ mono-icon
144
+ aria-hidden="true"
145
+ >
146
+ <span class=${`mono-menu-iconify ${item.icon}`} mono-glyph></span>
147
+ </span>
148
+ `;
149
+ if (item.icon) return html`
150
+ <span
151
+ class=${clsFor("mono-menu-icon", "icon", ctx.cssClass)}
152
+ mono-icon
153
+ aria-hidden="true"
154
+ >
155
+ ${item.icon}
156
+ </span>
157
+ `;
158
+ const alias = getMenuAlias(item.title || item.id);
159
+ if (alias) return html`
160
+ <span
161
+ class=${`${clsFor("mono-menu-icon", "icon", ctx.cssClass)} alias`}
162
+ mono-icon
163
+ mono-alias
164
+ aria-hidden="true"
165
+ data-mono-alias=${alias}
166
+ >
167
+ ${alias}
168
+ </span>
169
+ `;
170
+ return nothing;
171
+ }
172
+ function renderMenuBadge(item, ctx) {
173
+ if (item.badge === void 0 || item.badge === null || item.badge === "") return nothing;
174
+ const colorClass = item.badgeColor && item.badgeColor !== "default" ? item.badgeColor : "";
175
+ return html`
176
+ <span
177
+ class=${`${clsFor("mono-menu-badge", "badge", ctx.cssClass)} ${colorClass}`.trim()}
178
+ mono-badge=${colorClass}
179
+ >
180
+ ${item.badge}
181
+ </span>
182
+ `;
183
+ }
184
+ function renderMenuAppend(item, ctx) {
185
+ if (item.badge !== void 0 && item.badge !== null && item.badge !== "") return renderMenuBadge(item, ctx);
186
+ if (!item.appendIcon) return nothing;
187
+ return html`
188
+ <span
189
+ class=${clsFor("mono-menu-append", "appendIcon", ctx.cssClass)}
190
+ mono-append
191
+ aria-hidden="true"
192
+ >
193
+ ${item.appendIcon}
194
+ </span>
195
+ `;
196
+ }
197
+ function renderMenuItemRow(item, ctx) {
198
+ const active = ctx.isSelected(item.id);
199
+ const itemClasses = [
200
+ clsFor("mono-menu-item", "item", ctx.cssClass),
201
+ active ? "active" : "",
202
+ active && ctx.cssClass?.itemActive ? ctx.cssClass.itemActive : "",
203
+ item.disabled ? "disabled" : "",
204
+ item.disabled && ctx.cssClass?.itemDisabled ? ctx.cssClass.itemDisabled : ""
205
+ ].filter(Boolean).join(" ");
206
+ const tag = item.href ? "a" : "button";
207
+ const actionInner = html`
208
+ ${renderMenuIcon(item, ctx)}
209
+ <span class=${clsFor("mono-menu-content", "content", ctx.cssClass)} mono-content>
210
+ <span class=${clsFor("mono-menu-title", "title", ctx.cssClass)} mono-title>
211
+ ${item.title ?? item.id}
212
+ </span>
213
+ ${item.subtitle ? html`<span
214
+ class=${clsFor("mono-menu-subtitle", "subtitle", ctx.cssClass)}
215
+ mono-subtitle
216
+ >${item.subtitle}</span
217
+ >` : nothing}
218
+ </span>
219
+ ${renderMenuAppend(item, ctx)}
220
+ `;
221
+ return html`
222
+ <li class=${itemClasses} mono-item ?mono-active=${active} ?mono-disabled=${!!item.disabled}>
223
+ ${tag === "a" ? html`
224
+ <a
225
+ class=${clsFor("mono-menu-action", "action", ctx.cssClass)}
226
+ mono-action
227
+ href=${item.href}
228
+ role=${ctx.selectable ? "option" : "link"}
229
+ aria-current=${active ? "page" : "false"}
230
+ aria-disabled=${item.disabled ? "true" : "false"}
231
+ @click=${(e) => ctx.onItemClick(item, e)}
232
+ >
233
+ ${actionInner}
234
+ </a>
235
+ ` : html`
236
+ <button
237
+ type="button"
238
+ class=${clsFor("mono-menu-action", "action", ctx.cssClass)}
239
+ mono-action
240
+ role=${ctx.selectable ? "option" : "menuitem"}
241
+ aria-selected=${ctx.selectable ? active ? "true" : "false" : nothing}
242
+ aria-disabled=${item.disabled ? "true" : "false"}
243
+ ?disabled=${item.disabled || ctx.disabled}
244
+ @click=${(e) => ctx.onItemClick(item, e)}
245
+ >
246
+ ${actionInner}
247
+ </button>
248
+ `}
249
+ ${ctx.bodySlot && !isGroup(item) ? html`<ul
250
+ class=${clsFor("mono-menu-list", "list", ctx.cssClass)}
251
+ mono-list
252
+ data-mono-slot="body"
253
+ ></ul>` : item.items?.length && !isGroup(item) ? html`<ul class=${clsFor("mono-menu-list", "list", ctx.cssClass)} mono-list>
254
+ ${renderMenuList(item.items, ctx)}
255
+ </ul>` : nothing}
256
+ </li>
257
+ `;
258
+ }
259
+ function renderMenuGroup(group, ctx) {
260
+ const open = ctx.isGroupOpen(group.id);
261
+ const ancestorActive = ctx.isGroupActive?.(group) ?? false;
262
+ const groupClasses = [clsFor("mono-menu-group", "group", ctx.cssClass), ancestorActive ? "active" : ""].filter(Boolean).join(" ");
263
+ return html`
264
+ <li
265
+ class=${groupClasses}
266
+ mono-item
267
+ mono-group
268
+ ?mono-open=${open}
269
+ ?mono-active=${ancestorActive}
270
+ ?mono-disabled=${!!group.disabled}
271
+ data-open=${open ? "true" : "false"}
272
+ >
273
+ <button
274
+ type="button"
275
+ class=${clsFor("mono-menu-group-header", "groupHeader", ctx.cssClass)}
276
+ mono-group-header
277
+ aria-expanded=${open ? "true" : "false"}
278
+ ?disabled=${group.disabled || ctx.disabled}
279
+ @click=${(e) => ctx.onGroupToggle(group, e)}
280
+ >
281
+ ${renderMenuIcon(group, ctx)}
282
+ <span class=${clsFor("mono-menu-content", "content", ctx.cssClass)} mono-content>
283
+ <span class=${clsFor("mono-menu-title", "title", ctx.cssClass)} mono-title>
284
+ ${group.title ?? group.id}
285
+ </span>
286
+ ${group.subtitle ? html`<span
287
+ class=${clsFor("mono-menu-subtitle", "subtitle", ctx.cssClass)}
288
+ mono-subtitle
289
+ >${group.subtitle}</span
290
+ >` : nothing}
291
+ </span>
292
+ <span
293
+ class=${clsFor("mono-menu-chevron", "groupChevron", ctx.cssClass)}
294
+ mono-chevron
295
+ aria-hidden="true"
296
+ >
297
+ ${ctx.chevronSvg ?? html`<span class="mono-icon i-mdi-chevron-right" aria-hidden="true"></span>`}
298
+ </span>
299
+ </button>
300
+ ${ctx.bodySlot ? html`<ul
301
+ class=${clsFor("mono-menu-list", "groupBody", ctx.cssClass)}
302
+ mono-list
303
+ mono-group-body
304
+ data-mono-slot="body"
305
+ ></ul>` : group.items?.length ? html`<ul
306
+ class=${clsFor("mono-menu-list", "groupBody", ctx.cssClass)}
307
+ mono-list
308
+ mono-group-body
309
+ >
310
+ ${renderMenuList(group.items, ctx)}
311
+ </ul>` : nothing}
312
+ </li>
313
+ `;
314
+ }
315
+ function renderMenuDivider(item, ctx) {
316
+ return html`<li
317
+ class=${clsFor("mono-menu-divider", "divider", ctx.cssClass)}
318
+ mono-divider
319
+ role="separator"
320
+ data-id=${item.id}
321
+ ></li>`;
322
+ }
323
+ function renderMenuSubheader(item, ctx) {
324
+ return html`<li
325
+ class=${clsFor("mono-menu-subheader", "subheader", ctx.cssClass)}
326
+ mono-subheader
327
+ data-id=${item.id}
328
+ >
329
+ ${item.title ?? ""}
330
+ </li>`;
331
+ }
332
+ function renderMenuList(list, ctx) {
333
+ return list.map((item) => {
334
+ if (isDivider(item)) return renderMenuDivider(item, ctx);
335
+ if (isSubheader(item)) return renderMenuSubheader(item, ctx);
336
+ if (isGroup(item)) return renderMenuGroup(item, ctx);
337
+ return renderMenuItemRow(item, ctx);
338
+ });
339
+ }
340
+ /**
341
+ * Render only the group rows from `list` — non-group items are skipped.
342
+ * Used by `<mono-menu-list type="group">`.
343
+ */
344
+ function renderMenuGroupsOnly(list, ctx) {
345
+ const out = [];
346
+ for (const item of list) if (isGroup(item)) out.push(renderMenuGroup(item, ctx));
347
+ return out;
348
+ }
349
+
350
+ //#endregion
351
+ //#region src/components/menu/menu-core.ts
352
+ /** Coerce any `items` input (array, JSON string, or other) to a MenuItem array. */
353
+ function coerceItems(value) {
354
+ if (Array.isArray(value)) return value;
355
+ if (typeof value === "string") {
356
+ if (!value) return [];
357
+ try {
358
+ const parsed = JSON.parse(value);
359
+ return Array.isArray(parsed) ? parsed : [];
360
+ } catch {
361
+ return [];
362
+ }
363
+ }
364
+ return [];
365
+ }
366
+ /**
367
+ * `MonoMenuCore` — all render-mode-agnostic logic for `mono-menu`: reactive
368
+ * props, hybrid aliases, css-class interop, selection + open-group state,
369
+ * default-open seeding, the click/toggle/change events, the full public API, and
370
+ * the chrome `render()` (which delegates the body to a `_renderBody()` hook).
371
+ *
372
+ * Leaves to each build: `createRenderRoot()`, the body strategy (light: slot
373
+ * capture / declarative `slot="body"`; shadow: items-driven only), and
374
+ * `_chevronSvg()` (light: undefined → UnoCSS icon span; shadow: inline SVG).
375
+ */
376
+ const MonoMenuCore = (superClass) => {
377
+ class MonoMenuCoreClass extends superClass {
378
+ constructor(...args) {
379
+ super(...args);
380
+ this.items = [];
381
+ this.modelValue = "";
382
+ this.multiple = false;
383
+ this.density = "comfortable";
384
+ this.color = "primary";
385
+ this.nav = true;
386
+ this.selectable = true;
387
+ this.disabled = false;
388
+ this.controlled = false;
389
+ this.cssClass = {};
390
+ this.cssClassName = "";
391
+ this._openGroups = /* @__PURE__ */ new Set();
392
+ this._seededGroups = /* @__PURE__ */ new Set();
393
+ this._slotIcons = /* @__PURE__ */ new Map();
394
+ this._listChildren = /* @__PURE__ */ new Set();
395
+ this._railSidebar = null;
396
+ this._railObserver = null;
397
+ this._railRetryRaf = null;
398
+ this._railRetryTimer = null;
399
+ defineHybridPropAliases(this, ["modelValue", "cssClass"]);
400
+ Object.defineProperty(this, "css-class", {
401
+ get: () => this.cssClass,
402
+ set: (value) => this._setCssClass(value),
403
+ configurable: true,
404
+ enumerable: false
405
+ });
406
+ Object.defineProperty(this, "cssclass", {
407
+ get: () => this.cssClass,
408
+ set: (value) => this._setCssClass(value),
409
+ configurable: true,
410
+ enumerable: false
411
+ });
412
+ }
413
+ static get observedAttributes() {
414
+ return [
415
+ ...super.observedAttributes ?? [],
416
+ "modelvalue",
417
+ "css-class",
418
+ "cssclass"
419
+ ];
420
+ }
421
+ attributeChangedCallback(name, oldValue, newValue) {
422
+ super.attributeChangedCallback(name, oldValue, newValue);
423
+ if (oldValue === newValue) return;
424
+ if (name === "modelvalue") {
425
+ this.modelValue = newValue ?? "";
426
+ return;
427
+ }
428
+ if (name === "css-class" || name === "cssclass") this._setCssClass(newValue);
429
+ }
430
+ connectedCallback() {
431
+ super.connectedCallback();
432
+ if (isServer) return;
433
+ this._setupRailSync();
434
+ }
435
+ disconnectedCallback() {
436
+ if (!isServer) this._teardownRailSync();
437
+ super.disconnectedCallback();
438
+ }
439
+ willUpdate(changed) {
440
+ if (typeof this.items === "string") this.items = coerceItems(this.items);
441
+ super.willUpdate?.(changed);
442
+ if (changed.has("items")) this._seedDefaultOpenGroups();
443
+ }
444
+ _seedDefaultOpenGroups() {
445
+ const existing = new Set(this._openGroups);
446
+ let changed = false;
447
+ for (const id of collectDefaultOpenGroups(this.items)) {
448
+ if (this._seededGroups.has(id)) continue;
449
+ this._seededGroups.add(id);
450
+ if (!existing.has(id)) {
451
+ existing.add(id);
452
+ changed = true;
453
+ }
454
+ }
455
+ if (!changed) return;
456
+ this._openGroups = existing;
457
+ }
458
+ _setCssClass(value) {
459
+ if (value == null) {
460
+ this.cssClass = {};
461
+ this.cssClassName = "";
462
+ return;
463
+ }
464
+ if (typeof value === "object") {
465
+ this.cssClass = value;
466
+ return;
467
+ }
468
+ if (typeof value === "string") {
469
+ const trimmed = value.trim();
470
+ if (!trimmed) {
471
+ this.cssClass = {};
472
+ this.cssClassName = "";
473
+ return;
474
+ }
475
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) try {
476
+ this.cssClass = JSON.parse(trimmed);
477
+ return;
478
+ } catch {}
479
+ this.cssClassName = trimmed;
480
+ }
481
+ }
482
+ _cls(base, key) {
483
+ const extra = this.cssClass?.[key];
484
+ return extra ? `${base} ${extra}` : base;
485
+ }
486
+ get _rootClasses() {
487
+ return generateMenuRootClasses({
488
+ density: this.density,
489
+ color: this.color,
490
+ nav: this.nav,
491
+ selectable: this.selectable,
492
+ disabled: this.disabled,
493
+ cssClassName: this.cssClassName,
494
+ rootExtra: this.cssClass?.root
495
+ });
496
+ }
497
+ _isSelected(id) {
498
+ if (this.multiple) return Array.isArray(this.modelValue) && this.modelValue.includes(id);
499
+ return !this.multiple && this.modelValue === id;
500
+ }
501
+ _isGroupOpen(id) {
502
+ return this._openGroups.has(id);
503
+ }
504
+ /** A group is "active" when the currently-selected item is a descendant. */
505
+ _isGroupActive(group) {
506
+ const selected = this.multiple ? Array.isArray(this.modelValue) ? this.modelValue : [] : [this.modelValue];
507
+ const ids = new Set(selected.filter(Boolean));
508
+ if (!ids.size) return false;
509
+ const contains = (node) => !!node.items?.some((child) => ids.has(child.id) || contains(child));
510
+ return contains(group);
511
+ }
512
+ _findRegisteredItem(id) {
513
+ for (const child of this._listChildren) {
514
+ const items = child.getMenuItems?.() ?? [];
515
+ const found = findItem(items, id);
516
+ if (found) return found;
517
+ }
518
+ return null;
519
+ }
520
+ _findAnyItem(id) {
521
+ return findItem(this.items, id) ?? this._findRegisteredItem(id);
522
+ }
523
+ _getRegisteredActivePath(id) {
524
+ for (const child of this._listChildren) {
525
+ const items = child.getMenuItems?.() ?? [];
526
+ const path = findActivePath(items, id);
527
+ if (path.length) return path;
528
+ }
529
+ return [];
530
+ }
531
+ select(id) {
532
+ const item = this._findAnyItem(id);
533
+ if (!item || !isItem(item)) return;
534
+ this._handleItemActivation(item);
535
+ }
536
+ deselect(id) {
537
+ if (!this.multiple) {
538
+ if (this.modelValue === id) {
539
+ const oldValue = this.modelValue;
540
+ this.modelValue = "";
541
+ this._emitChange(id, this._findAnyItem(id) ?? { id }, false, oldValue);
542
+ }
543
+ return;
544
+ }
545
+ if (Array.isArray(this.modelValue) && this.modelValue.includes(id)) {
546
+ const oldValue = [...this.modelValue];
547
+ this.modelValue = this.modelValue.filter((v) => v !== id);
548
+ this._emitChange(id, this._findAnyItem(id) ?? { id }, false, oldValue);
549
+ }
550
+ }
551
+ toggleGroup(id) {
552
+ const item = this._findAnyItem(id);
553
+ if (!item || !isGroup(item)) return;
554
+ this._handleGroupToggle(item);
555
+ }
556
+ expandGroup(id) {
557
+ if (this._openGroups.has(id)) return;
558
+ const next = new Set(this._openGroups);
559
+ next.add(id);
560
+ this._openGroups = next;
561
+ }
562
+ collapseGroup(id) {
563
+ if (!this._openGroups.has(id)) return;
564
+ const next = new Set(this._openGroups);
565
+ next.delete(id);
566
+ this._openGroups = next;
567
+ }
568
+ focus() {
569
+ this.querySelector(".mono-menu-action, .mono-menu-group-header")?.focus();
570
+ }
571
+ getActivePath() {
572
+ const id = !this.multiple ? this.modelValue : Array.isArray(this.modelValue) && this.modelValue.length ? this.modelValue[this.modelValue.length - 1] : "";
573
+ if (!id) return [];
574
+ const ownPath = findActivePath(this.items, id);
575
+ if (ownPath.length) return ownPath;
576
+ return this._getRegisteredActivePath(id);
577
+ }
578
+ requestItemActivation(item, event) {
579
+ this._handleItemActivation(item, event);
580
+ }
581
+ requestGroupToggle(group, event) {
582
+ this._handleGroupToggle(group, event);
583
+ }
584
+ isItemSelected(id) {
585
+ return this._isSelected(id);
586
+ }
587
+ isGroupOpenPublic(id) {
588
+ return this._isGroupOpen(id);
589
+ }
590
+ getSlotIconNodes(id) {
591
+ return this._slotIcons.get(id);
592
+ }
593
+ /** @internal called by `<mono-menu-list>` from its connectedCallback. */
594
+ _registerListChild(child) {
595
+ this._listChildren.add(child);
596
+ }
597
+ /** @internal called by `<mono-menu-list>` from its disconnectedCallback. */
598
+ _unregisterListChild(child) {
599
+ this._listChildren.delete(child);
600
+ }
601
+ /** Walk up across slot + shadow boundaries to the host `<mono-sidebar>`, if any. */
602
+ _findAncestorSidebar() {
603
+ let node = this.assignedSlot ?? this.parentNode;
604
+ while (node) {
605
+ if (node instanceof Element && (node.localName === "mono-sidebar" || node.localName === "mono-shadow-sidebar")) return node;
606
+ node = node.assignedSlot ?? (node instanceof ShadowRoot ? node.host : node.parentNode);
607
+ }
608
+ return null;
609
+ }
610
+ _setupRailSync(retries = 30) {
611
+ if (this._railObserver) this._teardownRailSync();
612
+ const sidebar = this._findAncestorSidebar();
613
+ if (!sidebar) {
614
+ if (retries <= 0 || isServer) return;
615
+ let fired = false;
616
+ const retry = () => {
617
+ if (fired) return;
618
+ fired = true;
619
+ this._railRetryRaf = null;
620
+ this._railRetryTimer = null;
621
+ if (this.isConnected) this._setupRailSync(retries - 1);
622
+ };
623
+ this._cancelRailRetry();
624
+ if (typeof requestAnimationFrame !== "undefined") this._railRetryRaf = requestAnimationFrame(retry);
625
+ this._railRetryTimer = setTimeout(retry, 32);
626
+ return;
627
+ }
628
+ this._railSidebar = sidebar;
629
+ this._applyRailCollapsed(sidebar.hasAttribute("data-rail-collapsed"));
630
+ this._railObserver = new MutationObserver(() => {
631
+ this._applyRailCollapsed(sidebar.hasAttribute("data-rail-collapsed"));
632
+ });
633
+ this._railObserver.observe(sidebar, {
634
+ attributes: true,
635
+ attributeFilter: ["data-rail-collapsed"]
636
+ });
637
+ }
638
+ _cancelRailRetry() {
639
+ if (this._railRetryRaf !== null && typeof cancelAnimationFrame !== "undefined") cancelAnimationFrame(this._railRetryRaf);
640
+ if (this._railRetryTimer !== null) clearTimeout(this._railRetryTimer);
641
+ this._railRetryRaf = null;
642
+ this._railRetryTimer = null;
643
+ }
644
+ _teardownRailSync() {
645
+ this._cancelRailRetry();
646
+ this._railObserver?.disconnect();
647
+ this._railObserver = null;
648
+ this._railSidebar = null;
649
+ }
650
+ static {
651
+ this._RAIL_COLLAPSE_VARS = [
652
+ ["--mono-menu-label-display", "none"],
653
+ ["--mono-menu-row-display", "flex"],
654
+ ["--mono-menu-row-justify", "center"],
655
+ ["--mono-menu-action-width", "auto"],
656
+ ["--mono-menu-action-justify", "center"],
657
+ ["--mono-menu-action-gap", "0"],
658
+ ["--mono-menu-group-children-display", "none"]
659
+ ];
660
+ }
661
+ _applyRailCollapsed(collapsed) {
662
+ this.toggleAttribute("rail-collapsed", collapsed);
663
+ const vars = MonoMenuCoreClass._RAIL_COLLAPSE_VARS;
664
+ if (collapsed) for (const [name, value] of vars) this.style.setProperty(name, value);
665
+ else for (const [name] of vars) this.style.removeProperty(name);
666
+ }
667
+ _handleItemActivation(item, event) {
668
+ if (item.disabled || this.disabled) return;
669
+ dispatchMonoEvent(this, "click", {
670
+ value: item.id,
671
+ item,
672
+ sourceEvent: event
673
+ });
674
+ if (this.controlled) return;
675
+ if (!this.selectable) return;
676
+ if (this.multiple) {
677
+ const oldArr = Array.isArray(this.modelValue) ? [...this.modelValue] : [];
678
+ let nextArr;
679
+ let selected;
680
+ if (oldArr.includes(item.id)) {
681
+ nextArr = oldArr.filter((v) => v !== item.id);
682
+ selected = false;
683
+ } else {
684
+ nextArr = [...oldArr, item.id];
685
+ selected = true;
686
+ }
687
+ this.modelValue = nextArr;
688
+ this._emitChange(item.id, item, selected, oldArr, event);
689
+ return;
690
+ }
691
+ const oldValue = this.modelValue;
692
+ if (oldValue === item.id) return;
693
+ this.modelValue = item.id;
694
+ this._emitChange(item.id, item, true, oldValue, event);
695
+ }
696
+ _emitChange(value, item, selected, oldValue, event) {
697
+ const detail = {
698
+ modelValue: this.modelValue,
699
+ oldValue,
700
+ value,
701
+ item,
702
+ selected,
703
+ sourceEvent: event
704
+ };
705
+ dispatchMonoEvent(this, "change", detail);
706
+ }
707
+ _handleGroupToggle(group, event) {
708
+ if (group.disabled || this.disabled) return;
709
+ const oldOpen = this._openGroups.has(group.id);
710
+ const next = new Set(this._openGroups);
711
+ if (oldOpen) next.delete(group.id);
712
+ else next.add(group.id);
713
+ this._openGroups = next;
714
+ const detail = {
715
+ groupId: group.id,
716
+ open: !oldOpen,
717
+ oldOpen,
718
+ group,
719
+ sourceEvent: event
720
+ };
721
+ dispatchMonoEvent(this, "toggle-group", detail);
722
+ }
723
+ /** Inline chevron — light: undefined (UnoCSS span); shadow: inline SVG. */
724
+ _chevronSvg() {}
725
+ /** Whether to project icons via native `<slot>` — light: false; shadow: true. */
726
+ _useIconSlots() {
727
+ return false;
728
+ }
729
+ _renderContext() {
730
+ return {
731
+ multiple: this.multiple,
732
+ selectable: this.selectable,
733
+ disabled: this.disabled,
734
+ cssClass: this.cssClass,
735
+ chevronSvg: this._chevronSvg(),
736
+ iconSlot: this._useIconSlots(),
737
+ isSelected: (id) => this._isSelected(id),
738
+ isGroupOpen: (id) => this._isGroupOpen(id),
739
+ isGroupActive: (group) => this._isGroupActive(group),
740
+ getSlotIconNodes: (id) => this._slotIcons.get(id),
741
+ onItemClick: (item, e) => this._handleItemActivation(item, e),
742
+ onGroupToggle: (group, e) => this._handleGroupToggle(group, e)
743
+ };
744
+ }
745
+ /** Default body — items-driven. Light overrides to add the slot="body" path. */
746
+ _renderBody() {
747
+ return html`
748
+ <ul
749
+ class=${this._cls("mono-menu-list", "list")}
750
+ mono-list
751
+ role=${this.selectable ? "listbox" : "menu"}
752
+ >
753
+ ${renderMenuList(this.items, this._renderContext())}
754
+ </ul>
755
+ `;
756
+ }
757
+ /**
758
+
759
+ * Carries a literal `color` (`#7c3aed`, `rgb(…)`) that no stylesheet can know about.
760
+ * Empty for a palette slot, which resolves entirely through the `.mono-menu.<token>`
761
+ * rules instead.
762
+ *
763
+ * Must land on the ROOT element, not the host: a class-based `-preset` declared on
764
+ * the root beats an inherited one, so a host-level write would silently lose. If a
765
+ * `_syncRootFromState`-style attribute re-assert is ever added here (sidebar has one),
766
+ * it has to serialize from THIS getter or it will wipe the colour.
767
+ */
768
+ get _inlineRootStyle() {
769
+ const raw = isThemeColorToken(this.color) || this.color === "surface" ? "" : this.color;
770
+ return customColorStyle(raw, "menu");
771
+ }
772
+ render() {
773
+ const attrs = menuRootAttrs(this);
774
+ return html`
775
+ <nav
776
+ class=${this._rootClasses}
777
+ style=${this._inlineRootStyle}
778
+ role="navigation"
779
+ mono-menu
780
+ mono-density=${attrs.density ?? nothing}
781
+ mono-color=${attrs.color ?? nothing}
782
+ ?mono-plain=${!this.nav}
783
+ ?mono-disabled=${this.disabled}
784
+ >
785
+ ${this._renderBody()}
786
+ </nav>
787
+ `;
788
+ }
789
+ }
790
+ __decorate([property({
791
+ attribute: "items",
792
+ converter: {
793
+ fromAttribute: (value) => coerceItems(value),
794
+ toAttribute: () => null
795
+ },
796
+ hasChanged: arrayHasChanged
797
+ })], MonoMenuCoreClass.prototype, "items", void 0);
798
+ __decorate([property({
799
+ attribute: "model-value",
800
+ reflect: true
801
+ })], MonoMenuCoreClass.prototype, "modelValue", void 0);
802
+ __decorate([property({
803
+ reflect: true,
804
+ converter: booleanStringConverter
805
+ })], MonoMenuCoreClass.prototype, "multiple", void 0);
806
+ __decorate([property({ type: String })], MonoMenuCoreClass.prototype, "density", void 0);
807
+ __decorate([property({ type: String })], MonoMenuCoreClass.prototype, "color", void 0);
808
+ __decorate([property({
809
+ reflect: true,
810
+ converter: booleanStringConverter
811
+ })], MonoMenuCoreClass.prototype, "nav", void 0);
812
+ __decorate([property({
813
+ reflect: true,
814
+ converter: booleanStringConverter
815
+ })], MonoMenuCoreClass.prototype, "selectable", void 0);
816
+ __decorate([property({
817
+ reflect: true,
818
+ converter: booleanStringConverter
819
+ })], MonoMenuCoreClass.prototype, "disabled", void 0);
820
+ __decorate([property({
821
+ reflect: true,
822
+ converter: booleanStringConverter
823
+ })], MonoMenuCoreClass.prototype, "controlled", void 0);
824
+ __decorate([property({ attribute: false })], MonoMenuCoreClass.prototype, "cssClass", void 0);
825
+ __decorate([property({ attribute: false })], MonoMenuCoreClass.prototype, "cssClassName", void 0);
826
+ __decorate([state()], MonoMenuCoreClass.prototype, "_openGroups", void 0);
827
+ return MonoMenuCoreClass;
828
+ };
829
+
830
+ //#endregion
831
+ export { isGroup as _, renderMenuGroup as a, validateMenuProps as b, renderMenuItemRow as c, collectDefaultOpenGroups as d, findActivePath as f, isDivider as g, getMenuAlias as h, renderMenuDivider as i, renderMenuList as l, generateMenuRootClasses as m, renderMenuAppend as n, renderMenuGroupsOnly as o, findItem as p, renderMenuBadge as r, renderMenuIcon as s, MonoMenuCore as t, renderMenuSubheader as u, isItem as v, isSubheader as y };