@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
@@ -1,5 +1,4 @@
1
- import { NodeTypes, parse } from "@vue/compiler-dom";
2
- import { parse as parse$1 } from "@vue/compiler-sfc";
1
+ import { parse } from "vue/compiler-sfc";
3
2
  import MagicString from "magic-string";
4
3
 
5
4
  //#region src/vite/shadow-manifest.ts
@@ -74,6 +73,13 @@ function shadowTagsFromScript(script) {
74
73
 
75
74
  //#endregion
76
75
  //#region src/vite/mono-client-only.ts
76
+ const NodeTypes = {
77
+ ELEMENT: 1,
78
+ TEXT: 2,
79
+ COMMENT: 3,
80
+ ATTRIBUTE: 6,
81
+ DIRECTIVE: 7
82
+ };
77
83
  const LIT_DIRECTIVES_TO_MOVE = [
78
84
  "v-for",
79
85
  ":key",
@@ -121,18 +127,19 @@ function monoClientOnlyPlugin(options = {}) {
121
127
  if (!filename.endsWith(".vue")) return null;
122
128
  if (filename.includes("/node_modules/") || filename.includes("\\node_modules\\")) return null;
123
129
  if (!source.toLowerCase().includes(`<${normalizedPrefix}`)) return null;
124
- const { descriptor, errors } = parse$1(source, { filename });
125
- if (errors.length > 0 || !descriptor.template) return null;
130
+ const { descriptor, errors } = parse(source, {
131
+ filename,
132
+ templateParseOptions: { comments: true }
133
+ });
134
+ if (errors.length > 0 || !descriptor.template?.ast) return null;
126
135
  const fileShadowTags = /* @__PURE__ */ new Set();
127
136
  if (litWrapper) {
128
137
  for (const tag of shadowOverride) fileShadowTags.add(tag);
129
138
  const script = `${descriptor.scriptSetup?.content ?? ""}\n${descriptor.script?.content ?? ""}`;
130
139
  for (const tag of shadowTagsFromScript(script)) fileShadowTags.add(tag);
131
140
  }
132
- const template = descriptor.template;
133
- const ast = parse(template.content, { comments: true });
141
+ const ast = descriptor.template.ast;
134
142
  const magicString = new MagicString(source);
135
- const templateOffset = template.loc.start.offset;
136
143
  let changed = false;
137
144
  /** A `mono-*` element whose shadow build this file imports → SSR-wrapped. */
138
145
  function isShadowElement(node) {
@@ -154,8 +161,8 @@ function monoClientOnlyPlugin(options = {}) {
154
161
  * No skeleton fallback — the element is server-rendered to DSD.
155
162
  */
156
163
  function wrapLit(node) {
157
- const start = templateOffset + node.loc.start.offset;
158
- const end = templateOffset + node.loc.end.offset;
164
+ const start = node.loc.start.offset;
165
+ const end = node.loc.end.offset;
159
166
  const moved = node.props.filter((prop) => prop.type === NodeTypes.DIRECTIVE && !!prop.rawName && LIT_DIRECTIVES_TO_MOVE.includes(prop.rawName));
160
167
  const directivesToAdd = moved.length ? ` ${moved.map((prop) => prop.loc.source).join(" ")}` : "";
161
168
  const startTag = `<${litWrapperComponent}${directivesToAdd}>`;
@@ -165,7 +172,7 @@ function monoClientOnlyPlugin(options = {}) {
165
172
  magicString.overwrite(start, end, `${startTag}${stripped}${endTag}`);
166
173
  } else {
167
174
  const lastProp = node.props.length ? node.props[node.props.length - 1] : void 0;
168
- const contentStart = lastProp ? templateOffset + lastProp.loc.end.offset : start + node.tag.length + 2;
175
+ const contentStart = lastProp ? lastProp.loc.end.offset : start + node.tag.length + 2;
169
176
  const stripped = source.slice(start, contentStart).replace(litDirectivesRegex, "").trim();
170
177
  magicString.overwrite(start, contentStart, stripped);
171
178
  magicString.prependLeft(start, startTag);
@@ -174,13 +181,13 @@ function monoClientOnlyPlugin(options = {}) {
174
181
  changed = true;
175
182
  }
176
183
  function wrapRange(firstNode, lastNode) {
177
- const start = templateOffset + firstNode.loc.start.offset;
178
- const end = templateOffset + lastNode.loc.end.offset;
184
+ const start = firstNode.loc.start.offset;
185
+ const end = lastNode.loc.end.offset;
179
186
  function extractAndRemoveStaticAttr(name) {
180
187
  const attribute = getStaticAttribute(firstNode, name);
181
188
  if (!attribute) return "";
182
- const attributeStart = templateOffset + attribute.loc.start.offset;
183
- const attributeEnd = templateOffset + attribute.loc.end.offset;
189
+ const attributeStart = attribute.loc.start.offset;
190
+ const attributeEnd = attribute.loc.end.offset;
184
191
  let removalStart = attributeStart;
185
192
  while (removalStart > start && /\s/.test(source[removalStart - 1] ?? "")) removalStart--;
186
193
  magicString.remove(removalStart, attributeEnd);
package/dist/vite.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as monoSsrStubPlugin, r as monoClientOnlyPlugin, t as monoSsr } from "./vite-CivRCJaf.js";
1
+ import { n as monoSsrStubPlugin, r as monoClientOnlyPlugin, t as monoSsr } from "./vite-CfW7z2wn.js";
2
2
 
3
3
  export { monoClientOnlyPlugin, monoSsr, monoSsrStubPlugin };
package/dist/vue.d.ts CHANGED
@@ -78,6 +78,7 @@ import type { TableCheckboxEvents } from './src/components/table/mono-table-chec
78
78
  import type { TableDetailEvents } from './src/components/table/mono-table-detail-core.js'
79
79
  import type { TableEmptyEvents } from './src/components/table/mono-table-empty-core.js'
80
80
  import type { TableErrorEvents } from './src/components/table/mono-table-error-core.js'
81
+ import type { TableSearchEvents } from './src/components/table/table-types.js'
81
82
  import type { TabsEvents } from './src/components/tabs/tabs-types.js'
82
83
  import type { TagInputEvents } from './src/components/tag-input/tag-input-types.js'
83
84
  import type { TextareaEvents } from './src/components/textarea/textarea-types.js'
@@ -202,7 +203,7 @@ declare module 'vue' {
202
203
  'mono-shadow-table-page-size': MonoElement<TablePageSizeProps>
203
204
  'mono-shadow-table-paging': MonoElement<TablePagingProps>
204
205
  'mono-shadow-table-paging-group': MonoElement<TablePagingGroupProps>
205
- 'mono-shadow-table-search': MonoElement<TableSearchProps>
206
+ 'mono-shadow-table-search': MonoElement<TableSearchProps, TableSearchEvents>
206
207
  'mono-shadow-table-sort': MonoElement<TableSortProps>
207
208
  'mono-shadow-table-summary': MonoElement<TableSummaryProps>
208
209
  'mono-shadow-table-th': MonoElement<TableThProps>
@@ -221,7 +222,7 @@ declare module 'vue' {
221
222
  'mono-table-page-size': MonoElement<TablePageSizeProps>
222
223
  'mono-table-paging': MonoElement<TablePagingProps>
223
224
  'mono-table-paging-group': MonoElement<TablePagingGroupProps>
224
- 'mono-table-search': MonoElement<TableSearchProps>
225
+ 'mono-table-search': MonoElement<TableSearchProps, TableSearchEvents>
225
226
  'mono-table-sort': MonoElement<TableSortProps>
226
227
  'mono-table-summary': MonoElement<TableSummaryProps>
227
228
  'mono-table-th': MonoElement<TableThProps>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mono-lit/helper",
3
- "version": "0.0.9",
3
+ "version": "0.1.0",
4
4
  "description": "Lit web components (tables, forms, inputs, dialogs, charts) for Vue and Nuxt, with light-DOM and shadow-DOM builds.",
5
5
  "keywords": [
6
6
  "lit",
@@ -328,15 +328,17 @@
328
328
  "@floating-ui/core": "1.8.0",
329
329
  "@floating-ui/dom": "1.8.0",
330
330
  "@iconify/json": "2.2.505",
331
+ "@nuxt/schema": "^4.6.2",
331
332
  "@tsdown/css": "0.23.1",
332
333
  "@unocss/preset-web-fonts": "66.11.0",
334
+ "@vue/compiler-dom": "3.5.44",
333
335
  "basecoat-css": "1.0.2",
334
336
  "chart.js": "4.5.1",
335
337
  "cross-env": "10.1.0",
336
338
  "dotenv": "^17.4.2",
337
339
  "dotenv-cli": "^11.0.0",
338
340
  "exceljs": "4.4.0",
339
- "handlebars": "4.7.9",
341
+ "handlebars": "4.7.10",
340
342
  "postcss": "^8.5.6",
341
343
  "postcss-import": "17.0.1",
342
344
  "suneditor": "3.3.3",
@@ -350,20 +352,17 @@
350
352
  "vue": "3.5.44",
351
353
  "yup": "1.7.1",
352
354
  "@mono-lit/devextreme": "0.0.2",
353
- "@mono-lit/utility": "0.0.6"
355
+ "@mono-lit/utility": "0.1.0"
354
356
  },
355
357
  "dependencies": {
356
358
  "@lit-labs/ssr": "3.2.2",
357
359
  "@lit-labs/ssr-client": "^1.1.7",
358
360
  "@nuxt/kit": "^4.6.2",
359
- "@nuxt/schema": "^4.6.2",
360
361
  "@types/mdast": "^4.0.4",
361
- "@vue/compiler-dom": "3.5.44",
362
- "@vue/compiler-sfc": "3.5.44",
363
362
  "@webcomponents/template-shadowroot": "^0.2.1",
364
363
  "flatpickr": "4.6.13",
365
364
  "jexl": "^2.3.0",
366
- "lit": "3.3.3",
365
+ "lit": "^3.3.3",
367
366
  "magic-string": "^0.30.21",
368
367
  "p-debounce": "^5.1.0",
369
368
  "p-throttle": "^8.1.0",
@@ -377,11 +376,11 @@
377
376
  "@floating-ui/dom": "^1.7.0",
378
377
  "@mono-lit/utility": "*",
379
378
  "chart.js": "4.5.1",
380
- "exceljs": ">=4",
381
- "handlebars": ">=4",
379
+ "exceljs": "4.4.0",
380
+ "handlebars": "4.7.10",
382
381
  "suneditor": "^3.3.3",
383
- "vite": ">=5",
384
- "vue": ">=3.3"
382
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
383
+ "vue": "^3.4.0"
385
384
  },
386
385
  "peerDependenciesMeta": {
387
386
  "vue": {
@@ -1,215 +0,0 @@
1
- //#region src/composables/chip-limits.ts
2
- const KEBAB = {
3
- max: "max",
4
- min: "min",
5
- maxVisible: "max-visible",
6
- minVisible: "min-visible"
7
- };
8
- /** A non-negative integer, or undefined for anything that is not one (`''`, null, NaN, -1). */
9
- function limitNumber(value) {
10
- if (value == null || value === "") return void 0;
11
- const n = Math.floor(Number(value));
12
- return Number.isFinite(n) && n >= 0 ? n : void 0;
13
- }
14
- /**
15
- * Resolve one limit: the `chip` object's key (camel, then kebab) pins, the
16
- * element's own prop is the fallback. Sanitised through {@link limitNumber}.
17
- */
18
- function resolveChipLimit(chip, key, elementValue) {
19
- return limitNumber(chip ? chip[key] ?? chip[KEBAB[key]] : void 0) ?? limitNumber(elementValue);
20
- }
21
- /**
22
- * How many chips to draw before the rest collapse into "+N more" — `Infinity`
23
- * when there is no cap, when the cap is `0` (uncapped, like before), or while
24
- * the total sits at or under the collapse floor.
25
- */
26
- function visibleChipCap(total, maxVisible, minVisible) {
27
- if (maxVisible === void 0 || maxVisible <= 0) return Infinity;
28
- if (minVisible !== void 0 && total <= minVisible) return Infinity;
29
- return maxVisible;
30
- }
31
-
32
- //#endregion
33
- //#region src/composables/chip-strip.ts
34
- /** Slack (px) absorbing sub-pixel layout noise in the overflow comparisons. */
35
- const EPSILON = 1;
36
- var ChipStripController = class {
37
- constructor(host, opts) {
38
- this._canScrollStart = false;
39
- this._canScrollEnd = false;
40
- this._observer = null;
41
- this._observed = null;
42
- this.host = host;
43
- this.opts = opts;
44
- host.addController(this);
45
- }
46
- /** True once the strip is scrolled away from its start — render `‹`. */
47
- get canScrollStart() {
48
- return this._canScrollStart;
49
- }
50
- /** True while content remains past the right edge — render `›`. */
51
- get canScrollEnd() {
52
- return this._canScrollEnd;
53
- }
54
- /** True when either button should show — i.e. the chips overflow the strip. */
55
- get overflowing() {
56
- return this._canScrollStart || this._canScrollEnd;
57
- }
58
- hostConnected() {
59
- if (this.opts.enabled()) this._attach();
60
- }
61
- hostDisconnected() {
62
- this._teardown();
63
- }
64
- /**
65
- * Only re-target the observer — deliberately does NOT measure. Measuring here
66
- * would force a layout on every render of every host, and its `requestUpdate`
67
- * would schedule an update from inside `updated()`. `invalidate()` and the
68
- * ResizeObserver cover the cases that can actually change the answer.
69
- */
70
- hostUpdated() {
71
- if (!this.opts.enabled()) {
72
- if (this._observed) {
73
- this._teardown();
74
- this._publish(false, false);
75
- }
76
- return;
77
- }
78
- this._attach();
79
- }
80
- /**
81
- * Re-measure because the CONTENT changed — a chip added, removed or relabelled.
82
- * The host calls this from `updated()` when such state actually changed, which
83
- * is far rarer than "every update".
84
- */
85
- invalidate() {
86
- this.sync();
87
- }
88
- /**
89
- * Recompute both flags from the live geometry and re-render only when one
90
- * actually flipped.
91
- */
92
- sync() {
93
- if (!this.opts.enabled()) return;
94
- const strip = this.opts.strip();
95
- let start = false;
96
- let end = false;
97
- if (strip) {
98
- const max = strip.scrollWidth - strip.clientWidth;
99
- if (max > EPSILON) {
100
- start = strip.scrollLeft > EPSILON;
101
- end = strip.scrollLeft < max - EPSILON;
102
- }
103
- }
104
- this._publish(start, end);
105
- }
106
- /**
107
- * Scroll one "page" toward `dir`, aligned to a chip boundary so a chip is
108
- * never left half-cut at the leading edge.
109
- *
110
- * Forward: the first chip whose right edge passes the visible right edge
111
- * becomes the new leftmost chip. Backward: the chip that would end at the
112
- * current left edge becomes the new leftmost chip. If no chip qualifies
113
- * (one chip wider than the strip), fall back to a plain viewport-width step
114
- * so the button is never a no-op.
115
- */
116
- page(dir) {
117
- const strip = this.opts.strip();
118
- if (!strip) return;
119
- const max = strip.scrollWidth - strip.clientWidth;
120
- if (max <= EPSILON) return;
121
- const viewLeft = strip.scrollLeft;
122
- const viewRight = viewLeft + strip.clientWidth;
123
- const stripLeft = strip.getBoundingClientRect().left;
124
- const chips = Array.from(strip.children).map((chip) => {
125
- const rect = chip.getBoundingClientRect();
126
- const left = rect.left - stripLeft + viewLeft;
127
- return {
128
- left,
129
- right: left + rect.width
130
- };
131
- });
132
- let target = null;
133
- if (dir === 1) {
134
- for (const chip of chips) if (chip.right > viewRight + EPSILON) {
135
- target = chip.left;
136
- break;
137
- }
138
- } else for (let i = chips.length - 1; i >= 0; i--) if (chips[i].left < viewLeft - EPSILON) {
139
- target = chips[i].right - strip.clientWidth;
140
- break;
141
- }
142
- if (target === null) target = viewLeft + dir * strip.clientWidth;
143
- this._scrollTo(strip, target, max);
144
- }
145
- /** Pin the strip to its end — used after a chip is added, to reveal it. */
146
- scrollToEnd() {
147
- const strip = this.opts.strip();
148
- if (!strip) return;
149
- const max = strip.scrollWidth - strip.clientWidth;
150
- this._scrollTo(strip, max, max);
151
- }
152
- /**
153
- * Move the strip and republish from the CLAMPED TARGET rather than by reading
154
- * `scrollLeft` back.
155
- *
156
- * Scrolling is instant (no `scroll-behavior: smooth`), so the read would agree
157
- * — but not reading avoids a second forced layout, and more importantly the
158
- * strip's scroll events are expensive well beyond this controller: the shared
159
- * popup controller listens for `scroll` on `window` in the CAPTURE phase, so
160
- * every scroll event the strip emits repositions any open dropdown, forcing a
161
- * layout and a `getComputedStyle` ancestor walk. One event per click is the
162
- * budget; a smooth animation's ~30 was what made the page crawl.
163
- */
164
- _scrollTo(strip, target, max) {
165
- const clamped = Math.max(0, Math.min(max, target));
166
- strip.scrollLeft = clamped;
167
- if (max <= EPSILON) {
168
- this._publish(false, false);
169
- return;
170
- }
171
- this._publish(clamped > EPSILON, clamped < max - EPSILON);
172
- }
173
- /**
174
- * Store the flags and re-render only on a real change.
175
- *
176
- * The request is deferred a microtask: `invalidate()` / `scrollToEnd()` are
177
- * called from the host's `updated()` (a chip landed, a preset value arrived),
178
- * and a synchronous `requestUpdate()` there is Lit's change-in-update warning
179
- * on every such edge. The flags are already stored, so the deferred render
180
- * reads the same answer — it just doesn't get scheduled from inside the
181
- * render that asked for it.
182
- */
183
- _publish(start, end) {
184
- if (start === this._canScrollStart && end === this._canScrollEnd) return;
185
- this._canScrollStart = start;
186
- this._canScrollEnd = end;
187
- if (typeof queueMicrotask === "function") queueMicrotask(() => this.host.requestUpdate());
188
- else this.host.requestUpdate();
189
- }
190
- /**
191
- * Observe the strip so the buttons re-evaluate when the FIELD is resized —
192
- * a window resize changes `clientWidth` without any render or scroll event.
193
- *
194
- * Only the strip is observed, not the chips: a chip add/remove always comes
195
- * with a host render, and the host calls `invalidate()` for those.
196
- */
197
- _attach() {
198
- const strip = this.opts.strip();
199
- if (strip === this._observed) return;
200
- this._observer?.disconnect();
201
- this._observed = strip;
202
- if (!strip) return;
203
- if (typeof ResizeObserver === "undefined") return;
204
- this._observer ??= new ResizeObserver(() => this.sync());
205
- this._observer.observe(strip);
206
- }
207
- _teardown() {
208
- this._observer?.disconnect();
209
- this._observer = null;
210
- this._observed = null;
211
- }
212
- };
213
-
214
- //#endregion
215
- export { resolveChipLimit as n, visibleChipCap as r, ChipStripController as t };
@@ -1,243 +0,0 @@
1
- import { n as describeError, o as isCanceled } from "./normalize-error-D93O4q8g.js";
2
-
3
- //#region src/composables/data-source-controller.ts
4
- /**
5
- * Encapsulates the generic DataSource + incremental-loading logic shared by
6
- * `mono-select`, `mono-tag-input`, etc. The host owns the rendering and any
7
- * scroll/height ergonomics; this controller owns binding, event wiring, page
8
- * accumulation, and array-mode chunking.
9
- *
10
- * Every state mutation calls `host.requestUpdate()` so the host re-renders.
11
- */
12
- var DataSourceController = class {
13
- constructor(host, opts) {
14
- this._dsItems = [];
15
- this._dsLoading = false;
16
- this._loadingMore = false;
17
- this._isLastPage = false;
18
- this._error = null;
19
- this._hasLoaded = false;
20
- this._retrying = false;
21
- this._internalLoad = false;
22
- this._bound = null;
23
- this._onChanged = () => {
24
- if (this._internalLoad) return;
25
- this._markLoaded();
26
- if (this.opts.getLoadMoreMode()) {
27
- const ds = this._bound;
28
- this._dsItems = ds ? [...ds.items?.() ?? []] : [];
29
- this._isLastPage = ds?.isLastPage?.() ?? false;
30
- this._dsLoading = ds?.isLoading?.() ?? false;
31
- this._changed();
32
- return;
33
- }
34
- this._sync();
35
- };
36
- this._onLoadingChanged = () => {
37
- this._dsLoading = this._bound?.isLoading?.() ?? false;
38
- this._changed();
39
- };
40
- this._onLoadError = (err) => {
41
- this._dsLoading = this._bound?.isLoading?.() ?? false;
42
- this.setError(err ?? /* @__PURE__ */ new Error("Request failed"));
43
- };
44
- this.host = host;
45
- this.opts = opts;
46
- this._visibleCount = opts.getPageSize();
47
- host.addController(this);
48
- }
49
- hostConnected() {
50
- const ds = this.opts.getDataSource();
51
- if (ds && this._bound !== ds) this.bind(ds);
52
- }
53
- hostDisconnected() {
54
- this._detach();
55
- }
56
- /** Attach/detach listeners for a (possibly new) DataSource and seed state. */
57
- bind(ds) {
58
- if (this._bound === ds) return;
59
- this._detach();
60
- this._bound = ds;
61
- this._error = null;
62
- this._retrying = false;
63
- this._hasLoaded = !!ds && (ds.items?.() ?? []).length > 0;
64
- if (!ds) {
65
- this._dsItems = [];
66
- this._dsLoading = false;
67
- this._isLastPage = false;
68
- this._changed();
69
- return;
70
- }
71
- ds.on("changed", this._onChanged);
72
- ds.on("loadingChanged", this._onLoadingChanged);
73
- ds.on("loadError", this._onLoadError);
74
- this._sync();
75
- this.maybeImmediateLoad();
76
- }
77
- maybeImmediateLoad() {
78
- const ds = this._bound;
79
- if (!ds || !this.opts.getImmediate()) return;
80
- const hasItems = (ds.items?.() ?? []).length > 0;
81
- const loading = ds.isLoading?.() ?? false;
82
- if (hasItems || loading) return;
83
- this._loadFirstPage();
84
- }
85
- /** Call when the load-more mode changes; refreshes paging assumptions. */
86
- onLoadMoreModeChange() {
87
- if (!this.opts.getLoadMoreMode()) return;
88
- this._bound?.paginate?.(true);
89
- this._isLastPage = this._bound?.isLastPage?.() ?? false;
90
- this._changed();
91
- }
92
- /** Reset array-mode paging to the first chunk. */
93
- resetVisible() {
94
- this._visibleCount = this.opts.getPageSize();
95
- this._changed();
96
- }
97
- /** Load/reveal the next page and append it to the accumulated list. */
98
- async loadMore() {
99
- if (!this.opts.getLoadMoreMode() || this.atLastPage) return;
100
- if (this.isArrayLoadMore) {
101
- this._visibleCount = Math.min(this.opts.getItems().length, this._visibleCount + this.opts.getPageSize());
102
- this._changed();
103
- return;
104
- }
105
- const ds = this._bound;
106
- if (!ds || this._loadingMore || this._dsLoading) return;
107
- if (typeof ds.pageIndex !== "function") return;
108
- const current = ds.pageIndex() ?? 0;
109
- this._internalLoad = true;
110
- this._loadingMore = true;
111
- this._changed();
112
- try {
113
- ds.paginate?.(true);
114
- ds.pageIndex(current + 1);
115
- await Promise.resolve(ds.load());
116
- this._dsItems = [...this._dsItems, ...ds.items?.() ?? []];
117
- this._isLastPage = ds.isLastPage?.() ?? false;
118
- this._error = null;
119
- } catch (err) {
120
- ds.pageIndex(current);
121
- this.setError(err);
122
- } finally {
123
- this._loadingMore = false;
124
- this._internalLoad = false;
125
- this._changed();
126
- }
127
- }
128
- /**
129
- * Re-run the request after a failure. Reloads the source as it stands, so a
130
- * failed search is retried with the same query. While it runs the field is
131
- * {@link busy} again.
132
- *
133
- * `load` replaces the plain `ds.load()` — a host whose failed request was a
134
- * search passes one that clears the query on the source and reloads.
135
- */
136
- async retry(load) {
137
- if (!this._bound) return;
138
- this._error = null;
139
- this._retrying = true;
140
- this._changed();
141
- try {
142
- await this._loadFirstPage(load);
143
- } finally {
144
- this._retrying = false;
145
- this._changed();
146
- }
147
- }
148
- /**
149
- * Record a failure from a request the host drove itself (e.g. a server
150
- * select-all drain). Cancelled loads are ignored.
151
- */
152
- setError(raw) {
153
- if (isCanceled(raw)) return;
154
- this._error = describeError(raw);
155
- this._changed();
156
- }
157
- /** Raw source array: accumulated DataSource items, or the plain `items`. */
158
- get sourceItems() {
159
- return this._bound ? this._dsItems : this.opts.getItems();
160
- }
161
- /** Rows to actually render (array-mode reveals a slice; else everything). */
162
- get visibleItems() {
163
- if (this.isArrayLoadMore) return this.opts.getItems().slice(0, this._visibleCount);
164
- return this.sourceItems;
165
- }
166
- get loading() {
167
- return this._dsLoading;
168
- }
169
- get loadingMore() {
170
- return this._loadingMore;
171
- }
172
- /**
173
- * The field must be locked: the FIRST load (or a retry) is in flight. A
174
- * search / filter reload after the source has answered once does not count —
175
- * the person is typing into the field and it must stay usable.
176
- */
177
- get busy() {
178
- return !!this._bound && (this._dsLoading && !this._hasLoaded || this._retrying);
179
- }
180
- /** The last load failure, described for a person; null once a load succeeds. */
181
- get error() {
182
- return this._error;
183
- }
184
- /** load-more is driving a plain `items` array (no DataSource bound). */
185
- get isArrayLoadMore() {
186
- return !this.opts.getDataSource() && !!this.opts.getLoadMoreMode();
187
- }
188
- /** Whether there's nothing left to load/reveal. */
189
- get atLastPage() {
190
- if (this.isArrayLoadMore) return this._visibleCount >= this.opts.getItems().length;
191
- return this._isLastPage;
192
- }
193
- /** A load answered: the source is usable and any earlier failure is over. */
194
- _markLoaded() {
195
- this._hasLoaded = true;
196
- this._error = null;
197
- }
198
- _sync() {
199
- const ds = this._bound;
200
- this._dsItems = ds ? [...ds.items?.() ?? []] : [];
201
- this._dsLoading = ds?.isLoading?.() ?? false;
202
- this._isLastPage = ds?.isLastPage?.() ?? false;
203
- this._changed();
204
- }
205
- /** Load the first page, replacing the accumulated list. */
206
- async _loadFirstPage(load) {
207
- const ds = this._bound;
208
- if (!ds) return;
209
- this._internalLoad = true;
210
- this._dsLoading = true;
211
- this._changed();
212
- try {
213
- if (this.opts.getLoadMoreMode()) {
214
- ds.paginate?.(true);
215
- ds.pageIndex?.(0);
216
- }
217
- await Promise.resolve(load ? load() : ds.load());
218
- this._dsItems = [...ds.items?.() ?? []];
219
- this._isLastPage = ds.isLastPage?.() ?? false;
220
- this._markLoaded();
221
- } catch (err) {
222
- this.setError(err);
223
- } finally {
224
- this._dsLoading = ds.isLoading?.() ?? false;
225
- this._internalLoad = false;
226
- this._changed();
227
- }
228
- }
229
- _detach() {
230
- const ds = this._bound;
231
- if (!ds) return;
232
- ds.off("changed", this._onChanged);
233
- ds.off("loadingChanged", this._onLoadingChanged);
234
- ds.off("loadError", this._onLoadError);
235
- this._bound = null;
236
- }
237
- _changed() {
238
- this.host.requestUpdate();
239
- }
240
- };
241
-
242
- //#endregion
243
- export { DataSourceController as t };