@bridge-ui/vue 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/ai/skills/bridge-ui-components/SKILL.md +3 -1
  2. package/dist/Components/Autocomplete/composables/useAutocomplete.d.ts +1 -1
  3. package/dist/Components/ColorField/composables/useColorField.d.ts +2 -1
  4. package/dist/Components/DataTable/DataTable.js +5 -0
  5. package/dist/Components/DataTable/DataTable.vue.d.ts +43 -0
  6. package/dist/Components/DataTable/DataTable.vue_vue_type_script_setup_true_lang.js +382 -0
  7. package/dist/Components/DataTable/DataTableCellContent.js +5 -0
  8. package/dist/Components/DataTable/DataTableCellContent.vue.d.ts +23 -0
  9. package/dist/Components/DataTable/DataTableCellContent.vue_vue_type_script_setup_true_lang.js +38 -0
  10. package/dist/Components/DataTable/DataTableColumnsMenu.js +5 -0
  11. package/dist/Components/DataTable/DataTableColumnsMenu.vue.d.ts +11 -0
  12. package/dist/Components/DataTable/DataTableColumnsMenu.vue_vue_type_script_setup_true_lang.js +47 -0
  13. package/dist/Components/DataTable/DataTableFilterMenu.js +5 -0
  14. package/dist/Components/DataTable/DataTableFilterMenu.vue.d.ts +17 -0
  15. package/dist/Components/DataTable/DataTableFilterMenu.vue_vue_type_script_setup_true_lang.js +132 -0
  16. package/dist/Components/DataTable/DataTableFilterOptions.js +5 -0
  17. package/dist/Components/DataTable/DataTableFilterOptions.vue.d.ts +14 -0
  18. package/dist/Components/DataTable/DataTableFilterOptions.vue_vue_type_script_setup_true_lang.js +73 -0
  19. package/dist/Components/DataTable/DataTableSearch.js +5 -0
  20. package/dist/Components/DataTable/DataTableSearch.vue.d.ts +12 -0
  21. package/dist/Components/DataTable/DataTableSearch.vue_vue_type_script_setup_true_lang.js +39 -0
  22. package/dist/Components/DataTable/DataTableSelection.js +5 -0
  23. package/dist/Components/DataTable/DataTableSelection.vue.d.ts +20 -0
  24. package/dist/Components/DataTable/DataTableSelection.vue_vue_type_script_setup_true_lang.js +55 -0
  25. package/dist/Components/DataTable/DataTableSortButton.js +5 -0
  26. package/dist/Components/DataTable/DataTableSortButton.vue.d.ts +17 -0
  27. package/dist/Components/DataTable/DataTableSortButton.vue_vue_type_script_setup_true_lang.js +43 -0
  28. package/dist/Components/DataTable/DataTableToolbarButton.js +5 -0
  29. package/dist/Components/DataTable/DataTableToolbarButton.vue.d.ts +13 -0
  30. package/dist/Components/DataTable/DataTableToolbarButton.vue_vue_type_script_setup_true_lang.js +31 -0
  31. package/dist/Components/DataTable/composables/useDataTable.d.ts +557 -0
  32. package/dist/Components/DataTable/composables/useDataTable.js +479 -0
  33. package/dist/Components/DataTable/dataTable.types.d.ts +480 -0
  34. package/dist/Components/DataTable/index.d.ts +3 -0
  35. package/dist/Components/DataTable/index.js +3 -0
  36. package/dist/Components/DateField/composables/useDateField.d.ts +2 -1
  37. package/dist/Components/DateRangeField/composables/useDateRangeField.d.ts +2 -1
  38. package/dist/Components/DateTimeField/composables/useDateTimeField.d.ts +2 -1
  39. package/dist/Components/DateTimeRangeField/composables/useDateTimeRangeField.d.ts +2 -1
  40. package/dist/Components/FormField/composables/useFormField.d.ts +1 -1
  41. package/dist/Components/Menu/Menu.vue_vue_type_script_setup_true_lang.js +1 -0
  42. package/dist/Components/Menu/composables/useMenu.d.ts +1 -1
  43. package/dist/Components/Menu/composables/useMenu.js +7 -3
  44. package/dist/Components/Menu/menu.types.d.ts +6 -0
  45. package/dist/Components/NumberField/composables/useNumberField.d.ts +1 -1
  46. package/dist/Components/PasswordField/composables/usePasswordField.d.ts +1 -1
  47. package/dist/Components/Radio/Radio.vue_vue_type_script_setup_true_lang.js +9 -9
  48. package/dist/Components/Radio/composables/useRadio.js +57 -54
  49. package/dist/Components/Select/composables/useSelect.d.ts +1 -1
  50. package/dist/Components/Slider/composables/useSlider.d.ts +2 -2
  51. package/dist/Components/Snackbar/composables/useSnackbar.d.ts +1 -1
  52. package/dist/Components/Table/Table.js +5 -0
  53. package/dist/Components/Table/Table.vue.d.ts +16 -0
  54. package/dist/Components/Table/Table.vue_vue_type_script_setup_true_lang.js +44 -0
  55. package/dist/Components/Table/TableBody.js +5 -0
  56. package/dist/Components/Table/TableBody.vue.d.ts +11 -0
  57. package/dist/Components/Table/TableBody.vue_vue_type_script_setup_true_lang.js +17 -0
  58. package/dist/Components/Table/TableCaption.js +5 -0
  59. package/dist/Components/Table/TableCaption.vue.d.ts +11 -0
  60. package/dist/Components/Table/TableCaption.vue_vue_type_script_setup_true_lang.js +17 -0
  61. package/dist/Components/Table/TableCell.js +5 -0
  62. package/dist/Components/Table/TableCell.vue.d.ts +11 -0
  63. package/dist/Components/Table/TableCell.vue_vue_type_script_setup_true_lang.js +19 -0
  64. package/dist/Components/Table/TableFooter.js +5 -0
  65. package/dist/Components/Table/TableFooter.vue.d.ts +11 -0
  66. package/dist/Components/Table/TableFooter.vue_vue_type_script_setup_true_lang.js +17 -0
  67. package/dist/Components/Table/TableHead.js +5 -0
  68. package/dist/Components/Table/TableHead.vue.d.ts +11 -0
  69. package/dist/Components/Table/TableHead.vue_vue_type_script_setup_true_lang.js +19 -0
  70. package/dist/Components/Table/TableHeader.js +5 -0
  71. package/dist/Components/Table/TableHeader.vue.d.ts +11 -0
  72. package/dist/Components/Table/TableHeader.vue_vue_type_script_setup_true_lang.js +17 -0
  73. package/dist/Components/Table/TableRow.js +5 -0
  74. package/dist/Components/Table/TableRow.vue.d.ts +11 -0
  75. package/dist/Components/Table/TableRow.vue_vue_type_script_setup_true_lang.js +17 -0
  76. package/dist/Components/Table/composables/useTable.d.ts +16 -0
  77. package/dist/Components/Table/composables/useTable.js +88 -0
  78. package/dist/Components/Table/composables/useTableCell.d.ts +12 -0
  79. package/dist/Components/Table/composables/useTableCell.js +40 -0
  80. package/dist/Components/Table/composables/useTablePart.d.ts +12 -0
  81. package/dist/Components/Table/composables/useTablePart.js +32 -0
  82. package/dist/Components/Table/composables/useTableRow.d.ts +6 -0
  83. package/dist/Components/Table/composables/useTableRow.js +29 -0
  84. package/dist/Components/Table/index.d.ts +14 -0
  85. package/dist/Components/Table/index.js +14 -0
  86. package/dist/Components/Table/table.types.d.ts +416 -0
  87. package/dist/Components/Table/tableInjectionKey.d.ts +114 -0
  88. package/dist/Components/Table/tableInjectionKey.js +4 -0
  89. package/dist/Components/TextField/composables/useTextField.d.ts +1 -1
  90. package/dist/Components/Textarea/composables/useTextarea.d.ts +1 -1
  91. package/dist/Components/TimeField/composables/useTimeField.d.ts +2 -1
  92. package/dist/Components/TimeRangeField/composables/useTimeRangeField.d.ts +2 -1
  93. package/docs/README.md +2 -0
  94. package/docs/components/CalendarDate.md +1 -1
  95. package/docs/components/DataTable.md +345 -0
  96. package/docs/components/DateField.md +2 -2
  97. package/docs/components/DatePicker.md +3 -3
  98. package/docs/components/DateRangePicker.md +1 -1
  99. package/docs/components/Pagination.md +2 -2
  100. package/docs/components/Table.md +122 -0
  101. package/docs/examples/i18n-dictionary.ts +4 -0
  102. package/docs/examples/icon-fontawesome.ts +8 -0
  103. package/docs/examples/icon-heroicons.ts +8 -0
  104. package/docs/examples/icon-lucide.ts +8 -0
  105. package/docs/examples/icon-phosphor.ts +8 -0
  106. package/docs/examples/icon-tabler.ts +8 -0
  107. package/package.json +9 -2
