@soft-stech/bootsman-ui-shadcn 1.4.24 → 1.4.26

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 (27) hide show
  1. package/dist/BuiDataTableColumnList.vue_vue_type_script_setup_true_lang-DsrMMFKz.js +1338 -0
  2. package/dist/BuiTable.vue_vue_type_script_setup_true_lang-QoPGiEYZ.js +28 -0
  3. package/dist/{BuiTableHeader.vue_vue_type_script_setup_true_lang-B2getNR7.js → BuiTableHeader.vue_vue_type_script_setup_true_lang-BXgL487_.js} +1 -1
  4. package/dist/{BuiTooltipContent.vue_vue_type_script_setup_true_lang-ZfTnapKW.js → BuiTooltipContent.vue_vue_type_script_setup_true_lang-CZ1I3edy.js} +3 -3
  5. package/dist/assets/main.css +1 -1
  6. package/dist/components/ui/table/BuiDataTable.vue.d.ts +12 -2
  7. package/dist/components/ui/table/BuiDataTableColumnList.js +4 -0
  8. package/dist/components/ui/table/BuiDataTableColumnList.vue.d.ts +24 -0
  9. package/dist/components/ui/table/BuiTable.js +1 -1
  10. package/dist/components/ui/table/BuiTable.vue.d.ts +1 -0
  11. package/dist/components/ui/table/BuiTableHeader.js +1 -1
  12. package/dist/components/ui/table/index.d.ts +1 -0
  13. package/dist/components/ui/table/index.js +310 -190
  14. package/dist/components/ui/tooltip/BuiTooltipContent.js +1 -1
  15. package/dist/components/ui/tooltip/index.js +1 -1
  16. package/dist/index.js +18 -16
  17. package/dist/variables.css +1 -1
  18. package/package.json +7 -5
  19. package/src/assets/variables.css +9 -8
  20. package/src/components/stories/BuiDataTable.story.vue +20 -4
  21. package/src/components/ui/table/BuiDataTable.vue +136 -20
  22. package/src/components/ui/table/BuiDataTableColumnList.vue +32 -0
  23. package/src/components/ui/table/BuiTable.vue +1 -0
  24. package/src/components/ui/table/BuiTableHeader.vue +2 -2
  25. package/src/components/ui/table/index.ts +1 -0
  26. package/src/components/ui/tooltip/BuiTooltipContent.vue +1 -1
  27. package/dist/BuiTable.vue_vue_type_script_setup_true_lang-D8Tseif4.js +0 -27
@@ -1,4 +1,4 @@
1
- import { _ as f } from "../../../BuiTooltipContent.vue_vue_type_script_setup_true_lang-ZfTnapKW.js";
1
+ import { _ as f } from "../../../BuiTooltipContent.vue_vue_type_script_setup_true_lang-CZ1I3edy.js";
2
2
  export {
3
3
  f as default
4
4
  };
@@ -1,5 +1,5 @@
1
1
  import { _ as i } from "../../../BuiTooltip.vue_vue_type_script_setup_true_lang-Cas1FHjM.js";
2
- import { _ as p } from "../../../BuiTooltipContent.vue_vue_type_script_setup_true_lang-ZfTnapKW.js";
2
+ import { _ as p } from "../../../BuiTooltipContent.vue_vue_type_script_setup_true_lang-CZ1I3edy.js";
3
3
  import { _ as T } from "../../../BuiTooltipTrigger.vue_vue_type_script_setup_true_lang-CnGv207Y.js";
4
4
  import { _ as f } from "../../../BuiTooltipProvider.vue_vue_type_script_setup_true_lang-CCOYEiUg.js";
