@bridge-ui/vue 0.1.1 → 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 (136) hide show
  1. package/ai/skills/bridge-ui-components/SKILL.md +4 -1
  2. package/dist/Components/Autocomplete/composables/useAutocomplete.d.ts +1 -1
  3. package/dist/Components/CalendarRange/CalendarRange.vue_vue_type_script_setup_true_lang.js +135 -109
  4. package/dist/Components/CalendarRange/calendarRange.types.d.ts +17 -5
  5. package/dist/Components/CalendarRange/composables/useCalendarRange.d.ts +4 -2
  6. package/dist/Components/CalendarRange/composables/useCalendarRange.js +85 -86
  7. package/dist/Components/ColorField/composables/useColorField.d.ts +2 -1
  8. package/dist/Components/DataTable/DataTable.js +5 -0
  9. package/dist/Components/DataTable/DataTable.vue.d.ts +43 -0
  10. package/dist/Components/DataTable/DataTable.vue_vue_type_script_setup_true_lang.js +382 -0
  11. package/dist/Components/DataTable/DataTableCellContent.js +5 -0
  12. package/dist/Components/DataTable/DataTableCellContent.vue.d.ts +23 -0
  13. package/dist/Components/DataTable/DataTableCellContent.vue_vue_type_script_setup_true_lang.js +38 -0
  14. package/dist/Components/DataTable/DataTableColumnsMenu.js +5 -0
  15. package/dist/Components/DataTable/DataTableColumnsMenu.vue.d.ts +11 -0
  16. package/dist/Components/DataTable/DataTableColumnsMenu.vue_vue_type_script_setup_true_lang.js +47 -0
  17. package/dist/Components/DataTable/DataTableFilterMenu.js +5 -0
  18. package/dist/Components/DataTable/DataTableFilterMenu.vue.d.ts +17 -0
  19. package/dist/Components/DataTable/DataTableFilterMenu.vue_vue_type_script_setup_true_lang.js +132 -0
  20. package/dist/Components/DataTable/DataTableFilterOptions.js +5 -0
  21. package/dist/Components/DataTable/DataTableFilterOptions.vue.d.ts +14 -0
  22. package/dist/Components/DataTable/DataTableFilterOptions.vue_vue_type_script_setup_true_lang.js +73 -0
  23. package/dist/Components/DataTable/DataTableSearch.js +5 -0
  24. package/dist/Components/DataTable/DataTableSearch.vue.d.ts +12 -0
  25. package/dist/Components/DataTable/DataTableSearch.vue_vue_type_script_setup_true_lang.js +39 -0
  26. package/dist/Components/DataTable/DataTableSelection.js +5 -0
  27. package/dist/Components/DataTable/DataTableSelection.vue.d.ts +20 -0
  28. package/dist/Components/DataTable/DataTableSelection.vue_vue_type_script_setup_true_lang.js +55 -0
  29. package/dist/Components/DataTable/DataTableSortButton.js +5 -0
  30. package/dist/Components/DataTable/DataTableSortButton.vue.d.ts +17 -0
  31. package/dist/Components/DataTable/DataTableSortButton.vue_vue_type_script_setup_true_lang.js +43 -0
  32. package/dist/Components/DataTable/DataTableToolbarButton.js +5 -0
  33. package/dist/Components/DataTable/DataTableToolbarButton.vue.d.ts +13 -0
  34. package/dist/Components/DataTable/DataTableToolbarButton.vue_vue_type_script_setup_true_lang.js +31 -0
  35. package/dist/Components/DataTable/composables/useDataTable.d.ts +557 -0
  36. package/dist/Components/DataTable/composables/useDataTable.js +479 -0
  37. package/dist/Components/DataTable/dataTable.types.d.ts +480 -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/composables/useDateField.d.ts +2 -1
  41. package/dist/Components/DateRangeField/composables/useDateRangeField.d.ts +2 -1
  42. package/dist/Components/DateTimeField/composables/useDateTimeField.d.ts +2 -1
  43. package/dist/Components/DateTimeRangeField/composables/useDateTimeRangeField.d.ts +2 -1
  44. package/dist/Components/DateTimeRangePicker/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js +1 -6
  45. package/dist/Components/Drawer/composables/useDrawer.js +1 -1
  46. package/dist/Components/FieldOverlay/FieldOverlay.vue_vue_type_script_setup_true_lang.js +35 -35
  47. package/dist/Components/FieldOverlay/composables/useFieldOverlay.d.ts +1 -0
  48. package/dist/Components/FieldOverlay/composables/useFieldOverlay.js +21 -19
  49. package/dist/Components/FieldOverlay/fieldOverlay.types.d.ts +11 -3
  50. package/dist/Components/FormField/composables/useFormField.d.ts +1 -1
  51. package/dist/Components/Listbox/composables/useListbox.js +1 -1
  52. package/dist/Components/Menu/Menu.vue_vue_type_script_setup_true_lang.js +1 -0
  53. package/dist/Components/Menu/composables/useMenu.d.ts +1 -1
  54. package/dist/Components/Menu/composables/useMenu.js +7 -3
  55. package/dist/Components/Menu/menu.types.d.ts +6 -0
  56. package/dist/Components/Modal/composables/useModal.js +1 -1
  57. package/dist/Components/NumberField/composables/useNumberField.d.ts +1 -1
  58. package/dist/Components/PasswordField/composables/usePasswordField.d.ts +1 -1
  59. package/dist/Components/Radio/Radio.vue_vue_type_script_setup_true_lang.js +9 -9
  60. package/dist/Components/Radio/composables/useRadio.js +57 -54
  61. package/dist/Components/Select/composables/useSelect.d.ts +1 -1
  62. package/dist/Components/Slider/composables/useSlider.d.ts +2 -2
  63. package/dist/Components/Snackbar/composables/useSnackbar.d.ts +1 -1
  64. package/dist/Components/Table/Table.js +5 -0
  65. package/dist/Components/Table/Table.vue.d.ts +16 -0
  66. package/dist/Components/Table/Table.vue_vue_type_script_setup_true_lang.js +44 -0
  67. package/dist/Components/Table/TableBody.js +5 -0
  68. package/dist/Components/Table/TableBody.vue.d.ts +11 -0
  69. package/dist/Components/Table/TableBody.vue_vue_type_script_setup_true_lang.js +17 -0
  70. package/dist/Components/Table/TableCaption.js +5 -0
  71. package/dist/Components/Table/TableCaption.vue.d.ts +11 -0
  72. package/dist/Components/Table/TableCaption.vue_vue_type_script_setup_true_lang.js +17 -0
  73. package/dist/Components/Table/TableCell.js +5 -0
  74. package/dist/Components/Table/TableCell.vue.d.ts +11 -0
  75. package/dist/Components/Table/TableCell.vue_vue_type_script_setup_true_lang.js +19 -0
  76. package/dist/Components/Table/TableFooter.js +5 -0
  77. package/dist/Components/Table/TableFooter.vue.d.ts +11 -0
  78. package/dist/Components/Table/TableFooter.vue_vue_type_script_setup_true_lang.js +17 -0
  79. package/dist/Components/Table/TableHead.js +5 -0
  80. package/dist/Components/Table/TableHead.vue.d.ts +11 -0
  81. package/dist/Components/Table/TableHead.vue_vue_type_script_setup_true_lang.js +19 -0
  82. package/dist/Components/Table/TableHeader.js +5 -0
  83. package/dist/Components/Table/TableHeader.vue.d.ts +11 -0
  84. package/dist/Components/Table/TableHeader.vue_vue_type_script_setup_true_lang.js +17 -0
  85. package/dist/Components/Table/TableRow.js +5 -0
  86. package/dist/Components/Table/TableRow.vue.d.ts +11 -0
  87. package/dist/Components/Table/TableRow.vue_vue_type_script_setup_true_lang.js +17 -0
  88. package/dist/Components/Table/composables/useTable.d.ts +16 -0
  89. package/dist/Components/Table/composables/useTable.js +88 -0
  90. package/dist/Components/Table/composables/useTableCell.d.ts +12 -0
  91. package/dist/Components/Table/composables/useTableCell.js +40 -0
  92. package/dist/Components/Table/composables/useTablePart.d.ts +12 -0
  93. package/dist/Components/Table/composables/useTablePart.js +32 -0
  94. package/dist/Components/Table/composables/useTableRow.d.ts +6 -0
  95. package/dist/Components/Table/composables/useTableRow.js +29 -0
  96. package/dist/Components/Table/index.d.ts +14 -0
  97. package/dist/Components/Table/index.js +14 -0
  98. package/dist/Components/Table/table.types.d.ts +416 -0
  99. package/dist/Components/Table/tableInjectionKey.d.ts +114 -0
  100. package/dist/Components/Table/tableInjectionKey.js +4 -0
  101. package/dist/Components/TextField/composables/useTextField.d.ts +1 -1
  102. package/dist/Components/Textarea/composables/useTextarea.d.ts +1 -1
  103. package/dist/Components/TimeField/composables/useTimeField.d.ts +2 -1
  104. package/dist/Components/TimePanel/composables/useTimePanel.d.ts +4 -0
  105. package/dist/Components/TimePanel/composables/useTimePanel.js +13 -12
  106. package/dist/Components/TimeRangeField/composables/useTimeRangeField.d.ts +2 -1
  107. package/dist/Components/TimeRangePicker/TimeRangePicker.vue_vue_type_script_setup_true_lang.js +103 -89
  108. package/dist/Components/TimeRangePicker/composables/useTimeRangePicker.d.ts +4 -2
  109. package/dist/Components/TimeRangePicker/composables/useTimeRangePicker.js +55 -54
  110. package/dist/Components/TimeRangePicker/timeRangePicker.types.d.ts +1 -7
  111. package/dist/index.js +32 -32
  112. package/dist/theme.css +2 -0
  113. package/docs/README.md +6 -0
  114. package/docs/ScrollUtilities.md +89 -0
  115. package/docs/components/Autocomplete.md +2 -0
  116. package/docs/components/CalendarDate.md +1 -1
  117. package/docs/components/CalendarRange.md +4 -3
  118. package/docs/components/DataTable.md +345 -0
  119. package/docs/components/DateField.md +2 -2
  120. package/docs/components/DatePicker.md +3 -3
  121. package/docs/components/DateRangePicker.md +4 -3
  122. package/docs/components/Drawer.md +21 -21
  123. package/docs/components/FieldOverlay.md +19 -8
  124. package/docs/components/Modal.md +19 -19
  125. package/docs/components/Pagination.md +2 -2
  126. package/docs/components/Select.md +2 -0
  127. package/docs/components/Table.md +122 -0
  128. package/docs/components/TimePanel.md +2 -0
  129. package/docs/components/TimeRangePicker.md +0 -1
  130. package/docs/examples/i18n-dictionary.ts +4 -0
  131. package/docs/examples/icon-fontawesome.ts +8 -0
  132. package/docs/examples/icon-heroicons.ts +8 -0
  133. package/docs/examples/icon-lucide.ts +8 -0
  134. package/docs/examples/icon-phosphor.ts +8 -0
  135. package/docs/examples/icon-tabler.ts +8 -0
  136. package/package.json +9 -2
