@atscript/vue-table 0.1.131 → 0.1.133

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 (111) hide show
  1. package/dist/as-action-form-dialog.cjs +42 -30
  2. package/dist/as-action-form-dialog.mjs +42 -30
  3. package/dist/{as-action-menu-content-4UfcabUe.mjs → as-action-menu-content-4D7CJNgr.mjs} +1 -1
  4. package/dist/{as-action-menu-content-C5qx9MPE.cjs → as-action-menu-content-DiS37BYK.cjs} +1 -1
  5. package/dist/as-column-menu.d.cts +1 -1
  6. package/dist/as-column-menu.d.mts +1 -1
  7. package/dist/{as-column-menu.vue-DL5N9mKR.d.mts → as-column-menu.vue-CZ8XqHl0.d.cts} +2 -2
  8. package/dist/{as-column-menu.vue-u_DNy3f-.d.cts → as-column-menu.vue-Cuelpv3p.d.mts} +2 -2
  9. package/dist/{as-config-dialog-BehfqIGd.mjs → as-config-dialog-BKsm8OHR.mjs} +30 -22
  10. package/dist/{as-config-dialog-BOYWPYYH.cjs → as-config-dialog-Bt8oP8qg.cjs} +29 -21
  11. package/dist/as-config-dialog.cjs +1 -1
  12. package/dist/as-config-dialog.mjs +1 -1
  13. package/dist/{as-confirm-dialog-bpN4A-KN.mjs → as-confirm-dialog-BV01t7dn.mjs} +12 -9
  14. package/dist/{as-confirm-dialog-UwhDHysk.cjs → as-confirm-dialog-Cw7KErhz.cjs} +12 -9
  15. package/dist/as-confirm-dialog.cjs +1 -1
  16. package/dist/as-confirm-dialog.mjs +1 -1
  17. package/dist/{as-filter-dialog-Dh2Ylthb.cjs → as-filter-dialog-Bxii-mYH.cjs} +31 -23
  18. package/dist/{as-filter-dialog-D1qzq-8b.mjs → as-filter-dialog-Ckrl79kU.mjs} +32 -24
  19. package/dist/as-filter-dialog.cjs +1 -1
  20. package/dist/as-filter-dialog.mjs +1 -1
  21. package/dist/{as-filter-field-DirBmnbb.mjs → as-filter-field-C-IFnj8K.mjs} +4 -4
  22. package/dist/{as-filter-field-DRsDJdpx.cjs → as-filter-field-xBr6TtKo.cjs} +4 -4
  23. package/dist/as-filter-field.cjs +1 -1
  24. package/dist/as-filter-field.mjs +1 -1
  25. package/dist/as-filters-DJEQj7_p.mjs +125 -0
  26. package/dist/as-filters-DuCk8nkk.cjs +130 -0
  27. package/dist/as-filters.cjs +1 -1
  28. package/dist/as-filters.d.cts +1 -1
  29. package/dist/as-filters.d.mts +1 -1
  30. package/dist/as-filters.mjs +1 -1
  31. package/dist/as-filters.vue-BG_ysCkC.d.mts +65 -0
  32. package/dist/as-filters.vue-DcxDnWAU.d.cts +65 -0
  33. package/dist/{as-preset-dialog-CDqCAR7N.mjs → as-preset-dialog-CCIacZ2C.mjs} +70 -20
  34. package/dist/{as-preset-dialog-DpM06jqR.cjs → as-preset-dialog-jZeyXJeJ.cjs} +74 -24
  35. package/dist/as-preset-dialog.cjs +1 -1
  36. package/dist/as-preset-dialog.mjs +1 -1
  37. package/dist/{as-preset-picker-jUS_YDX8.cjs → as-preset-picker-4xXU1KQz.cjs} +45 -21
  38. package/dist/{as-preset-picker-CISaxEZ0.mjs → as-preset-picker-DGSqQl9A.mjs} +39 -15
  39. package/dist/as-preset-picker.cjs +1 -1
  40. package/dist/as-preset-picker.mjs +1 -1
  41. package/dist/{as-row-actions-Bm6Bzyno.cjs → as-row-actions-B_OHWIAt.cjs} +2 -2
  42. package/dist/{as-row-actions-xqJeAdQl.mjs → as-row-actions-pukI1JT7.mjs} +2 -2
  43. package/dist/as-row-actions.cjs +1 -1
  44. package/dist/as-row-actions.mjs +1 -1
  45. package/dist/{as-table-BWUPzjRn.cjs → as-table-BejpMVid.cjs} +22 -4
  46. package/dist/{as-table-CDSG2yED.mjs → as-table-D5_bQ0p5.mjs} +22 -4
  47. package/dist/{as-table-actions-DMxeaczm.mjs → as-table-actions-DKYK_mTO.mjs} +57 -11
  48. package/dist/{as-table-actions-gV4lqqxc.cjs → as-table-actions-qb0gQz2D.cjs} +56 -10
  49. package/dist/as-table-actions.cjs +1 -1
  50. package/dist/as-table-actions.d.cts +1 -1
  51. package/dist/as-table-actions.d.mts +1 -1
  52. package/dist/as-table-actions.mjs +1 -1
  53. package/dist/{as-table-actions.vue-DTGYOsZh.d.mts → as-table-actions.vue-CckRRsL6.d.cts} +1 -1
  54. package/dist/{as-table-actions.vue-WXkllHVw.d.cts → as-table-actions.vue-DsqauvXR.d.mts} +1 -1
  55. package/dist/{as-table-base-BaTE3VSN.mjs → as-table-base-B0arhJI8.mjs} +141 -46
  56. package/dist/{as-table-base-RG2TEIgV.cjs → as-table-base-Dfw012G5.cjs} +141 -46
  57. package/dist/{as-table-header-cell-CIqlO6Lw.cjs → as-table-header-cell-Bb4ddLmQ.cjs} +1 -1
  58. package/dist/{as-table-header-cell-Bdhl5Lox.mjs → as-table-header-cell-q-c_QklI.mjs} +1 -1
  59. package/dist/as-table-header-cell.cjs +1 -1
  60. package/dist/as-table-header-cell.d.cts +1 -1
  61. package/dist/as-table-header-cell.d.mts +1 -1
  62. package/dist/as-table-header-cell.mjs +1 -1
  63. package/dist/{as-table-header-cell.vue-BCszzxtU.d.mts → as-table-header-cell.vue-BjVOEFqz.d.mts} +1 -1
  64. package/dist/{as-table-header-cell.vue-BzTzfGRo.d.cts → as-table-header-cell.vue-qS1Xfc-U.d.cts} +1 -1
  65. package/dist/{as-table-root-BLReUbRH.mjs → as-table-root-Bpsrp0Vz.mjs} +5 -5
  66. package/dist/{as-table-root-DLJ_3Jf4.cjs → as-table-root-CUDO9ybm.cjs} +5 -5
  67. package/dist/as-table-root.cjs +1 -1
  68. package/dist/as-table-root.d.cts +1 -1
  69. package/dist/as-table-root.d.mts +1 -1
  70. package/dist/as-table-root.mjs +1 -1
  71. package/dist/{as-table-root.vue-BqZl6JQ0.d.mts → as-table-root.vue-BPU92_Ns.d.mts} +59 -16
  72. package/dist/{as-table-root.vue-umgSvVUB.d.cts → as-table-root.vue-szvjZsCn.d.cts} +59 -16
  73. package/dist/{as-table-status-DGTZlpyq.mjs → as-table-status-B9jlzPPV.mjs} +53 -37
  74. package/dist/{as-table-status-Du4WLF4k.cjs → as-table-status-BgDexT2x.cjs} +53 -37
  75. package/dist/as-table.cjs +1 -1
  76. package/dist/as-table.d.cts +1 -1
  77. package/dist/as-table.d.mts +1 -1
  78. package/dist/as-table.mjs +1 -1
  79. package/dist/{as-table.vue-DxtfL26P.d.mts → as-table.vue-4WhMA8AM.d.mts} +27 -3
  80. package/dist/{as-table.vue-D9cCjbtr.d.cts → as-table.vue-_urybtQj.d.cts} +27 -3
  81. package/dist/{as-window-table-jD_y9yet.cjs → as-window-table-CXq6UuUx.cjs} +98 -19
  82. package/dist/{as-window-table-DWujiUQy.mjs → as-window-table-S1XWpDHQ.mjs} +98 -19
  83. package/dist/as-window-table.cjs +1 -1
  84. package/dist/as-window-table.d.cts +1 -1
  85. package/dist/as-window-table.d.mts +1 -1
  86. package/dist/as-window-table.mjs +1 -1
  87. package/dist/{as-window-table.vue-BpvgmsC1.d.mts → as-window-table.vue-CWsJvOkL.d.mts} +26 -3
  88. package/dist/{as-window-table.vue-BavmqDeH.d.cts → as-window-table.vue-h1bdyMv7.d.cts} +26 -3
  89. package/dist/error-message-CglODWl4.cjs +18 -0
  90. package/dist/error-message-hPSAu8Ug.mjs +13 -0
  91. package/dist/index.cjs +61 -29
  92. package/dist/index.d.cts +9 -9
  93. package/dist/index.d.mts +9 -9
  94. package/dist/index.mjs +62 -30
  95. package/dist/{types-CTMxE_zA.d.cts → types-BZ0HssRY.d.cts} +126 -4
  96. package/dist/{types-ByU4O0Yf.d.mts → types-CXz-4dPz.d.mts} +126 -4
  97. package/dist/{use-table-CyFcVtUN.mjs → use-table-Bk-jSxOM.mjs} +26 -11
  98. package/dist/{use-table-nvBq1dZ4.cjs → use-table-CdFFqaEx.cjs} +24 -9
  99. package/dist/{use-table-component-DO_kvKSf.cjs → use-table-component-DlLganVc.cjs} +1 -1
  100. package/dist/{use-table-component-K6xj1obF.mjs → use-table-component-KuzZxAP8.mjs} +1 -1
  101. package/dist/{use-table-nav-bridge-DeGeaQX-.mjs → use-table-nav-bridge-B9SSEajW.mjs} +1 -1
  102. package/dist/{use-table-nav-bridge-uOQUDooh.cjs → use-table-nav-bridge-CVUmTjDr.cjs} +1 -1
  103. package/dist/{use-table-state-Oi2ds4_a.cjs → use-table-state-D6dHOFrA.cjs} +329 -53
  104. package/dist/{use-table-state-BxX3SpeW.mjs → use-table-state-DLJbW753.mjs} +295 -55
  105. package/package.json +9 -9
  106. package/dist/as-filters-DCZTHjf5.cjs +0 -51
  107. package/dist/as-filters-beIud9sF.mjs +0 -46
  108. package/dist/as-filters.vue-DmECMd1v.d.mts +0 -10
  109. package/dist/as-filters.vue-fv-tRL2H.d.cts +0 -10
  110. package/dist/preset-aspect-display-IICxAlVo.mjs +0 -43
  111. package/dist/preset-aspect-display-TWwf6j1B.cjs +0 -72
