@zeyos/zx 2.1.0 → 2.2.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 (311) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +15 -0
  3. package/dist/types/compat/base.d.ts +156 -0
  4. package/dist/types/compat/globals.d.ts +20 -0
  5. package/dist/types/compat/index.d.ts +128 -0
  6. package/dist/types/compat/map/basic.d.ts +175 -0
  7. package/dist/types/compat/map/data.d.ts +102 -0
  8. package/dist/types/compat/map/date-time.d.ts +80 -0
  9. package/dist/types/compat/map/factory.d.ts +9 -0
  10. package/dist/types/compat/map/form.d.ts +98 -0
  11. package/dist/types/compat/map/helpers.d.ts +12 -0
  12. package/dist/types/compat/map/http.d.ts +36 -0
  13. package/dist/types/compat/map/layout.d.ts +106 -0
  14. package/dist/types/compat/map/options.d.ts +80 -0
  15. package/dist/types/compat/map/select.d.ts +95 -0
  16. package/dist/types/compat/map/stubs.d.ts +32 -0
  17. package/dist/types/compat/map/utilities.d.ts +37 -0
  18. package/dist/types/compat-entry.d.ts +5 -0
  19. package/dist/types/components/badge/badge.d.ts +46 -0
  20. package/dist/types/components/breadcrumb/breadcrumb.d.ts +200 -0
  21. package/dist/types/components/button/button.d.ts +42 -0
  22. package/dist/types/components/check-button/check-button.d.ts +98 -0
  23. package/dist/types/components/checklist/checklist.d.ts +143 -0
  24. package/dist/types/components/checklist/field-adapter.d.ts +5 -0
  25. package/dist/types/components/context-menu/context-menu.d.ts +130 -0
  26. package/dist/types/components/copy/copy-button.d.ts +48 -0
  27. package/dist/types/components/copy/copy-input.d.ts +91 -0
  28. package/dist/types/components/data-filter/data-filter.d.ts +250 -0
  29. package/dist/types/components/data-filter/filter-core.d.ts +52 -0
  30. package/dist/types/components/date-picker/date-picker.d.ts +137 -0
  31. package/dist/types/components/date-picker/date-range-picker.d.ts +350 -0
  32. package/dist/types/components/date-picker/field-adapter.d.ts +6 -0
  33. package/dist/types/components/date-picker/month-picker.d.ts +75 -0
  34. package/dist/types/components/date-picker/range-field-adapter.d.ts +7 -0
  35. package/dist/types/components/date-picker/time-picker.d.ts +127 -0
  36. package/dist/types/components/datebox/date-range-box.d.ts +218 -0
  37. package/dist/types/components/datebox/datebox.d.ts +160 -0
  38. package/dist/types/components/datebox/field-adapter.d.ts +5 -0
  39. package/dist/types/components/dialog/dialog.d.ts +284 -0
  40. package/dist/types/components/dropdown/dropdown.d.ts +118 -0
  41. package/dist/types/components/empty-state/empty-state.d.ts +38 -0
  42. package/dist/types/components/field/field.d.ts +231 -0
  43. package/dist/types/components/field-upload/field-adapter.d.ts +5 -0
  44. package/dist/types/components/field-upload/field-upload.d.ts +213 -0
  45. package/dist/types/components/fieldset/fieldset.d.ts +125 -0
  46. package/dist/types/components/finder/finder.d.ts +252 -0
  47. package/dist/types/components/form/form.d.ts +194 -0
  48. package/dist/types/components/groupbox/groupbox.d.ts +89 -0
  49. package/dist/types/components/layout/layout.d.ts +132 -0
  50. package/dist/types/components/loading/inline-loading.d.ts +86 -0
  51. package/dist/types/components/loading/progress-bar.d.ts +168 -0
  52. package/dist/types/components/loading/spinner.d.ts +34 -0
  53. package/dist/types/components/master-panel/master-panel.d.ts +112 -0
  54. package/dist/types/components/menu-button/menu-button.d.ts +142 -0
  55. package/dist/types/components/message/message.d.ts +212 -0
  56. package/dist/types/components/modal/modal.d.ts +105 -0
  57. package/dist/types/components/multi-value-editor/field-adapter.d.ts +5 -0
  58. package/dist/types/components/multi-value-editor/multi-value-editor.d.ts +66 -0
  59. package/dist/types/components/navigation-bar/navigation-bar.d.ts +229 -0
  60. package/dist/types/components/number-field/field-adapter.d.ts +5 -0
  61. package/dist/types/components/number-field/number-field.d.ts +292 -0
  62. package/dist/types/components/pagination/pagination.d.ts +267 -0
  63. package/dist/types/components/panel/panel.d.ts +194 -0
  64. package/dist/types/components/permission/permission.d.ts +93 -0
  65. package/dist/types/components/rating/field-adapter.d.ts +5 -0
  66. package/dist/types/components/rating/rating.d.ts +213 -0
  67. package/dist/types/components/search/search.d.ts +98 -0
  68. package/dist/types/components/select/field-adapter.d.ts +5 -0
  69. package/dist/types/components/select/filter.d.ts +11 -0
  70. package/dist/types/components/select/select.d.ts +235 -0
  71. package/dist/types/components/skeleton/skeleton.d.ts +97 -0
  72. package/dist/types/components/slider/field-adapter.d.ts +5 -0
  73. package/dist/types/components/slider/slider.d.ts +216 -0
  74. package/dist/types/components/split-view/split-view.d.ts +335 -0
  75. package/dist/types/components/stepper/stepper.d.ts +314 -0
  76. package/dist/types/components/stepper/steps.d.ts +131 -0
  77. package/dist/types/components/tabbox/tabbox.d.ts +230 -0
  78. package/dist/types/components/table/sort.d.ts +49 -0
  79. package/dist/types/components/table/table.d.ts +872 -0
  80. package/dist/types/components/tag-picker/field-adapter.d.ts +5 -0
  81. package/dist/types/components/tag-picker/tag-picker.d.ts +375 -0
  82. package/dist/types/components/timebox/field-adapter.d.ts +5 -0
  83. package/dist/types/components/timebox/timebox.d.ts +121 -0
  84. package/dist/types/components/toggle/field-adapter.d.ts +5 -0
  85. package/dist/types/components/toggle/toggle.d.ts +94 -0
  86. package/dist/types/components/toolbar/toolbar.d.ts +230 -0
  87. package/dist/types/components/tooltip/tooltip.d.ts +183 -0
  88. package/dist/types/components/tree/hierarchy.d.ts +113 -0
  89. package/dist/types/components/tree/tree.d.ts +383 -0
  90. package/dist/types/components/truncate/truncate.d.ts +61 -0
  91. package/dist/types/components/value-list/field-adapter.d.ts +5 -0
  92. package/dist/types/components/value-list/value-list.d.ts +143 -0
  93. package/dist/types/core/breakpoint.d.ts +68 -0
  94. package/dist/types/core/component.d.ts +115 -0
  95. package/dist/types/core/date.d.ts +50 -0
  96. package/dist/types/core/dom.d.ts +86 -0
  97. package/dist/types/core/export.d.ts +70 -0
  98. package/dist/types/core/fontawesome.d.ts +107 -0
  99. package/dist/types/core/format.d.ts +107 -0
  100. package/dist/types/core/http.d.ts +122 -0
  101. package/dist/types/core/i18n.d.ts +35 -0
  102. package/dist/types/core/icons.d.ts +137 -0
  103. package/dist/types/core/keyboard.d.ts +72 -0
  104. package/dist/types/core/position.d.ts +45 -0
  105. package/dist/types/core/storage.d.ts +46 -0
  106. package/dist/types/core/util.d.ts +117 -0
  107. package/dist/types/elements/define.d.ts +73 -0
  108. package/dist/types/elements/reflect.d.ts +27 -0
  109. package/dist/types/index.d.ts +79 -0
  110. package/dist/types/zeyos/connect.d.ts +65 -0
  111. package/dist/types/zeyos/form.d.ts +140 -0
  112. package/dist/types/zeyos/icons.d.ts +104 -0
  113. package/dist/types/zeyos/index.d.ts +12 -0
  114. package/dist/types/zeyos/modules.d.ts +110 -0
  115. package/dist/types/zeyos/query.d.ts +157 -0
  116. package/dist/types/zeyos/schema.d.ts +79 -0
  117. package/dist/types/zeyos/select.d.ts +167 -0
  118. package/dist/types/zeyos/table.d.ts +205 -0
  119. package/dist/zx-compat.esm.js +362 -33
  120. package/dist/zx-compat.esm.min.js +1 -1
  121. package/dist/zx-compat.global.js +359 -67
  122. package/dist/zx-compat.global.min.js +3 -3
  123. package/dist/zx-zeyos.esm.js +342 -43
  124. package/dist/zx-zeyos.esm.min.js +1 -1
  125. package/dist/zx.css +68 -6
  126. package/dist/zx.esm.js +346 -67
  127. package/dist/zx.esm.min.js +3 -3
  128. package/dist/zx.global.js +346 -67
  129. package/dist/zx.global.min.js +3 -3
  130. package/dist/zx.min.css +1 -1
  131. package/docs/api.json +48 -2
  132. package/docs/llms.md +28 -0
  133. package/package.json +37 -9
  134. package/src/compat/base.js +291 -0
  135. package/src/compat/globals.js +165 -0
  136. package/src/compat/index.js +84 -0
  137. package/src/compat/map/basic.js +464 -0
  138. package/src/compat/map/data.js +232 -0
  139. package/src/compat/map/date-time.js +177 -0
  140. package/src/compat/map/factory.js +45 -0
  141. package/src/compat/map/form.js +330 -0
  142. package/src/compat/map/helpers.js +46 -0
  143. package/src/compat/map/http.js +117 -0
  144. package/src/compat/map/layout.js +256 -0
  145. package/src/compat/map/options.js +267 -0
  146. package/src/compat/map/select.js +198 -0
  147. package/src/compat/map/stubs.js +26 -0
  148. package/src/compat/map/utilities.js +113 -0
  149. package/src/compat-entry.js +11 -0
  150. package/src/components/badge/badge.css +147 -0
  151. package/src/components/badge/badge.js +92 -0
  152. package/src/components/breadcrumb/breadcrumb.css +105 -0
  153. package/src/components/breadcrumb/breadcrumb.js +331 -0
  154. package/src/components/button/button.css +104 -0
  155. package/src/components/button/button.js +76 -0
  156. package/src/components/check-button/check-button.css +66 -0
  157. package/src/components/check-button/check-button.js +167 -0
  158. package/src/components/checklist/checklist.css +65 -0
  159. package/src/components/checklist/checklist.js +282 -0
  160. package/src/components/checklist/field-adapter.js +46 -0
  161. package/src/components/context-menu/context-menu.css +54 -0
  162. package/src/components/context-menu/context-menu.js +334 -0
  163. package/src/components/copy/copy-button.css +27 -0
  164. package/src/components/copy/copy-button.js +78 -0
  165. package/src/components/copy/copy-input.css +59 -0
  166. package/src/components/copy/copy-input.js +123 -0
  167. package/src/components/data-filter/data-filter.css +53 -0
  168. package/src/components/data-filter/data-filter.js +400 -0
  169. package/src/components/data-filter/filter-core.js +128 -0
  170. package/src/components/date-picker/date-picker.css +181 -0
  171. package/src/components/date-picker/date-picker.js +500 -0
  172. package/src/components/date-picker/date-range-picker.css +264 -0
  173. package/src/components/date-picker/date-range-picker.js +990 -0
  174. package/src/components/date-picker/field-adapter.js +36 -0
  175. package/src/components/date-picker/month-picker.js +223 -0
  176. package/src/components/date-picker/range-field-adapter.js +31 -0
  177. package/src/components/date-picker/time-picker.css +191 -0
  178. package/src/components/date-picker/time-picker.js +406 -0
  179. package/src/components/datebox/date-range-box.css +128 -0
  180. package/src/components/datebox/date-range-box.js +492 -0
  181. package/src/components/datebox/datebox.css +108 -0
  182. package/src/components/datebox/datebox.js +358 -0
  183. package/src/components/datebox/field-adapter.js +34 -0
  184. package/src/components/dialog/dialog.css +74 -0
  185. package/src/components/dialog/dialog.js +450 -0
  186. package/src/components/dropdown/dropdown.css +24 -0
  187. package/src/components/dropdown/dropdown.js +288 -0
  188. package/src/components/empty-state/empty-state.css +80 -0
  189. package/src/components/empty-state/empty-state.js +92 -0
  190. package/src/components/field/field.css +127 -0
  191. package/src/components/field/field.js +605 -0
  192. package/src/components/field-upload/field-adapter.js +21 -0
  193. package/src/components/field-upload/field-upload.css +108 -0
  194. package/src/components/field-upload/field-upload.js +475 -0
  195. package/src/components/fieldset/fieldset.css +37 -0
  196. package/src/components/fieldset/fieldset.js +307 -0
  197. package/src/components/finder/finder.css +98 -0
  198. package/src/components/finder/finder.js +509 -0
  199. package/src/components/form/form.css +32 -0
  200. package/src/components/form/form.js +302 -0
  201. package/src/components/groupbox/groupbox.css +51 -0
  202. package/src/components/groupbox/groupbox.js +199 -0
  203. package/src/components/layout/layout.css +117 -0
  204. package/src/components/layout/layout.js +136 -0
  205. package/src/components/loading/inline-loading.css +34 -0
  206. package/src/components/loading/inline-loading.js +140 -0
  207. package/src/components/loading/progress-bar.css +115 -0
  208. package/src/components/loading/progress-bar.js +259 -0
  209. package/src/components/loading/spinner.css +58 -0
  210. package/src/components/loading/spinner.js +57 -0
  211. package/src/components/master-panel/master-panel.css +51 -0
  212. package/src/components/master-panel/master-panel.js +203 -0
  213. package/src/components/menu-button/menu-button.css +49 -0
  214. package/src/components/menu-button/menu-button.js +294 -0
  215. package/src/components/message/message.css +122 -0
  216. package/src/components/message/message.js +499 -0
  217. package/src/components/modal/modal.css +47 -0
  218. package/src/components/modal/modal.js +203 -0
  219. package/src/components/multi-value-editor/field-adapter.js +44 -0
  220. package/src/components/multi-value-editor/multi-value-editor.css +56 -0
  221. package/src/components/multi-value-editor/multi-value-editor.js +170 -0
  222. package/src/components/navigation-bar/navigation-bar.css +130 -0
  223. package/src/components/navigation-bar/navigation-bar.js +450 -0
  224. package/src/components/number-field/field-adapter.js +40 -0
  225. package/src/components/number-field/number-field.css +77 -0
  226. package/src/components/number-field/number-field.js +545 -0
  227. package/src/components/pagination/pagination.css +95 -0
  228. package/src/components/pagination/pagination.js +481 -0
  229. package/src/components/panel/panel.css +123 -0
  230. package/src/components/panel/panel.js +336 -0
  231. package/src/components/permission/permission.css +47 -0
  232. package/src/components/permission/permission.js +198 -0
  233. package/src/components/rating/field-adapter.js +34 -0
  234. package/src/components/rating/rating.css +97 -0
  235. package/src/components/rating/rating.js +395 -0
  236. package/src/components/search/search.css +70 -0
  237. package/src/components/search/search.js +193 -0
  238. package/src/components/select/field-adapter.js +24 -0
  239. package/src/components/select/filter.js +39 -0
  240. package/src/components/select/select.css +180 -0
  241. package/src/components/select/select.js +663 -0
  242. package/src/components/skeleton/skeleton.css +76 -0
  243. package/src/components/skeleton/skeleton.js +139 -0
  244. package/src/components/slider/field-adapter.js +36 -0
  245. package/src/components/slider/slider.css +181 -0
  246. package/src/components/slider/slider.js +399 -0
  247. package/src/components/split-view/split-view.css +139 -0
  248. package/src/components/split-view/split-view.js +806 -0
  249. package/src/components/stepper/stepper.css +234 -0
  250. package/src/components/stepper/stepper.js +459 -0
  251. package/src/components/stepper/steps.js +131 -0
  252. package/src/components/tabbox/tabbox.css +281 -0
  253. package/src/components/tabbox/tabbox.js +484 -0
  254. package/src/components/table/sort.js +85 -0
  255. package/src/components/table/table.css +364 -0
  256. package/src/components/table/table.js +1693 -0
  257. package/src/components/tag-picker/field-adapter.js +35 -0
  258. package/src/components/tag-picker/tag-picker.css +169 -0
  259. package/src/components/tag-picker/tag-picker.js +837 -0
  260. package/src/components/timebox/field-adapter.js +24 -0
  261. package/src/components/timebox/timebox.css +51 -0
  262. package/src/components/timebox/timebox.js +276 -0
  263. package/src/components/toggle/field-adapter.js +24 -0
  264. package/src/components/toggle/toggle.css +66 -0
  265. package/src/components/toggle/toggle.js +150 -0
  266. package/src/components/toolbar/toolbar.css +81 -0
  267. package/src/components/toolbar/toolbar.js +511 -0
  268. package/src/components/tooltip/tooltip.css +36 -0
  269. package/src/components/tooltip/tooltip.js +420 -0
  270. package/src/components/tree/hierarchy.js +151 -0
  271. package/src/components/tree/tree.css +99 -0
  272. package/src/components/tree/tree.js +784 -0
  273. package/src/components/truncate/truncate.css +20 -0
  274. package/src/components/truncate/truncate.js +92 -0
  275. package/src/components/value-list/field-adapter.js +24 -0
  276. package/src/components/value-list/value-list.css +108 -0
  277. package/src/components/value-list/value-list.js +336 -0
  278. package/src/core/breakpoint.js +150 -0
  279. package/src/core/component.js +292 -0
  280. package/src/core/date.js +216 -0
  281. package/src/core/dom.js +260 -0
  282. package/src/core/export.js +204 -0
  283. package/src/core/fontawesome.js +177 -0
  284. package/src/core/format.js +283 -0
  285. package/src/core/http.js +246 -0
  286. package/src/core/i18n.js +83 -0
  287. package/src/core/icons.js +283 -0
  288. package/src/core/keyboard.js +240 -0
  289. package/src/core/position.js +177 -0
  290. package/src/core/storage.js +175 -0
  291. package/src/core/util.js +336 -0
  292. package/src/elements/define.js +715 -0
  293. package/src/elements/reflect.js +79 -0
  294. package/src/index.js +131 -0
  295. package/src/zeyos/connect.js +142 -0
  296. package/src/zeyos/form.js +254 -0
  297. package/src/zeyos/icons.js +92 -0
  298. package/src/zeyos/index.js +21 -0
  299. package/src/zeyos/modules.js +269 -0
  300. package/src/zeyos/query.js +199 -0
  301. package/src/zeyos/schema.js +474 -0
  302. package/src/zeyos/select.js +175 -0
  303. package/src/zeyos/table.js +272 -0
  304. package/styles/base.css +124 -0
  305. package/styles/icons.css +34 -0
  306. package/styles/tokens/dark.css +84 -0
  307. package/styles/tokens/density.css +9 -0
  308. package/styles/tokens/global.css +80 -0
  309. package/styles/tokens/modules.css +109 -0
  310. package/styles/tokens/semantic.css +49 -0
  311. package/styles/zx.css +61 -0
