@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.
- package/ai/skills/bridge-ui-components/SKILL.md +3 -1
- package/dist/Components/Autocomplete/composables/useAutocomplete.d.ts +1 -1
- package/dist/Components/ColorField/composables/useColorField.d.ts +2 -1
- package/dist/Components/DataTable/DataTable.js +5 -0
- package/dist/Components/DataTable/DataTable.vue.d.ts +43 -0
- package/dist/Components/DataTable/DataTable.vue_vue_type_script_setup_true_lang.js +382 -0
- package/dist/Components/DataTable/DataTableCellContent.js +5 -0
- package/dist/Components/DataTable/DataTableCellContent.vue.d.ts +23 -0
- package/dist/Components/DataTable/DataTableCellContent.vue_vue_type_script_setup_true_lang.js +38 -0
- package/dist/Components/DataTable/DataTableColumnsMenu.js +5 -0
- package/dist/Components/DataTable/DataTableColumnsMenu.vue.d.ts +11 -0
- package/dist/Components/DataTable/DataTableColumnsMenu.vue_vue_type_script_setup_true_lang.js +47 -0
- package/dist/Components/DataTable/DataTableFilterMenu.js +5 -0
- package/dist/Components/DataTable/DataTableFilterMenu.vue.d.ts +17 -0
- package/dist/Components/DataTable/DataTableFilterMenu.vue_vue_type_script_setup_true_lang.js +132 -0
- package/dist/Components/DataTable/DataTableFilterOptions.js +5 -0
- package/dist/Components/DataTable/DataTableFilterOptions.vue.d.ts +14 -0
- package/dist/Components/DataTable/DataTableFilterOptions.vue_vue_type_script_setup_true_lang.js +73 -0
- package/dist/Components/DataTable/DataTableSearch.js +5 -0
- package/dist/Components/DataTable/DataTableSearch.vue.d.ts +12 -0
- package/dist/Components/DataTable/DataTableSearch.vue_vue_type_script_setup_true_lang.js +39 -0
- package/dist/Components/DataTable/DataTableSelection.js +5 -0
- package/dist/Components/DataTable/DataTableSelection.vue.d.ts +20 -0
- package/dist/Components/DataTable/DataTableSelection.vue_vue_type_script_setup_true_lang.js +55 -0
- package/dist/Components/DataTable/DataTableSortButton.js +5 -0
- package/dist/Components/DataTable/DataTableSortButton.vue.d.ts +17 -0
- package/dist/Components/DataTable/DataTableSortButton.vue_vue_type_script_setup_true_lang.js +43 -0
- package/dist/Components/DataTable/DataTableToolbarButton.js +5 -0
- package/dist/Components/DataTable/DataTableToolbarButton.vue.d.ts +13 -0
- package/dist/Components/DataTable/DataTableToolbarButton.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/Components/DataTable/composables/useDataTable.d.ts +557 -0
- package/dist/Components/DataTable/composables/useDataTable.js +479 -0
- package/dist/Components/DataTable/dataTable.types.d.ts +480 -0
- package/dist/Components/DataTable/index.d.ts +3 -0
- package/dist/Components/DataTable/index.js +3 -0
- package/dist/Components/DateField/composables/useDateField.d.ts +2 -1
- package/dist/Components/DateRangeField/composables/useDateRangeField.d.ts +2 -1
- package/dist/Components/DateTimeField/composables/useDateTimeField.d.ts +2 -1
- package/dist/Components/DateTimeRangeField/composables/useDateTimeRangeField.d.ts +2 -1
- package/dist/Components/FormField/composables/useFormField.d.ts +1 -1
- package/dist/Components/Menu/Menu.vue_vue_type_script_setup_true_lang.js +1 -0
- package/dist/Components/Menu/composables/useMenu.d.ts +1 -1
- package/dist/Components/Menu/composables/useMenu.js +7 -3
- package/dist/Components/Menu/menu.types.d.ts +6 -0
- package/dist/Components/NumberField/composables/useNumberField.d.ts +1 -1
- package/dist/Components/PasswordField/composables/usePasswordField.d.ts +1 -1
- package/dist/Components/Radio/Radio.vue_vue_type_script_setup_true_lang.js +9 -9
- package/dist/Components/Radio/composables/useRadio.js +57 -54
- package/dist/Components/Select/composables/useSelect.d.ts +1 -1
- package/dist/Components/Slider/composables/useSlider.d.ts +2 -2
- package/dist/Components/Snackbar/composables/useSnackbar.d.ts +1 -1
- package/dist/Components/Table/Table.js +5 -0
- package/dist/Components/Table/Table.vue.d.ts +16 -0
- package/dist/Components/Table/Table.vue_vue_type_script_setup_true_lang.js +44 -0
- package/dist/Components/Table/TableBody.js +5 -0
- package/dist/Components/Table/TableBody.vue.d.ts +11 -0
- package/dist/Components/Table/TableBody.vue_vue_type_script_setup_true_lang.js +17 -0
- package/dist/Components/Table/TableCaption.js +5 -0
- package/dist/Components/Table/TableCaption.vue.d.ts +11 -0
- package/dist/Components/Table/TableCaption.vue_vue_type_script_setup_true_lang.js +17 -0
- package/dist/Components/Table/TableCell.js +5 -0
- package/dist/Components/Table/TableCell.vue.d.ts +11 -0
- package/dist/Components/Table/TableCell.vue_vue_type_script_setup_true_lang.js +19 -0
- package/dist/Components/Table/TableFooter.js +5 -0
- package/dist/Components/Table/TableFooter.vue.d.ts +11 -0
- package/dist/Components/Table/TableFooter.vue_vue_type_script_setup_true_lang.js +17 -0
- package/dist/Components/Table/TableHead.js +5 -0
- package/dist/Components/Table/TableHead.vue.d.ts +11 -0
- package/dist/Components/Table/TableHead.vue_vue_type_script_setup_true_lang.js +19 -0
- package/dist/Components/Table/TableHeader.js +5 -0
- package/dist/Components/Table/TableHeader.vue.d.ts +11 -0
- package/dist/Components/Table/TableHeader.vue_vue_type_script_setup_true_lang.js +17 -0
- package/dist/Components/Table/TableRow.js +5 -0
- package/dist/Components/Table/TableRow.vue.d.ts +11 -0
- package/dist/Components/Table/TableRow.vue_vue_type_script_setup_true_lang.js +17 -0
- package/dist/Components/Table/composables/useTable.d.ts +16 -0
- package/dist/Components/Table/composables/useTable.js +88 -0
- package/dist/Components/Table/composables/useTableCell.d.ts +12 -0
- package/dist/Components/Table/composables/useTableCell.js +40 -0
- package/dist/Components/Table/composables/useTablePart.d.ts +12 -0
- package/dist/Components/Table/composables/useTablePart.js +32 -0
- package/dist/Components/Table/composables/useTableRow.d.ts +6 -0
- package/dist/Components/Table/composables/useTableRow.js +29 -0
- package/dist/Components/Table/index.d.ts +14 -0
- package/dist/Components/Table/index.js +14 -0
- package/dist/Components/Table/table.types.d.ts +416 -0
- package/dist/Components/Table/tableInjectionKey.d.ts +114 -0
- package/dist/Components/Table/tableInjectionKey.js +4 -0
- package/dist/Components/TextField/composables/useTextField.d.ts +1 -1
- package/dist/Components/Textarea/composables/useTextarea.d.ts +1 -1
- package/dist/Components/TimeField/composables/useTimeField.d.ts +2 -1
- package/dist/Components/TimeRangeField/composables/useTimeRangeField.d.ts +2 -1
- package/docs/README.md +2 -0
- package/docs/components/CalendarDate.md +1 -1
- package/docs/components/DataTable.md +345 -0
- package/docs/components/DateField.md +2 -2
- package/docs/components/DatePicker.md +3 -3
- package/docs/components/DateRangePicker.md +1 -1
- package/docs/components/Pagination.md +2 -2
- package/docs/components/Table.md +122 -0
- package/docs/examples/i18n-dictionary.ts +4 -0
- package/docs/examples/icon-fontawesome.ts +8 -0
- package/docs/examples/icon-heroicons.ts +8 -0
- package/docs/examples/icon-lucide.ts +8 -0
- package/docs/examples/icon-phosphor.ts +8 -0
- package/docs/examples/icon-tabler.ts +8 -0
- 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>>;
|
|
@@ -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?: "
|
|
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?: "
|
|
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?: "
|
|
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?: "
|
|
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)
|
|
@@ -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"
|
|
68
|
-
<button type="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"
|
|
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"
|
|
31
|
-
<button type="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"
|
|
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
|
-
|
|
59
|
+
v-on:next="fetchPage(nextCursor)"
|
|
61
60
|
:has-previous="Boolean(prevCursor)"
|
|
61
|
+
v-on:previous="fetchPage(prevCursor)"
|
|
62
62
|
/>
|
|
63
63
|
```
|