@@ -1,7 +1,7 @@
1
- const require_use_table_state = require("./use-table-state-Oi2ds4_a.cjs");
2
- const require_use_table_component = require("./use-table-component-DO_kvKSf.cjs");
3
- const require_as_table_header_cell = require("./as-table-header-cell-CIqlO6Lw.cjs");
4
- const require_as_row_actions = require("./as-row-actions-Bm6Bzyno.cjs");
1
+ const require_use_table_state = require("./use-table-state-D6dHOFrA.cjs");
2
+ const require_use_table_component = require("./use-table-component-DlLganVc.cjs");
3
+ const require_as_table_header_cell = require("./as-table-header-cell-Bb4ddLmQ.cjs");
4
+ const require_as_row_actions = require("./as-row-actions-B_OHWIAt.cjs");
5
5
  const require_as_table_cell_value = require("./as-table-cell-value-D1JkTQt0.cjs");
6
6
  let _atscript_ui = require("@atscript/ui");
7
7
  let vue = require("vue");
@@ -532,6 +532,18 @@ var as_table_header_default = /* @__PURE__ */ (0, vue.defineComponent)({
532
532
  table.style.tableLayout = origTableLayout;
533
533
  return measured;
534
534
  }
535
+ /**
536
+ * The select-all control is a `role="checkbox"` span, not a `<button>`, so
537
+ * it gets no native key activation: bind Space (checkbox semantics) and
538
+ * Enter (the table's row-activation key) explicitly.
539
+ */
540
+ function onSelectAllKeydown(event) {
541
+ if (event.key !== " " && event.key !== "Enter") return;
542
+ if (!props.selectAllState) return;
543
+ event.preventDefault();
544
+ event.stopPropagation();
545
+ emit("select-all-toggle", props.selectAllState);
546
+ }
535
547
  return (_ctx, _cache) => {
536
548
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("thead", null, [(0, vue.createElementVNode)("tr", null, [
537
549
  __props.hasSelectColumn ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("th", _hoisted_1$1, [__props.selectAllState ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
@@ -542,9 +554,11 @@ var as_table_header_default = /* @__PURE__ */ (0, vue.defineComponent)({
542
554
  }]),
543
555
  role: "checkbox",
544
556
  tabindex: "0",
557
+ "aria-label": "Select all rows",
545
558
  "aria-checked": __props.selectAllState === "none" ? "false" : __props.selectAllState === "all" ? "true" : "mixed",
546
- onClick: _cache[0] || (_cache[0] = ($event) => emit("select-all-toggle", __props.selectAllState))
547
- }, [__props.selectAllState === "all" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$1)) : __props.selectAllState === "some" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_4$1)) : (0, vue.createCommentVNode)("v-if", true)], 10, _hoisted_2$1)) : (0, vue.createCommentVNode)("v-if", true)])) : (0, vue.createCommentVNode)("v-if", true),
559
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("select-all-toggle", __props.selectAllState)),
560
+ onKeydown: onSelectAllKeydown
561
+ }, [__props.selectAllState === "all" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_3$1)) : __props.selectAllState === "some" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_4$1)) : (0, vue.createCommentVNode)("v-if", true)], 42, _hoisted_2$1)) : (0, vue.createCommentVNode)("v-if", true)])) : (0, vue.createCommentVNode)("v-if", true),
548
562
  ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.columns, (col) => {
549
563
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("th", {
550
564
  key: col.path,
@@ -557,37 +571,39 @@ var as_table_header_default = /* @__PURE__ */ (0, vue.defineComponent)({
557
571
  onDragover: ($event) => col.fixed ? void 0 : (0, vue.unref)(onHeaderDragOver)($event),
558
572
  onDrop: ($event) => col.fixed ? void 0 : (0, vue.unref)(onHeaderDrop)($event),
559
573
  onDragend: ($event) => col.fixed ? void 0 : (0, vue.unref)(onHeaderDragEnd)()
560
- }, [!col.fixed ? (0, vue.renderSlot)(_ctx.$slots, `header-${col.path}`, {
561
- key: 0,
562
- column: col
563
- }, () => [((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(HeaderCell)), {
564
- column: col,
565
- "sort-direction": sortMap.value[col.path] ?? null,
566
- filters: __props.filters?.[col.path],
567
- "column-menu": __props.columnMenu,
568
- "width-entry": __props.columnWidths[col.path],
569
- onSort: _cache[1] || (_cache[1] = (c, d) => emit("sort", c, d)),
570
- onHide: _cache[2] || (_cache[2] = (c) => emit("hide", c)),
571
- onFilter: _cache[3] || (_cache[3] = (c) => emit("filter", c)),
572
- onFiltersOff: _cache[4] || (_cache[4] = (c) => emit("filters-off", c)),
573
- onResetWidth: _cache[5] || (_cache[5] = (c) => emit("reset-width", c))
574
- }, null, 40, [
575
- "column",
576
- "sort-direction",
577
- "filters",
578
- "column-menu",
579
- "width-entry"
580
- ]))]) : (0, vue.createCommentVNode)("v-if", true), __props.resizable && !col.fixed ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
581
- key: 1,
582
- class: "as-th-resize-handle",
583
- draggable: "false",
584
- onDragstart: _cache[6] || (_cache[6] = (0, vue.withModifiers)(() => {}, ["prevent", "stop"])),
585
- onPointerdown: _cache[7] || (_cache[7] = (0, vue.withModifiers)((...args) => (0, vue.unref)(onResizeHandlePointerDown) && (0, vue.unref)(onResizeHandlePointerDown)(...args), ["stop"])),
586
- onPointermove: _cache[8] || (_cache[8] = (...args) => (0, vue.unref)(onResizeHandlePointerMove) && (0, vue.unref)(onResizeHandlePointerMove)(...args)),
587
- onPointerup: _cache[9] || (_cache[9] = (...args) => (0, vue.unref)(onResizeHandleEnd) && (0, vue.unref)(onResizeHandleEnd)(...args)),
588
- onPointercancel: _cache[10] || (_cache[10] = (...args) => (0, vue.unref)(onResizeHandleEnd) && (0, vue.unref)(onResizeHandleEnd)(...args)),
589
- onDblclick: _cache[11] || (_cache[11] = (0, vue.withModifiers)((...args) => (0, vue.unref)(onResizeHandleDoubleClick) && (0, vue.unref)(onResizeHandleDoubleClick)(...args), ["stop"]))
590
- }, null, 32)) : (0, vue.createCommentVNode)("v-if", true)], 46, _hoisted_5$1);
574
+ }, [
575
+ (0, vue.createCommentVNode)(" An explicitly supplied `header-<path>` slot renders for fixed\n (synthesised) columns too; only the DEFAULT header cell is\n suppressed there, so `__actions` keeps its blank gutter unless\n the consumer fills it. Reorder/resize stay disabled regardless. "),
576
+ (0, vue.renderSlot)(_ctx.$slots, `header-${col.path}`, { column: col }, () => [!col.fixed ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(HeaderCell)), {
577
+ key: 0,
578
+ column: col,
579
+ "sort-direction": sortMap.value[col.path] ?? null,
580
+ filters: __props.filters?.[col.path],
581
+ "column-menu": __props.columnMenu,
582
+ "width-entry": __props.columnWidths[col.path],
583
+ onSort: _cache[1] || (_cache[1] = (c, d) => emit("sort", c, d)),
584
+ onHide: _cache[2] || (_cache[2] = (c) => emit("hide", c)),
585
+ onFilter: _cache[3] || (_cache[3] = (c) => emit("filter", c)),
586
+ onFiltersOff: _cache[4] || (_cache[4] = (c) => emit("filters-off", c)),
587
+ onResetWidth: _cache[5] || (_cache[5] = (c) => emit("reset-width", c))
588
+ }, null, 40, [
589
+ "column",
590
+ "sort-direction",
591
+ "filters",
592
+ "column-menu",
593
+ "width-entry"
594
+ ])) : (0, vue.createCommentVNode)("v-if", true)]),
595
+ __props.resizable && !col.fixed ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
596
+ key: 0,
597
+ class: "as-th-resize-handle",
598
+ draggable: "false",
599
+ onDragstart: _cache[6] || (_cache[6] = (0, vue.withModifiers)(() => {}, ["prevent", "stop"])),
600
+ onPointerdown: _cache[7] || (_cache[7] = (0, vue.withModifiers)((...args) => (0, vue.unref)(onResizeHandlePointerDown) && (0, vue.unref)(onResizeHandlePointerDown)(...args), ["stop"])),
601
+ onPointermove: _cache[8] || (_cache[8] = (...args) => (0, vue.unref)(onResizeHandlePointerMove) && (0, vue.unref)(onResizeHandlePointerMove)(...args)),
602
+ onPointerup: _cache[9] || (_cache[9] = (...args) => (0, vue.unref)(onResizeHandleEnd) && (0, vue.unref)(onResizeHandleEnd)(...args)),
603
+ onPointercancel: _cache[10] || (_cache[10] = (...args) => (0, vue.unref)(onResizeHandleEnd) && (0, vue.unref)(onResizeHandleEnd)(...args)),
604
+ onDblclick: _cache[11] || (_cache[11] = (0, vue.withModifiers)((...args) => (0, vue.unref)(onResizeHandleDoubleClick) && (0, vue.unref)(onResizeHandleDoubleClick)(...args), ["stop"]))
605
+ }, null, 32)) : (0, vue.createCommentVNode)("v-if", true)
606
+ ], 46, _hoisted_5$1);
591
607
  }), 128)),