@@ -23,7 +23,8 @@ function deepMerge(a, b) {
23
23
  );
24
24
  }
25
25
  function isElement(value) {
26
- return Boolean(value && typeof value === "object" && value.nodeType === 1);
26
+ return Boolean(value && typeof value === "object" && /** @type {{nodeType?: unknown}} */
27
+ value.nodeType === 1);
27
28
  }
28
29
  function clamp(n, min, max) {
29
30
  return Math.min(max, Math.max(min, n));
@@ -112,8 +113,12 @@ function resolveElement(target) {
112
113
  }
113
114
  function isPropsObject(value) {
114
115
  if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
115
- if (typeof value.nodeType === "number") return false;
116
- return typeof value.toElement !== "function";
116
+ const candidate = (
117
+ /** @type {Record<string, unknown>} */
118
+ value
119
+ );
120
+ if (typeof candidate.nodeType === "number") return false;
121
+ return typeof candidate.toElement !== "function";
117
122
  }
118
123
  function applyProperty(element, key, value) {
119
124
  if (key === "ref") {
@@ -171,15 +176,33 @@ function ariaAttribute(key) {
171
176
  return "aria-" + key.slice(4).toLowerCase();
172
177
  }
173
178
  function appendChildren(parent, children) {
174
- for (const child of children.flat(Infinity)) {
175
- if (child == null) continue;
176
- if (typeof child === "string" || typeof child === "number") {
177
- parent.append(document.createTextNode(String(child)));
178
- } else if (child && typeof child === "object" && typeof child.nodeType === "number") {
179
- parent.append(child);
180
- } else if (typeof child === "object" && typeof child.toElement === "function") {
179
+ const host = (
180
+ /** @type {ParentNode} */
181
+ parent
182
+ );
183
+ for (
184
+ const raw2 of
185
+ /** @type {any[]} */
186
+ children.flat(Infinity)
187
+ ) {
188
+ if (raw2 == null) continue;
189
+ if (typeof raw2 === "string" || typeof raw2 === "number") {
190
+ host.append(document.createTextNode(String(raw2)));
191
+ continue;
192
+ }
193
+ if (typeof raw2 !== "object") continue;
194
+ const child = (
195
+ /** @type {{nodeType?: number, toElement?: () => Node|null}} */
196
+ raw2
197
+ );
198
+ if (typeof child.nodeType === "number") {
199
+ host.append(
200
+ /** @type {Node} */
201
+ raw2
202
+ );
203
+ } else if (typeof child.toElement === "function") {
181
204
  const element = child.toElement();
182
- if (element) parent.append(element);
205
+ if (element) host.append(element);
183
206
  }
184
207
  }
185
208
  }
@@ -617,11 +640,18 @@ var registry = /* @__PURE__ */ new WeakMap();
617
640
  var Component = class extends EventTarget {
618
641
  /** @type {ComponentOptions} */
619
642
  static defaults = {};
643
+ /**
644
+ * BEM block a subclass wants on its root, without the `zx-` prefix. Empty on the base, which is
645
+ * the same falsy answer the undeclared property gave — declared so the statics are visible to
646
+ * `this.constructor` and to the generated declarations.
647
+ * @type {string}
648
+ */
649
+ static cssName = "";
620
650
  /** @type {Element} Root element. */
621
651
  el;
622
652
  /** @type {Record<string, Element>} Elements captured by `h()` ref properties. */
623
653
  refs;
624
- /** @type {Readonly<ComponentOptions>} Merged component options. */
654
+ /** @type {Readonly<TOptions>} Merged component options. */
625
655
  options;
626
656
  #abort = new AbortController();
627
657
  #created = false;
@@ -630,17 +660,27 @@ var Component = class extends EventTarget {
630
660
  /**
631
661
  * Creates a component around an existing target, or asks `render()` to create its root.
632
662
  * @param {Element|string|null} target Existing element, selector, or null.
633
- * @param {ComponentOptions} [options={}] Component options.
663
+ * @param {TOptions} [options={}] Component options.
634
664
  */
635
- constructor(target, options = {}) {
665
+ constructor(target, options = (
666
+ /** @type {TOptions} */
667
+ {}
668
+ )) {
636
669
  super();
670
+ const self = (
671
+ /** @type {typeof Component} */
672
+ this.constructor
673
+ );
637
674
  this.#created = target === null;
638
675
  const resolved = resolveElement(target);
639
676
  if (target !== null && !resolved) throw new TypeError("Component target could not be resolved");
640
677
  this.el = /** @type {Element} */
641
678
  resolved;
642
679
  this.refs = {};
643
- const merged = mergeOptions(this.constructor, options);
680
+ const merged = (
681
+ /** @type {TOptions} */
682
+ mergeOptions(self, options)
683
+ );
644
684
  const eventOptions = [];
645
685
  for (const [key, value] of Object.entries(merged)) {
646
686
  if (/^on[a-z]/.test(key) && typeof value === "function") {
@@ -670,7 +710,7 @@ var Component = class extends EventTarget {
670
710
  this.#abort.abort();
671
711
  throw new TypeError("Component requires a root Element");
672
712
  }
673
- const cssName = this.constructor.cssName;
713
+ const cssName = self.cssName;
674
714
  if (typeof cssName === "string" && cssName) {
675
715
  const className = `zx-${cssName}`;
676
716
  this.#addedRootClass = !this.el.classList.contains(className);
@@ -791,7 +831,10 @@ var Component = class extends EventTarget {
791
831
  this.#destroyed = true;
792
832
  this.#abort.abort();
793
833
  if (registry.get(this.el) === this) registry.delete(this.el);
794
- const cssName = this.constructor.cssName;
834
+ const cssName = (
835
+ /** @type {typeof Component} */
836
+ this.constructor.cssName
837
+ );
795
838
  if (this.#addedRootClass && typeof cssName === "string" && this.el) {
796
839
  this.el.classList.remove(`zx-${cssName}`);
797
840
  }
@@ -1775,7 +1818,10 @@ function getWeekStart(lang = getLanguage()) {
1775
1818
  if (!lang) return 1;
1776
1819
  if (lang.toLowerCase() === "en") return 1;
1777
1820
  try {
1778
- const locale = new Intl.Locale(lang);
1821
+ const locale = (
1822
+ /** @type {Intl.Locale & {getWeekInfo?: () => {firstDay?: number}, weekInfo?: {firstDay?: number}}} */
1823
+ new Intl.Locale(lang)
1824
+ );
1779
1825
  const weekInfo = locale.getWeekInfo?.() ?? locale.weekInfo;
1780
1826
  if (weekInfo?.firstDay) return weekInfo.firstDay % 7;
1781
1827
  } catch {
@@ -3111,9 +3157,11 @@ function updateFallback(anchor, floating, { placement, offset, flip, matchWidth
3111
3157
  const topY = anchorRect.top - offset - floatingRect.height;
3112
3158
  if (flip) {
3113
3159
  if (prefersBottom && bottomY + floatingRect.height > viewportHeight && topY >= 0) {
3114
- actualPlacement = placement.replace("bottom", "top");
3160
+ actualPlacement = /** @type {typeof placement} */
3161
+ placement.replace("bottom", "top");
3115
3162
  } else if (!prefersBottom && topY < 0 && bottomY + floatingRect.height <= viewportHeight) {
3116
- actualPlacement = placement.replace("top", "bottom");
3163
+ actualPlacement = /** @type {typeof placement} */
3164
+ placement.replace("top", "bottom");
3117
3165
  }
3118
3166
  }
3119
3167
  let left;
@@ -6087,10 +6135,13 @@ function rovingTabindex(container, itemSelector, { orientation = "vertical", wra
6087
6135
  const originals = /* @__PURE__ */ new Map();
6088
6136
  let destroyed = false;
6089
6137
  function items() {
6090
- return Array.from(container.querySelectorAll(itemSelector)).filter((item) => {
6091
- remember(item);
6092
- return isAvailable(item);
6093
- });
6138
+ return (
6139
+ /** @type {HTMLElement[]} */
6140
+ Array.from(container.querySelectorAll(itemSelector)).filter((item) => {
6141
+ remember(item);
6142
+ return isAvailable(item);
6143
+ })
6144
+ );
6094
6145
  }
6095
6146
  function remember(item) {
6096
6147
  if (!originals.has(item)) originals.set(item, item.getAttribute("tabindex"));
@@ -6105,7 +6156,11 @@ function rovingTabindex(container, itemSelector, { orientation = "vertical", wra
6105
6156
  }
6106
6157
  function onKeydown(event) {
6107
6158
  const available = items();
6108
- const current = event.target?.closest?.(itemSelector);
6159
+ const current = (
6160
+ /** @type {HTMLElement|null} */
6161
+ /** @type {Element|null} */
6162
+ event.target?.closest?.(itemSelector) ?? null
6163
+ );
6109
6164
  const index = available.indexOf(current);
6110
6165
  if (index < 0) return;
6111
6166
  const previousKey = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
@@ -6123,7 +6178,11 @@ function rovingTabindex(container, itemSelector, { orientation = "vertical", wra
6123
6178
  available[nextIndex].focus();
6124
6179
  }
6125
6180
  function onFocus(event) {
6126
- const item = event.target?.closest?.(itemSelector);
6181
+ const item = (
6182
+ /** @type {HTMLElement|null} */
6183
+ /** @type {Element|null} */
6184
+ event.target?.closest?.(itemSelector) ?? null
6185
+ );
6127
6186
  if (item && container.contains(item)) update(item);
6128
6187
  }
6129
6188
  container.addEventListener("keydown", onKeydown, { signal: controller.signal });
@@ -6193,7 +6252,11 @@ function itemText(item) {
6193
6252
  return String(item.textContent ?? "").trim().toLocaleLowerCase();
6194
6253
  }
6195
6254
  if (item && typeof item === "object") {
6196
- const value = item.label ?? item.text ?? item.value;
6255
+ const shape = (
6256
+ /** @type {{label?: unknown, text?: unknown, value?: unknown}} */
6257
+ item
6258
+ );
6259
+ const value = shape.label ?? shape.text ?? shape.value;
6197
6260
  if (value != null) return String(value).trim().toLocaleLowerCase();
6198
6261
  }
6199
6262
  return String(item ?? "").trim().toLocaleLowerCase();
@@ -8654,6 +8717,75 @@ function registerValueListFieldAdapter() {
8654
8717
  });
8655
8718
  }
8656
8719
 
8720
+ // src/core/breakpoint.js
8721
+ var breakpoints = Object.freeze({ sm: 480, md: 768, lg: 1024, xl: 1280 });
8722
+ var ORDER = (
8723
+ /** @type {const} */
8724
+ ["xl", "lg", "md", "sm"]
8725
+ );
8726
+ function breakpointOf(width) {
8727
+ const value = Number(width);
8728
+ if (!Number.isFinite(value)) return "xs";
8729
+ for (const name of ORDER) {
8730
+ if (value >= breakpoints[name]) return name;
8731
+ }
8732
+ return "xs";
8733
+ }
8734
+ function onBreakpoint(handler, options = {}) {
8735
+ if (typeof handler !== "function") throw new TypeError("onBreakpoint requires a handler");
8736
+ if ("target" in options && !isElement(options.target) && /** @type {unknown} */
8737
+ options.target !== /** @type {unknown} */
8738
+ globalThis) {
8739
+ throw new TypeError("onBreakpoint target must be an Element or the window");
8740
+ }
8741
+ const target = options.target ?? globalThis;
8742
+ const element = isElement(target) ? (
8743
+ /** @type {Element} */
8744
+ target
8745
+ ) : null;
8746
+ let name = (
8747
+ /** @type {BreakpointName|null} */
8748
+ null
8749
+ );
8750
+ let destroyed = false;
8751
+ let observer = null;
8752
+ const measure = () => element ? element.getBoundingClientRect().width : Number(globalThis.innerWidth) || 0;
8753
+ const update = () => {
8754
+ if (destroyed) return;
8755
+ const width = measure();
8756
+ if (element && width === 0) return;
8757
+ const next = breakpointOf(width);
8758
+ if (next === name) return;
8759
+ name = next;
8760
+ handler(name, width);
8761
+ };
8762
+ update();
8763
+ let frame = 0;
8764
+ const schedule = () => {
8765
+ if (frame || destroyed) return;
8766
+ frame = requestAnimationFrame(() => {
8767
+ frame = 0;
8768
+ update();
8769
+ });
8770
+ };
8771
+ if (element && typeof ResizeObserver === "function") {
8772
+ observer = new ResizeObserver(schedule);
8773
+ observer.observe(element);
8774
+ } else {
8775
+ globalThis.addEventListener?.("resize", update, { passive: true });
8776
+ }
8777
+ return {
8778
+ current: () => name ?? breakpointOf(measure()),
8779
+ destroy: () => {
8780
+ if (destroyed) return;
8781
+ destroyed = true;
8782
+ if (frame) cancelAnimationFrame(frame);
8783
+ observer?.disconnect();
8784
+ globalThis.removeEventListener?.("resize", update);
8785
+ }
8786
+ };
8787
+ }
8788
+
8657
8789
  // src/core/http.js
8658
8790
  var Http = class {
8659
8791
  /** @type {string} */
@@ -8714,7 +8846,10 @@ var Http = class {
8714
8846
  try {
8715
8847
  json = JSON.parse(text3);
8716
8848
  } catch (cause) {
8717
- const error = new Error("Invalid JSON response", { cause });
8849
+ const error = (
8850
+ /** @type {Error & {response?: Response}} */
8851
+ new Error("Invalid JSON response", { cause })
8852
+ );
8718
8853
  error.response = response;
8719
8854
  throw error;
8720
8855
  }
@@ -8726,7 +8861,10 @@ var Http = class {
8726
8861
  error2.response = response;
8727
8862
  throw error2;
8728
8863
  }
8729
- const error = new Error(`HTTP ${response.status} ${response.statusText}`.trim());
8864
+ const error = (
8865
+ /** @type {Error & {response?: Response}} */
8866
+ new Error(`HTTP ${response.status} ${response.statusText}`.trim())
8867
+ );
8730
8868
  error.response = response;
8731
8869
  throw error;
8732
8870
  }
@@ -8834,7 +8972,10 @@ function appendFormValue2(form, key, value) {
8834
8972
  for (const item of value) appendFormValue2(form, key, item);
8835
8973
  } else {
8836
8974
  const isBlob = typeof Blob === "function" && value instanceof Blob;
8837
- form.append(key, typeof value === "object" && !isBlob ? JSON.stringify(value) : value);
8975
+ form.append(key, typeof value === "object" && !isBlob ? JSON.stringify(value) : (
8976
+ /** @type {string|Blob} */
8977
+ value
8978
+ ));
8838
8979
  }
8839
8980
  }
8840
8981
  function isFileList(value) {
@@ -10226,6 +10367,8 @@ var Table = class extends Component {
10226
10367
  sortMode: "local",
10227
10368
  selectable: false,
10228
10369
  stickyHeader: true,
10370
+ responsive: false,
10371
+ growing: false,
10229
10372
  height: null,
10230
10373
  emptyText: null,
10231
10374
  rowClass: null,
@@ -10246,6 +10389,7 @@ var Table = class extends Component {
10246
10389
  /** @type {HTMLElement} */
10247
10390
  this.el ?? h("div")
10248
10391
  );
10392
+ this.el = root;
10249
10393
  this._originalChildren = this.el ? Array.from(this.el.childNodes) : null;
10250
10394
  this._columns = Array.isArray(this.options.columns) ? this.options.columns.map((column) => ({ ...column })) : [];
10251
10395
  this._data = Array.isArray(this.options.data) ? [...this.options.data] : [];
@@ -10258,6 +10402,11 @@ var Table = class extends Component {
10258
10402
  this._editMode = normalizeEditMode(this.options.editMode);
10259
10403
  this._edit = null;
10260
10404
  this._editMessage = null;
10405
+ this._stacked = false;
10406
+ this._width = null;
10407
+ this._growStep = growStep(this.options.growing);
10408
+ this._rendered = this._growStep ?? Infinity;
10409
+ this._more = null;
10261
10410
  this._rovingKey = null;
10262
10411
  this._rovingCell = null;
10263
10412
  this._rovingMatched = false;
@@ -10292,6 +10441,7 @@ var Table = class extends Component {
10292
10441
  this._renderColumns();
10293
10442
  this._renderHeader();
10294
10443
  this._renderBody();
10444
+ this._watchWidth();
10295
10445
  this.listen(this._tbody, "click", (event) => this._handleBodyClick(event));
10296
10446
  this.listen(this._tbody, "dblclick", (event) => this._handleBodyDoubleClick(event));
10297
10447
  if (this._editMode !== false) {
@@ -10325,6 +10475,7 @@ var Table = class extends Component {
10325
10475
  * @fires Table#editcancel
10326
10476
  */
10327
10477
  setData(rows) {
10478
+ this._rendered = this._growStep ?? Infinity;
10328
10479
  this.setLoading(false);
10329
10480
  assertRows(rows);
10330
10481
  this._data = [...rows];
@@ -10599,9 +10750,150 @@ var Table = class extends Component {
10599
10750
  getEditing() {
10600
10751
  return this._edit ? { id: this._edit.id, columnId: this._edit.columnId } : null;
10601
10752
  }
10753
+ /**
10754
+ * The rows currently rendered — all of them unless `growing` is on.
10755
+ * @returns {TableRow[]}
10756
+ */
10757
+ _visibleData() {
10758
+ return this._rendered === Infinity ? this._data : this._data.slice(0, this._rendered);
10759
+ }
10760
+ /**
10761
+ * Renders the next batch of rows.
10762
+ * @param {number} [count] How many to add; defaults to the configured batch size.
10763
+ * @returns {this}
10764
+ * @fires Table#grow
10765
+ */
10766
+ growBy(count) {
10767
+ if (!this._growStep) return this;
10768
+ const step = Number(count) > 0 ? Math.trunc(Number(count)) : this._growStep;
10769
+ const before = this._rendered;
10770
+ this._rendered = Math.min(this._data.length, this._rendered + step);
10771
+ if (this._rendered === before) return this;
10772
+ this._renderBody();
10773
+ this.emit("grow", { rendered: this._rendered, total: this._data.length });
10774
+ return this;
10775
+ }
10776
+ /**
10777
+ * Renders every remaining row.
10778
+ * @returns {this}
10779
+ * @fires Table#grow
10780
+ */
10781
+ showAll() {
10782
+ return this.growBy(this._data.length);
10783
+ }
10784
+ /**
10785
+ * How many rows are currently rendered.
10786
+ * @returns {number}
10787
+ */
10788
+ getRenderedCount() {
10789
+ return Math.min(this._rendered, this._data.length);
10790
+ }
10791
+ /**
10792
+ * Keeps the "show more" control in step with what is rendered.
10793
+ *
10794
+ * The control sits outside the table rather than in a `<tfoot>` row spanning every column: it is
10795
+ * a command, not data, and a button inside the grid would be reachable by the row navigation
10796
+ * keys as though it were a cell.
10797
+ * @returns {void}
10798
+ */
10799
+ _syncGrowing() {
10800
+ if (!this._growStep) return;
10801
+ const remaining = this._data.length - this.getRenderedCount();
10802
+ if (remaining <= 0) {
10803
+ this._more?.remove();
10804
+ this._more = null;
10805
+ return;
10806
+ }
10807
+ const label = this._message("table.more", "Show %1 more", [remaining]);
10808
+ if (!this._more) {
10809
+ this._more = h("button", {
10810
+ class: "zx-table__more",
10811
+ type: "button",
10812
+ onclick: () => this.growBy()
10813
+ });
10814
+ this.el.append(this._more);
10815
+ }
10816
+ this._more.textContent = label;
10817
+ this._more.setAttribute("aria-label", label);
10818
+ }
10819
+ /**
10820
+ * Resolves a localized message, falling back to a built-in template.
10821
+ * @param {string} key Message key.
10822
+ * @param {string} fallback Template used when the host has no translation.
10823
+ * @param {unknown[]} args Positional interpolation values.
10824
+ * @returns {string}
10825
+ */
10826
+ _message(key, fallback, args) {
10827
+ const message = this.msg(key, ...args);
10828
+ return message === key ? printf(fallback, args) : message;
10829
+ }
10830
+ /**
10831
+ * Watches the table's own width and stacks the rows below `responsive`.
10832
+ *
10833
+ * The width comes from `onBreakpoint` observing this element rather than the window, which is the
10834
+ * whole point of the option: a table inside a split pane or a modal has no idea how wide the
10835
+ * viewport is, and a media query would stack it on a phone while leaving it unreadable in a
10836
+ * 320px pane on a desktop.
10837
+ * @returns {void}
10838
+ */
10839
+ _watchWidth() {
10840
+ this._width?.destroy();
10841
+ this._width = null;
10842
+ const threshold = this.options.responsive;
10843
+ if (!threshold || !(threshold in breakpoints)) return;
10844
+ this._width = onBreakpoint(
10845
+ (_name, width) => this._setStacked(width > 0 && width < breakpoints[threshold]),
10846
+ { target: this.el }
10847
+ );
10848
+ }
10849
+ /**
10850
+ * Enters or leaves stacked mode.
10851
+ * @param {boolean} stacked Whether rows should stack.
10852
+ * @returns {void}
10853
+ * @fires Table#stackedchange
10854
+ */
10855
+ _setStacked(stacked) {
10856
+ if (this._stacked === stacked) return;
10857
+ this._stacked = stacked;
10858
+ this.el.toggleAttribute("data-stacked", stacked);
10859
+ this._applyStackedRoles(stacked);
10860
+ this.emit("stackedchange", { stacked });
10861
+ }
10862
+ /**
10863
+ * States the table roles explicitly while stacked, and removes them again on the way out.
10864
+ *
10865
+ * Stacking works by changing `display` on the table elements, and a table whose display is not
10866
+ * `table` loses its implicit ARIA roles — leaving a screen reader with a pile of generic blocks
10867
+ * where a table used to be. The roles are only asserted while the layout has taken them away.
10868
+ * @param {boolean} stacked Whether the roles should be present.
10869
+ * @returns {void}
10870
+ */
10871
+ _applyStackedRoles(stacked) {
10872
+ const parts = [[this._table, "table"], [this._thead, "rowgroup"], [this._tbody, "rowgroup"]];
10873
+ for (const [element, role] of parts) {
10874
+ if (!element) continue;
10875
+ if (stacked) element.setAttribute("role", role);
10876
+ else element.removeAttribute("role");
10877
+ }
10878
+ for (const [selector, role] of [["tr", "row"], ["td", "cell"], ["th", "columnheader"]]) {
10879
+ for (const element of this._table.querySelectorAll(selector)) {
10880
+ if (stacked) element.setAttribute("role", role);
10881
+ else element.removeAttribute("role");
10882
+ }
10883
+ }
10884
+ }
10885
+ /**
10886
+ * Reports whether the rows are currently stacked.
10887
+ * @returns {boolean}
10888
+ */
10889
+ isStacked() {
10890
+ return Boolean(this._stacked);
10891
+ }
10602
10892
  /** Restores an enhanced target and releases all component listeners. @returns {void} */
10603
10893
  destroy() {
10604
10894
  this._teardownEdit();
10895
+ this._width?.destroy();
10896
+ this._width = null;
10605
10897
  if (this.el) delete this.el.dataset.editMode;
10606
10898
  if (!this._restored && this._originalChildren) {
10607
10899
  this.el.replaceChildren(...this._originalChildren);
@@ -10686,17 +10978,35 @@ var Table = class extends Component {
10686
10978
  this._rovingCell = null;
10687
10979
  this._rovingMatched = false;
10688
10980
  if (this._data.length === 0) {
10689
- const text3 = this.options.emptyText == null ? this.msg("table.empty") : String(this.options.emptyText);
10690
10981
  fragment.append(h(
10691
10982
  "tr",
10692
10983
  { class: "zx-table__empty-row" },
10693
- h("td", { class: "zx-table__empty", colspan: this._columns.length + (this.options.selectable === "multi" ? 1 : 0) }, text3)
10984
+ h("td", {
10985
+ class: "zx-table__empty",
10986
+ colspan: this._columns.length + (this.options.selectable === "multi" ? 1 : 0)
10987
+ }, this._emptyContent())
10694
10988
  ));
10695
10989
  } else {
10696
- this._data.forEach((row, index) => fragment.append(this._createRow(row, index)));
10990
+ this._visibleData().forEach((row, index) => fragment.append(this._createRow(row, index)));
10697
10991
  }
10698
10992
  this._tbody.replaceChildren(fragment);
10699
10993
  this._syncSelectAll();
10994
+ this._syncGrowing();
10995
+ if (this._stacked) this._applyStackedRoles(true);
10996
+ }
10997
+ /**
10998
+ * What to put in the empty row.
10999
+ *
11000
+ * An empty table is a screen in its own right — the place to say why there is nothing and what to
11001
+ * do about it — so this takes a node as readily as a string. A function is re-called on every
11002
+ * render, which matters when the placeholder contains a button: reusing one node would move the
11003
+ * same element between renders and quietly share its listeners.
11004
+ * @returns {Node|string}
11005
+ */
11006
+ _emptyContent() {
11007
+ const empty = this.options.emptyText;
11008
+ if (empty == null) return this.msg("table.empty");
11009
+ return typeof empty === "function" ? empty() : empty;
10700
11010
  }
10701
11011
  /** @param {TableRow} row @param {number} index @returns {HTMLTableRowElement} */
10702
11012
  _createRow(row, index) {
@@ -10727,6 +11037,8 @@ var Table = class extends Component {
10727
11037
  h("td")
10728
11038
  );
10729
11039
  if (column.align) cell.dataset.align = column.align;
11040
+ cell.dataset.label = column.label;
11041
+ if (column.popin === false) cell.dataset.popin = "false";
10730
11042
  if (this._editMode !== false) {
10731
11043
  cell.dataset.column = column.id;
10732
11044
  if (resolveEditable(column, row) !== false) {
@@ -11345,6 +11657,10 @@ function assertRows(rows) {
11345
11657
  function sameSet(left, right) {
11346
11658
  return left.size === right.size && [...left].every((value) => right.has(value));
11347
11659
  }
11660
+ function growStep(growing) {
11661
+ const step = Math.trunc(Number(growing));
11662
+ return Number.isFinite(step) && step > 0 ? step : null;
11663
+ }
11348
11664
 
11349
11665
  // src/components/button/button.js
11350
11666
  var defaults = Object.freeze({
@@ -15314,6 +15630,12 @@ var Datebox2 = class extends GxWrapper {
15314
15630
  };
15315
15631
  var PickerBase = class extends GxWrapper {
15316
15632
  static legacyName = "gx.zeyos.DatePicker";
15633
+ /*
15634
+ * A constructor type rather than `typeof ZxDatePicker`: each subclass points this at a different
15635
+ * picker, and inferring the base from its own default would make every subclass's static side
15636
+ * incompatible with it.
15637
+ */
15638
+ /** @type {new (target: Element|string|null, options?: any) => any} */
15317
15639
  static Picker = DatePicker;
15318
15640
  /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
15319
15641
  constructor(display, options = {}) {
@@ -16468,6 +16790,13 @@ function normalizeButtons(list) {
16468
16790
  // src/compat/map/select.js
16469
16791
  var SelectBase = class extends GxWrapper {
16470
16792
  static legacyName = "gx.zeyos.Select";
16793
+ /*
16794
+ * Widened deliberately: the subclasses below set `'local' | 'async' | 'priority' | 'rest'`, and
16795
+ * a static field annotated with that union would still clash with the `string` each subclass
16796
+ * infers from its own literal. The static sides have to agree or the emitted declarations do
16797
+ * not type-check for a consumer running without `skipLibCheck`.
16798
+ */
16799
+ /** @type {string|false} */
16471
16800
  static filterMode = false;
16472
16801
  /** @param {Element|string|null} display @param {Record<string, any>} [options={}] */
16473
16802
  constructor(display, options = {}) {