@bridge-ui/vue 0.2.0 → 0.4.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 (135) hide show
  1. package/ai/skills/bridge-ui-components/SKILL.md +3 -1
  2. package/dist/Components/Autocomplete/Autocomplete.vue_vue_type_script_setup_true_lang.js +40 -45
  3. package/dist/Components/Autocomplete/composables/useAutocomplete.d.ts +2 -1
  4. package/dist/Components/ColorField/ColorField.vue_vue_type_script_setup_true_lang.js +39 -44
  5. package/dist/Components/ColorField/composables/useColorField.d.ts +3 -1
  6. package/dist/Components/DataTable/DataTable.js +5 -0
  7. package/dist/Components/DataTable/DataTable.vue.d.ts +43 -0
  8. package/dist/Components/DataTable/DataTable.vue_vue_type_script_setup_true_lang.js +396 -0
  9. package/dist/Components/DataTable/DataTableCellContent.js +5 -0
  10. package/dist/Components/DataTable/DataTableCellContent.vue.d.ts +23 -0
  11. package/dist/Components/DataTable/DataTableCellContent.vue_vue_type_script_setup_true_lang.js +38 -0
  12. package/dist/Components/DataTable/DataTableColumnsMenu.js +5 -0
  13. package/dist/Components/DataTable/DataTableColumnsMenu.vue.d.ts +17 -0
  14. package/dist/Components/DataTable/DataTableColumnsMenu.vue_vue_type_script_setup_true_lang.js +92 -0
  15. package/dist/Components/DataTable/DataTableFilterMenu.js +5 -0
  16. package/dist/Components/DataTable/DataTableFilterMenu.vue.d.ts +20 -0
  17. package/dist/Components/DataTable/DataTableFilterMenu.vue_vue_type_script_setup_true_lang.js +151 -0
  18. package/dist/Components/DataTable/DataTableFilterOptions.js +5 -0
  19. package/dist/Components/DataTable/DataTableFilterOptions.vue.d.ts +17 -0
  20. package/dist/Components/DataTable/DataTableFilterOptions.vue_vue_type_script_setup_true_lang.js +81 -0
  21. package/dist/Components/DataTable/DataTableSearch.js +5 -0
  22. package/dist/Components/DataTable/DataTableSearch.vue.d.ts +12 -0
  23. package/dist/Components/DataTable/DataTableSearch.vue_vue_type_script_setup_true_lang.js +39 -0
  24. package/dist/Components/DataTable/DataTableSelection.js +5 -0
  25. package/dist/Components/DataTable/DataTableSelection.vue.d.ts +20 -0
  26. package/dist/Components/DataTable/DataTableSelection.vue_vue_type_script_setup_true_lang.js +56 -0
  27. package/dist/Components/DataTable/DataTableSortButton.js +5 -0
  28. package/dist/Components/DataTable/DataTableSortButton.vue.d.ts +17 -0
  29. package/dist/Components/DataTable/DataTableSortButton.vue_vue_type_script_setup_true_lang.js +43 -0
  30. package/dist/Components/DataTable/DataTableToolbarButton.js +5 -0
  31. package/dist/Components/DataTable/DataTableToolbarButton.vue.d.ts +14 -0
  32. package/dist/Components/DataTable/DataTableToolbarButton.vue_vue_type_script_setup_true_lang.js +31 -0
  33. package/dist/Components/DataTable/composables/useDataTable.d.ts +565 -0
  34. package/dist/Components/DataTable/composables/useDataTable.js +511 -0
  35. package/dist/Components/DataTable/composables/useDataTableColumnsMenu.d.ts +27 -0
  36. package/dist/Components/DataTable/composables/useDataTableColumnsMenu.js +54 -0
  37. package/dist/Components/DataTable/dataTable.types.d.ts +497 -0
  38. package/dist/Components/DataTable/index.d.ts +3 -0
  39. package/dist/Components/DataTable/index.js +3 -0
  40. package/dist/Components/DateField/DateField.vue_vue_type_script_setup_true_lang.js +52 -57
  41. package/dist/Components/DateField/composables/useDateField.d.ts +3 -1
  42. package/dist/Components/DateRangeField/DateRangeField.vue_vue_type_script_setup_true_lang.js +50 -55
  43. package/dist/Components/DateRangeField/composables/useDateRangeField.d.ts +3 -1
  44. package/dist/Components/DateTimeField/DateTimeField.vue_vue_type_script_setup_true_lang.js +56 -61
  45. package/dist/Components/DateTimeField/composables/useDateTimeField.d.ts +3 -1
  46. package/dist/Components/DateTimeRangeField/DateTimeRangeField.vue_vue_type_script_setup_true_lang.js +56 -61
  47. package/dist/Components/DateTimeRangeField/composables/useDateTimeRangeField.d.ts +3 -1
  48. package/dist/Components/FormField/composables/useFormField.d.ts +2 -1
  49. package/dist/Components/FormField/composables/useFormField.js +80 -75
  50. package/dist/Components/Menu/Menu.vue_vue_type_script_setup_true_lang.js +1 -0
  51. package/dist/Components/Menu/composables/useMenu.d.ts +1 -1
  52. package/dist/Components/Menu/composables/useMenu.js +7 -3
  53. package/dist/Components/Menu/menu.types.d.ts +6 -0
  54. package/dist/Components/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js +53 -43
  55. package/dist/Components/NumberField/composables/useNumberField.d.ts +9 -2
  56. package/dist/Components/NumberField/composables/useNumberField.js +49 -36
  57. package/dist/Components/NumberField/index.d.ts +1 -1
  58. package/dist/Components/NumberField/numberField.types.d.ts +13 -1
  59. package/dist/Components/PasswordField/PasswordField.vue_vue_type_script_setup_true_lang.js +28 -33
  60. package/dist/Components/PasswordField/composables/usePasswordField.d.ts +2 -1
  61. package/dist/Components/Radio/Radio.vue_vue_type_script_setup_true_lang.js +9 -9
  62. package/dist/Components/Radio/composables/useRadio.js +57 -54
  63. package/dist/Components/Select/Select.vue_vue_type_script_setup_true_lang.js +42 -47
  64. package/dist/Components/Select/composables/useSelect.d.ts +2 -1
  65. package/dist/Components/Slider/Slider.vue_vue_type_script_setup_true_lang.js +43 -48
  66. package/dist/Components/Slider/composables/useSlider.d.ts +3 -3
  67. package/dist/Components/Snackbar/composables/useSnackbar.d.ts +1 -1
  68. package/dist/Components/Table/Table.js +5 -0
  69. package/dist/Components/Table/Table.vue.d.ts +16 -0
  70. package/dist/Components/Table/Table.vue_vue_type_script_setup_true_lang.js +44 -0
  71. package/dist/Components/Table/TableBody.js +5 -0
  72. package/dist/Components/Table/TableBody.vue.d.ts +11 -0
  73. package/dist/Components/Table/TableBody.vue_vue_type_script_setup_true_lang.js +17 -0
  74. package/dist/Components/Table/TableCaption.js +5 -0
  75. package/dist/Components/Table/TableCaption.vue.d.ts +11 -0
  76. package/dist/Components/Table/TableCaption.vue_vue_type_script_setup_true_lang.js +17 -0
  77. package/dist/Components/Table/TableCell.js +5 -0
  78. package/dist/Components/Table/TableCell.vue.d.ts +11 -0
  79. package/dist/Components/Table/TableCell.vue_vue_type_script_setup_true_lang.js +19 -0
  80. package/dist/Components/Table/TableFooter.js +5 -0
  81. package/dist/Components/Table/TableFooter.vue.d.ts +11 -0
  82. package/dist/Components/Table/TableFooter.vue_vue_type_script_setup_true_lang.js +17 -0
  83. package/dist/Components/Table/TableHead.js +5 -0
  84. package/dist/Components/Table/TableHead.vue.d.ts +11 -0
  85. package/dist/Components/Table/TableHead.vue_vue_type_script_setup_true_lang.js +19 -0
  86. package/dist/Components/Table/TableHeader.js +5 -0
  87. package/dist/Components/Table/TableHeader.vue.d.ts +11 -0
  88. package/dist/Components/Table/TableHeader.vue_vue_type_script_setup_true_lang.js +17 -0
  89. package/dist/Components/Table/TableRow.js +5 -0
  90. package/dist/Components/Table/TableRow.vue.d.ts +11 -0
  91. package/dist/Components/Table/TableRow.vue_vue_type_script_setup_true_lang.js +17 -0
  92. package/dist/Components/Table/composables/useTable.d.ts +19 -0
  93. package/dist/Components/Table/composables/useTable.js +89 -0
  94. package/dist/Components/Table/composables/useTableCell.d.ts +12 -0
  95. package/dist/Components/Table/composables/useTableCell.js +40 -0
  96. package/dist/Components/Table/composables/useTablePart.d.ts +12 -0
  97. package/dist/Components/Table/composables/useTablePart.js +32 -0
  98. package/dist/Components/Table/composables/useTableRow.d.ts +6 -0
  99. package/dist/Components/Table/composables/useTableRow.js +29 -0
  100. package/dist/Components/Table/index.d.ts +14 -0
  101. package/dist/Components/Table/index.js +14 -0
  102. package/dist/Components/Table/table.types.d.ts +417 -0
  103. package/dist/Components/Table/tableInjectionKey.d.ts +114 -0
  104. package/dist/Components/Table/tableInjectionKey.js +4 -0
  105. package/dist/Components/TextField/TextField.vue_vue_type_script_setup_true_lang.js +11 -16
  106. package/dist/Components/TextField/composables/useTextField.d.ts +2 -1
  107. package/dist/Components/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +15 -20
  108. package/dist/Components/Textarea/composables/useTextarea.d.ts +2 -1
  109. package/dist/Components/TimeField/TimeField.vue_vue_type_script_setup_true_lang.js +45 -50
  110. package/dist/Components/TimeField/composables/useTimeField.d.ts +3 -1
  111. package/dist/Components/TimeRangeField/TimeRangeField.vue_vue_type_script_setup_true_lang.js +45 -50
  112. package/dist/Components/TimeRangeField/composables/useTimeRangeField.d.ts +3 -1
  113. package/dist/Utils/index.d.ts +1 -0
  114. package/dist/Utils/index.js +28 -27
  115. package/dist/Utils/useOptionalModel.d.ts +6 -0
  116. package/dist/Utils/useOptionalModel.js +13 -0
  117. package/dist/augments.d.ts +1 -1
  118. package/dist/index.d.ts +1 -1
  119. package/dist/theme.css +46 -42
  120. package/docs/README.md +2 -0
  121. package/docs/components/CalendarDate.md +1 -1
  122. package/docs/components/DataTable.md +371 -0
  123. package/docs/components/DateField.md +2 -2
  124. package/docs/components/DatePicker.md +3 -3
  125. package/docs/components/DateRangePicker.md +1 -1
  126. package/docs/components/NumberField.md +17 -6
  127. package/docs/components/Pagination.md +2 -2
  128. package/docs/components/Table.md +122 -0
  129. package/docs/examples/i18n-dictionary.ts +10 -0
  130. package/docs/examples/icon-fontawesome.ts +12 -0
  131. package/docs/examples/icon-heroicons.ts +12 -0
  132. package/docs/examples/icon-lucide.ts +12 -0
  133. package/docs/examples/icon-phosphor.ts +12 -0
  134. package/docs/examples/icon-tabler.ts +12 -0
  135. package/package.json +9 -2
