@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/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.0.10",
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",
@@ -349,8 +349,8 @@
349
349
  "vite-plugin-html-inject": "1.1.2",
350
350
  "vue": "3.5.44",
351
351
  "yup": "1.7.1",
352
- "@mono-lit/devextreme": "0.0.2",
353
- "@mono-lit/utility": "0.0.6"
352
+ "@mono-lit/utility": "0.0.6",
353
+ "@mono-lit/devextreme": "0.0.2"
354
354
  },
355
355
  "dependencies": {
356
356
  "@lit-labs/ssr": "3.2.2",
@@ -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 };