@zeyos/zx 2.1.0 → 2.2.1

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 +51 -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 +375 -39
  120. package/dist/zx-compat.esm.min.js +1 -1
  121. package/dist/zx-compat.global.js +372 -73
  122. package/dist/zx-compat.global.min.js +3 -3
  123. package/dist/zx-zeyos.esm.js +355 -49
  124. package/dist/zx-zeyos.esm.min.js +1 -1
  125. package/dist/zx.css +68 -6
  126. package/dist/zx.esm.js +359 -73
  127. package/dist/zx.esm.min.js +3 -3
  128. package/dist/zx.global.js +359 -73
  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 +31 -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 +1711 -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
package/dist/zx.global.js CHANGED
@@ -241,7 +241,8 @@ var zx = (() => {
241
241
  );
242
242
  }
243
243
  function isElement(value) {
244
- return Boolean(value && typeof value === "object" && value.nodeType === 1);
244
+ return Boolean(value && typeof value === "object" && /** @type {{nodeType?: unknown}} */
245
+ value.nodeType === 1);
245
246
  }
246
247
  function clamp(n, min, max) {
247
248
  return Math.min(max, Math.max(min, n));
@@ -249,11 +250,15 @@ var zx = (() => {
249
250
  function toArray(value) {
250
251
  if (value == null) return [];
251
252
  if (Array.isArray(value)) return value.slice();
252
- if (typeof value !== "string" && typeof value[Symbol.iterator] === "function") {
253
- return Array.from(value);
253
+ const candidate = (
254
+ /** @type {any} */
255
+ value
256
+ );
257
+ if (typeof value !== "string" && typeof candidate?.[Symbol.iterator] === "function") {
258
+ return Array.from(candidate);
254
259
  }
255
- if (typeof value !== "string" && typeof value.length === "number") {
256
- return Array.from(value);
260
+ if (typeof value !== "string" && typeof candidate?.length === "number") {
261
+ return Array.from(candidate);
257
262
  }
258
263
  return [
259
264
  /** @type {T} */
@@ -462,8 +467,12 @@ var zx = (() => {
462
467
  }
463
468
  function isPropsObject(value) {
464
469
  if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
465
- if (typeof value.nodeType === "number") return false;
466
- return typeof value.toElement !== "function";
470
+ const candidate = (
471
+ /** @type {Record<string, unknown>} */
472
+ value
473
+ );
474
+ if (typeof candidate.nodeType === "number") return false;
475
+ return typeof candidate.toElement !== "function";
467
476
  }
468
477
  function applyProperty(element, key, value) {
469
478
  if (key === "ref") {
@@ -521,15 +530,33 @@ var zx = (() => {
521
530
  return "aria-" + key.slice(4).toLowerCase();
522
531
  }
523
532
  function appendChildren(parent, children) {
524
- for (const child of children.flat(Infinity)) {
525
- if (child == null) continue;
526
- if (typeof child === "string" || typeof child === "number") {
527
- parent.append(document.createTextNode(String(child)));
528
- } else if (child && typeof child === "object" && typeof child.nodeType === "number") {
529
- parent.append(child);
530
- } else if (typeof child === "object" && typeof child.toElement === "function") {
533
+ const host = (
534
+ /** @type {ParentNode} */
535
+ parent
536
+ );
537
+ for (
538
+ const raw2 of
539
+ /** @type {any[]} */
540
+ children.flat(Infinity)
541
+ ) {
542
+ if (raw2 == null) continue;
543
+ if (typeof raw2 === "string" || typeof raw2 === "number") {
544
+ host.append(document.createTextNode(String(raw2)));
545
+ continue;
546
+ }
547
+ if (typeof raw2 !== "object") continue;
548
+ const child = (
549
+ /** @type {{nodeType?: number, toElement?: () => Node|null}} */
550
+ raw2
551
+ );
552
+ if (typeof child.nodeType === "number") {
553
+ host.append(
554
+ /** @type {Node} */
555
+ raw2
556
+ );
557
+ } else if (typeof child.toElement === "function") {
531
558
  const element = child.toElement();
532
- if (element) parent.append(element);
559
+ if (element) host.append(element);
533
560
  }
534
561
  }
535
562
  }
@@ -584,11 +611,18 @@ var zx = (() => {
584
611
  var Component = class extends EventTarget {
585
612
  /** @type {ComponentOptions} */
586
613
  static defaults = {};
614
+ /**
615
+ * BEM block a subclass wants on its root, without the `zx-` prefix. Empty on the base, which is
616
+ * the same falsy answer the undeclared property gave — declared so the statics are visible to
617
+ * `this.constructor` and to the generated declarations.
618
+ * @type {string}
619
+ */
620
+ static cssName = "";
587
621
  /** @type {Element} Root element. */
588
622
  el;
589
623
  /** @type {Record<string, Element>} Elements captured by `h()` ref properties. */
590
624
  refs;
591
- /** @type {Readonly<ComponentOptions>} Merged component options. */
625
+ /** @type {Readonly<TOptions>} Merged component options. */
592
626
  options;
593
627
  #abort = new AbortController();
594
628
  #created = false;
@@ -597,17 +631,27 @@ var zx = (() => {
597
631
  /**
598
632
  * Creates a component around an existing target, or asks `render()` to create its root.
599
633
  * @param {Element|string|null} target Existing element, selector, or null.
600
- * @param {ComponentOptions} [options={}] Component options.
634
+ * @param {TOptions} [options={}] Component options.
601
635
  */
602
- constructor(target, options = {}) {
636
+ constructor(target, options = (
637
+ /** @type {TOptions} */
638
+ {}
639
+ )) {
603
640
  super();
641
+ const self = (
642
+ /** @type {typeof Component} */
643
+ this.constructor
644
+ );
604
645
  this.#created = target === null;
605
646
  const resolved = resolveElement(target);
606
647
  if (target !== null && !resolved) throw new TypeError("Component target could not be resolved");
607
648
  this.el = /** @type {Element} */
608
649
  resolved;
609
650
  this.refs = {};
610
- const merged = mergeOptions(this.constructor, options);
651
+ const merged = (
652
+ /** @type {TOptions} */
653
+ mergeOptions(self, options)
654
+ );
611
655
  const eventOptions = [];
612
656
  for (const [key, value] of Object.entries(merged)) {
613
657
  if (/^on[a-z]/.test(key) && typeof value === "function") {
@@ -637,7 +681,7 @@ var zx = (() => {
637
681
  this.#abort.abort();
638
682
  throw new TypeError("Component requires a root Element");
639
683
  }
640
- const cssName = this.constructor.cssName;
684
+ const cssName = self.cssName;
641
685
  if (typeof cssName === "string" && cssName) {
642
686
  const className = `zx-${cssName}`;
643
687
  this.#addedRootClass = !this.el.classList.contains(className);
@@ -758,7 +802,10 @@ var zx = (() => {
758
802
  this.#destroyed = true;
759
803
  this.#abort.abort();
760
804
  if (registry.get(this.el) === this) registry.delete(this.el);
761
- const cssName = this.constructor.cssName;
805
+ const cssName = (
806
+ /** @type {typeof Component} */
807
+ this.constructor.cssName
808
+ );
762
809
  if (this.#addedRootClass && typeof cssName === "string" && this.el) {
763
810
  this.el.classList.remove(`zx-${cssName}`);
764
811
  }
@@ -1742,7 +1789,10 @@ var zx = (() => {
1742
1789
  if (!lang) return 1;
1743
1790
  if (lang.toLowerCase() === "en") return 1;
1744
1791
  try {
1745
- const locale = new Intl.Locale(lang);
1792
+ const locale = (
1793
+ /** @type {Intl.Locale & {getWeekInfo?: () => {firstDay?: number}, weekInfo?: {firstDay?: number}}} */
1794
+ new Intl.Locale(lang)
1795
+ );
1746
1796
  const weekInfo = locale.getWeekInfo?.() ?? locale.weekInfo;
1747
1797
  if (weekInfo?.firstDay) return weekInfo.firstDay % 7;
1748
1798
  } catch {
@@ -1870,25 +1920,28 @@ var zx = (() => {
1870
1920
  const url = kitUrl(kit);
1871
1921
  const pending = kitLoads.get(url);
1872
1922
  if (pending) return pending;
1873
- const promise = new Promise((resolve, reject) => {
1874
- const absolute = new URL(url, document.baseURI).href;
1875
- const existing = [...document.scripts].find((script2) => script2.src === absolute);
1876
- if (existing && globalThis.FontAwesomeKitConfig) {
1877
- resolve();
1878
- return;
1879
- }
1880
- const script = existing ?? document.createElement("script");
1881
- script.addEventListener("load", () => resolve(), { once: true });
1882
- script.addEventListener("error", () => {
1883
- kitLoads.delete(url);
1884
- reject(new Error(`Font Awesome kit failed to load: ${url}`));
1885
- }, { once: true });
1886
- if (existing) return;
1887
- script.src = url;
1888
- script.async = true;
1889
- script.crossOrigin = "anonymous";
1890
- document.head.append(script);
1891
- });
1923
+ const promise = (
1924
+ /** @type {Promise<void>} */
1925
+ new Promise((resolve, reject) => {
1926
+ const absolute = new URL(url, document.baseURI).href;
1927
+ const existing = [...document.scripts].find((script2) => script2.src === absolute);
1928
+ if (existing && globalThis.FontAwesomeKitConfig) {
1929
+ resolve();
1930
+ return;
1931
+ }
1932
+ const script = existing ?? document.createElement("script");
1933
+ script.addEventListener("load", () => resolve(), { once: true });
1934
+ script.addEventListener("error", () => {
1935
+ kitLoads.delete(url);
1936
+ reject(new Error(`Font Awesome kit failed to load: ${url}`));
1937
+ }, { once: true });
1938
+ if (existing) return;
1939
+ script.src = url;
1940
+ script.async = true;
1941
+ script.crossOrigin = "anonymous";
1942
+ document.head.append(script);
1943
+ })
1944
+ );
1892
1945
  kitLoads.set(url, promise);
1893
1946
  return promise;
1894
1947
  }
@@ -3145,9 +3198,11 @@ var zx = (() => {
3145
3198
  const topY = anchorRect.top - offset - floatingRect.height;
3146
3199
  if (flip) {
3147
3200
  if (prefersBottom && bottomY + floatingRect.height > viewportHeight && topY >= 0) {
3148
- actualPlacement = placement.replace("bottom", "top");
3201
+ actualPlacement = /** @type {typeof placement} */
3202
+ placement.replace("bottom", "top");
3149
3203
  } else if (!prefersBottom && topY < 0 && bottomY + floatingRect.height <= viewportHeight) {
3150
- actualPlacement = placement.replace("top", "bottom");
3204
+ actualPlacement = /** @type {typeof placement} */
3205
+ placement.replace("top", "bottom");
3151
3206
  }
3152
3207
  }
3153
3208
  let left;
@@ -6160,10 +6215,13 @@ var zx = (() => {
6160
6215
  const originals = /* @__PURE__ */ new Map();
6161
6216
  let destroyed = false;
6162
6217
  function items() {
6163
- return Array.from(container.querySelectorAll(itemSelector)).filter((item) => {
6164
- remember(item);
6165
- return isAvailable(item);
6166
- });
6218
+ return (
6219
+ /** @type {HTMLElement[]} */
6220
+ Array.from(container.querySelectorAll(itemSelector)).filter((item) => {
6221
+ remember(item);
6222
+ return isAvailable(item);
6223
+ })
6224
+ );
6167
6225
  }
6168
6226
  function remember(item) {
6169
6227
  if (!originals.has(item)) originals.set(item, item.getAttribute("tabindex"));
@@ -6178,7 +6236,11 @@ var zx = (() => {
6178
6236
  }
6179
6237
  function onKeydown(event) {
6180
6238
  const available = items();
6181
- const current = event.target?.closest?.(itemSelector);
6239
+ const current = (
6240
+ /** @type {HTMLElement|null} */
6241
+ /** @type {Element|null} */
6242
+ event.target?.closest?.(itemSelector) ?? null
6243
+ );
6182
6244
  const index = available.indexOf(current);
6183
6245
  if (index < 0) return;
6184
6246
  const previousKey = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
@@ -6196,7 +6258,11 @@ var zx = (() => {
6196
6258
  available[nextIndex].focus();
6197
6259
  }
6198
6260
  function onFocus(event) {
6199
- const item = event.target?.closest?.(itemSelector);
6261
+ const item = (
6262
+ /** @type {HTMLElement|null} */
6263
+ /** @type {Element|null} */
6264
+ event.target?.closest?.(itemSelector) ?? null
6265
+ );
6200
6266
  if (item && container.contains(item)) update(item);
6201
6267
  }
6202
6268
  container.addEventListener("keydown", onKeydown, { signal: controller.signal });
@@ -6256,8 +6322,9 @@ var zx = (() => {
6256
6322
  };
6257
6323
  }
6258
6324
  function focusableItems(container) {
6259
- return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
6260
- (item) => isAvailable(item) && item.getClientRects().length > 0
6325
+ return (
6326
+ /** @type {HTMLElement[]} */
6327
+ Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter((item) => isAvailable(item) && item.getClientRects().length > 0)
6261
6328
  );
6262
6329
  }
6263
6330
  function isAvailable(item) {
@@ -6271,7 +6338,11 @@ var zx = (() => {
6271
6338
  return String(item.textContent ?? "").trim().toLocaleLowerCase();
6272
6339
  }
6273
6340
  if (item && typeof item === "object") {
6274
- const value = item.label ?? item.text ?? item.value;
6341
+ const shape = (
6342
+ /** @type {{label?: unknown, text?: unknown, value?: unknown}} */
6343
+ item
6344
+ );
6345
+ const value = shape.label ?? shape.text ?? shape.value;
6275
6346
  if (value != null) return String(value).trim().toLocaleLowerCase();
6276
6347
  }
6277
6348
  return String(item ?? "").trim().toLocaleLowerCase();
@@ -8754,11 +8825,19 @@ var zx = (() => {
8754
8825
  }
8755
8826
  function onBreakpoint(handler, options = {}) {
8756
8827
  if (typeof handler !== "function") throw new TypeError("onBreakpoint requires a handler");
8828
+ if ("target" in options && !isElement(options.target) && /** @type {unknown} */
8829
+ options.target !== /** @type {unknown} */
8830
+ globalThis) {
8831
+ throw new TypeError("onBreakpoint target must be an Element or the window");
8832
+ }
8757
8833
  const target = options.target ?? globalThis;
8758
- const element = target instanceof Element ? target : null;
8834
+ const element = isElement(target) ? (
8835
+ /** @type {Element} */
8836
+ target
8837
+ ) : null;
8759
8838
  let name = (
8760
- /** @type {BreakpointName} */
8761
- "xs"
8839
+ /** @type {BreakpointName|null} */
8840
+ null
8762
8841
  );
8763
8842
  let destroyed = false;
8764
8843
  let observer = null;
@@ -8766,24 +8845,33 @@ var zx = (() => {
8766
8845
  const update = () => {
8767
8846
  if (destroyed) return;
8768
8847
  const width = measure();
8848
+ if (element && width === 0) return;
8769
8849
  const next = breakpointOf(width);
8770
8850
  if (next === name) return;
8771
8851
  name = next;
8772
8852
  handler(name, width);
8773
8853
  };
8774
- name = breakpointOf(measure());
8775
- handler(name, measure());
8854
+ update();
8855
+ let frame = 0;
8856
+ const schedule = () => {
8857
+ if (frame || destroyed) return;
8858
+ frame = requestAnimationFrame(() => {
8859
+ frame = 0;
8860
+ update();
8861
+ });
8862
+ };
8776
8863
  if (element && typeof ResizeObserver === "function") {
8777
- observer = new ResizeObserver(update);
8864
+ observer = new ResizeObserver(schedule);
8778
8865
  observer.observe(element);
8779
8866
  } else {
8780
8867
  globalThis.addEventListener?.("resize", update, { passive: true });
8781
8868
  }
8782
8869
  return {
8783
- current: () => name,
8870
+ current: () => name ?? breakpointOf(measure()),
8784
8871
  destroy: () => {
8785
8872
  if (destroyed) return;
8786
8873
  destroyed = true;
8874
+ if (frame) cancelAnimationFrame(frame);
8787
8875
  observer?.disconnect();
8788
8876
  globalThis.removeEventListener?.("resize", update);
8789
8877
  }
@@ -8850,7 +8938,10 @@ var zx = (() => {
8850
8938
  try {
8851
8939
  json2 = JSON.parse(text4);
8852
8940
  } catch (cause) {
8853
- const error = new Error("Invalid JSON response", { cause });
8941
+ const error = (
8942
+ /** @type {Error & {response?: Response}} */
8943
+ new Error("Invalid JSON response", { cause })
8944
+ );
8854
8945
  error.response = response;
8855
8946
  throw error;
8856
8947
  }
@@ -8862,7 +8953,10 @@ var zx = (() => {
8862
8953
  error2.response = response;
8863
8954
  throw error2;
8864
8955
  }
8865
- const error = new Error(`HTTP ${response.status} ${response.statusText}`.trim());
8956
+ const error = (
8957
+ /** @type {Error & {response?: Response}} */
8958
+ new Error(`HTTP ${response.status} ${response.statusText}`.trim())
8959
+ );
8866
8960
  error.response = response;
8867
8961
  throw error;
8868
8962
  }
@@ -8970,7 +9064,10 @@ var zx = (() => {
8970
9064
  for (const item of value) appendFormValue2(form, key, item);
8971
9065
  } else {
8972
9066
  const isBlob = typeof Blob === "function" && value instanceof Blob;
8973
- form.append(key, typeof value === "object" && !isBlob ? JSON.stringify(value) : value);
9067
+ form.append(key, typeof value === "object" && !isBlob ? JSON.stringify(value) : (
9068
+ /** @type {string|Blob} */
9069
+ value
9070
+ ));
8974
9071
  }
8975
9072
  }
8976
9073
  function isFileList(value) {
@@ -9043,7 +9140,11 @@ var zx = (() => {
9043
9140
  const diff = target.getTime() - reference.getTime();
9044
9141
  const division = TIME_DIVISIONS.find(({ ms, limit }) => Math.abs(diff) / ms < limit) ?? TIME_DIVISIONS[TIME_DIVISIONS.length - 1];
9045
9142
  const value = Math.round(diff / division.ms);
9046
- return relativeFormatter(locale, numeric).format(value, division.unit);
9143
+ return relativeFormatter(locale, numeric).format(
9144
+ value,
9145
+ /** @type {Intl.RelativeTimeFormatUnit} */
9146
+ division.unit
9147
+ );
9047
9148
  }
9048
9149
  function format(locale, options, value) {
9049
9150
  const key = `${locale}\0${JSON.stringify(options)}`;
@@ -9347,7 +9448,10 @@ var zx = (() => {
9347
9448
  }
9348
9449
  function toBlob(data, type) {
9349
9450
  if (typeof Blob === "function" && data instanceof Blob) return data;
9350
- const parts = typeof data === "string" && /^text\/csv\b/i.test(type) ? ["\uFEFF", data] : [data];
9451
+ const parts = (
9452
+ /** @type {BlobPart[]} */
9453
+ typeof data === "string" && /^text\/csv\b/i.test(type) ? ["\uFEFF", data] : [data]
9454
+ );
9351
9455
  return new Blob(parts, { type });
9352
9456
  }
9353
9457
 
@@ -10736,6 +10840,8 @@ var zx = (() => {
10736
10840
  sortMode: "local",
10737
10841
  selectable: false,
10738
10842
  stickyHeader: true,
10843
+ responsive: false,
10844
+ growing: false,
10739
10845
  height: null,
10740
10846
  emptyText: null,
10741
10847
  rowClass: null,
@@ -10756,6 +10862,7 @@ var zx = (() => {
10756
10862
  /** @type {HTMLElement} */
10757
10863
  this.el ?? h("div")
10758
10864
  );
10865
+ this.el = root;
10759
10866
  this._originalChildren = this.el ? Array.from(this.el.childNodes) : null;
10760
10867
  this._columns = Array.isArray(this.options.columns) ? this.options.columns.map((column) => ({ ...column })) : [];
10761
10868
  this._data = Array.isArray(this.options.data) ? [...this.options.data] : [];
@@ -10768,6 +10875,11 @@ var zx = (() => {
10768
10875
  this._editMode = normalizeEditMode(this.options.editMode);
10769
10876
  this._edit = null;
10770
10877
  this._editMessage = null;
10878
+ this._stacked = false;
10879
+ this._width = null;
10880
+ this._growStep = growStep(this.options.growing);
10881
+ this._rendered = this._growStep ?? Infinity;
10882
+ this._more = null;
10771
10883
  this._rovingKey = null;
10772
10884
  this._rovingCell = null;
10773
10885
  this._rovingMatched = false;
@@ -10802,6 +10914,7 @@ var zx = (() => {
10802
10914
  this._renderColumns();
10803
10915
  this._renderHeader();
10804
10916
  this._renderBody();
10917
+ this._watchWidth();
10805
10918
  this.listen(this._tbody, "click", (event) => this._handleBodyClick(event));
10806
10919
  this.listen(this._tbody, "dblclick", (event) => this._handleBodyDoubleClick(event));
10807
10920
  if (this._editMode !== false) {
@@ -10835,6 +10948,7 @@ var zx = (() => {
10835
10948
  * @fires Table#editcancel
10836
10949
  */
10837
10950
  setData(rows) {
10951
+ this._rendered = this._growStep ?? Infinity;
10838
10952
  this.setLoading(false);
10839
10953
  assertRows(rows);
10840
10954
  this._data = [...rows];
@@ -11109,9 +11223,150 @@ var zx = (() => {
11109
11223
  getEditing() {
11110
11224
  return this._edit ? { id: this._edit.id, columnId: this._edit.columnId } : null;
11111
11225
  }
11226
+ /**
11227
+ * The rows currently rendered — all of them unless `growing` is on.
11228
+ * @returns {TableRow[]}
11229
+ */
11230
+ _visibleData() {
11231
+ return this._rendered === Infinity ? this._data : this._data.slice(0, this._rendered);
11232
+ }
11233
+ /**
11234
+ * Renders the next batch of rows.
11235
+ * @param {number} [count] How many to add; defaults to the configured batch size.
11236
+ * @returns {this}
11237
+ * @fires Table#grow
11238
+ */
11239
+ growBy(count2) {
11240
+ if (!this._growStep) return this;
11241
+ const step = Number(count2) > 0 ? Math.trunc(Number(count2)) : this._growStep;
11242
+ const before = this._rendered;
11243
+ this._rendered = Math.min(this._data.length, this._rendered + step);
11244
+ if (this._rendered === before) return this;
11245
+ this._renderBody();
11246
+ this.emit("grow", { rendered: this._rendered, total: this._data.length });
11247
+ return this;
11248
+ }
11249
+ /**
11250
+ * Renders every remaining row.
11251
+ * @returns {this}
11252
+ * @fires Table#grow
11253
+ */
11254
+ showAll() {
11255
+ return this.growBy(this._data.length);
11256
+ }
11257
+ /**
11258
+ * How many rows are currently rendered.
11259
+ * @returns {number}
11260
+ */
11261
+ getRenderedCount() {
11262
+ return Math.min(this._rendered, this._data.length);
11263
+ }
11264
+ /**
11265
+ * Keeps the "show more" control in step with what is rendered.
11266
+ *
11267
+ * The control sits outside the table rather than in a `<tfoot>` row spanning every column: it is
11268
+ * a command, not data, and a button inside the grid would be reachable by the row navigation
11269
+ * keys as though it were a cell.
11270
+ * @returns {void}
11271
+ */
11272
+ _syncGrowing() {
11273
+ if (!this._growStep) return;
11274
+ const remaining = this._data.length - this.getRenderedCount();
11275
+ if (remaining <= 0) {
11276
+ this._more?.remove();
11277
+ this._more = null;
11278
+ return;
11279
+ }
11280
+ const label = this._message("table.more", "Show %1 more", [remaining]);
11281
+ if (!this._more) {
11282
+ this._more = h("button", {
11283
+ class: "zx-table__more",
11284
+ type: "button",
11285
+ onclick: () => this.growBy()
11286
+ });
11287
+ this.el.append(this._more);
11288
+ }
11289
+ this._more.textContent = label;
11290
+ this._more.setAttribute("aria-label", label);
11291
+ }
11292
+ /**
11293
+ * Resolves a localized message, falling back to a built-in template.
11294
+ * @param {string} key Message key.
11295
+ * @param {string} fallback Template used when the host has no translation.
11296
+ * @param {unknown[]} args Positional interpolation values.
11297
+ * @returns {string}
11298
+ */
11299
+ _message(key, fallback, args) {
11300
+ const message = this.msg(key, ...args);
11301
+ return message === key ? printf(fallback, args) : message;
11302
+ }
11303
+ /**
11304
+ * Watches the table's own width and stacks the rows below `responsive`.
11305
+ *
11306
+ * The width comes from `onBreakpoint` observing this element rather than the window, which is the
11307
+ * whole point of the option: a table inside a split pane or a modal has no idea how wide the
11308
+ * viewport is, and a media query would stack it on a phone while leaving it unreadable in a
11309
+ * 320px pane on a desktop.
11310
+ * @returns {void}
11311
+ */
11312
+ _watchWidth() {
11313
+ this._width?.destroy();
11314
+ this._width = null;
11315
+ const threshold = this.options.responsive;
11316
+ if (!threshold || !(threshold in breakpoints)) return;
11317
+ this._width = onBreakpoint(
11318
+ (_name, width) => this._setStacked(width > 0 && width < breakpoints[threshold]),
11319
+ { target: this.el }
11320
+ );
11321
+ }
11322
+ /**
11323
+ * Enters or leaves stacked mode.
11324
+ * @param {boolean} stacked Whether rows should stack.
11325
+ * @returns {void}
11326
+ * @fires Table#stackedchange
11327
+ */
11328
+ _setStacked(stacked) {
11329
+ if (this._stacked === stacked) return;
11330
+ this._stacked = stacked;
11331
+ this.el.toggleAttribute("data-stacked", stacked);
11332
+ this._applyStackedRoles(stacked);
11333
+ this.emit("stackedchange", { stacked });
11334
+ }
11335
+ /**
11336
+ * States the table roles explicitly while stacked, and removes them again on the way out.
11337
+ *
11338
+ * Stacking works by changing `display` on the table elements, and a table whose display is not
11339
+ * `table` loses its implicit ARIA roles — leaving a screen reader with a pile of generic blocks
11340
+ * where a table used to be. The roles are only asserted while the layout has taken them away.
11341
+ * @param {boolean} stacked Whether the roles should be present.
11342
+ * @returns {void}
11343
+ */
11344
+ _applyStackedRoles(stacked) {
11345
+ const parts = [[this._table, "table"], [this._thead, "rowgroup"], [this._tbody, "rowgroup"]];
11346
+ for (const [element, role] of parts) {
11347
+ if (!element) continue;
11348
+ if (stacked) element.setAttribute("role", role);
11349
+ else element.removeAttribute("role");
11350
+ }
11351
+ for (const [selector, role] of [["tr", "row"], ["td", "cell"], ["th", "columnheader"]]) {
11352
+ for (const element of this._table.querySelectorAll(selector)) {
11353
+ if (stacked) element.setAttribute("role", role);
11354
+ else element.removeAttribute("role");
11355
+ }
11356
+ }
11357
+ }
11358
+ /**
11359
+ * Reports whether the rows are currently stacked.
11360
+ * @returns {boolean}
11361
+ */
11362
+ isStacked() {
11363
+ return Boolean(this._stacked);
11364
+ }
11112
11365
  /** Restores an enhanced target and releases all component listeners. @returns {void} */
11113
11366
  destroy() {
11114
11367
  this._teardownEdit();
11368
+ this._width?.destroy();
11369
+ this._width = null;
11115
11370
  if (this.el) delete this.el.dataset.editMode;
11116
11371
  if (!this._restored && this._originalChildren) {
11117
11372
  this.el.replaceChildren(...this._originalChildren);
@@ -11139,6 +11394,7 @@ var zx = (() => {
11139
11394
  /** @returns {void} */
11140
11395
  _renderHeader() {
11141
11396
  const row2 = h("tr", { class: "zx-table__header-row" });
11397
+ if (this._growStep) row2.setAttribute("aria-rowindex", "1");
11142
11398
  if (this.options.selectable === "multi") {
11143
11399
  this._selectAll = h("input", {
11144
11400
  class: "zx-table__checkbox zx-table__select-all",
@@ -11152,9 +11408,9 @@ var zx = (() => {
11152
11408
  row2.append(selectionHeader);
11153
11409
  this.listen(this._selectAll, "click", () => {
11154
11410
  if (this._selectAll.checked) {
11155
- for (const dataRow of this._data) this._selected.add(this._idFor(dataRow));
11411
+ for (const dataRow of this._visibleData()) this._selected.add(this._idFor(dataRow));
11156
11412
  } else {
11157
- this._selected.clear();
11413
+ for (const dataRow of this._visibleData()) this._selected.delete(this._idFor(dataRow));
11158
11414
  }
11159
11415
  this._selectionAnchorId = null;
11160
11416
  this._syncSelection();
@@ -11196,17 +11452,36 @@ var zx = (() => {
11196
11452
  this._rovingCell = null;
11197
11453
  this._rovingMatched = false;
11198
11454
  if (this._data.length === 0) {
11199
- const text4 = this.options.emptyText == null ? this.msg("table.empty") : String(this.options.emptyText);
11200
11455
  fragment.append(h(
11201
11456
  "tr",
11202
11457
  { class: "zx-table__empty-row" },
11203
- h("td", { class: "zx-table__empty", colspan: this._columns.length + (this.options.selectable === "multi" ? 1 : 0) }, text4)
11458
+ h("td", {
11459
+ class: "zx-table__empty",
11460
+ colspan: this._columns.length + (this.options.selectable === "multi" ? 1 : 0)
11461
+ }, this._emptyContent())
11204
11462
  ));
11205
11463
  } else {
11206
- this._data.forEach((row2, index) => fragment.append(this._createRow(row2, index)));
11464
+ this._visibleData().forEach((row2, index) => fragment.append(this._createRow(row2, index)));
11207
11465
  }
11208
11466
  this._tbody.replaceChildren(fragment);
11467
+ if (this._growStep) this._table.setAttribute("aria-rowcount", String(this._data.length + 1));
11209
11468
  this._syncSelectAll();
11469
+ this._syncGrowing();
11470
+ if (this._stacked) this._applyStackedRoles(true);
11471
+ }
11472
+ /**
11473
+ * What to put in the empty row.
11474
+ *
11475
+ * An empty table is a screen in its own right — the place to say why there is nothing and what to
11476
+ * do about it — so this takes a node as readily as a string. A function is re-called on every
11477
+ * render, which matters when the placeholder contains a button: reusing one node would move the
11478
+ * same element between renders and quietly share its listeners.
11479
+ * @returns {Node|string}
11480
+ */
11481
+ _emptyContent() {
11482
+ const empty = this.options.emptyText;
11483
+ if (empty == null) return this.msg("table.empty");
11484
+ return typeof empty === "function" ? empty() : empty;
11210
11485
  }
11211
11486
  /** @param {TableRow} row @param {number} index @returns {HTMLTableRowElement} */
11212
11487
  _createRow(row2, index) {
@@ -11215,6 +11490,7 @@ var zx = (() => {
11215
11490
  /** @type {HTMLTableRowElement} */
11216
11491
  h("tr", { dataset: { row: "" } })
11217
11492
  );
11493
+ if (this._growStep) tr.setAttribute("aria-rowindex", String(index + 2));
11218
11494
  const rowClass = typeof this.options.rowClass === "function" ? this.options.rowClass(row2) : "";
11219
11495
  if (rowClass) tr.classList.add(...String(rowClass).split(/\s+/).filter(Boolean));
11220
11496
  if (this.options.selectable !== false) tr.setAttribute("aria-selected", String(this._selected.has(id)));
@@ -11237,6 +11513,8 @@ var zx = (() => {
11237
11513
  h("td")
11238
11514
  );
11239
11515
  if (column.align) cell.dataset.align = column.align;
11516
+ cell.dataset.label = column.label;
11517
+ if (column.popin === false) cell.dataset.popin = "false";
11240
11518
  if (this._editMode !== false) {
11241
11519
  cell.dataset.column = column.id;
11242
11520
  if (resolveEditable(column, row2) !== false) {
@@ -11720,10 +11998,14 @@ var zx = (() => {
11720
11998
  /** @returns {void} */
11721
11999
  _syncSelectAll() {
11722
12000
  if (!this._selectAll) return;
11723
- const selectedRows = this._data.reduce((count2, row2) => count2 + Number(this._selected.has(this._idFor(row2))), 0);
11724
- this._selectAll.disabled = this._data.length === 0;
11725
- this._selectAll.checked = this._data.length > 0 && selectedRows === this._data.length;
11726
- this._selectAll.indeterminate = selectedRows > 0 && selectedRows < this._data.length;
12001
+ const visible = this._visibleData();
12002
+ const selectedRows = visible.reduce(
12003
+ (count2, row2) => count2 + Number(this._selected.has(this._idFor(row2))),
12004
+ 0
12005
+ );
12006
+ this._selectAll.disabled = visible.length === 0;
12007
+ this._selectAll.checked = visible.length > 0 && selectedRows === visible.length;
12008
+ this._selectAll.indeterminate = selectedRows > 0 && selectedRows < visible.length;
11727
12009
  }
11728
12010
  /** @returns {void} */
11729
12011
  _syncSortHeader() {
@@ -11855,6 +12137,10 @@ var zx = (() => {
11855
12137
  function sameSet(left, right) {
11856
12138
  return left.size === right.size && [...left].every((value) => right.has(value));
11857
12139
  }
12140
+ function growStep(growing) {
12141
+ const step = Math.trunc(Number(growing));
12142
+ return Number.isFinite(step) && step > 0 ? step : null;
12143
+ }
11858
12144
 
11859
12145
  // src/elements/reflect.js
11860
12146
  var INVALID_ATTRIBUTE = /* @__PURE__ */ Symbol("invalid attribute");