@@ -0,0 +1,371 @@
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. The bordered wrapper, per-page select, and pagination follow that width. Default `full` stretches the table to the wrapper width:
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
+ 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:
130
+
131
+ ```vue
132
+ <DataTable
133
+ :rows="pageRows"
134
+ :columns="columns"
135
+ v-model:page="page"
136
+ :page-count="pageCount"
137
+ v-model:filters="filters"
138
+ v-model:sorting="sorting"
139
+ />
140
+ ```
141
+
142
+ ### Empty, loading, and footer
143
+
144
+ 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:
145
+
146
+ ```vue
147
+ <DataTable :rows="[]" :columns="columns" :loading="isLoading">
148
+ <template #empty>No users</template>
149
+ <template #footer>Here is footer</template>
150
+ </DataTable>
151
+ ```
152
+
153
+ ```vue
154
+ <DataTable
155
+ :rows="users"
156
+ :columns="columns"
157
+ :loading="isLoading"
158
+ loading-variant="bar"
159
+ />
160
+ ```
161
+
162
+ 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.
163
+
164
+ ### Columns
165
+
166
+ 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:
167
+
168
+ ```vue
169
+ <DataTable :rows="users" :columns="columns">
170
+ <template #item.role="{ row }">
171
+ <Badge>{{ row.role }}</Badge>
172
+ </template>
173
+ </DataTable>
174
+ ```
175
+
176
+ ```ts
177
+ const columns = [
178
+ { id: "name", header: "Name" },
179
+ { id: "role", header: "Role" },
180
+ ];
181
+ ```
182
+
183
+ 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.
184
+
185
+ ### Selection
186
+
187
+ `selectionMode="multiple"` (default) uses checkboxes and select-all. `selectionMode="single"` uses radios and keeps at most one id. `v-model:selection` is always `string[]`.
188
+
189
+ ```vue
190
+ <DataTable
191
+ :rows="users"
192
+ :columns="columns"
193
+ selection-mode="single"
194
+ v-model:selection="selected"
195
+ :get-row-id="(row) => row.id"
196
+ />
197
+ ```
198
+
199
+ ### Filters
200
+
201
+ 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.
202
+
203
+ Set `searchable` on a column to add a text field in that same overlay. Queries are stored in `columnSearch` (column id → string), not used to filter the option list.
204
+
205
+ Column filters open in a `FieldOverlay`. Default `filter-overlay` is `auto` (`menu` on desktop, `drawer` on mobile). Pass `menu`, `modal`, or `drawer` to pin a shell:
206
+
207
+ ```vue
208
+ <DataTable
209
+ :rows="users"
210
+ :columns="columns"
211
+ filter-overlay="drawer"
212
+ v-model:filters="filters"
213
+ />
214
+ ```
215
+
216
+ ```vue
217
+ <DataTable
218
+ :rows="users"
219
+ :columns="columns"
220
+ v-model:filters="filters"
221
+ v-model:column-search="columnSearch"
222
+ />
223
+ ```
224
+
225
+ ```ts
226
+ const columns = [
227
+ {
228
+ id: "name",
229
+ header: "Name",
230
+ searchable: true,
231
+ cell: (row) => row.name,
232
+ },
233
+ {
234
+ id: "role",
235
+ header: "Role",
236
+ cell: (row) => row.role,
237
+ filters: [
238
+ { label: "Engineer", value: "Engineer" },
239
+ { label: "Researcher", value: "Researcher" },
240
+ ],
241
+ },
242
+ ];
243
+ ```
244
+
245
+ 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.
246
+
247
+ ### Sticky columns
248
+
249
+ `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"`.
250
+
251
+ ```ts
252
+ const columns = [
253
+ {
254
+ id: "name",
255
+ width: 120,
256
+ header: "Name",
257
+ sticky: "start",
258
+ cell: (row) => row.name,
259
+ },
260
+ { id: "role", header: "Role", cell: (row) => row.role },
261
+ {
262
+ id: "actions",
263
+ header: "Actions",
264
+ sticky: "end",
265
+ cell: (row) => row.id,
266
+ },
267
+ ];
268
+ ```
269
+
270
+ ### Ellipsis
271
+
272
+ `ellipsis` truncates overflowing cell text. The tooltip uses the column accessor (or `row[id]`).
273
+
274
+ ```ts
275
+ const columns = [
276
+ {
277
+ id: "name",
278
+ header: "Name",
279
+ ellipsis: true,
280
+ cell: (row) => row.name,
281
+ },
282
+ ];
283
+ ```
284
+
285
+ ### Column classes
286
+
287
+ `classes.header` and `classes.cell` merge onto that column’s `th` / `td`. Use width utilities for breakpoint-based sizing. Do not set `width` on the same column when the class should control width — inline `width` wins.
288
+
289
+ ```ts
290
+ const columns = [
291
+ {
292
+ id: "name",
293
+ header: "Name",
294
+ cell: (row) => row.name,
295
+ classes: {
296
+ cell: "w-24 sm:w-40",
297
+ header: "w-24 sm:w-40",
298
+ },
299
+ },
300
+ ];
301
+ ```
302
+
303
+ ### Column visibility
304
+
305
+ 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.
306
+
307
+ The panel opens in a `FieldOverlay`. Default `columns-overlay` is `auto` (`menu` on desktop, `drawer` on mobile). Pass `menu`, `modal`, or `drawer` to pin a shell.
308
+
309
+ When unset, `columns-show-footer` is `true` for `modal` / `drawer` (`false` for `menu`). Reset restores hideable columns; OK commits and closes. Closing without OK discards.
310
+
311
+ ```vue
312
+ <DataTable
313
+ :rows="users"
314
+ :columns="columns"
315
+ columns-overlay="drawer"
316
+ v-model:hidden-columns="hidden"
317
+ />
318
+ ```
319
+
320
+ ### Search
321
+
322
+ 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.
323
+
324
+ ```vue
325
+ <DataTable :rows="users" :columns="columns" v-model:search="search" />
326
+ ```
327
+
328
+ ### Toolbar
329
+
330
+ `#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.
331
+
332
+ ```vue
333
+ <DataTable :rows="users" :columns="columns" v-model:search="search">
334
+ <template #toolbar-actions>
335
+ <Button v-on:click="onPrint">Print</Button>
336
+ </template>
337
+ </DataTable>
338
+ ```
339
+
340
+ ### Expand
341
+
342
+ Controlled `expanded` row ids. `#expanded="{ row }"` renders in a spanning row under the data row.
343
+
344
+ ```vue
345
+ <DataTable
346
+ :rows="users"
347
+ :columns="columns"
348
+ v-model:expanded="expanded"
349
+ :get-row-id="(row) => row.id"
350
+ >
351
+ <template #expanded="{ row }">
352
+ {{ row.bio }}
353
+ </template>
354
+ </DataTable>
355
+ ```
356
+
357
+ ### Summary
358
+
359
+ Set `summary` on a column to render a footer row over the current (filtered) rows. Chrome cells stay empty.
360
+
361
+ ```ts
362
+ const columns = [
363
+ { id: "name", header: "Name", cell: (row) => row.name },
364
+ {
365
+ id: "role",
366
+ header: "Role",
367
+ cell: (row) => row.role,
368
+ summary: (items) => `${items.length} roles`,
369
+ },
370
+ ];
371
+ ```
@@ -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
@@ -28,6 +28,16 @@ import { NumberField } from "@bridge-ui/vue/Components/NumberField";
28
28
  />