592
608
  __props.withFiller ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("th", _hoisted_6$1)) : (0, vue.createCommentVNode)("v-if", true)
593
609
  ])]);
package/dist/as-table.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const require_as_table = require("./as-table-BWUPzjRn.cjs");
1
+ const require_as_table = require("./as-table-BejpMVid.cjs");
2
2
  module.exports = require_as_table.as_table_default;
@@ -1,2 +1,2 @@
1
- import { t as _default } from "./as-table.vue-D9cCjbtr.cjs";
1
+ import { t as _default } from "./as-table.vue-_urybtQj.cjs";
2
2
  export = _default;
@@ -1,2 +1,2 @@
1
- import { t as _default } from "./as-table.vue-DxtfL26P.mjs";
1
+ import { t as _default } from "./as-table.vue-4WhMA8AM.mjs";
2
2
  export { _default as default };
package/dist/as-table.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as as_table_default } from "./as-table-CDSG2yED.mjs";
1
+ import { t as as_table_default } from "./as-table-D5_bQ0p5.mjs";
2
2
  export { as_table_default as default };
@@ -1,4 +1,4 @@
1
- import { f as RowDeleteOpt, n as ColumnMenuConfig } from "./types-ByU4O0Yf.mjs";
1
+ import { f as RowAttrsHook, g as RowSelectableHook, m as RowDeleteOpt, n as ColumnMenuConfig, p as RowClassHook } from "./types-CXz-4dPz.mjs";
2
2
  import { ColumnDef } from "@atscript/ui";
