@atscript/vue-table 0.1.132 → 0.1.134

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 (163) 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-C5qx9MPE.cjs → as-action-menu-content-C_D_Fepo.cjs} +1 -1
  4. package/dist/{as-action-menu-content-4UfcabUe.mjs → as-action-menu-content-rim8hAO9.mjs} +1 -1
  5. package/dist/{as-cell-array-2qmJ1lT2.mjs → as-cell-array-BWHkJX3I.mjs} +2 -2
  6. package/dist/{as-cell-array-iPeUnk2G.cjs → as-cell-array-D-8Pqlgo.cjs} +2 -2
  7. package/dist/as-cell-array.cjs +1 -1
  8. package/dist/as-cell-array.mjs +1 -1
  9. package/dist/{as-cell-date-DyixWKuS.cjs → as-cell-date-DviMJEqs.cjs} +2 -2
  10. package/dist/{as-cell-date-BwFgi6O0.mjs → as-cell-date-mGlnDeLP.mjs} +2 -2
  11. package/dist/as-cell-date.cjs +1 -1
  12. package/dist/as-cell-date.mjs +1 -1
  13. package/dist/{as-cell-json--95Xq6yq.mjs → as-cell-json-2I081xnO.mjs} +2 -2
  14. package/dist/{as-cell-json-Bvv2P7YV.cjs → as-cell-json-CaVB6e7V.cjs} +2 -2
  15. package/dist/as-cell-json.cjs +1 -1
  16. package/dist/as-cell-json.mjs +1 -1
  17. package/dist/{as-cell-number-DuPMOesI.cjs → as-cell-number-BnYbxOiG.cjs} +2 -2
  18. package/dist/{as-cell-number-DKRaS9pM.mjs → as-cell-number-CP2AZI9g.mjs} +2 -2
  19. package/dist/as-cell-number.cjs +1 -1
  20. package/dist/as-cell-number.mjs +1 -1
  21. package/dist/{as-cell-union-DJNsEKTi.cjs → as-cell-union-BjMP91PS.cjs} +3 -3
  22. package/dist/{as-cell-union-C9FukGqF.mjs → as-cell-union-NHpDCXty.mjs} +3 -3
  23. package/dist/as-cell-union.cjs +1 -1
  24. package/dist/as-cell-union.mjs +1 -1
  25. package/dist/as-column-menu.cjs +1 -1
  26. package/dist/as-column-menu.d.cts +1 -1
  27. package/dist/as-column-menu.d.mts +1 -1
  28. package/dist/as-column-menu.mjs +1 -1
  29. package/dist/{as-column-menu.vue-u_DNy3f-.d.cts → as-column-menu.vue-De7SRhj6.d.cts} +1 -1
  30. package/dist/{as-column-menu.vue-DL5N9mKR.d.mts → as-column-menu.vue-Dg0H1dOd.d.mts} +1 -1
  31. package/dist/{as-config-dialog-BehfqIGd.mjs → as-config-dialog-BUBHiVlf.mjs} +56 -35
  32. package/dist/{as-config-dialog-BOYWPYYH.cjs → as-config-dialog-DvBptYMS.cjs} +55 -34
  33. package/dist/as-config-dialog.cjs +1 -1
  34. package/dist/as-config-dialog.mjs +1 -1
  35. package/dist/{as-confirm-dialog-UwhDHysk.cjs → as-confirm-dialog-ByMfIG0A.cjs} +12 -9
  36. package/dist/{as-confirm-dialog-bpN4A-KN.mjs → as-confirm-dialog-G4ZoL_Xo.mjs} +12 -9
  37. package/dist/as-confirm-dialog.cjs +1 -1
  38. package/dist/as-confirm-dialog.mjs +1 -1
  39. package/dist/{as-filter-dialog-D1qzq-8b.mjs → as-filter-dialog-BJWH8cvc.mjs} +34 -26
  40. package/dist/{as-filter-dialog-Dh2Ylthb.cjs → as-filter-dialog-C2oyT0yt.cjs} +33 -25
  41. package/dist/as-filter-dialog.cjs +1 -1
  42. package/dist/as-filter-dialog.mjs +1 -1
  43. package/dist/{as-filter-field-DirBmnbb.mjs → as-filter-field-B2skq4K0.mjs} +4 -4
  44. package/dist/{as-filter-field-DRsDJdpx.cjs → as-filter-field-DxGfasQj.cjs} +4 -4
  45. package/dist/as-filter-field.cjs +1 -1
  46. package/dist/as-filter-field.mjs +1 -1
  47. package/dist/as-filter-input.cjs +1 -1
  48. package/dist/as-filter-input.mjs +1 -1
  49. package/dist/as-filters-Bhte22La.cjs +130 -0
  50. package/dist/as-filters-DogNVlqr.mjs +125 -0
  51. package/dist/as-filters.cjs +1 -1
  52. package/dist/as-filters.d.cts +1 -1
  53. package/dist/as-filters.d.mts +1 -1
  54. package/dist/as-filters.mjs +1 -1
  55. package/dist/as-filters.vue-BG_ysCkC.d.mts +65 -0
  56. package/dist/as-filters.vue-DcxDnWAU.d.cts +65 -0
  57. package/dist/{as-preset-dialog-CDqCAR7N.mjs → as-preset-dialog-BwHV6Y77.mjs} +71 -21
  58. package/dist/{as-preset-dialog-DpM06jqR.cjs → as-preset-dialog-D2a6nxEX.cjs} +75 -25
  59. package/dist/as-preset-dialog.cjs +1 -1
  60. package/dist/as-preset-dialog.mjs +1 -1
  61. package/dist/{as-preset-picker-CISaxEZ0.mjs → as-preset-picker-B0JnyAPA.mjs} +39 -15
  62. package/dist/{as-preset-picker-jUS_YDX8.cjs → as-preset-picker-DbkmapBx.cjs} +45 -21
  63. package/dist/as-preset-picker.cjs +1 -1
  64. package/dist/as-preset-picker.mjs +1 -1
  65. package/dist/{as-row-actions-xqJeAdQl.mjs → as-row-actions-BkIsJVBm.mjs} +24 -11
  66. package/dist/{as-row-actions-Bm6Bzyno.cjs → as-row-actions-CRg8LHGk.cjs} +24 -11
  67. package/dist/as-row-actions.cjs +1 -1
  68. package/dist/as-row-actions.d.cts +1 -1
  69. package/dist/as-row-actions.d.mts +1 -1
  70. package/dist/as-row-actions.mjs +1 -1
  71. package/dist/{as-row-actions.vue-Bvcc2tUN.d.cts → as-row-actions.vue-VpJsBAJ4.d.mts} +8 -0
  72. package/dist/{as-row-actions.vue-DUSDuoR2.d.mts → as-row-actions.vue-dn_DKcMm.d.cts} +8 -0
  73. package/dist/{as-table-CDSG2yED.mjs → as-table-BEvsX87E.mjs} +26 -8
  74. package/dist/{as-table-actions-DMxeaczm.mjs → as-table-actions-B5upF1bQ.mjs} +69 -18
  75. package/dist/{as-table-actions-gV4lqqxc.cjs → as-table-actions-B6sKd4sl.cjs} +68 -17
  76. package/dist/as-table-actions.cjs +1 -1
  77. package/dist/as-table-actions.d.cts +1 -1
  78. package/dist/as-table-actions.d.mts +1 -1
  79. package/dist/as-table-actions.mjs +1 -1
  80. package/dist/{as-table-actions.vue-B-cgiCXP.d.cts → as-table-actions.vue-CoxhpIlJ.d.mts} +2 -2
  81. package/dist/{as-table-actions.vue-ClMa0OD1.d.mts → as-table-actions.vue-Kic8m28V.d.cts} +2 -2
  82. package/dist/{as-table-base-BaTE3VSN.mjs → as-table-base-BxKBdIdS.mjs} +142 -47
  83. package/dist/{as-table-base-RG2TEIgV.cjs → as-table-base-DLuhKz69.cjs} +142 -47
  84. package/dist/{as-table-cell-value-D1JkTQt0.cjs → as-table-cell-value-BAi5yadc.cjs} +2 -2
  85. package/dist/{as-table-cell-value-CPcFxSOj.mjs → as-table-cell-value-BVcfhhCb.mjs} +2 -2
  86. package/dist/as-table-cell-value.cjs +1 -1
  87. package/dist/as-table-cell-value.mjs +1 -1
  88. package/dist/{as-table-header-cell-CIqlO6Lw.cjs → as-table-header-cell-Bv6q5iKA.cjs} +2 -2
  89. package/dist/{as-table-header-cell-Bdhl5Lox.mjs → as-table-header-cell-Xd3cvnII.mjs} +2 -2
  90. package/dist/as-table-header-cell.cjs +1 -1
  91. package/dist/as-table-header-cell.d.cts +1 -1
  92. package/dist/as-table-header-cell.d.mts +1 -1
  93. package/dist/as-table-header-cell.mjs +1 -1
  94. package/dist/{as-table-header-cell.vue-BCszzxtU.d.mts → as-table-header-cell.vue-AS6u4e6v.d.cts} +2 -2
  95. package/dist/{as-table-header-cell.vue-BzTzfGRo.d.cts → as-table-header-cell.vue-zKOmlzhT.d.mts} +2 -2
  96. package/dist/{as-table-root-BLReUbRH.mjs → as-table-root-C1A6JkwL.mjs} +112 -10
  97. package/dist/{as-table-root-DLJ_3Jf4.cjs → as-table-root-DlYjnZax.cjs} +112 -10
  98. package/dist/as-table-root.cjs +1 -1
  99. package/dist/as-table-root.d.cts +1 -1
  100. package/dist/as-table-root.d.mts +1 -1
  101. package/dist/as-table-root.mjs +1 -1
  102. package/dist/{as-table-root.vue-QMT93qPk.d.mts → as-table-root.vue-CWk9YgpG.d.mts} +257 -41
  103. package/dist/{as-table-root.vue-D0T3n-Vm.d.cts → as-table-root.vue-D94eypcL.d.cts} +258 -42
  104. package/dist/{as-table-status-Du4WLF4k.cjs → as-table-status-B2HPerJT.cjs} +54 -38
  105. package/dist/{as-table-status-DGTZlpyq.mjs → as-table-status-QzlBdSiR.mjs} +54 -38
  106. package/dist/{as-table-BWUPzjRn.cjs → as-table-vJbZyZVx.cjs} +26 -8
  107. package/dist/as-table.cjs +1 -1
  108. package/dist/as-table.d.cts +1 -1
  109. package/dist/as-table.d.mts +1 -1
  110. package/dist/as-table.mjs +1 -1
  111. package/dist/{as-table.vue-Ds7MEp37.d.cts → as-table.vue-BB1vaNL6.d.cts} +28 -4
  112. package/dist/{as-table.vue-Ce5606ZO.d.mts → as-table.vue-BUDFTCpo.d.mts} +28 -4
  113. package/dist/{as-window-table-DWujiUQy.mjs → as-window-table-BH0tDDnr.mjs} +107 -24
  114. package/dist/{as-window-table-jD_y9yet.cjs → as-window-table-Bl_q72WL.cjs} +107 -24
  115. package/dist/as-window-table.cjs +1 -1
  116. package/dist/as-window-table.d.cts +1 -1
  117. package/dist/as-window-table.d.mts +1 -1
  118. package/dist/as-window-table.mjs +1 -1
  119. package/dist/{as-window-table.vue-DfZF1Mux.d.mts → as-window-table.vue-Be2IA0Eb.d.cts} +27 -4
  120. package/dist/{as-window-table.vue-Bhf9BK8E.d.cts → as-window-table.vue-CLqFM2ff.d.mts} +27 -4
  121. package/dist/error-message-CfKpn_5w.cjs +18 -0
  122. package/dist/error-message-gNEXnnbb.mjs +13 -0
  123. package/dist/index.cjs +237 -41
  124. package/dist/index.d.cts +10 -10
  125. package/dist/index.d.mts +10 -10
  126. package/dist/index.mjs +230 -43
  127. package/dist/{types-ByU4O0Yf.d.mts → types--ex8BJIO.d.cts} +263 -5
  128. package/dist/{types-CTMxE_zA.d.cts → types-CBGaTR2Z.d.mts} +263 -5
  129. package/dist/{use-table-CyFcVtUN.mjs → use-table-BFhbfWgY.mjs} +48 -23
  130. package/dist/{use-table-component-K6xj1obF.mjs → use-table-component-CRmLHdqi.mjs} +1 -1
  131. package/dist/{use-table-component-DO_kvKSf.cjs → use-table-component-DS5NJPzs.cjs} +1 -1
  132. package/dist/{use-table-nav-bridge-uOQUDooh.cjs → use-table-nav-bridge-DS14D_rG.cjs} +1 -1
  133. package/dist/{use-table-nav-bridge-DeGeaQX-.mjs → use-table-nav-bridge-DzJN5v9a.mjs} +1 -1
  134. package/dist/{use-table-nvBq1dZ4.cjs → use-table-nvuZdgUd.cjs} +51 -20
  135. package/dist/{use-table-state-BxX3SpeW.mjs → use-table-state-mBXx11aH.mjs} +501 -105
  136. package/dist/{use-table-state-Oi2ds4_a.cjs → use-table-state-mhm-YWnu.cjs} +541 -109
  137. package/package.json +9 -9
  138. package/dist/as-filters-DCZTHjf5.cjs +0 -51
  139. package/dist/as-filters-beIud9sF.mjs +0 -46
  140. package/dist/as-filters.vue-DmECMd1v.d.mts +0 -10
  141. package/dist/as-filters.vue-fv-tRL2H.d.cts +0 -10
  142. package/dist/preset-aspect-display-IICxAlVo.mjs +0 -43
  143. package/dist/preset-aspect-display-TWwf6j1B.cjs +0 -72
  144. /package/dist/{as-cell-json-popover-Dkdv5Y9E.mjs → as-cell-json-popover-CH5bAcLE.mjs} +0 -0
  145. /package/dist/{as-cell-json-popover-BM2QLgfk.cjs → as-cell-json-popover-vty5vMjW.cjs} +0 -0
  146. /package/dist/{as-column-menu-kTIQfLTi.mjs → as-column-menu-BMTS3DO2.mjs} +0 -0
  147. /package/dist/{as-column-menu-fZVbJ9lU.cjs → as-column-menu-D_8NxujZ.cjs} +0 -0
  148. /package/dist/{as-filter-input-BM23TNeh.mjs → as-filter-input-C8KmOus8.mjs} +0 -0
  149. /package/dist/{as-filter-input-DJu2k9gO.cjs → as-filter-input-DUqpkTkg.cjs} +0 -0
  150. /package/dist/{format-cell-D1Ziv96Q.mjs → format-cell-Bx7wNc4X.mjs} +0 -0
  151. /package/dist/{format-cell-vCNTh4WZ.cjs → format-cell-DaxV6WIJ.cjs} +0 -0
  152. /package/dist/{get-cell-value-4rHKP-TG.cjs → get-cell-value-CJT4fk4y.cjs} +0 -0
  153. /package/dist/{get-cell-value-C8LLc_Rr.mjs → get-cell-value-Cb3X8nUn.mjs} +0 -0
  154. /package/dist/{use-cell-locale-MQXoONh5.mjs → use-cell-locale-CxQOQsns.mjs} +0 -0
  155. /package/dist/{use-cell-locale-BGBRQB7s.cjs → use-cell-locale-caG2Fzpc.cjs} +0 -0
  156. /package/dist/{use-has-emit-listener-hhOH8CBI.cjs → use-has-emit-listener-BaGFZDyM.cjs} +0 -0
  157. /package/dist/{use-has-emit-listener-BTMDIv2e.mjs → use-has-emit-listener-DrBbsLHQ.mjs} +0 -0
  158. /package/dist/{use-seed-on-open-Dg9I89fU.cjs → use-seed-on-open-9TSm1Vbv.cjs} +0 -0
  159. /package/dist/{use-seed-on-open-DO3A1kIb.mjs → use-seed-on-open-DSh4XFyp.mjs} +0 -0
  160. /package/dist/{use-table-column-handlers-ehreEzcx.cjs → use-table-column-handlers-BMrP0WY2.cjs} +0 -0
  161. /package/dist/{use-table-column-handlers-CpiiIniD.mjs → use-table-column-handlers-Bx3JERqs.mjs} +0 -0
  162. /package/dist/{use-table-selection-Cmiu1h4S.cjs → use-table-selection-DtCV3rhu.cjs} +0 -0
  163. /package/dist/{use-table-selection-C84z4OZy.mjs → use-table-selection-ULbKT2xW.mjs} +0 -0