@@ -0,0 +1,89 @@
1
+ # Scroll utilities
2
+
3
+ CSS utilities for overflow scrollers. They ship in `theme.css` — no extra import.
4
+
5
+ Not a component. Put the class on the element that has `overflow-y-auto` / `overflow-x-auto`.
6
+
7
+ ## Classes
8
+
9
+ | Class | Role |
10
+ | ------------------------- | ---------------------------------------------------------------------- |
11
+ | `bridge-scroll-fade` | Vertical fade (alias of `-y`). |
12
+ | `bridge-scroll-fade-y` | Vertical fade on the overflow scroller. |
13
+ | `bridge-scroll-fade-x` | Horizontal fade on the overflow scroller. |
14
+ | `bridge-scroll-fade-none` | Disable the fade. Works in any class order. |
15
+ | `bridge-soft-scrollbar` | Thin, rounded thumb. |
16
+ | `bridge-hide-scrollbar` | Hide the scrollbar; wheel / keyboard / programmatic scroll still work. |
17
+
18
+ ## Examples
19
+
20
+ ### Vertical fade
21
+
22
+ ```vue
23
+ <div class="bridge-scroll-fade-y overflow-y-auto">…</div>
24
+ ```
25
+
26
+ ### Horizontal fade
27
+
28
+ ```vue
29
+ <div class="flex bridge-scroll-fade-x overflow-x-auto">…</div>
30
+ ```
31
+
32
+ ### Hide scrollbar
33
+
34
+ ```vue
35
+ <div class="bridge-scroll-fade-y bridge-hide-scrollbar overflow-y-auto">
36
+
37
+ </div>
38
+ ```
39
+
40
+ ### Fade size
41
+
42
+ Depth defaults to `12%` of the container, capped at `40px`. Override with `--bridge-scroll-fade-size`:
43
+
44
+ ```vue
45
+ <div
46
+ class="bridge-scroll-fade-y overflow-y-auto [--bridge-scroll-fade-size:1.5rem]"
47
+ >
48
+
49
+ </div>
50
+ ```
51
+
52
+ ### Disable the fade
53
+
54
+ ```vue
55
+ <div class="bridge-scroll-fade-y bridge-scroll-fade-none overflow-y-auto">
56
+
57
+ </div>
58
+ ```
59
+
60
+ ### Soft scrollbar
61
+
62
+ ```vue
63
+ <div class="bridge-soft-scrollbar overflow-y-auto">…</div>
64
+ ```
65
+
66
+ Do not pair `bridge-scroll-fade-*` with `bridge-soft-scrollbar` on the same node — the mask dissolves the thumb at the edges. Use fade + `bridge-hide-scrollbar` when the fade is the overflow hint.
67
+
68
+ Do not put `bridge-scroll-fade-x` and `bridge-scroll-fade-y` on the same node — both set `mask-image`, and the later rule wins.
69
+
70
+ Put background and border on a wrapper; put `bridge-scroll-fade-*` on the inner scroller so the mask dissolves content, not the card chrome.
71
+
72
+ ## Behavior
73
+
74
+ - Scroll-aware when the browser supports scroll-driven animations: crisp start edge at rest, both edges mid-scroll, crisp end edge at the end.
75
+ - If content does not overflow, no fade.
76
+ - Without scroll-driven animations, no fade. Wheel / keyboard / programmatic scroll still work.
77
+ - `bridge-scroll-fade-x` follows reading direction (RTL included).
78
+
79
+ ## TimePanel
80
+
81
+ TimePanel columns use `bridge-scroll-fade-y` and `bridge-hide-scrollbar` by default. Add `bridge-scroll-fade-none` via `classes.column` to disable the fade.
82
+
83
+ ## Also used by
84
+
85
+ | Component | Classes |
86
+ | ------------------------------- | ------------------------------------------------------------------------ |
87
+ | Select / Listbox | `bridge-soft-scrollbar` on the options scroller. |
88
+ | Modal / Drawer `scroll="paper"` | `bridge-scroll-fade-y` and `bridge-hide-scrollbar` on the panel. |
89
+ | FieldOverlay drawer | Inner `bridge-scroll-fade-x`; vertical fade comes from `scroll="paper"`. |
@@ -2,6 +2,8 @@
2
2
 