3
3
  import * as vue from "vue";
4
4
  import { SelectionMode } from "@atscript/ui-table";
@@ -54,19 +54,43 @@ type __VLS_Props = {
54
54
  * (sort/filter/reorder/resize) are unavailable in headless mode.
55
55
  */
56
56
  headless?: boolean;
57
+ /**
58
+ * Per-row selectability. Return `false` — or a string, surfaced as the
59
+ * disabled reason on the row's selection control — to make a row not
60
+ * selectable. Enforced on every path: row click, Space/Enter toggle, and
61
+ * the header select-all (which also stops counting ineligible rows).
62
+ * Since 0.1.133.
63
+ *
64
+ * @example
65
+ * `:row-selectable="(row) => row.locked ? 'Locked by another user' : true"`
66
+ */
67
+ rowSelectable?: RowSelectableHook;
68
+ /**
69
+ * Extra classes for the row element — string, array, or
70
+ * `{ class: boolean }` map, merged with the framework's own row classes.
71
+ * Since 0.1.133.
72
+ */
73
+ rowClass?: RowClassHook;
74
+ /**
75
+ * Extra attributes for the row element. The framework's own `id`, `role`,
76
+ * `aria-*`, `data-*`, `class` and `style` always win, so a hook can
77
+ * decorate a row but never rewrite its accessibility contract.
78
+ * Since 0.1.133.
79
+ */
80
+ rowAttrs?: RowAttrsHook;
57
81
  };