29
29
  ```
30
30
 
31
+ ### Control variants
32
+
33
+ ```vue
34
+ <NumberField label="Stacked" />
35
+
36
+ <NumberField label="Split" control-variant="split" />
37
+
38
+ <NumberField label="Inline" control-variant="inline" />
39
+ ```
40
+
31
41
  ### Min, max, and step
32
42
 
33
43
  ```vue
@@ -51,12 +61,13 @@ import { NumberField } from "@bridge-ui/vue/Components/NumberField";
51
61
 
52
62
  ### NumberField-specific
53
63
 
54
- | Prop | Type | Default | Description |
55
- | --------- | -------------------- | ------- | ----------------------------------------- |
56
- | `classes` | `NumberFieldClasses` | — | The classes to apply to the number field. |
57
- | `max` | `number` | | The maximum value. |
58
- | `min` | `number` | — | The minimum value. |
59
- | `step` | `number` | 1 | The step increment value. |
64
+ | Prop | Type | Default | Description |
65
+ | ---------------- | ---------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------ |
66
+ | `classes` | `NumberFieldClasses` | — | The classes to apply to the number field. |
67
+ | `controlVariant` | `"inline" \| "split" \| "stacked"` | `"stacked"` | Layout of increment and decrement controls. `split` uses minus/plus icons and occupies the start slot. |
68
+ | `max` | `number` | — | The maximum value. |
69
+ | `min` | `number` | | The minimum value. |
70
+ | `step` | `number` | 1 | The step increment value. |
60
71
 