@@ -0,0 +1,114 @@
1
+ import { ComputedRef, InjectionKey } from 'vue';
2
+ import { TableAlign } from '@bridge-ui/core/Tokens';
3
+ /**
4
+ * Table section for row hover / stripe and sticky header cells.
5
+ */
6
+ export type TableSection = "body" | "footer" | "header";
7
+ /**
8
+ * Merged token classes for table parts.
9
+ */
10
+ export type TableTokenClasses = {
11
+ /**
12
+ * Merged align class maps for cells and header cells.
13
+ */
14
+ align: TableAlign;
15
+ /**
16
+ * Footer corner radius classes.
17
+ */
18
+ roundedFooter?: string;
19
+ /**
20
+ * Header corner radius classes.
21
+ */
22
+ roundedHeader?: string;
23
+ /**
24
+ * Caption size classes.
25
+ */
26
+ sizeCaption?: string;
27
+ /**
28
+ * Body cell size classes.
29
+ */
30
+ sizeCell?: string;
31
+ /**
32
+ * Header cell size classes.
33
+ */
34
+ sizeHead?: string;
35
+ /**
36
+ * Body variant classes.
37
+ */
38
+ variantBody?: string;
39
+ /**
40
+ * Caption variant classes.
41
+ */
42
+ variantCaption?: string;
43
+ /**
44
+ * Body cell variant classes.
45
+ */
46
+ variantCell?: string;
47
+ /**
48
+ * Footer variant classes.
49
+ */
50
+ variantFooter?: string;
51
+ /**
52
+ * Header cell variant classes.
53
+ */
54
+ variantHead?: string;
55
+ /**
56
+ * Header variant classes.
57
+ */
58
+ variantHeader?: string;
59
+ /**
60
+ * Sticky header cell variant classes.
61
+ */
62
+ variantHeadSticky?: string;
63
+ /**
64
+ * Row variant classes.
65
+ */
66
+ variantRow?: string;
67
+ /**
68
+ * Hoverable body row variant classes.
69
+ */
70
+ variantRowHover?: string;
71
+ /**
72
+ * Striped body row variant classes.
73
+ */
74
+ variantRowStriped?: string;
75
+ };
76
+ /**
77
+ * Shared table chrome for `Table*` descendants.
78
+ */
79
+ export type TableContextValue = {
80
+ /**
81
+ * Whether the table is full width.
82
+ */
83
+ full: boolean;
84
+ /**
85
+ * Whether body rows show hover styles.
86
+ */
87
+ hoverable: boolean;
88
+ /**
89
+ * Registry / instance classes for parts.
90
+ */
91
+ mergedClasses: {
92
+ body?: string;
93
+ caption?: string;
94
+ cell?: string;
95
+ footer?: string;
96
+ head?: string;
97
+ header?: string;
98
+ row?: string;
99
+ };
100
+ /**
101
+ * Whether header cells stick to the nearest scrollport (usually the page).
102
+ */
103
+ stickyHeader: boolean;
104
+ /**
105
+ * Whether body rows alternate surfaces.
106
+ */
107
+ striped: boolean;
108
+ /**
109
+ * Merged token classes for parts.
110
+ */
111
+ tokenClasses: TableTokenClasses;
112
+ };
113
+ export declare const TABLE_INJECTION_KEY: InjectionKey<ComputedRef<TableContextValue>>;
114
+ export declare const TABLE_SECTION_INJECTION_KEY: InjectionKey<ComputedRef<TableSection>>;
@@ -0,0 +1,4 @@
1
+ //#region src/Components/Table/tableInjectionKey.ts
2
+ var e = Symbol("bridge-table"), t = Symbol("bridge-table-section");
3
+ //#endregion
4
+ export { e as TABLE_INJECTION_KEY, t as TABLE_SECTION_INJECTION_KEY };
@@ -170,7 +170,7 @@ export declare function useTextField(props: TextFieldOwnProps): {
170
170
  dir?: string | undefined | undefined;
171
171
  draggable?: (boolean | "true" | "false") | undefined;
172
172
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
173
- enterKeyHint?: "done" | "search" | "enter" | "go" | "next" | "previous" | "send" | undefined;
173
+ enterKeyHint?: "search" | "done" | "enter" | "go" | "next" | "previous" | "send" | undefined;
174
174
  hidden?: "" | "until-found" | "hidden" | (boolean | "true" | "false") | undefined;
175
175
  inert?: (boolean | "true" | "false") | undefined;
176
176
  placeholder?: string | undefined | undefined;
@@ -171,7 +171,7 @@ export declare function useTextarea(props: TextareaOwnProps, textareaRef: Ref<nu
171
171
  dir?: string | undefined | undefined;
172
172
  draggable?: (boolean | "true" | "false") | undefined;
173
173
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
174
- enterKeyHint?: "done" | "search" | "enter" | "go" | "next" | "previous" | "send" | undefined;
174
+ enterKeyHint?: "search" | "done" | "enter" | "go" | "next" | "previous" | "send" | undefined;
175
175
  hidden?: "" | "until-found" | "hidden" | (boolean | "true" | "false") | undefined;
176
176
  inert?: (boolean | "true" | "false") | undefined;
177
177
  placeholder?: string | undefined | undefined;
@@ -181,7 +181,7 @@ export declare function useTimeField(props: TimeFieldOwnProps, model: Ref<null |
181
181
  dir?: string | undefined | undefined;
182
182
  draggable?: (boolean | "true" | "false") | undefined;
183
183
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
184
- enterKeyHint?: "done" | "search" | "enter" | "go" | "next" | "previous" | "send" | undefined;
184
+ enterKeyHint?: "search" | "done" | "enter" | "go" | "next" | "previous" | "send" | undefined;
185
185
  hidden?: "" | "until-found" | "hidden" | (boolean | "true" | "false") | undefined;
186
186
  inert?: (boolean | "true" | "false") | undefined;
187
187
  placeholder?: string | undefined | undefined;
@@ -730,6 +730,7 @@ export declare function useTimeField(props: TimeFieldOwnProps, model: Ref<null |
730
730
  disableAutoFocus?: boolean;
731
731
  disableScrollLock?: boolean;
732
732
  keepMounted?: boolean;
733
+ matchWidth?: boolean;
733
734
  offset?: number;
734
735
  onShowChange?: (show: boolean) => void;
735
736
  persistent?: boolean;
@@ -181,7 +181,7 @@ export declare function useTimeRangeField(props: TimeRangeFieldOwnProps, model:
181
181
  dir?: string | undefined | undefined;
182
182
  draggable?: (boolean | "true" | "false") | undefined;
183
183
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
184
- enterKeyHint?: "done" | "search" | "enter" | "go" | "next" | "previous" | "send" | undefined;
184
+ enterKeyHint?: "search" | "done" | "enter" | "go" | "next" | "previous" | "send" | undefined;
185
185
  hidden?: "" | "until-found" | "hidden" | (boolean | "true" | "false") | undefined;
186
186
  inert?: (boolean | "true" | "false") | undefined;
187
187
  placeholder?: string | undefined | undefined;
@@ -722,6 +722,7 @@ export declare function useTimeRangeField(props: TimeRangeFieldOwnProps, model:
722
722
  disableAutoFocus?: boolean;
723
723
  disableScrollLock?: boolean;
724
724
  keepMounted?: boolean;
725
+ matchWidth?: boolean;
725
726
  offset?: number;
726
727
  onShowChange?: (show: boolean) => void;
727
728
  persistent?: boolean;
package/docs/README.md CHANGED
@@ -22,6 +22,7 @@ Component reference and adapter samples for **Vue**. This folder ships with the
22
22
  - [Checkbox](./components/Checkbox.md)
23
23
  - [ColorField](./components/ColorField.md)
24
24
  - [ColorPicker](./components/ColorPicker.md)
25
+ - [DataTable](./components/DataTable.md)
25
26
  - [DateField](./components/DateField.md)
26
27
  - [DatePicker](./components/DatePicker.md)
27
28
  - [DateRangeField](./components/DateRangeField.md)
@@ -54,6 +55,7 @@ Component reference and adapter samples for **Vue**. This folder ships with the
54
55
  - [Spinner](./components/Spinner.md)
55
56
  - [Stepper](./components/Stepper.md)
56
57
  - [Switch](./components/Switch.md)
58
+ - [Table](./components/Table.md)
57
59
  - [Tabs](./components/Tabs.md)
58
60
  - [Textarea](./components/Textarea.md)
59
61
  - [TextField](./components/TextField.md)
@@ -19,7 +19,7 @@ import { CalendarDate } from "@bridge-ui/vue/Components/CalendarDate";
19
19
  range
20
20
  v-model="range"
21
21
  :view-date="month"
22
- @view-date-change="month = $event"
22
+ v-on:view-date-change="month = $event"
23
23
  />
24
24
  ```
25
25
 
@@ -0,0 +1,345 @@
1
+ # DataTable
2
+
3
+ Opinionated data grid: columns, rows, sorting, selection, empty/loading, and pagination wiring. DataTable composes `Table` (`<table>` / `thead` / `tbody`) for layout, sticky header, and column alignment. `size`, `variant`, `full`, `striped`, `hoverable`, and `rounded` are forwarded to `Table`. Chrome tokens (`size`, `variant`, `rounded`, column `align`) live on `Table`. Apps own the fetch; Bridge owns interaction and chrome.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { DataTable } from "@bridge-ui/vue/Components/DataTable";
9
+ ```
10
+
11
+ ## Examples
12
+
13
+ ### Usage
14
+
15
+ ```vue
16
+ <DataTable
17
+ :rows="users"
18
+ v-model:sorting="sorting"
19
+ :get-row-id="(row) => row.id"
20
+ :columns="[
21
+ { id: 'name', header: 'Name', cell: (row) => row.name },
22
+ { id: 'role', header: 'Role', cell: (row) => row.role, sortable: true },
23
+ ]"
24
+ />
25
+ ```
26
+
27
+ ### Variants
28
+
29
+ DataTable chrome (`plain` / `ghost` / `bordered`). Built-in `Pagination` follows the matching variant unless the `pagination` slot overrides it:
30
+
31
+ ```vue
32
+ <DataTable :rows="users" variant="plain" :columns="columns" />
33
+ <DataTable :rows="users" variant="ghost" :columns="columns" />
34
+ <DataTable :rows="users" variant="bordered" :columns="columns" />
35
+ ```
36
+
37
+ | DataTable `variant` | Pagination `variant` |
38
+ | ------------------- | -------------------- |
39
+ | `plain` | `text` |
40
+ | `ghost` | `ghost` |
41
+ | `bordered` | `outlined` |
42
+
43
+ `striped` is independent of variant:
44
+
45
+ ```vue
46
+ <DataTable striped :rows="users" :columns="columns" />
47
+ ```
48
+
49
+ `:full="false"` sizes columns to content instead of stretching the table:
50
+
51
+ ```vue
52
+ <DataTable :full="false" :rows="users" :columns="columns" />
53
+ ```
54
+
55
+ `sticky-header` pins header cells to the page. `"boxed"` pins them inside the wrapper — set a max height on `classes.wrapper` or `classes.root`:
56
+
57
+ ```vue
58
+ <DataTable sticky-header :rows="users" :columns="columns" />
59
+ <DataTable
60
+ :rows="users"
61
+ :columns="columns"
62
+ sticky-header="boxed"
63
+ :classes="{ wrapper: 'max-h-96' }"
64
+ />
65
+ ```
66
+
67
+ ### Selection + pagination
68
+
69
+ Built-in Pagination when `page` is set with `page-count` or `total-count` (server fetch stays in the app). `page` + `per-page` without those totals slices `rows` locally. `per-page` also renders a Select (`per-page-options`, default 10 / 25 / 50 / 100). `#pagination` and `#perPage` replace each control:
70
+
71
+ ```vue
72
+ <DataTable
73
+ :rows="users"
74
+ :columns="columns"
75
+ v-model:page="page"
76
+ :page-count="pageCount"
77
+ v-model:selection="selected"
78
+ :get-row-id="(row) => row.id"
79
+ />
80
+ ```
81
+
82
+ Client paging slices `rows`. Server paging with a total uses `total-count` instead of `page-count`:
83
+
84
+ ```vue
85
+ <DataTable
86
+ :rows="users"
87
+ :columns="columns"
88
+ v-model:page="page"
89
+ v-model:per-page="perPage"
90
+ />
91
+
92
+ <DataTable
93
+ :rows="pageRows"
94
+ :columns="columns"
95
+ v-model:page="page"
96
+ :total-count="total"
97
+ v-model:per-page="perPage"
98
+ />
99
+ ```
100
+
101
+ Slot replaces the built-in Pagination and/or per-page Select (`#pagination` / `#perPage`; slot props match the built-ins):
102
+
103
+ ```vue
104
+ <DataTable :rows="users" :columns="columns" :get-row-id="(row) => row.id">
105
+ <template #pagination>
106
+ <Pagination
107
+ mode="simple"
108
+ :has-next="Boolean(nextCursor)"
109
+ v-on:next="fetchPage(nextCursor)"
110
+ :has-previous="Boolean(prevCursor)"
111
+ v-on:previous="fetchPage(prevCursor)"
112
+ />
113
+ </template>
114
+
115
+ <template #per-page="{ perPage, options, onPerPageChange }">
116
+ <select
117
+ :value="perPage"
118
+ aria-label="Rows per page"
119
+ v-on:change="onPerPageChange(Number($event.target.value))"
120
+ >
121
+ <option v-for="value in options" :key="value" :value="value">
122
+ {{ value }}
123
+ </option>
124
+ </select>
125
+ </template>
126
+ </DataTable>
127
+ ```
128
+
129
+ Align the built-in Pagination with `pagination-align` (`start` / `center` / `end`, default `end`):
130
+
131
+ ```vue
132
+ <DataTable
133
+ :rows="users"
134
+ :columns="columns"
135
+ v-model:page="page"
136
+ :page-count="pageCount"
137
+ pagination-align="start"
138
+ />
139
+ ```
140
+
141
+ When `page` and `page-count` (or `total-count`) are set, DataTable does not sort or filter `rows` locally — bind `sorting` / `filters` / `page` / `per-page` and fetch the current page in the app:
142
+
143
+ ```vue
144
+ <DataTable
145
+ :rows="pageRows"
146
+ :columns="columns"
147
+ v-model:page="page"
148
+ :page-count="pageCount"
149
+ v-model:filters="filters"
150
+ v-model:sorting="sorting"
151
+ />
152
+ ```
153
+
154
+ ### Empty, loading, and footer
155
+
156
+ Empty rows show a default empty state; `#empty` replaces it. `loading` keeps the table visible. `loadingVariant="overlay"` (default) dims the table with a spin; `loadingVariant="bar"` dims the table and draws a progress line under the header. `#loading` replaces the indicator. `#footer` renders below the table, above pagination:
157
+
158
+ ```vue
159
+ <DataTable :rows="[]" :columns="columns" :loading="isLoading">
160
+ <template #empty>No users</template>
161
+ <template #footer>Here is footer</template>
162
+ </DataTable>
163
+ ```
164
+
165
+ ```vue
166
+ <DataTable
167
+ :rows="users"
168
+ :columns="columns"
169
+ :loading="isLoading"
170
+ loading-variant="bar"
171
+ />
172
+ ```
173
+
174
+ Install `@tanstack/vue-table` next to `@bridge-ui/vue` when you use `DataTable`. The public API stays `columns` / `rows` / `sorting` / `selection` / `filters` / `columnSearch` / `hiddenColumns` / `search` / `expanded` — the table engine is not exported.
175
+
176
+ ### Columns
177
+
178
+ Cell content is the column accessor (`row[id]`, or `accessor`) unless you override it. `cell` on the column is for portable renderers (`h(…)` or JSX). `#item.{id}` wins over `cell` and stays in the template:
179
+
180
+ ```vue
181
+ <DataTable :rows="users" :columns="columns">
182
+ <template #item.role="{ row }">
183
+ <Badge>{{ row.role }}</Badge>
184
+ </template>
185
+ </DataTable>
186
+ ```
187
+
188
+ ```ts
189
+ const columns = [
190
+ { id: "name", header: "Name" },
191
+ { id: "role", header: "Role" },
192
+ ];
193
+ ```
194
+
195
+ Table-level slots stay `empty` / `expanded` / `footer` / `item.{id}` / `item` / `loading` / `pagination` / `perPage` / `search` / `toolbar` / `toolbarActions`. `#item` is a catch-all when `#item.{id}` is not set.
196
+
197
+ ### Selection
198
+
199
+ `selectionMode="multiple"` (default) uses checkboxes and select-all. `selectionMode="single"` uses radios and keeps at most one id. `v-model:selection` is always `string[]`.
200
+
201
+ ```vue
202
+ <DataTable
203
+ :rows="users"
204
+ :columns="columns"
205
+ selection-mode="single"
206
+ v-model:selection="selected"
207
+ :get-row-id="(row) => row.id"
208
+ />
209
+ ```
210
+
211
+ ### Filters
212
+
213
+ Set `filters` on a column to show a funnel in that header. The panel uses checkboxes (`filterMultiple`, default) or radios (`:filter-multiple="false"`), and **Select all items** for multiple filters. Nested `children` render as a group in the same panel. **OK** commits; **Reset** clears the draft (commit on **OK**); closing without **OK** discards it.
214
+
215
+ Set `searchable` on a column to add a text field in that same menu. Queries are stored in `columnSearch` (column id → string), not used to filter the option list.
216
+
217
+ ```vue
218
+ <DataTable
219
+ :rows="users"
220
+ :columns="columns"
221
+ v-model:filters="filters"
222
+ v-model:column-search="columnSearch"
223
+ />
224
+ ```
225
+
226
+ ```ts
227
+ const columns = [
228
+ {
229
+ id: "name",
230
+ header: "Name",
231
+ searchable: true,
232
+ cell: (row) => row.name,
233
+ },
234
+ {
235
+ id: "role",
236
+ header: "Role",
237
+ cell: (row) => row.role,
238
+ filters: [
239
+ { label: "Engineer", value: "Engineer" },
240
+ { label: "Researcher", value: "Researcher" },
241
+ ],
242
+ },
243
+ ];
244
+ ```
245
+
246
+ Client-side filtering applies when the table is not server-paged (`page` + `pageCount`). With server paging, `filters` and `columnSearch` are still controlled — the app owns the fetch.
247
+
248
+ ### Sticky columns
249
+
250
+ `sticky="start"` or `sticky="end"` pins a column while the table scrolls horizontally. Selection and expand chrome pin to start when any data column uses `sticky="start"`.
251
+
252
+ ```ts
253
+ const columns = [
254
+ {
255
+ id: "name",
256
+ width: 160,
257
+ header: "Name",
258
+ sticky: "start",
259
+ cell: (row) => row.name,
260
+ },
261
+ { id: "role", header: "Role", cell: (row) => row.role },
262
+ {
263
+ id: "actions",
264
+ header: "Actions",
265
+ sticky: "end",
266
+ cell: (row) => row.id,
267
+ },
268
+ ];
269
+ ```
270
+
271
+ ### Ellipsis
272
+
273
+ `ellipsis` truncates overflowing cell text. The tooltip uses the column accessor (or `row[id]`).
274
+
275
+ ```ts
276
+ const columns = [
277
+ {
278
+ id: "name",
279
+ header: "Name",
280
+ ellipsis: true,
281
+ cell: (row) => row.name,
282
+ },
283
+ ];
284
+ ```
285
+
286
+ ### Column visibility
287
+
288
+ Pass `hiddenColumns` and/or listen to `update:hiddenColumns` to show a **Columns** icon in the toolbar. `hideable: false` keeps a column out of the toggle (or disabled). At least one column stays visible.
289
+
290
+ ```vue
291
+ <DataTable :rows="users" :columns="columns" v-model:hidden-columns="hidden" />
292
+ ```
293
+
294
+ ### Search
295
+
296
+ Pass `search` and/or listen to `update:search` to show a search field in the toolbar. Client-side tables filter visible columns; server-paged tables emit the query only.
297
+
298
+ ```vue
299
+ <DataTable :rows="users" :columns="columns" v-model:search="search" />
300
+ ```
301
+
302
+ ### Toolbar
303
+
304
+ `#toolbar` is the leading region (left). `#toolbar-actions` sits in the end cluster beside Columns and Search. The toolbar shows when either slot is set, or when Columns / Search are enabled.
305
+
306
+ ```vue
307
+ <DataTable :rows="users" :columns="columns" v-model:search="search">
308
+ <template #toolbar-actions>
309
+ <Button v-on:click="onPrint">Print</Button>
310
+ </template>
311
+ </DataTable>
312
+ ```
313
+
314
+ ### Expand
315
+
316
+ Controlled `expanded` row ids. `#expanded="{ row }"` renders in a spanning row under the data row.
317
+
318
+ ```vue
319
+ <DataTable
320
+ :rows="users"
321
+ :columns="columns"
322
+ v-model:expanded="expanded"
323
+ :get-row-id="(row) => row.id"
324
+ >
325
+ <template #expanded="{ row }">
326
+ {{ row.bio }}
327
+ </template>
328
+ </DataTable>
329
+ ```
330
+
331
+ ### Summary
332
+
333
+ Set `summary` on a column to render a footer row over the current (filtered) rows. Chrome cells stay empty.
334
+
335
+ ```ts
336
+ const columns = [
337
+ { id: "name", header: "Name", cell: (row) => row.name },
338
+ {
339
+ id: "role",
340
+ header: "Role",
341
+ cell: (row) => row.role,
342
+ summary: (items) => `${items.length} roles`,
343
+ },
344
+ ];
345
+ ```
@@ -64,8 +64,8 @@ Replaces Cancel / Apply on the nested picker. `apply()` commits and closes; `can
64
64
  ```vue
65
65
  <DateField overlay="modal">
66
66
  <template #footer="{ apply, cancel }">
67
- <button type="button" @click="cancel">Discard</button>
68
- <button type="button" @click="apply">Save</button>
67
+ <button type="button" v-on:click="cancel">Discard</button>
68
+ <button type="button" v-on:click="apply">Save</button>
69
69
  </template>
70
70
  </DateField>
71
71
  ```
@@ -17,7 +17,7 @@ import { DatePicker } from "@bridge-ui/vue/Components/DatePicker";
17
17
 
18
18
  <DatePicker v-model="date" />
19
19
 
20
- <DatePicker range show-footer v-model="range" @cancel="() => {}" />
20
+ <DatePicker range show-footer v-model="range" v-on:cancel="() => {}" />
21
21
  ```
22
22
 
23
23
  ### Custom footer
@@ -27,8 +27,8 @@ Call `apply()` to commit and close the overlay, or `cancel()` to discard and clo
27
27
  ```vue
28
28
  <DatePicker show-footer>
29
29
  <template #footer="{ apply, cancel }">
30
- <button type="button" @click="cancel">Discard</button>
31
- <button type="button" @click="apply">Save</button>
30
+ <button type="button" v-on:click="cancel">Discard</button>
31
+ <button type="button" v-on:click="apply">Save</button>
32
32
  </template>
33
33
  </DatePicker>
34
34
  ```
@@ -21,7 +21,7 @@ import { DateRangePicker } from "@bridge-ui/vue/Components/DateRangePicker";
21
21
 
22
22
  <DateRangePicker orientation="vertical" />
23
23
 
24
- <DateRangePicker show-footer v-model="range" @cancel="() => {}" />
24
+ <DateRangePicker show-footer v-model="range" v-on:cancel="() => {}" />
25
25
  ```
26
26
 
27
27
  ## Props
@@ -55,9 +55,9 @@ For APIs that do not expose a total page count:
55
55
  <Pagination
56
56
  mode="simple"
57
57
  aria-label="Pagination"
58
- @next="fetchPage(nextCursor)"
59
58
  :has-next="Boolean(nextCursor)"
60
- @previous="fetchPage(prevCursor)"
59
+ v-on:next="fetchPage(nextCursor)"
61
60
  :has-previous="Boolean(prevCursor)"
61
+ v-on:previous="fetchPage(prevCursor)"
62
62
  />
63
63
  ```