5
5
  export {
package/dist/index.js CHANGED
@@ -113,7 +113,7 @@ import { BuiTabsList as Rt, BuiTabsTrigger as Gt, tabsListVariants as Et, tabsTr
113
113
  import { BuiTextarea as Nt, textareaVariants as jt } from "./components/ui/textarea/index.js";
114
114
  import { BuiToast as Jt, BuiToaster as Kt, toastVariants as Ut } from "./components/ui/toast/index.js";
115
115
  import { _ as zt } from "./BuiTooltip.vue_vue_type_script_setup_true_lang-Cas1FHjM.js";
116
- import { _ as Wt } from "./BuiTooltipContent.vue_vue_type_script_setup_true_lang-ZfTnapKW.js";
116
+ import { _ as Wt } from "./BuiTooltipContent.vue_vue_type_script_setup_true_lang-CZ1I3edy.js";
117
117
  import { _ as Zt } from "./BuiTooltipTrigger.vue_vue_type_script_setup_true_lang-CnGv207Y.js";
118
118
  import { _ as oa } from "./BuiTooltipProvider.vue_vue_type_script_setup_true_lang-CCOYEiUg.js";
119
119
  import { BuiToggle as ea, toggleVariants as ta } from "./components/ui/toggle/index.js";
@@ -145,11 +145,11 @@ import { _ as ai } from "./BuiAlertDescription.vue_vue_type_script_setup_true_la
145
145
  import { _ as ui } from "./BuiAvatarImage.vue_vue_type_script_setup_true_lang-DELf2i8H.js";
146
146
  import { _ as si } from "./BuiAvatarFallback.vue_vue_type_script_setup_true_lang-B1ncuXZ0.js";
147
147
  import "./BuiCalendar.vue_vue_type_style_index_0_lang-DK4yUiXC.js";
148
- import { _ as Bi } from "./BuiTable.vue_vue_type_script_setup_true_lang-D8Tseif4.js";
148
+ import { _ as Bi } from "./BuiTable.vue_vue_type_script_setup_true_lang-QoPGiEYZ.js";
149
149
  import { _ as fi } from "./BuiTableBody.vue_vue_type_script_setup_true_lang-DblqmDim.js";
150
150
  import { _ as _i } from "./BuiTableCell.vue_vue_type_script_setup_true_lang-CYBx0oJL.js";
151
151
  import { _ as di } from "./BuiTableHead.vue_vue_type_script_setup_true_lang-BDSRArVd.js";
152
- import { _ as Ci } from "./BuiTableHeader.vue_vue_type_script_setup_true_lang-B2getNR7.js";
152
+ import { _ as Ci } from "./BuiTableHeader.vue_vue_type_script_setup_true_lang-BXgL487_.js";
153
153
  import { _ as Fi } from "./BuiTableRow.vue_vue_type_script_setup_true_lang-Bl4nF6yV.js";
154
154
  import { _ as Si } from "./BuiTableCaption.vue_vue_type_script_setup_true_lang-CTEP1Sde.js";
155
155
  import { _ as Ai } from "./BuiTableEmpty.vue_vue_type_script_setup_true_lang-BTyX0sT5.js";
@@ -165,12 +165,13 @@ import { _ as ji } from "./BuiSheetHeader.vue_vue_type_script_setup_true_lang-vG
165
165
  import { _ as Ji } from "./BuiSheetTitle.vue_vue_type_script_setup_true_lang-D-bamlaT.js";
166
166
  import { _ as Ui } from "./BuiSheetTrigger.vue_vue_type_script_setup_true_lang-Bo3F1V-i.js";
167
167
  import { Form as zi, Field as Qi, FieldArray as Wi, useField as Xi, useFieldArray as Zi, useForm as $i } from "vee-validate";
168
- import { _ as ru } from "./BuiToastViewport.vue_vue_type_script_setup_true_lang-BBDzM6Br.js";
169
- import { _ as tu } from "./BuiToastClose.vue_vue_type_script_setup_true_lang-fLjieQsa.js";
170
- import { _ as iu } from "./BuiToastTitle.vue_vue_type_script_setup_true_lang-D1VfRzjv.js";
171
- import { _ as pu } from "./BuiToastDescription.vue_vue_type_script_setup_true_lang-CZ5Gk9K4.js";
172
- import { _ as mu } from "./BuiToastProvider.vue_vue_type_script_setup_true_lang-ZXzJkgBD.js";
173
- import { toast as xu, useToast as fu } from "./components/ui/toast/use-toast.js";
168
+ import { _ as ru } from "./BuiDataTableColumnList.vue_vue_type_script_setup_true_lang-DsrMMFKz.js";
169
+ import { _ as tu } from "./BuiToastViewport.vue_vue_type_script_setup_true_lang-BBDzM6Br.js";
170
+ import { _ as iu } from "./BuiToastClose.vue_vue_type_script_setup_true_lang-fLjieQsa.js";
171
+ import { _ as pu } from "./BuiToastTitle.vue_vue_type_script_setup_true_lang-D1VfRzjv.js";
172
+ import { _ as mu } from "./BuiToastDescription.vue_vue_type_script_setup_true_lang-CZ5Gk9K4.js";
173
+ import { _ as xu } from "./BuiToastProvider.vue_vue_type_script_setup_true_lang-ZXzJkgBD.js";
174
+ import { toast as nu, useToast as _u } from "./components/ui/toast/use-toast.js";
174
175
  export {
175
176
  a as BuiAccordion,
176
177
  u as BuiAccordionContent,
@@ -244,6 +245,7 @@ export {
244
245
  pr as BuiContextMenuSubTrigger,
245
246
  Oo as BuiContextMenuTrigger,
246
247
  vt as BuiDataTable,
248
+ ru as BuiDataTableColumnList,
247
249
  xr as BuiDialog,
248
250
  nr as BuiDialogClose,
249
251
  br as BuiDialogContent,
@@ -343,11 +345,11 @@ export {
343
345
  Nt as BuiTextarea,
344
346
  Jt as BuiToast,
345
347
  vi as BuiToastAction,
346
- tu as BuiToastClose,
347
- pu as BuiToastDescription,
348
- mu as BuiToastProvider,
349
- iu as BuiToastTitle,
350
- ru as BuiToastViewport,
348
+ iu as BuiToastClose,
349
+ mu as BuiToastDescription,
350
+ xu as BuiToastProvider,
351
+ pu as BuiToastTitle,
352
+ tu as BuiToastViewport,
351
353
  Kt as BuiToaster,
352
354
  ea as BuiToggle,
353
355
  ia as BuiToggleGroup,
@@ -380,12 +382,12 @@ export {
380
382
  Ot as tabsTriggerVariants,
381
383
  oi as tailwind,
382
384
  jt as textareaVariants,
383
- xu as toast,
385
+ nu as toast,
384
386
  Ut as toastVariants,
385
387
  ta as toggleVariants,
386
388
  Xi as useBuiField,
387
389
  Zi as useBuiFieldArray,
388
390
  $i as useBuiForm,
389
- fu as useToast,
391
+ _u as useToast,
390
392
  $ as valueUpdater
391
393
  };
@@ -1 +1 @@
1
- :root{--background: 0 0% 100%;--foreground: 242 24% 21%;--muted: 210 40% 96.1%;--muted-foreground: 225 5% 47%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--card-shadow: 241 92% 71%, .16;--tab-shadow: 228, 51%, 11%, .08;--border: 241 92% 71%;--input: 225 11% 84%;--primary: 241 92% 71%;--primary-hover: 241 76% 62%;--primary-active: 241 54% 54%;--primary-foreground: 0 0% 100%;--secondary: 210 40% 96.1%;--secondary-foreground: 241 76% 62%;--accent: 241 92% 71%;--accent-foreground: 241 76% 62%;--destructive: 328, 68%, 63%, .16;--destructive-foreground: 328, 68%, 63%;--success: 181, 34%, 39%, .16;--success-foreground: 181, 34%, 39%;--warning: 48, 79%, 45%, .16;--warning-foreground: 48, 79%, 45%;--info: 198, 85%, 45%, .16;--info-foreground: 198 85% 45%;--ring: 241 92% 71%;--radius: .5rem;--tooltip: 225 5% 47%}.dark{--background: 242 24% 21%;--foreground: 0 0% 100%;--muted: 217.2 32.6% 17.5%;--muted-foreground: 0, 0%, 100%, .32;--popover: 222.2 84% 4.9%;--popover-foreground: 210 40% 98%;--card: 242 24% 21%;--card-foreground: 210 40% 98%;--card-shadow: 241 92% 71%, .4;--tab-shadow: 228, 51%, 11%, .08;--border: 241 92% 71%;--input: 0, 0%, 100%, .32;--primary: 241 92% 71%;--primary-hover: 241 76% 62%;--primary-active: 241 54% 54%;--primary-foreground: 0 0% 100%;--secondary: 217.2 32.6% 17.5%;--secondary-foreground: 210 40% 98%;--accent: 241 92% 71%;--accent-foreground: 240 100% 77%;--destructive: 328, 68%, 63%, .16;--destructive-foreground: 328, 68%, 63%;--success: 181, 34%, 39%, .16;--success-foreground: 152 80% 38%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}
1
+ :root{--background: 0 0% 100%;--foreground: 242 24% 21%;--muted: 210 40% 96.1%;--muted-foreground: 225 5% 47%;--popover: 0 0% 100%;--popover-foreground: 222.2 84% 4.9%;--card: 0 0% 100%;--card-foreground: 222.2 84% 4.9%;--card-shadow: 241, 92%, 71%, .16;--tab-shadow: 228, 51%, 11%, .08;--border: 241 92% 71%;--input: 225 11% 84%;--primary: 241 92% 71%;--primary-hover: 241 76% 62%;--primary-active: 241 54% 54%;--primary-foreground: 0 0% 100%;--secondary: 210 40% 96.1%;--secondary-foreground: 241 76% 62%;--accent: 241 92% 71%;--accent-foreground: 241 76% 62%;--destructive: 328, 68%, 63%, .16;--destructive-foreground: 328 68% 63%;--success: 181, 34%, 39%, .16;--success-foreground: 181 34% 39%;--warning: 48, 79%, 45%, .16;--warning-foreground: 48 79% 45%;--info: 198, 85%, 45%, .16;--info-foreground: 198 85% 45%;--ring: 241 92% 71%;--radius: .5rem;--tooltip: 225 5% 47%;--tooltip-link: 241 100% 88%}.dark{--background: 242 24% 21%;--foreground: 0 0% 100%;--muted: 217.2 32.6% 17.5%;--muted-foreground: 0, 0%, 100%, .32;--popover: 222.2 84% 4.9%;--popover-foreground: 210 40% 98%;--card: 242 24% 21%;--card-foreground: 210 40% 98%;--card-shadow: 241, 92%, 71%, .4;--tab-shadow: 228, 51%, 11%, .08;--border: 241 92% 71%;--input: 0, 0%, 100%, .32;--primary: 241 92% 71%;--primary-hover: 241 76% 62%;--primary-active: 241 54% 54%;--primary-foreground: 0 0% 100%;--secondary: 217.2 32.6% 17.5%;--secondary-foreground: 210 40% 98%;--accent: 241 92% 71%;--accent-foreground: 240 100% 77%;--destructive: 328, 68%, 63%, .16;--destructive-foreground: 328 68% 63%;--success: 154, 84%, 45%, .16;--success-foreground: 181 35% 49%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soft-stech/bootsman-ui-shadcn",
3
- "version": "1.4.24",
3
+ "version": "1.4.26",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -15,19 +15,21 @@
15
15
  "url": "https://github.com/soft-stech/bootsman-ui-shadcn"
16
16
  },
17
17
  "peerDependencies": {
18
- "vue": "^3.5.6",
19
- "zod": "^3.23.6",
20
- "vee-validate": "^4.13.2",
21
18
  "@tanstack/vue-table": "8.20.5",
22
19
  "@vee-validate/zod": "4.13.2",
23
- "@vueuse/core": "11.1.0"
20
+ "@vueuse/core": "11.1.0",
21
+ "vee-validate": "^4.13.2",
22
+ "vue": "^3.5.6",
23
+ "zod": "^3.23.6"
24
24
  },
25
25
  "dependencies": {
26
26
  "@internationalized/date": "^3.5.5",
27
+ "@vueuse/integrations": "^13.0.0",
27
28
  "class-variance-authority": "0.7.0",
28
29
  "clsx": "2.1.1",
29
30
  "lucide-vue-next": "0.441.0",
30
31
  "radix-vue": "1.9.8",
32
+ "sortablejs": "^1",
31
33
  "tailwind-merge": "2.5.2",
32
34
  "tailwindcss-animate": "1.0.7",
33
35
  "v-calendar": "3.1.2"
@@ -10,7 +10,7 @@
10
10
 
11
11
  --card: 0 0% 100%;
12
12
  --card-foreground: 222.2 84% 4.9%;
13
- --card-shadow: 241 92% 71%, 0.16;
13
+ --card-shadow: 241, 92%, 71%, 0.16;
14
14
  --tab-shadow: 228, 51%, 11%, 0.08;
15
15
 
16
16
  --border: 241 92% 71%;
@@ -28,13 +28,13 @@
28
28
  --accent-foreground: 241 76% 62%;
29
29
 
30
30
  --destructive: 328, 68%, 63%, 0.16;
31
- --destructive-foreground: 328, 68%, 63%;
31
+ --destructive-foreground: 328 68% 63%;
32
32
 
33
33
  --success: 181, 34%, 39%, 0.16;
34
- --success-foreground: 181, 34%, 39%;
34
+ --success-foreground: 181 34% 39%;
35
35
 
36
36
  --warning: 48, 79%, 45%, 0.16;
37
- --warning-foreground: 48, 79%, 45%;
37
+ --warning-foreground: 48 79% 45%;
38
38
 
39
39
  --info: 198, 85%, 45%, 0.16;
40
40
  --info-foreground: 198 85% 45%;
@@ -44,6 +44,7 @@
44
44
  --radius: 0.5rem;
45
45
 
46
46
  --tooltip: 225 5% 47%;
47
+ --tooltip-link: 241 100% 88%;
47
48
  }
48
49
 
49
50
  .dark {
@@ -58,7 +59,7 @@
58
59
 
59
60
  --card: 242 24% 21%;
60
61
  --card-foreground: 210 40% 98%;
61
- --card-shadow: 241 92% 71%, 0.4;
62
+ --card-shadow: 241, 92%, 71%, 0.4;
62
63
  --tab-shadow: 228, 51%, 11%, 0.08;
63
64
 
64
65
  --border: 241 92% 71%;
@@ -76,10 +77,10 @@
76
77
  --accent-foreground: 240 100% 77%;
77
78
 
78
79
  --destructive: 328, 68%, 63%, 0.16;
79
- --destructive-foreground: 328, 68%, 63%;
80
+ --destructive-foreground: 328 68% 63%;
80
81
 
81
- --success: 181, 34%, 39%, 0.16;
82
- --success-foreground: 152 80% 38%;
82
+ --success: 154, 84%, 45%, 0.16;
83
+ --success-foreground: 181 35% 49%;
83
84
  }
84
85
 
85
86
  * {
@@ -3,7 +3,15 @@ import { BuiDataTable } from '@/components/ui/table'
3
3
  import RowActionsMenuContent from './components/ActionsMenuContent.vue'
4
4
  import { BuiButton, BuiCheckbox, BuiTabs, BuiTabsList, BuiTabsTrigger } from '@/index'
5
5
  import { tableColumnSortCommon } from '@/lib/utils'
6
- import type { ColumnDef, PaginationState, Row, RowSelectionState } from '@tanstack/vue-table'
6
+ import type {
7
+ ColumnDef,
8
+ PaginationState,
9
+ Row,
10
+ RowSelectionState,
11
+ ColumnSizingState,
12
+ VisibilityState,
13
+ ColumnOrderState
14
+ } from '@tanstack/vue-table'
7
15
  import { sort, type ISortByObjectSorter } from 'fast-sort'
8
16
  import { logEvent } from 'histoire/client'
9
17
  import {
@@ -55,7 +63,8 @@ const columns: ColumnDef<Task>[] = [
55
63
  ariaLabel: 'Select row'
56
64
  }),
57
65
  `${row.getValue('id')}`
58
- ])
66
+ ]),
67
+ enableHiding: false
59
68
  },
60
69
  {
61
70
  accessorKey: 'title',
@@ -63,7 +72,8 @@ const columns: ColumnDef<Task>[] = [
63
72
  },
64
73
  {
65
74
  accessorKey: 'status',
66
- header: ({ column }) => tableColumnSortCommon(column, 'Status')
75
+ header: ({ column }) => tableColumnSortCommon(column, 'Status'),
76
+ meta: { title: 'Статус таска' }
67
77
  },
68
78
  {
69
79
  accessorKey: 'priority',
@@ -96,6 +106,10 @@ function updateSelection(val: RowSelectionState) {
96
106
  selection.value = val
97
107
  }
98
108
 
109
+ const columnVisibility = ref<VisibilityState>({ hiddenColumn: false })
110
+ const columnSizing = ref<ColumnSizingState>({ title: 300 })
111
+ const columnOrder = ref<ColumnOrderState>()
112
+
99
113
  type GroupBy = 'none' | 'status' | 'priority'
100
114
  const groupBy = ref<GroupBy>('none')
101
115
  const groupLabels = {
@@ -175,6 +189,9 @@ function groupName(group: string | number) {
175
189
  :data="sortedData"
176
190
  v-model:sorting="sorting"
177
191
  v-model:pagination="pagination"
192
+ v-model:column-sizing="columnSizing"
193
+ v-model:column-visibility="columnVisibility"
194
+ v-model:column-order="columnOrder"
178
195
  @update:selection="updateSelection"
179
196
  :total-items="totalItems"
180
197
  class="caption-top"
@@ -183,7 +200,6 @@ function groupName(group: string | number) {
183
200
  :groupBy="groupBy === 'none' ? undefined : groupBy"
184
201
  :groupLabels="groupLabels"
185
202
  :renderSubComponent="renderSubComponent"
186
- :columnVisibility="{ hiddenColumn: false }"
187
203
  >
188
204
  <template #caption="{ table }">
189
205
  <div class="flex justify-between">
@@ -6,9 +6,12 @@ import {
6
6
  } from '@/components/ui/collapsible'
7
7
  import { BuiPaginationCommon, type PageSize } from '@/components/ui/pagination'
8
8
  import BuiTableRowSubrow from '@/components/ui/table/BuiTableRowSubrow.vue'
9
- import { valueUpdater } from '@/lib/utils'
9
+ import { valueUpdater, cn } from '@/lib/utils'
10
10
  import type {
11
+ Column,
11
12
  ColumnDef,
13
+ ColumnOrderState,
14
+ ColumnSizingState,
12
15
  PaginationState,
13
16
  Row,
14
17
  RowSelectionState,
@@ -22,7 +25,7 @@ import {
22
25
  getSortedRowModel,
23
26
  useVueTable
24
27
  } from '@tanstack/vue-table'
25
- import { computed, watchEffect } from 'vue'
28
+ import { computed, watchEffect, ref, watch } from 'vue'
26
29
  import {
27
30
  BuiTable,
28
31
  BuiTableBody,
@@ -31,8 +34,19 @@ import {
31
34
  BuiTableHead,
32
35
  BuiTableHeader,
33
36
  BuiTableRow,
34
- getPinningStyle
37
+ getPinningStyle,
38
+ BuiDataTableColumnList
35
39
  } from './'
40
+ import {
41
+ BuiCommand,
42
+ BuiCommandEmpty,
43
+ BuiCommandInput,
44
+ BuiCommandList
45
+ } from '@/components/ui/command'
46
+ import { BuiPopover, BuiPopoverContent, BuiPopoverTrigger } from '@/components/ui/popover'
47
+ import { BuiScrollArea } from '@/components/ui/scroll-area'
48
+ import { BuiButton } from '@/components/ui/button'
49
+ import { Settings2Icon } from 'lucide-vue-next'
36
50
 
37
51
  const NO_GROUP_KEY = '#UNDEFINED#'
38
52
 
@@ -50,21 +64,37 @@ const props = withDefaults(
50
64
  getRowId?: (originalRow: TData, index: number, parent?: Row<TData>) => string
51
65
  renderSubComponent?: (row: Row<TData>) => (() => any) | undefined
52
66
  freezeHeader?: boolean
67
+ columnSearchPlaceholder?: string
68
+ columnSearchNotFound?: string
53
69
  }>(),
54
- { pageSize: 10, showPagination: true, manualPagination: true, manualSorting: true, totalItems: 0 }
70
+ {
71
+ pageSize: 10,
72
+ showPagination: true,
73
+ manualPagination: true,
74
+ manualSorting: true,
75
+ totalItems: 0,
76
+ columnSearchPlaceholder: 'Column name',
77
+ columnSearchNotFound: 'Not found'
78
+ }
55
79
  )
56
80
 
57
81
  const sorting = defineModel<SortingState>('sorting')
58
82
  const pagination = defineModel<PaginationState>('pagination')
59
83
  const rowSelection = defineModel<RowSelectionState>('selection')
60
84
  const columnVisibility = defineModel<VisibilityState>('columnVisibility')
85
+ const columnSizing = defineModel<ColumnSizingState>('columnSizing')
86
+ const columnOrder = defineModel<ColumnOrderState>('columnOrder')
61
87
  const computedItems = computed(() =>
62
88
  props.manualPagination ? props.totalItems : props.data.length
63
89
  )
90
+ const pinnedColumns = props.columns
91
+ .map((col) => (col.meta?.pinLeft && col.id ? col.id : ''))
92
+ .filter(Boolean)
93
+
64
94
  const table = useVueTable({
65
95
  initialState: {
66
96
  // TODO: column freeze
67
- //columnPinning: { left: ['id'] },
97
+ columnPinning: { left: pinnedColumns },
68
98
  pagination: { pageSize: props.pageSize }
69
99
  },
70
100
  get data() {
@@ -85,9 +115,21 @@ const table = useVueTable({
85
115
  onRowSelectionChange: (updaterOrValue) => {
86
116
  valueUpdater(updaterOrValue, rowSelection)
87
117
  },
118
+ onColumnVisibilityChange: (updaterOrValue) => {
119
+ valueUpdater(updaterOrValue, columnVisibility)
120
+ },
121
+ onColumnSizingChange: (updaterOrValue) => {
122
+ valueUpdater(updaterOrValue, columnSizing)
123
+ },
124
+ onColumnOrderChange: (updaterOrValue) => {
125
+ valueUpdater(updaterOrValue, columnOrder)
126
+ },
88
127
  autoResetPageIndex: false,
89
128
  manualPagination: props.manualPagination, // set to false to enable client-side pagination
90
129
  manualSorting: props.manualSorting,
130
+ enableColumnResizing: true,
131
+ columnResizeMode: 'onChange',
132
+ columnResizeDirection: 'ltr',
91
133
  state: {
92
134
  get sorting() {
93
135
  return sorting.value
@@ -100,6 +142,12 @@ const table = useVueTable({
100
142
  },
101
143
  get columnVisibility() {
102
144
  return columnVisibility.value
145
+ },
146
+ get columnSizing() {
147
+ return columnSizing.value
148
+ },
149
+ get columnOrder() {
150
+ return columnOrder.value
103
151
  }
104
152
  },
105
153
  getRowId: props.getRowId
@@ -150,6 +198,31 @@ function getGroupLabel(index: number) {
150
198
  const labels = props.groupBy && props.groupLabels ? props.groupLabels[props.groupBy] || [] : []
151
199
  return labels[index]
152
200
  }
201
+
202
+ const columnsList = ref<Column<TData, unknown>[]>(
203
+ table
204
+ .getAllColumns()
205
+ .filter((column) => typeof column.accessorFn !== 'undefined' && column.getCanHide())
206
+ .sort((a, b) => {
207
+ if (!columnOrder.value) return 0
208
+ else if (columnOrder.value?.indexOf(a.id) < 0 && columnOrder.value?.indexOf(b.id) >= 0)
209
+ return 1
210
+ else if (columnOrder.value?.indexOf(a.id) >= 0 && columnOrder.value?.indexOf(b.id) < 0)
211
+ return -1
212
+ else return columnOrder.value?.indexOf(a.id) - columnOrder.value?.indexOf(b.id)
213
+ })
214
+ )
215
+ const columnsListIds = computed(() => columnsList.value.map((col) => col.id))
216
+ const open = ref(false)
217
+ const searchColumn = ref('')
218
+
219
+ const tableHeaders = computed(() =>
220
+ table.getHeaderGroups().length > 0 ? table.getHeaderGroups()[0].headers : undefined
221
+ )
222
+
223
+ watch(columnsListIds, () => {
224
+ table.setColumnOrder(columnsListIds.value)
225
+ })
153
226
  </script>
154
227
 
155
228
  <template>
@@ -157,21 +230,64 @@ function getGroupLabel(index: number) {
157
230
  <slot name="caption" :table="table" />
158
231
  </div>
159
232
  <BuiTable>
160
- <BuiTableHeader :freeze-header="props.freezeHeader">
161
- <BuiTableRow v-for="headerGroup in table.getHeaderGroups()" :key="headerGroup.id">
162
- <BuiTableHead
163
- v-for="header in headerGroup.headers"
164
- :key="header.id"
165
- :style="{ ...getPinningStyle(header.column) }"
166
- :freeze-header="props.freezeHeader"
167
- >
168
- <FlexRender
169
- v-if="!header.isPlaceholder"
170
- :render="header.column.columnDef.header"
171
- :props="header.getContext()"
172
- />
173
- </BuiTableHead>
174
- </BuiTableRow>
233
+ <template #columnVisibility>
234
+ <BuiPopover v-model:open="open">
235
+ <BuiPopoverTrigger as-child>
236
+ <div class="absolute right-0 top-0 z-10 h-10 bg-background">
237
+ <div
238
+ class="flex h-full items-center border-l border-border/[0.16] bg-foreground/[0.04] px-1"
239
+ >
240
+ <BuiButton
241
+ variant="ghost"
242
+ class="flex h-8 w-8 items-center justify-center text-foreground"
243
+ >
244
+ <Settings2Icon class="h-4 w-4 flex-shrink-0 opacity-50" />
245
+ </BuiButton>
246
+ </div>
247
+ </div>
248
+ </BuiPopoverTrigger>
249
+ <BuiPopoverContent class="w-[250px] p-0" align="start">
250
+ <BuiCommand>
251
+ <BuiCommandInput
252
+ :placeholder="columnSearchPlaceholder"
253
+ v-model="searchColumn"
254
+ @input="(event) => (searchColumn = event.target.value)"
255
+ />
256
+ <BuiCommandList>
257
+ <BuiScrollArea class="h-[300px]">
258
+ <BuiCommandEmpty>{{ columnSearchNotFound }}</BuiCommandEmpty>
259
+ <BuiDataTableColumnList
260
+ v-model:columns-list="columnsList as Column<TData, unknown>[]"
261
+ />
262
+ </BuiScrollArea>
263
+ </BuiCommandList>
264
+ </BuiCommand>
265
+ </BuiPopoverContent>
266
+ </BuiPopover>
267
+ </template>
268
+ <BuiTableHeader v-if="tableHeaders" :freeze-header="props.freezeHeader">
269
+ <BuiTableHead
270
+ v-for="header in tableHeaders"
271
+ :key="header.id"
272
+ :style="{ ...getPinningStyle(header.column), width: header.getSize() + 'px' }"
273
+ :freeze-header="props.freezeHeader"
274
+ >
275
+ <FlexRender
276
+ v-if="!header.isPlaceholder"
277
+ :render="header.column.columnDef.header"
278
+ :props="header.getContext()"
279
+ />
280
+ <div
281
+ @dblclick="() => header.column.resetSize()"
282
+ @mousedown="header.getResizeHandler()?.($event)"
283
+ :className="
284
+ cn(
285
+ 'absolute top-0 right-0 h-full w-1 bg-muted-foreground opacity-0 cursor-col-resize select-none touch-none hover:opacity-50',
286
+ header.column.getIsResizing() ? 'bg-primary opacity-50' : ''
287
+ )
288
+ "
289
+ />
290
+ </BuiTableHead>
175
291
  </BuiTableHeader>
176
292
  <BuiTableBody>
177
293
  <template v-if="table.getRowModel().rows?.length">
@@ -0,0 +1,32 @@
1
+ <script setup lang="ts" generic="TData, TValue">
2
+ import type { Column } from '@tanstack/vue-table'
3
+ import { useTemplateRef } from 'vue'
4
+
5
+ import { BuiCommandItem } from '@/components/ui/command'
6
+ import { BuiCheckbox } from '@/components/ui/checkbox'
7
+ import { useSortable } from '@vueuse/integrations/useSortable'
8
+
9
+ const columnsListRef = useTemplateRef<HTMLElement>('columnsListRef')
10
+ const columnsList = defineModel<Column<TData, unknown>[]>('columnsList', {
11
+ default: [],
12
+ required: true
13
+ })
14
+ useSortable(columnsListRef, columnsList, { handle: '.dragHandler' })
15
+ </script>
16
+
17
+ <template>
18
+ <div ref="columnsListRef">
19
+ <BuiCommandItem
20
+ v-for="col in columnsList"
21
+ :key="`column-${col.id}`"
22
+ :value="col.id"
23
+ class="flex gap-4 px-2 py-1.5 text-xs font-medium capitalize text-muted-foreground"
24
+ @select="col.toggleVisibility()"
25
+ >
26
+ <BuiCheckbox :checked="col.getIsVisible()" />
27
+ <div class="dragHandler grow">
28
+ {{ col.columnDef.meta?.title || col.id.replace(/([A-Z])/g, ' $1') }}
29
+ </div>
30
+ </BuiCommandItem>
31
+ </div>
32
+ </template>
@@ -7,6 +7,7 @@ const props = defineProps<{ class?: string }>()
7
7
 
8
8
  <template>
9
9
  <BuiScrollArea class="w-full grow overflow-auto rounded border border-border/[0.16]">
10
+ <slot name="columnVisibility" />
10
11
  <table :class="cn('w-full caption-top text-sm', props.class)">
11
12
  <slot />
12
13
  </table>
@@ -14,8 +14,8 @@ const props = defineProps<{
14
14
  '[&_tr]:border-border/[0.16]',
15
15
  props.class,
16
16
  props.freezeHeader
17
- ? 'sticky top-0 z-[1] [&_th:first-child>div>div]:pl-6 [&_th:last-child>div>div]:border-r-0 [&_th:last-child>div>div]:pr-6 [&_tr:last-child]:border-b-0'
18
- : '[&_th:first-child>div]:pl-6 [&_th:last-child>div]:border-0 [&_th:last-child>div]:pr-6 [&_tr]:border-b'
17
+ ? 'sticky top-0 z-[1] [&_th:first-child>div>div]:pl-6 [&_th:last-child>div>div]:border-r-0 [&_th:last-child>div>div]:pr-14 [&_tr:last-child]:border-b-0'
18
+ : '[&_th:first-child>div]:pl-6 [&_th:last-child>div]:border-0 [&_th:last-child>div]:pr-14 [&_tr]:border-b'
19
19
  )
20
20
  "
21
21
  >
@@ -12,6 +12,7 @@ export { default as BuiTableCaption } from './BuiTableCaption.vue'
12
12
  export { default as BuiTableEmpty } from './BuiTableEmpty.vue'
13
13
  export { default as BuiTableFooter } from './BuiTableFooter.vue'
14
14
  export { default as BuiDataTable } from './BuiDataTable.vue'
15
+ export { default as BuiDataTableColumnList } from './BuiDataTableColumnList.vue'
15
16
 
16
17
  export function getPinningStyle<TData>(column: Column<TData, unknown>): CSSProperties {
17
18
  const isPinned = column.getIsPinned()
@@ -22,7 +22,7 @@ const forwarded = useForwardPropsEmits(props, emits)
22
22
  v-bind="{ ...forwarded, ...$attrs }"
23
23
  :class="
24
24
  cn(
25
- 'shadow-level3 z-50 overflow-hidden rounded-md border border-muted bg-[hsl(var(--tooltip))] px-3 py-1.5 text-sm text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
25
+ 'z-50 overflow-hidden rounded-md border border-muted bg-[hsl(var(--tooltip))] px-3 py-1.5 text-sm text-primary-foreground shadow-level3 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 [&_a]:text-[hsl(var(--tooltip-link))] [&_a]:underline',
26
26
  $attrs.class ?? ''
27
27
  )
28
28
  "
@@ -1,27 +0,0 @@
1
- import { defineComponent as a, openBlock as s, createBlock as n, unref as o, withCtx as l, createElementVNode as c, normalizeClass as m, renderSlot as i, createVNode as f } from "vue";
2
- import { _ as p } from "./BuiScrollArea.vue_vue_type_script_setup_true_lang-D-nqw_Ka.js";
3
- import { _ } from "./BuiScrollBar.vue_vue_type_script_setup_true_lang-DNZ_v7U0.js";
4
- import { g as d } from "./utils-CwP7Up6y.js";
5
- const B = /* @__PURE__ */ a({
6
- __name: "BuiTable",
7
- props: {
8
- class: {}
9
- },
10
- setup(e) {
11
- const r = e;
12
- return (t, u) => (s(), n(o(p), { class: "w-full grow overflow-auto rounded border border-border/[0.16]" }, {
13
- default: l(() => [
14
- c("table", {
15
- class: m(o(d)("w-full caption-top text-sm", r.class))
16
- }, [
17
- i(t.$slots, "default")
18
- ], 2),
19
- f(o(_), { orientation: "horizontal" })
20
- ]),
21
- _: 3
22
- }));
23
- }
24
- });
25
- export {
26
- B as _
27
- };