58
82
  declare var __VLS_21: string, __VLS_22: any, __VLS_24: {};
59
83
  type __VLS_Slots = {} & { [K in NonNullable<typeof __VLS_21>]?: (props: typeof __VLS_22) => any } & {
60
84
  'query-loading'?: (props: typeof __VLS_24) => any;
61
85
  };
62
86
  declare const __VLS_base: vue.DefineComponent<__VLS_Props, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {} & {
87
+ "main-action": (row: Record<string, unknown>, absIndex: number, event: KeyboardEvent | MouseEvent) => any;
63
88
  "row-click": (row: Record<string, unknown>, event: MouseEvent) => any;
64
89
  "row-dblclick": (row: Record<string, unknown>, event: MouseEvent) => any;
65
- "main-action": (row: Record<string, unknown>, absIndex: number, event: MouseEvent | KeyboardEvent) => any;
66
90
  }, string, vue.PublicProps, Readonly<__VLS_Props> & Readonly<{
91
+ "onMain-action"?: ((row: Record<string, unknown>, absIndex: number, event: KeyboardEvent | MouseEvent) => any) | undefined;
67
92
  "onRow-click"?: ((row: Record<string, unknown>, event: MouseEvent) => any) | undefined;
68
93
  "onRow-dblclick"?: ((row: Record<string, unknown>, event: MouseEvent) => any) | undefined;
69
- "onMain-action"?: ((row: Record<string, unknown>, absIndex: number, event: MouseEvent | KeyboardEvent) => any) | undefined;
70
94
  }>, {
71
95
  stickyHeader: boolean;
72
96
  virtualOverscan: number;
@@ -1,4 +1,4 @@
1
- import { f as RowDeleteOpt, n as ColumnMenuConfig } from "./types-CTMxE_zA.cjs";
1
+ import { f as RowAttrsHook, g as RowSelectableHook, m as RowDeleteOpt, n as ColumnMenuConfig, p as RowClassHook } from "./types-BZ0HssRY.cjs";
2
2
  import * as vue from "vue";
3
3
  import { ColumnDef } from "@atscript/ui";
4
4
  import { SelectionMode } from "@atscript/ui-table";
@@ -54,19 +54,43 @@ type __VLS_Props = {
54
54
  * (sort/filter/reorder/resize) are unavailable in headless mode.
55
55
  */
56
56
  headless?: boolean;
57
+ /**
58
+ * Per-row selectability. Return `false` — or a string, surfaced as the
59
+ * disabled reason on the row's selection control — to make a row not
60
+ * selectable. Enforced on every path: row click, Space/Enter toggle, and
61
+ * the header select-all (which also stops counting ineligible rows).
62
+ * Since 0.1.133.
63
+ *
64
+ * @example
65
+ * `:row-selectable="(row) => row.locked ? 'Locked by another user' : true"`
66
+ */
67
+ rowSelectable?: RowSelectableHook;
68
+ /**
69
+ * Extra classes for the row element — string, array, or
70
+ * `{ class: boolean }` map, merged with the framework's own row classes.
71
+ * Since 0.1.133.
72
+ */
73
+ rowClass?: RowClassHook;
74
+ /**
75
+ * Extra attributes for the row element. The framework's own `id`, `role`,
76
+ * `aria-*`, `data-*`, `class` and `style` always win, so a hook can
77
+ * decorate a row but never rewrite its accessibility contract.
78
+ * Since 0.1.133.
79
+ */
80
+ rowAttrs?: RowAttrsHook;
57
81
  };
58
82
  declare var __VLS_21: string, __VLS_22: any, __VLS_24: {};
59
83
  type __VLS_Slots = {} & { [K in NonNullable<typeof __VLS_21>]?: (props: typeof __VLS_22) => any } & {
60
84
  'query-loading'?: (props: typeof __VLS_24) => any;
61
85
  };
62
86
  declare const __VLS_base: vue.DefineComponent<__VLS_Props, {}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {} & {
87
+ "main-action": (row: Record<string, unknown>, absIndex: number, event: KeyboardEvent | MouseEvent) => any;
63
88
  "row-click": (row: Record<string, unknown>, event: MouseEvent) => any;
64
89
  "row-dblclick": (row: Record<string, unknown>, event: MouseEvent) => any;
65
- "main-action": (row: Record<string, unknown>, absIndex: number, event: MouseEvent | KeyboardEvent) => any;
66
90
  }, string, vue.PublicProps, Readonly<__VLS_Props> & Readonly<{
91
+ "onMain-action"?: ((row: Record<string, unknown>, absIndex: number, event: KeyboardEvent | MouseEvent) => any) | undefined;
67
92
  "onRow-click"?: ((row: Record<string, unknown>, event: MouseEvent) => any) | undefined;
68
93
  "onRow-dblclick"?: ((row: Record<string, unknown>, event: MouseEvent) => any) | undefined;
69
- "onMain-action"?: ((row: Record<string, unknown>, absIndex: number, event: MouseEvent | KeyboardEvent) => any) | undefined;
70
94
  }>, {
71
95
  stickyHeader: boolean;
72
96
  virtualOverscan: number;
@@ -1,8 +1,8 @@
1
- const require_use_table_state = require("./use-table-state-Oi2ds4_a.cjs");
1
+ const require_use_table_state = require("./use-table-state-D6dHOFrA.cjs");
2
2
  const require_use_table_selection = require("./use-table-selection-Cmiu1h4S.cjs");
3
3
  const require_use_has_emit_listener = require("./use-has-emit-listener-hhOH8CBI.cjs");
4
4
  const require_get_cell_value = require("./get-cell-value-4rHKP-TG.cjs");
5
- const require_as_table_status = require("./as-table-status-Du4WLF4k.cjs");
5
+ const require_as_table_status = require("./as-table-status-BgDexT2x.cjs");
6
6
  const require_use_table_column_handlers = require("./use-table-column-handlers-ehreEzcx.cjs");
7
7
  let vue = require("vue");
8
8
  let _atscript_ui_table = require("@atscript/ui-table");
@@ -175,6 +175,7 @@ const _hoisted_2 = ["aria-rowcount", "aria-multiselectable"];
175
175
  const _hoisted_3 = ["aria-activedescendant"];
176
176
  const _hoisted_4 = [
177
177
  "id",
178
+ "data-selectable",
178
179
  "aria-rowindex",
179
180
  "aria-selected",
180
181
  "onClick",
@@ -185,7 +186,14 @@ const _hoisted_5 = {
185
186
  class: "as-td-select",
186
187
  role: "gridcell"
187
188
  };
188
- const _hoisted_6 = ["aria-checked"];
189
+ const _hoisted_6 = [
190
+ "tabindex",
191
+ "aria-label",
192
+ "title",
193
+ "aria-checked",
194
+ "aria-disabled",
195
+ "onKeydown"
196
+ ];
189
197
  const _hoisted_7 = {
190
198
  key: 0,
191
199
  class: "as-table-checkbox-tick",
@@ -241,6 +249,14 @@ var as_window_table_base_default = /* @__PURE__ */ (0, vue.defineComponent)({
241
249
  type: Boolean,
242
250
  required: false,
243
251
  default: false
252
+ },
253
+ rowClass: {
254
+ type: Function,
255
+ required: false
256
+ },
257
+ rowAttrs: {
258
+ type: Function,
259
+ required: false
244
260
  }
245
261
  },
246
262
  emits: [
@@ -267,6 +283,13 @@ var as_window_table_base_default = /* @__PURE__ */ (0, vue.defineComponent)({
267
283
  return out;
268
284
  });
269
285
  const rowStyle = (0, vue.computed)(() => ({ height: `${props.rowHeight}px` }));
286
+ /** Shared "selectable" verdict — frozen, so a hookless pool allocates nothing. */
287
+ const SELECTABLE = Object.freeze({ ok: true });
288
+ /** Accessible name for a row's selection control, carrying the disabled reason. */
289
+ function selectLabel(verdict) {
290
+ if (verdict.ok) return "Select row";
291
+ return verdict.reason ? `Select row, ${verdict.reason}` : "Select row, not selectable";
292
+ }
270
293
  const visibleSlots = (0, vue.computed)(() => {
271
294
  const viewport = state.viewportRowCount.value;
272
295
  if (viewport <= 0) return [];
@@ -276,19 +299,38 @@ var as_window_table_base_default = /* @__PURE__ */ (0, vue.defineComponent)({
276
299
  const rowValueFn = state.rowValueFn;
277
300
  const hasSelection = props.select !== "none";
278
301
  const selectedSet = hasSelection ? new Set(state.selectedRows.value) : null;
302
+ const gated = !!state.rowSelectable.value;
303
+ const hasHooks = gated || !!props.rowClass || !!props.rowAttrs;
279
304
  const out = [];
280
305
  for (let s = 0; s < count; s++) {
281
306
  const abs = top + s;
282
307
  const row = state.dataAt(abs);
283
308
  const pk = row === void 0 ? void 0 : rowValueFn(row);
284
309
  const selected = selectedSet !== null && row !== void 0 && selectedSet.has(pk);
310
+ let selectable = SELECTABLE;
311
+ let cls;
312
+ let attrs;
313
+ if (hasHooks && row !== void 0) {
314
+ const hookCtx = {
315
+ index: abs,
316
+ get selected() {
317
+ return selected;
318
+ }
319
+ };
320
+ if (gated) selectable = state.isRowSelectable(row, abs);
321
+ cls = props.rowClass?.(row, hookCtx);
322
+ attrs = props.rowAttrs?.(row, hookCtx);
323
+ }
285
324
  out.push({
286
325
  s,
287
326
  row,
288
327
  pk,
289
328
  errored: row === void 0 && state.errorAt(abs) !== null,
290
329
  selected,
291
- ariaSelected: hasSelection ? selected ? "true" : "false" : void 0
330
+ ariaSelected: hasSelection ? selected ? "true" : "false" : void 0,
331
+ selectable,
332
+ cls,
333
+ attrs
292
334
  });
293
335
  }
294
336
  return out;
@@ -324,6 +366,9 @@ var as_window_table_base_default = /* @__PURE__ */ (0, vue.defineComponent)({
324
366
  mode: props.select
325
367
  });
326
368
  }
369
+ function onSelectCellKeydown(event, absIdx) {
370
+ require_use_table_state.onSelectControlKeydown(event, absIdx, props.select, state);
371
+ }
327
372
  (0, vue.watch)([() => state.activeIndex.value, () => state.viewportRowCount.value], ([idx, viewport]) => {
328
373
  if (idx < 0) return;
329
374
  if (viewport <= 0) return;
@@ -362,11 +407,12 @@ var as_window_table_base_default = /* @__PURE__ */ (0, vue.defineComponent)({
362
407
  state.requestMainAction(event);
363
408
  }
364
409
  function onSelectAllToggle(headerState) {
365
- if (headerState === "none") {
366
- const pks = [];
367
- for (const row of state.windowCache.value.values()) pks.push(state.rowValueFn(row));
368
- state.selectedRows.value = pks;
369
- } else state.selectedRows.value = [];
410
+ if (headerState !== "none") {
411
+ state.selectedRows.value = [];
412
+ return;
413
+ }
414
+ const entries = [...state.windowCache.value.entries()].toSorted((a, b) => a[0] - b[0]);
415
+ state.selectAll(entries.map((e) => e[1]), (i) => entries[i][0]);
370
416
  }
371
417
  const { onSort, onHide, onFilter, onFiltersOff, onResetWidth, onReorder, onClearFilters } = require_use_table_column_handlers.useTableColumnHandlers(state);
372
418
  const wrapperRef = (0, vue.ref)(null);
@@ -488,23 +534,37 @@ var as_window_table_base_default = /* @__PURE__ */ (0, vue.defineComponent)({
488
534
  onTouchmove: (0, vue.withModifiers)(onTouchMove, ["prevent"]),
489
535
  onTouchend: onTouchEnd
490
536
  }, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(visibleSlots.value, (slot) => {
491
- return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: `slot-${slot.s}` }, [slot.row !== void 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("tr", {
537
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: `slot-${slot.s}` }, [(0, vue.createCommentVNode)("\n `v-bind=\"slot.attrs\"` comes FIRST so every framework binding\n after it wins — consumer attrs decorate a row, never rewrite its\n id / role / aria / data contract.\n "), slot.row !== void 0 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("tr", (0, vue.mergeProps)({
492
538
  key: 0,
539
+ ref_for: true
540
+ }, slot.attrs, {
493
541
  id: (0, vue.unref)(state).rowId((0, vue.unref)(state).topIndex.value + slot.s),
494
- class: (0, vue.normalizeClass)(["as-window-data-row", { "as-table-row-active": (0, vue.unref)(state).activeIndex.value === (0, vue.unref)(state).topIndex.value + slot.s }]),
542
+ class: [
543
+ "as-window-data-row",
544
+ { "as-table-row-active": (0, vue.unref)(state).activeIndex.value === (0, vue.unref)(state).topIndex.value + slot.s },
545
+ slot.cls
546
+ ],
547
+ "data-selectable": slot.selectable.ok ? void 0 : "false",
495
548
  role: "row",
496
549
  "aria-rowindex": (0, vue.unref)(state).topIndex.value + slot.s + 2,
497
550
  "aria-selected": slot.ariaSelected,
498
- style: (0, vue.normalizeStyle)(rowStyle.value),
551
+ style: rowStyle.value,
499
552
  onClick: ($event) => onRowClick(slot.row, $event, (0, vue.unref)(state).topIndex.value + slot.s),
500
553
  onDblclick: ($event) => onRowDblClick(slot.row, $event, (0, vue.unref)(state).topIndex.value + slot.s)
501
- }, [
554
+ }), [
502
555
  hasValue.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("td", _hoisted_5, [(0, vue.createElementVNode)("span", {
503
- class: (0, vue.normalizeClass)(["as-table-checkbox", { "as-table-checkbox-checked": slot.selected }]),
556
+ class: (0, vue.normalizeClass)(["as-table-checkbox", {
557
+ "as-table-checkbox-checked": slot.selected,
558
+ "as-table-checkbox-disabled": !slot.selectable.ok
559
+ }]),
504
560
  role: "checkbox",
505
- tabindex: "0",
506
- "aria-checked": slot.selected ? "true" : "false"
507
- }, [slot.selected ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_7)) : (0, vue.createCommentVNode)("v-if", true)], 10, _hoisted_6)])) : (0, vue.createCommentVNode)("v-if", true),
561
+ tabindex: slot.selectable.ok ? 0 : void 0,
562
+ "aria-label": selectLabel(slot.selectable),
563
+ title: slot.selectable.reason,
564
+ "aria-checked": slot.selected ? "true" : "false",
565
+ "aria-disabled": slot.selectable.ok ? void 0 : "true",
566
+ onKeydown: ($event) => onSelectCellKeydown($event, (0, vue.unref)(state).topIndex.value + slot.s)
567
+ }, [slot.selected ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_7)) : (0, vue.createCommentVNode)("v-if", true)], 42, _hoisted_6)])) : (0, vue.createCommentVNode)("v-if", true),
508
568
  (0, vue.unref)(hasAnyCellBindings) ? ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, (0, vue.renderList)((0, vue.unref)(state).columns.value, (col) => {
509
569
  return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: col.path }, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)([(0, vue.unref)(cellResolver)(col, slot.row, (0, vue.unref)(state).topIndex.value + slot.s)], (bindings) => {
510
570
  return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [cellSlotFlags.value[col.path] ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("td", (0, vue.mergeProps)({
@@ -537,7 +597,7 @@ var as_window_table_base_default = /* @__PURE__ */ (0, vue.defineComponent)({
537
597
  class: "as-td-filler",
538
598
  role: "gridcell"
539
599
  }, null, -1))
540
- ], 46, _hoisted_4)) : ((0, vue.openBlock)(), (0, vue.createBlock)(as_window_skeleton_row_default, {
600
+ ], 16, _hoisted_4)) : ((0, vue.openBlock)(), (0, vue.createBlock)(as_window_skeleton_row_default, {
541
601
  key: 1,
542
602
  columns: (0, vue.unref)(state).columns.value,
543
603
  "row-height": __props.rowHeight,
@@ -658,6 +718,18 @@ var as_window_table_default = /* @__PURE__ */ (0, vue.defineComponent)({
658
718
  type: Boolean,
659
719
  required: false,
660
720
  default: false
721
+ },
722
+ rowSelectable: {
723
+ type: Function,
724
+ required: false
725
+ },
726
+ rowClass: {
727
+ type: Function,
728
+ required: false
729
+ },
730
+ rowAttrs: {
731
+ type: Function,
732
+ required: false
661
733
  }
662
734
  },
663
735
  emits: [
@@ -673,6 +745,9 @@ var as_window_table_default = /* @__PURE__ */ (0, vue.defineComponent)({
673
745
  (0, vue.watch)(() => props.rowDelete, (val) => {
674
746
  state.rowDelete.value = val;
675
747
  }, { immediate: true });
748
+ (0, vue.watch)(() => props.rowSelectable, (val) => {
749
+ state.rowSelectable.value = val;
750
+ }, { immediate: true });
676
751
  require_use_table_selection.useSelectModeReset(state, () => props.select);
677
752
  require_use_table_state.useRegisterMainActionListener(state, (req) => emit("main-action", req.row, req.absIndex, req.event), require_use_has_emit_listener.useHasEmitListener("onMainAction"));
678
753
  const containerRef = (0, vue.ref)(null);
@@ -709,6 +784,8 @@ var as_window_table_default = /* @__PURE__ */ (0, vue.defineComponent)({
709
784
  select: __props.select,
710
785
  headless: __props.headless,
711
786
  "enter-action": __props.enterAction,
787
+ "row-class": __props.rowClass,
788
+ "row-attrs": __props.rowAttrs,
712
789
  onRowClick: _cache[0] || (_cache[0] = (row, ev) => emit("row-click", row, ev)),
713
790
  onRowDblclick: _cache[1] || (_cache[1] = (row, ev) => emit("row-dblclick", row, ev)),
714
791
  onViewportMetricsChange: onMetrics
@@ -726,7 +803,9 @@ var as_window_table_default = /* @__PURE__ */ (0, vue.defineComponent)({
726
803
  "column-min-width",
727
804
  "select",
728
805
  "headless",
729
- "enter-action"
806
+ "enter-action",
807
+ "row-class",
808
+ "row-attrs"
730
809
  ]), (0, vue.unref)(state).querying.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1, [(0, vue.renderSlot)(_ctx.$slots, "query-loading", {}, () => [_cache[2] || (_cache[2] = (0, vue.createElementVNode)("span", {
731
810
  class: "as-table-query-overlay-icon",
732
811
  "aria-hidden": "true"