61
72
  ### v-model
62
73
 
@@ -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
  ```
@@ -0,0 +1,122 @@
1
+ # Table
2
+
3
+ Presentational table primitives for static or lightly interactive tabular data. Compose with `TableHeader`, `TableBody`, `TableRow`, `TableHead`, and `TableCell`. Sorting, selection, and pagination live on `DataTable`.
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import {
9
+ Table,
10
+ TableBody,
11
+ TableCaption,
12
+ TableCell,
13
+ TableFooter,
14
+ TableHead,
15
+ TableHeader,
16
+ TableRow,
17
+ } from "@bridge-ui/vue/Components/Table";
18
+ ```
19
+
20
+ ## Examples
21
+
22
+ ### Usage
23
+
24
+ ```vue
25
+ <Table>
26
+ <TableHeader>
27
+ <TableRow>
28
+ <TableHead>Name</TableHead>
29
+ <TableHead>Role</TableHead>
30
+ <TableHead>Status</TableHead>
31
+ </TableRow>
32
+ </TableHeader>
33
+ <TableBody>
34
+ <TableRow>
35
+ <TableCell>Ada Lovelace</TableCell>
36
+ <TableCell>Engineer</TableCell>
37
+ <TableCell>Active</TableCell>
38
+ </TableRow>
39
+ </TableBody>
40
+ </Table>
41
+ ```
42
+
43
+ ### Variants
44
+
45
+ Same three chrome treatments as `DataTable`. Pair with `Pagination` under the table (Table does not render pagination itself):
46
+
47
+ ```vue
48
+ <Table variant="plain" />
49
+ <Pagination :count="12" v-model="page" variant="text" />
50
+
51
+ <Table variant="ghost" />
52
+ <Pagination :count="12" v-model="page" variant="ghost" />
53
+
54
+ <Table variant="bordered" />
55
+ <Pagination :count="12" v-model="page" variant="outlined" />
56
+ ```
57
+
58
+ | Table `variant` | Pagination `variant` |
59
+ | --------------- | -------------------- |
60
+ | `plain` | `text` |
61
+ | `ghost` | `ghost` |
62
+ | `bordered` | `outlined` |
63
+
64
+ `striped` is independent of variant (same as `hoverable`):
65
+
66
+ ```vue
67
+ <Table striped variant="bordered" />
68
+ ```
69
+
70
+ ### Rounded
71
+
72
+ Corner radius on the wrapper, header, and footer. Default `lg`.
73
+
74
+ ```vue
75
+ <Table rounded="none" />
76
+ <Table rounded="xl" variant="ghost" />
77
+ ```
78
+
79
+ ### Dense + sticky header
80
+
81
+ `sticky-header` pins header cells to the nearest scrollport (usually the page). The wrapper skips overflow so the header can stick. For a boxed scroll area, set `overflow-auto` and a max height on `classes.root`.
82
+
83
+ ```vue
84
+ <Table sticky-header size="sm" />
85
+ ```
86
+
87
+ ### Numeric cells
88
+
89
+ ```vue
90
+ <Table>
91
+ <TableHeader>
92
+ <TableRow>
93
+ <TableHead>Name</TableHead>
94
+ <TableHead numeric>Score</TableHead>
95
+ </TableRow>
96
+ </TableHeader>
97
+ <TableBody>
98
+ <TableRow>
99
+ <TableCell>Ada</TableCell>
100
+ <TableCell numeric>12</TableCell>
101
+ </TableRow>
102
+ </TableBody>
103
+ </Table>
104
+ ```
105
+
106
+ ### Caption
107
+
108
+ ```vue
109
+ <Table>
110
+ <TableCaption>Team roster</TableCaption>
111
+ <TableHeader>
112
+ <TableRow>
113
+ <TableHead>Name</TableHead>
114
+ </TableRow>
115
+ </TableHeader>
116
+ <TableBody>
117
+ <TableRow>
118
+ <TableCell>Ada Lovelace</TableCell>
119
+ </TableRow>
120
+ </TableBody>
121
+ </Table>
122
+ ```
@@ -19,14 +19,24 @@ import type { I18nAdapter } from "@bridge-ui/core/Adapters";
19
19
  const MESSAGES: Record<string, Record<string, string>> = {
20
20
  "en-US": {},
21
21
  "pt-BR": {
22
+ "OK": "OK",
22
23
  "Close": "Fechar",
24
+ "Reset": "Redefinir",
25
+ "Columns": "Colunas",
26
+ "Search": "Pesquisar",
27
+ "No data": "Sem dados",
28
+ "Per page:": "Por página:",
23
29
  "Loading...": "Carregando...",
24
30
  "No options": "Nenhuma opção",
31
+ "Select row": "Selecionar linha",
25
32
  "Hide password": "Ocultar senha",
26
33
  "Show password": "Mostrar senha",
34
+ "Filter column": "Filtrar coluna",
27
35
  "Clear selection": "Limpar seleção",
28
36
  "Decrement value": "Diminuir valor",
29
37
  "Increment value": "Aumentar valor",
38
+ "Select all rows": "Selecionar todas as linhas",
39
+ "Select all items": "Selecionar todos os itens",
30
40
  },
31
41
  };