@@ -1,8 +1,54 @@
1
+ import { Component, ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from "vue";
2
+ import { ClientError, PageResult, TDbActionInfo, TDbActionProcessor, TDbDeleteResult } from "@atscript/db-client";
3
+ import { Uniquery } from "@uniqu/core";
1
4
  import { ColumnDef, PaginationControl, SortControl, TableDef } from "@atscript/ui";
2
- import { Component, ComputedRef, Ref, ShallowRef } from "vue";
3
5
  import { AsPresetEntryRow, AspectMask, ColumnWidthsMap, ConfigTab, FieldFilters, PresetAspect, PresetCapabilities, PresetSnapshot, SelectionMode, SystemPreset, SystemPresetInput, TableStateMethods } from "@atscript/ui-table";
4
- import { ClientError, TDbActionInfo, TDbActionProcessor, TDbDeleteResult } from "@atscript/db-client";
5
6
 
7
+ //#region src/composables/state/intent-scope.d.ts
8
+ interface ActionBuckets {
9
+ default: TVueTableActionInfo | undefined;
10
+ others: TVueTableActionInfo[];
11
+ rows: TVueTableActionInfo[];
12
+ }
13
+ /**
14
+ * Build the identifier object to forward to `client.action` / `client.remove`.
15
+ *
16
+ * Per `@atscript/db-client` invariant #11, identifier bodies are object-only
17
+ * — never bare scalars, even for single-field PK tables. This helper accepts:
18
+ * - a row-shaped object (default `rowValueFn`) → picks `preferredId` fields;
19
+ * - a scalar value when `preferredId` has exactly one field (consumers that
20
+ * override `rowValueFn` to return the PK scalar) → wraps it.
21
+ *
22
+ * Returns `undefined` when no `preferredId` is declared, the source is
23
+ * `null`/`undefined`, or a scalar can't be paired with a single-field
24
+ * identifier.
25
+ */
26
+ declare function extractIdentifier(source: unknown, preferredId: readonly string[]): Record<string, unknown> | undefined;
27
+ //#endregion
28
+ //#region src/composables/state/row-actions-config.d.ts
29
+ /**
30
+ * A {@link RowActionsConfig} compiled into the two passes a surface runs per
31
+ * row. Built once per config change (not once per row per render), so the
32
+ * `include` / `exclude` sets and the override lookups exist once.
33
+ */
34
+ interface RowActionsPolicy {
35
+ /**
36
+ * Narrow + relabel already backend-gated buckets. Callers run
37
+ * `applyRowGate` FIRST — that order is the whole safety story: `include`
38
+ * can only narrow what the server allowed for the row, and `overrides`
39
+ * (presentation only) cannot resurrect an action the server gated away.
40
+ * Returns the input reference when the policy touches nothing.
41
+ */
42
+ apply: (buckets: ActionBuckets) => ActionBuckets;
43
+ /**
44
+ * The app-owned actions for `row`. `include` lists SERVER action names —
45
+ * being listed in `extra` IS an app action's opt-in — so only `exclude` and
46
+ * the action's own `enabled(row)` apply here. Pass no row to skip the
47
+ * per-row gate (a surface with no row in hand).
48
+ */
49
+ extra: (row?: Record<string, unknown>) => TVueTableActionInfo[];
50
+ }
51
+ //#endregion
6
52
  //#region src/types.d.ts
7
53
  /** UI-side sentinel for the synthesised row-delete processor. */
8
54
  declare const REMOVE_PROCESSOR = "__remove";
@@ -28,6 +74,52 @@ interface InvokeOpts {
28
74
  * actions without a form.
29
75
  */
30
76
  input?: unknown;
77
+ /**
78
+ * The row the action was triggered from. Only consumed by client-only row
79
+ * actions (`RowActionsConfig.extra`), whose `onInvoke(row, pk)` receives it.
80
+ * Since 0.1.134.
81
+ */
82
+ row?: Record<string, unknown>;
83
+ }
84
+ /**
85
+ * A row action the APP owns — it has no server counterpart, so the backend
86
+ * never gates it. Either `href` (rendered as a real anchor, mapped through
87
+ * `state.resolveHref`) or `onInvoke` (runs locally, then settles as an
88
+ * `@action` emit with `kind: 'custom'`). Since 0.1.134.
89
+ */
90
+ interface LocalRowAction {
91
+ /** Unique among the row actions; also the `@action` emit's `action.name`. */
92
+ name: string;
93
+ label: string;
94
+ icon?: string;
95
+ intent?: TDbActionInfo["intent"];
96
+ /** Confirmation copy — same `$1` / `$N` substitution as a server action. */
97
+ promptText?: string | [string, string];
98
+ /** Link target for the row. Rendered as an anchor, mapped through `state.resolveHref`. */
99
+ href?: (row: Record<string, unknown>) => string;
100
+ /** Local handler. Awaited; a rejection settles the action as an error result. */
101
+ onInvoke?: (row: Record<string, unknown>, pk?: Record<string, unknown>) => void | Promise<void>;
102
+ /** Per-row gate. Returning `false` hides the action for that row. */
103
+ enabled?: (row: Record<string, unknown>) => boolean;
104
+ }
105
+ /**
106
+ * Per-screen presentation policy for the row-actions cell. Narrows and
107
+ * relabels what the server declared, and appends app-owned actions.
108
+ *
109
+ * Backend eligibility stays authoritative: `include` / `exclude` can only
110
+ * narrow the set a row's `$actions` already allows, and `overrides` only
111
+ * change how an action looks — neither can surface an action the server
112
+ * gated away. Since 0.1.134.
113
+ */
114
+ interface RowActionsConfig {
115
+ /** Allowlist of server action names. Omitted = every eligible action. */
116
+ include?: string[];
117
+ /** Denylist of server action names, applied after `include`. */
118
+ exclude?: string[];
119
+ /** Presentation overrides keyed by server action name. */
120
+ overrides?: Record<string, Partial<Pick<TVueTableActionInfo, "label" | "icon" | "intent" | "promptText">>>;
121
+ /** App-owned actions appended after the server ones. */
122
+ extra?: LocalRowAction[];
31
123
  }
32
124
  /** Discriminated result returned by `state.actions.invoke`. Never throws. */
33
125
  type ActionResult = {
@@ -190,14 +282,62 @@ interface PresetConfig {
190
282
  * Add `'itemsPerPage'` for paginated tables; drop any aspect this app doesn't use.
191
283
  */
192
284
  aspects?: PresetAspect[];
285
+ /**
286
+ * Aspects a SYSTEM preset owns. Intersected with `aspects`; defaults to all
287
+ * of them. Narrow it to e.g. `['filterOps']` when system presets are
288
+ * filter-only views that must not reset the user's columns, displayed
289
+ * filters, sorters or page size. Since 0.1.133.
290
+ */
291
+ systemAspects?: PresetAspect[];
193
292
  /**
194
293
  * Opt-in localStorage overlay for the user's in-flight tweaks (default
195
294
  * `false`). Persists `columns` / `filters` / `sorters` / opt-in
196
295
  * `itemsPerPage`; `filterOps` / `searchTerm` / pagination are NOT persisted.
197
296
  */
198
297
  persistDrafts?: boolean;
298
+ /**
299
+ * Identity the draft is stored under — pass the signed-in user's id
300
+ * whenever `persistDrafts` is on, so a shared browser never restores the
301
+ * previous user's draft. Omitted keeps the pre-0.1.133 unscoped key.
302
+ * Since 0.1.133.
303
+ */
304
+ draftScope?: MaybeRefOrGetter<string | undefined>;
199
305
  }
200
306
  type QueryErrorKind = "initial" | "query" | "queryNext" | "loadRange";
307
+ /**
308
+ * Context handed to the per-row hooks of `<AsTable>` (`rowSelectable`,
309
+ * `rowClass`, `rowAttrs`). Since 0.1.133.
310
+ */
311
+ interface RowHookContext {
312
+ /** Position of the row in the rows the renderer is currently rendering. */
313
+ index: number;
314
+ /**
315
+ * Whether the row's pk is in `state.selectedRows` right now. A getter —
316
+ * reading it subscribes that hook call to the selection, so predicates
317
+ * that ignore it are not re-run when the selection changes.
318
+ */
319
+ readonly selected: boolean;
320
+ }
321
+ /**
322
+ * Per-row selectability predicate. Return `false` — or a string, which is
323
+ * surfaced as the disabled reason on the selection control — to make the row
324
+ * not selectable; `true` (or omitting the prop) keeps it selectable.
325
+ * Since 0.1.133.
326
+ */
327
+ type RowSelectableHook = (row: Record<string, unknown>, ctx: RowHookContext) => boolean | string | undefined | void;
328
+ /** Extra classes for the row element. Since 0.1.133. */
329
+ type RowClassHook = (row: Record<string, unknown>, ctx: RowHookContext) => string | string[] | Record<string, boolean> | undefined;
330
+ /**
331
+ * Extra attributes for the row element. The framework's own `id`, `role`,
332
+ * `aria-*`, `data-*`, `class` and `style` always win. Since 0.1.133.
333
+ */
334
+ type RowAttrsHook = (row: Record<string, unknown>, ctx: RowHookContext) => Record<string, unknown> | undefined;
335
+ /** Normalised {@link RowSelectableHook} verdict. */
336
+ interface RowSelectableVerdict {
337
+ ok: boolean;
338
+ /** Disabled reason, when the predicate returned a string. */
339
+ reason?: string;
340
+ }
201
341
  /** Controls which sections appear in the column header dropdown menu. */
202
342
  interface ColumnMenuConfig {
203
343
  sort?: boolean;
@@ -358,6 +498,13 @@ interface ReactiveTableState extends TableStateMethods {
358
498
  * remounting.
359
499
  */
360
500
  rowDelete: Ref<boolean | RowDeleteOpt>;
501
+ /**
502
+ * Per-screen row-action policy — writable ref owned by `<AsTableRoot>`,
503
+ * like {@link rowDelete}. `<AsRowActions>` reads it from the context, so a
504
+ * standalone `<AsRowActions>` inside the table honours it too (an explicit
505
+ * `:actions` prop on that component wins). Since 0.1.134.
506
+ */
507
+ rowActions: Ref<RowActionsConfig | undefined>;
361
508
  /**
362
509
  * `?$actions=true` opt-in — writable ref owned by the renderer.
363
510
  * `<AsTable>` / `<AsWindowTable>` flip this on whenever their
@@ -373,6 +520,31 @@ interface ReactiveTableState extends TableStateMethods {
373
520
  * naturally without consulting mode.
374
521
  */
375
522
  isPkSelected: (pk: unknown) => boolean;
523
+ /**
524
+ * Per-row selectability predicate — writable ref owned by the renderer,
525
+ * like {@link rowDelete}. `<AsTable>` / `<AsWindowTable>` push their
526
+ * `:row-selectable` prop into it, and every selection path in the model
527
+ * gates on it. Since 0.1.133.
528
+ */
529
+ rowSelectable: Ref<RowSelectableHook | undefined>;
530
+ /**
531
+ * Normalised `rowSelectable` verdict for one row. `index` is the row's
532
+ * position in what the renderer renders (absolute in window mode).
533
+ * Since 0.1.133.
534
+ */
535
+ isRowSelectable: (row: Record<string, unknown>, index: number) => RowSelectableVerdict;
536
+ /** The subset of `rows` the `rowSelectable` predicate lets through. Since 0.1.133. */
537
+ selectableRows: (rows: readonly Record<string, unknown>[]) => Record<string, unknown>[];
538
+ /** How many of `rows` the `rowSelectable` predicate lets through. Since 0.1.133. */
539
+ selectableCount: (rows: readonly Record<string, unknown>[]) => number;
540
+ /**
541
+ * Select every eligible row in `rows`. An ineligible row that is already
542
+ * selected stays selected. `indexOf` maps a position in `rows` to the
543
+ * index the `rowSelectable` predicate sees — windowed callers pass it
544
+ * because their rows come from a cache keyed by absolute index.
545
+ * Since 0.1.133.
546
+ */
547
+ selectAll: (rows: readonly Record<string, unknown>[], indexOf?: (position: number) => number) => void;
376
548
  /** Column currently open in the filter dialog (null when closed). */
377
549
  filterDialogColumn: Ref<ColumnDef | null>;
378
550
  /** Absolute index of the keyboard-active row. -1 = nothing active. */
@@ -398,7 +570,10 @@ interface ReactiveTableState extends TableStateMethods {
398
570
  setActive: (absIndex: number) => void;
399
571
  /** Reset the active-row index to `-1`. */
400
572
  clearActive: () => void;
401
- /** Toggle selection of the active row's PK in `selectedRows`. */
573
+ /**
574
+ * Toggle selection of the active row's PK in `selectedRows`. No-op in
575
+ * `select="none"` and on a row the `rowSelectable` predicate rejects.
576
+ */
402
577
  toggleActiveSelection: (mode: SelectionMode) => void;
403
578
  /** Ask the rendering component to emit `main-action` for the active row. */
404
579
  requestMainAction: (event: KeyboardEvent | MouseEvent) => void;
@@ -415,6 +590,12 @@ interface ReactiveTableState extends TableStateMethods {
415
590
  * consumers should not mutate directly.
416
591
  */
417
592
  confirmRequest: Ref<ConfirmRequest | null>;
593
+ /**
594
+ * The prompt request the dialog SURFACE renders: the last non-null
595
+ * `confirmRequest`, retained after it is answered so the copy survives the
596
+ * exit animation. Internal — used by the dialog. @since 0.1.133
597
+ */
598
+ confirmDisplay: Ref<ConfirmRequest | null>;
418
599
  /**
419
600
  * Open the in-app confirm dialog with `message` as the body. Resolves
420
601
  * `true` on accept, `false` on cancel/dismiss. Public — consumers can
@@ -431,12 +612,24 @@ interface ReactiveTableState extends TableStateMethods {
431
612
  acceptPrompt: () => void;
432
613
  /** Resolve the active prompt with `false`. Internal — used by the dialog. */
433
614
  dismissPrompt: () => void;
615
+ /**
616
+ * Clear `confirmDisplay` once the dialog surface has left (bound to the
617
+ * content's `after-leave`). A no-op while a prompt is pending. Internal.
618
+ * @since 0.1.133
619
+ */
620
+ releaseConfirm: () => void;
434
621
  /**
435
622
  * Currently pending action-form request — `null` when no form is open.
436
623
  * Writes are owned by `requestActionInput()` / `acceptActionForm()` /
437
624
  * `dismissActionForm()`; consumers should not mutate directly.
438
625
  */
439
626
  actionFormRequest: Ref<ActionFormRequest | null>;
627
+ /**
628
+ * The form request the dialog SURFACE renders: the last non-null
629
+ * `actionFormRequest`, retained after it is answered so the title, id chips
630
+ * and form survive the exit animation. Internal. @since 0.1.133
631
+ */
632
+ actionFormDisplay: Ref<ActionFormRequest | null>;
440
633
  /**
441
634
  * Open the action-form dialog. Resolves with the submitted form payload
442
635
  * on accept, or `null` on cancel/dismiss.
@@ -449,6 +642,12 @@ interface ReactiveTableState extends TableStateMethods {
449
642
  acceptActionForm: (input: unknown) => void;
450
643
  /** Resolve the active form request with `null`. Internal — used by the dialog. */
451
644
  dismissActionForm: () => void;
645
+ /**
646
+ * Clear `actionFormDisplay` (and the loaded schema/draft) once the dialog
647
+ * surface has left. A no-op while a request is pending. Internal.
648
+ * @since 0.1.133
649
+ */
650
+ releaseActionForm: () => void;
452
651
  /**
453
652
  * Hydrate state from a URL query string produced by `stateToUrlQueryString`.
454
653
  * Replaces filters / sorters / search / pagination with values decoded from
@@ -457,6 +656,43 @@ interface ReactiveTableState extends TableStateMethods {
457
656
  * watchers refetch in reaction to the writes.
458
657
  */
459
658
  applyUrlQuery: (urlString: string) => void;
659
+ /**
660
+ * Build the Uniquery the table's own fetch would send right now — same
661
+ * filters, sorters, search, force-filters and `$select` projection. Used by
662
+ * `useTableExport` so an export never drifts from what is on screen.
663
+ * Since 0.1.134.
664
+ */
665
+ buildQuery: (opts?: {
666
+ columnPaths?: string[];
667
+ includeActions?: boolean;
668
+ }) => Uniquery;
669
+ /**
670
+ * Run one page through the table's configured query function (or its
671
+ * client). The single fetch path — a custom `queryFn` is honoured here too.
672
+ * Since 0.1.134.
673
+ */
674
+ fetchPage: (query: Uniquery, page: number, size: number) => Promise<PageResult<Record<string, unknown>>>;
675
+ /**
676
+ * Paths of the client-owned (`local`) columns — the ones no server field
677
+ * backs, so they never enter `$select`, `$sort` or filters. Since 0.1.134.
678
+ */
679
+ localColumnPaths: ComputedRef<Set<string>>;
680
+ /**
681
+ * Re-order already-loaded rows so a sorter on a client-owned column takes
682
+ * effect: the page is sorted by the FULL sorter list, which leaves the
683
+ * server's own ordering intact and slots the local sorter in at its real
684
+ * priority. Page-local by definition — it can only order what is loaded —
685
+ * and a no-op (returns the input reference) without a local sorter, in
686
+ * window mode, or when the rows arrive pre-sorted. Since 0.1.134.
687
+ */
688
+ applyLocalSort: <T extends Record<string, unknown>>(rows: T[]) => T[];
689
+ /**
690
+ * The row-action policy from {@link rowActions}, compiled once per config
691
+ * change. Every surface that renders row actions reads it — the row-actions
692
+ * cell and the selection toolbar — so they cannot show different sets.
693
+ * Since 0.1.134.
694
+ */
695
+ rowActionsPolicy: ComputedRef<RowActionsPolicy>;
460
696
  /**
461
697
  * Preset feature surface. Always present; inert (`available=false`,
462
698
  * mutators throw) when `useTable({ preset })` was not configured.
@@ -487,9 +723,22 @@ interface PresetSurface {
487
723
  * `['columns', 'filters', 'filterOps', 'sorters']`.
488
724
  */
489
725
  availableAspects: PresetAspect[];
726
+ /**
727
+ * Aspects a SYSTEM preset owns — subset of `availableAspects`, equal to it
728
+ * unless `preset.systemAspects` narrowed it. Drives apply/reset, the dirty
729
+ * baseline, the picker/dialog badges and the Save-As defaults for system
730
+ * presets. Since 0.1.133.
731
+ */
732
+ systemAspects: PresetAspect[];
733
+ /**
734
+ * Aspects the preset `id` owns — the ones applying it writes. System →
735
+ * `systemAspects`, stored → what its snapshot claims, `null` (or an id
736
+ * with no row) → `availableAspects`. Since 0.1.133.
737
+ */
738
+ ownedAspects: (id: string | null) => PresetAspect[];
490
739
  /**
491
740
  * False when `preset` config is absent OR the initial load returned
492
- * 401/403 OR any other error. The picker / dialog should hide their UI.
741
+ * 401/403/404 OR any other error. The picker / dialog should hide their UI.
493
742
  */
494
743
  available: ComputedRef<boolean>;
495
744
  /** Currently active preset id (system `'sys:*'` or stored). null = no active. */
@@ -548,6 +797,15 @@ interface PresetSurface {
548
797
  * feature is off.
549
798
  */
550
799
  batch: <T>(fn: () => Promise<T>) => Promise<T>;
800
+ /**
801
+ * Error thrown by the most recent mutator, or null — the SINGLE channel
802
+ * for preset write failures. Cleared when an OUTERMOST mutator starts, so
803
+ * a `batch()` counts as one user action: a failure early in a batch is not
804
+ * wiped by a later write inside it, and the batch's last failure wins.
805
+ * Mutators rethrow as well, so a caller can handle a single call; this ref
806
+ * is for UI that only needs to render the failure. Since 0.1.133.
807
+ */
808
+ lastError: Ref<Error | null>;
551
809
  }
552
810
  //#endregion
553
- export { TableNavBridge as _, EnterAction as a, NavKeyOptions as c, ReactiveTableState as d, RowDeleteOpt as f, TableActionsState as g, TVueTableActionInfo as h, ConfirmOptions as i, PresetConfig as l, TAsTableControls as m, ColumnMenuConfig as n, InvokeOpts as o, TAsCellTypeComponents as p, ConfigTab as r, MainActionRequest as s, ActionResult as t, QueryErrorKind as u };
811
+ export { TableActionsState as C, TVueTableActionInfo as S, extractIdentifier as T, RowHookContext as _, EnterAction as a, TAsCellTypeComponents as b, MainActionRequest as c, QueryErrorKind as d, ReactiveTableState as f, RowDeleteOpt as g, RowClassHook as h, ConfirmOptions as i, NavKeyOptions as l, RowAttrsHook as m, ColumnMenuConfig as n, InvokeOpts as o, RowActionsConfig as p, ConfigTab as r, LocalRowAction as s, ActionResult as t, PresetConfig as u, RowSelectableHook as v, TableNavBridge as w, TAsTableControls as x, RowSelectableVerdict as y };