3
3
  Combobox with single/multiple value, search, async data, and optional free-solo input.
4
4
 
5
+ The options list uses `bridge-soft-scrollbar`. See [Scroll utilities](../ScrollUtilities.md).
6
+
5
7
  ## Import
6
8
 
7
9
  ```ts
@@ -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
 
@@ -1,7 +1,8 @@
1
1
  # CalendarRange
2
2
 
3
- Dual-month calendar for selecting a date range. Shared year/month selectors with
4
- two date panels (`orientation="horizontal"` side-by-side, or `"vertical"` stacked).
3
+ Dual-month calendar for selecting a date range. Year sits on the left and nav
4
+ on the right; month selectors sit inward from the header midpoint
5
+ (`orientation="horizontal"` side-by-side, or `"vertical"` stacked).
5
6
 
6
7
  ## Import
7
8
 
@@ -28,7 +29,7 @@ import { CalendarRange } from "@bridge-ui/vue/Components/CalendarRange";
28
29
  ```vue
29
30
  <CalendarRange
30
31
  :custom-props="{
31
- panels: { class: 'gap-4' },
32
+ startHeader: { class: 'pr-2' },
32
33
  root: { 'data-testid': 'calendar-range' },
33
34
  }"
34
35
  />
@@ -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
  ```
@@ -1,7 +1,8 @@
1
1
  # DateRangePicker
2
2
 
3
- Inline dual-month picker for an inclusive date range (`[start, end]`). The header
4
- exposes year, start month, and end month selectors in one row.
3
+ Inline dual-month picker for an inclusive date range (`[start, end]`). Year sits
4
+ on the left and nav on the right; month selectors sit inward from the header
5
+ midpoint.
5
6
 
6
7
  ## Import
7
8
 
@@ -20,7 +21,7 @@ import { DateRangePicker } from "@bridge-ui/vue/Components/DateRangePicker";
20
21
 
21
22
  <DateRangePicker orientation="vertical" />
22
23
 
23
- <DateRangePicker show-footer v-model="range" @cancel="() => {}" />
24
+ <DateRangePicker show-footer v-model="range" v-on:cancel="() => {}" />
24
25
  ```