32
42
 
@@ -22,10 +22,16 @@ import {
22
22
  faCircleInfo,
23
23
  faCircleXmark,
24
24
  faClock,
25
+ faDownload,
25
26
  faEye,
26
27
  faEyeSlash,
28
+ faFilter,
29
+ faMagnifyingGlass,
30
+ faMinus,
27
31
  faPalette,
32
+ faPlus,
28
33
  faSpinner,
34
+ faTableColumns,
29
35
  faTriangleExclamation,
30
36
  faUpDown,
31
37
  faUser,
@@ -87,18 +93,24 @@ const icons = {
87
93
  eye: faEye,
88
94
  bell: faBell,
89
95
  user: faUser,
96
+ plus: faPlus,
90
97
  clear: faXmark,
91
98
  check: faCheck,
92
99
  clock: faClock,
100
+ minus: faMinus,
101
+ filter: faFilter,
93
102
  loader: faSpinner,
94
103
  info: faCircleInfo,
95
104
  eyeOff: faEyeSlash,
96
105
  palette: faPalette,
97
106
  error: faCircleXmark,
107
+ download: faDownload,
98
108
  success: faCircleCheck,
99
109
  chevronUp: faChevronUp,
110
+ columns: faTableColumns,
100
111
  chevronUpDown: faUpDown,
101
112
  calendar: faCalendarDays,
113
+ search: faMagnifyingGlass,
102
114
  alert: faCircleExclamation,
103
115
  chevronDown: faChevronDown,
104
116
  chevronLeft: faChevronLeft,
@@ -6,6 +6,7 @@
6
6
 
7
7
  // ** External Imports
8
8
  import {
9
+ ArrowDownTrayIcon,
9
10
  ArrowPathIcon,
10
11
  BellIcon,
11
12
  CalendarDaysIcon,
@@ -21,9 +22,14 @@ import {
21
22
  ExclamationTriangleIcon,
22
23
  EyeIcon,
23
24
  EyeSlashIcon,
25
+ FunnelIcon,
24
26
  InformationCircleIcon,
27
+ MagnifyingGlassIcon,
28
+ MinusIcon,
29
+ PlusIcon,
25
30
  SwatchIcon,
26
31
  UserIcon,
32
+ ViewColumnsIcon,
27
33
  XCircleIcon,
28
34
  XMarkIcon,
29
35
  } from "@heroicons/vue/24/outline";
@@ -36,16 +42,22 @@ const icons = {
36
42
  eye: EyeIcon,
37
43
  bell: BellIcon,
38
44
  user: UserIcon,
45
+ plus: PlusIcon,
39
46
  clear: XMarkIcon,
40
47
  check: CheckIcon,
41
48
  clock: ClockIcon,
49
+ minus: MinusIcon,
42
50
  error: XCircleIcon,
51
+ filter: FunnelIcon,
43
52
  palette: SwatchIcon,
44
53
  eyeOff: EyeSlashIcon,
45
54
  loader: ArrowPathIcon,
46
55
  success: CheckCircleIcon,
47
56
  chevronUp: ChevronUpIcon,
57
+ columns: ViewColumnsIcon,
48
58
  calendar: CalendarDaysIcon,
59
+ download: ArrowDownTrayIcon,
60
+ search: MagnifyingGlassIcon,
49
61
  info: InformationCircleIcon,
50
62
  alert: ExclamationCircleIcon,
51
63
  chevronDown: ChevronDownIcon,