@mono-lit/helper 0.0.9 → 0.0.10

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