25
26
 
26
27
  ## Props
@@ -96,27 +96,27 @@ import { Drawer } from "@bridge-ui/vue/Components/Drawer";
96
96
 
97
97
  ## Props
98
98
 
99
- | Prop | Type | Default | Description |
100
- | --------------------- | ------------------- | ------- | ------------------------------------------------------------------------------------------ |
101
- | `ariaLabel` | `string` | — | Accessible name for the dialog (`aria-label`). |
102
- | `ariaLabelledBy` | `string` | — | Id of the element that labels the dialog (`aria-labelledby`). |
103
- | `autoFocus` | `boolean` | `false` | When true, focuses the first focusable element inside the drawer on open. |
104
- | `blur` | `DrawerBlur` | "none" | Backdrop blur on the overlay. |
105
- | `classes` | `DrawerClasses` | — | The classes to apply to the drawer. |
106
- | `closeOnEscape` | `boolean` | `true` | Whether the drawer closes on escape key press. |
107
- | `closeOnOverlay` | `boolean` | `true` | Whether the drawer closes on overlay click. |
108
- | `customProps` | `DrawerCustomProps` | — | Props forwarded to each drawer part. |
109
- | `disableEnforceFocus` | `boolean` | `false` | When true, focus is not trapped inside the drawer while open. |
110
- | `disableRestoreFocus` | `boolean` | `false` | When true, focus is not restored to the previously focused element on close. |
111
- | `disableScrollLock` | `boolean` | `false` | When true, body scroll is not locked while the drawer is open. |
112
- | `hideBackdrop` | `boolean` | `false` | When true, the backdrop overlay is not rendered. |
113
- | `keepMounted` | `boolean` | `false` | When true, the drawer stays mounted in the DOM after closing (hidden). |
114
- | `persistent` | `boolean` | `false` | When true, escape and overlay clicks do not close the drawer. |
115
- | `placement` | `DrawerPlacement` | "left" | Edge the panel docks to. |
116
- | `scroll` | `DrawerScroll` | "paper" | Where scroll happens: the page (`body`) or the drawer panel (`paper`). |
117
- | `size` | `DrawerSize` | "md" | Panel size along the placement axis (width for `left`/`right`, height for `top`/`bottom`). |
118
- | `teleportTo` | `string \| false` | "body" | Where to teleport the drawer. Pass `false` to render in place. |
119
- | `transition` | `DrawerTransition` | "slide" | Enter/leave animation for overlay and panel. |
99
+ | Prop | Type | Default | Description |
100
+ | --------------------- | ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- |
101
+ | `ariaLabel` | `string` | — | Accessible name for the dialog (`aria-label`). |
102
+ | `ariaLabelledBy` | `string` | — | Id of the element that labels the dialog (`aria-labelledby`). |
103
+ | `autoFocus` | `boolean` | `false` | When true, focuses the first focusable element inside the drawer on open. |
104
+ | `blur` | `DrawerBlur` | "none" | Backdrop blur on the overlay. |
105
+ | `classes` | `DrawerClasses` | — | The classes to apply to the drawer. |
106
+ | `closeOnEscape` | `boolean` | `true` | Whether the drawer closes on escape key press. |
107
+ | `closeOnOverlay` | `boolean` | `true` | Whether the drawer closes on overlay click. |
108
+ | `customProps` | `DrawerCustomProps` | — | Props forwarded to each drawer part. |
109
+ | `disableEnforceFocus` | `boolean` | `false` | When true, focus is not trapped inside the drawer while open. |
110
+ | `disableRestoreFocus` | `boolean` | `false` | When true, focus is not restored to the previously focused element on close. |
111
+ | `disableScrollLock` | `boolean` | `false` | When true, body scroll is not locked while the drawer is open. |
112
+ | `hideBackdrop` | `boolean` | `false` | When true, the backdrop overlay is not rendered. |
113
+ | `keepMounted` | `boolean` | `false` | When true, the drawer stays mounted in the DOM after closing (hidden). |
114
+ | `persistent` | `boolean` | `false` | When true, escape and overlay clicks do not close the drawer. |
115
+ | `placement` | `DrawerPlacement` | "left" | Edge the panel docks to. |
116
+ | `scroll` | `DrawerScroll` | "paper" | Where scroll happens: the page (`body`) or the drawer panel (`paper`). `paper` uses `bridge-scroll-fade-y` and `bridge-hide-scrollbar`. |
117
+ | `size` | `DrawerSize` | "md" | Panel size along the placement axis (width for `left`/`right`, height for `top`/`bottom`). |
118
+ | `teleportTo` | `string \| false` | "body" | Where to teleport the drawer. Pass `false` to render in place. |
119
+ | `transition` | `DrawerTransition` | "slide" | Enter/leave animation for overlay and panel. |
120
120
 
121
121
  ### v-model
122
122
 
@@ -2,9 +2,10 @@
2
2
 
3
3
  Switches between `Menu`, `Modal`, and `Drawer` shells for field pickers and listboxes.
4
4
  Dialog shells size to the picker: `modal` uses `w-fit` up to the viewport;
5
- `drawer` is full width and up to `90dvh`, and scrolls horizontally when dual
6
- calendars or time columns overflow. Nested pickers flush the bottom radius in a
7
- drawer so the shell meets the screen edge.
5
+ `drawer` is full width and up to `90dvh`. Dual calendars and time columns that
6
+ overflow the sheet width scroll on an inner scroller (`bridge-scroll-fade-x`).
7
+ Vertical fade comes from `scroll="paper"`. Nested pickers flush the bottom
8
+ radius in a drawer so the shell meets the screen edge.
8
9
 
9
10
  ## Import
10
11
 
@@ -38,7 +39,7 @@ import { FieldOverlay } from "@bridge-ui/vue/Components/FieldOverlay";
38
39
 
39
40
  ### customProps
40
41
 
41
- Forward props to the active shell via `customProps.menu`, `customProps.modal`, or `customProps.drawer`. Menu-only options such as `anchorEl`, `placement`, `disableAutoFocus`, and `rounded` go through `customProps.menu`.
42
+ Forward props to the active shell via `customProps.menu`, `customProps.modal`, or `customProps.drawer`. The drawer inner scroller accepts `customProps.drawerScroller`. Menu-only options such as `anchorEl`, `placement`, `disableAutoFocus`, and `rounded` go through `customProps.menu`.
42
43
 
43
44
  ```vue
44
45
  <FieldOverlay
@@ -64,6 +65,16 @@ Forward props to the active shell via `customProps.menu`, `customProps.modal`, o
64
65
  >
65
66
  <PickerContent />
66
67
  </FieldOverlay>
68
+
69
+ <FieldOverlay
70
+ v-model="open"
71
+ overlay="drawer"
72
+ :custom-props="{
73
+ drawerScroller: { class: 'bridge-scroll-fade-none' },
74
+ }"
75
+ >
76
+ <PickerContent />
77
+ </FieldOverlay>
67
78
  ```
68
79
 
69
80
  ### Footer close
@@ -79,10 +90,10 @@ overlay. Use the picker slot callbacks in custom footers so Apply still commits.
79
90
 
80
91
  ## Props
81
92
 
82
- | Prop | Type | Default | Description |
83
- | ------------- | ------------------------- | -------- | ---------------------------------------------------------- |
84
- | `customProps` | `FieldOverlayCustomProps` | — | Extra props for nested shells (`menu`, `modal`, `drawer`). |
85
- | `overlay` | `FieldOverlayMode` | `"auto"` | Overlay shell: `menu`, `modal`, `drawer`, or `auto`. |
93
+ | Prop | Type | Default | Description |
94
+ | ------------- | ------------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
95
+ | `customProps` | `FieldOverlayCustomProps` | — | Extra props for nested shells (`menu`, `modal`, `drawer`) and the drawer scroller (`drawerScroller`). |
96
+ | `overlay` | `FieldOverlayMode` | `"auto"` | Overlay shell: `menu`, `modal`, `drawer`, or `auto`. |
86
97
 
87
98
  ### v-model
88
99