Skip to content

Commit 1636f63

Browse files
committed
feat(VDataTable): customizable expand/collapse icons (#21698)
1 parent 01c9e91 commit 1636f63

File tree

11 files changed

+66
-8
lines changed

11 files changed

+66
-8
lines changed

packages/api-generator/src/locale/en/VDataTable.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"props": {
33
"calculateWidths": "Enables calculation of column widths. `widths` property will be available in select scoped slots.",
44
"checkboxColor": "Set the color of the checkboxes (showSelect must be used).",
5+
"collapseIcon": "Icon to display when the expandable row is expanded.",
56
"customFilter": "Function to filter items.",
67
"customGroup": "Function used to group items.",
78
"customSort": "Function used to sort items.",
@@ -10,9 +11,11 @@
1011
"disableFiltering": "Disables filtering completely.",
1112
"disablePagination": "Disables pagination completely.",
1213
"disableSort": "Disables sorting completely.",
13-
"expandIcon": "Icon used for expand toggle button.",
14+
"expandIcon": "Icon to display when the expandable row is collapsed.",
1415
"fixedHeader": "Fixed header to top of table.",
1516
"groupBy": "Configures attributes (and sort order) to group items together. Can be customized further with `group-header` slot.",
17+
"groupCollapseIcon": "Icon to display when the row group is expanded.",
18+
"groupExpandIcon": "Icon to display when the row group is collapsed.",
1619
"headerProps": "Pass props to the default header. See [`v-data-table-headers` API](/api/v-data-table-headers) for more information.",
1720
"headers": "An array of objects that each describe a header column.",
1821
"headersLength": "Can be used in combination with `hide-default-header` to specify the number of columns in the table to allow expansion rows and loading bar to function properly.",

packages/api-generator/src/locale/en/VDatePicker.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"displayDate": "The date displayed in the picker header.",
77
"eventColor": "Sets the color for event dot. It can be string (all events will have the same color) or `object` where attribute is the event date and value is boolean/color/array of colors for specified date or `function` taking date as a parameter and returning boolean/color/array of colors for that date.",
88
"events": "Array of dates or object defining events or colors or function returning boolean/color/array of colors.",
9-
"expandIcon": "Icon used for **view-mode** toggle.",
109
"headerColor": "Allows you to set a different color for the header when used in conjunction with the `color` prop.",
1110
"hideHeader": "Hides the header.",
1211
"hideWeekdays": "Hides the weekdays.",

packages/docs/src/data/new-in.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,29 @@
7979
},
8080
"VDataTable": {
8181
"props": {
82+
"collapseIcon": "3.10.0",
83+
"expandIcon": "3.10.0",
84+
"groupCollapseIcon": "3.10.0",
85+
"groupExpandIcon": "3.10.0",
8286
"headerProps": "3.5.0"
8387
}
8488
},
89+
"VDataTableServer": {
90+
"props": {
91+
"collapseIcon": "3.10.0",
92+
"expandIcon": "3.10.0",
93+
"groupCollapseIcon": "3.10.0",
94+
"groupExpandIcon": "3.10.0"
95+
}
96+
},
97+
"VDataTableVirtual": {
98+
"props": {
99+
"collapseIcon": "3.10.0",
100+
"expandIcon": "3.10.0",
101+
"groupCollapseIcon": "3.10.0",
102+
"groupExpandIcon": "3.10.0"
103+
}
104+
},
85105
"VDialog": {
86106
"props": {
87107
"stickToTarget": "3.10.0"

packages/vuetify/src/components/VDataTable/VDataTableGroupHeaderRow.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { VCheckboxBtn } from '@/components/VCheckbox'
77
import { useGroupBy } from './composables/group'
88
import { useHeaders } from './composables/headers'
99
import { useSelection } from './composables/select'
10+
import { IconValue } from '@/composables/icons'
1011

1112
// Utilities
1213
import { computed } from 'vue'
@@ -26,6 +27,14 @@ export const makeVDataTableGroupHeaderRowProps = propsFactory({
2627
type: Object as PropType<Group>,
2728
required: true,
2829
},
30+
groupCollapseIcon: {
31+
type: IconValue,
32+
default: '$tableGroupCollapse',
33+
},
34+
groupExpandIcon: {
35+
type: IconValue,
36+
default: '$tableGroupExpand',
37+
},
2938
}, 'VDataTableGroupHeaderRow')
3039

3140
export const VDataTableGroupHeaderRow = genericComponent<VDataTableGroupHeaderRowSlots>()({
@@ -51,7 +60,7 @@ export const VDataTableGroupHeaderRow = genericComponent<VDataTableGroupHeaderRo
5160
>
5261
{ columns.value.map(column => {
5362
if (column.key === 'data-table-group') {
54-
const icon = isGroupOpen(props.item) ? '$expand' : '$next'
63+
const icon = isGroupOpen(props.item) ? props.groupCollapseIcon : props.groupExpandIcon
5564
const onClick = () => toggleGroup(props.item)
5665

5766
return slots['data-table-group']?.({ item: props.item, count: rows.value.length, props: { icon, onClick } }) ?? (

packages/vuetify/src/components/VDataTable/VDataTableRow.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useHeaders } from './composables/headers'
99
import { useSelection } from './composables/select'
1010
import { useSort } from './composables/sort'
1111
import { makeDisplayProps, useDisplay } from '@/composables/display'
12+
import { IconValue } from '@/composables/icons'
1213

1314
// Utilities
1415
import { toDisplayString, withModifiers } from 'vue'
@@ -38,6 +39,15 @@ export const makeVDataTableRowProps = propsFactory({
3839
index: Number,
3940
item: Object as PropType<DataTableItem>,
4041
cellProps: [Object, Function] as PropType<CellProps<any>>,
42+
collapseIcon: {
43+
type: IconValue,
44+
default: '$collapse',
45+
},
46+
expandIcon: {
47+
type: IconValue,
48+
default: '$expand',
49+
},
50+
4151
onClick: EventProp<[MouseEvent]>(),
4252
onContextmenu: EventProp<[MouseEvent]>(),
4353
onDblclick: EventProp<[MouseEvent]>(),
@@ -166,14 +176,14 @@ export const VDataTableRow = genericComponent<new <T>(
166176
return slots['item.data-table-expand']?.({
167177
...slotProps,
168178
props: {
169-
icon: isExpanded(item) ? '$collapse' : '$expand',
179+
icon: isExpanded(item) ? props.collapseIcon : props.expandIcon,
170180
size: 'small',
171181
variant: 'text',
172182
onClick: withModifiers(() => toggleExpand(item), ['stop']),
173183
},
174184
}) ?? (
175185
<VBtn
176-
icon={ isExpanded(item) ? '$collapse' : '$expand' }
186+
icon={ isExpanded(item) ? props.collapseIcon : props.expandIcon }
177187
size="small"
178188
variant="text"
179189
onClick={ withModifiers(() => toggleExpand(item), ['stop']) }

packages/vuetify/src/components/VDataTable/VDataTableRows.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Components
2-
import { VDataTableGroupHeaderRow } from './VDataTableGroupHeaderRow'
3-
import { VDataTableRow } from './VDataTableRow'
2+
import { makeVDataTableGroupHeaderRowProps, VDataTableGroupHeaderRow } from './VDataTableGroupHeaderRow'
3+
import { makeVDataTableRowProps, VDataTableRow } from './VDataTableRow'
44

55
// Composables
66
import { useExpanded } from './composables/expand'
@@ -12,7 +12,7 @@ import { useLocale } from '@/composables/locale'
1212

1313
// Utilities
1414
import { Fragment, mergeProps } from 'vue'
15-
import { genericComponent, getPrefixedEventHandlers, propsFactory, useRender } from '@/util'
15+
import { genericComponent, getPrefixedEventHandlers, pick, propsFactory, useRender } from '@/util'
1616

1717
// Types
1818
import type { PropType } from 'vue'
@@ -48,6 +48,8 @@ export const makeVDataTableRowsProps = propsFactory({
4848
rowProps: [Object, Function] as PropType<RowProps<any>>,
4949
cellProps: [Object, Function] as PropType<CellProps<any>>,
5050

51+
...pick(makeVDataTableRowProps(), ['collapseIcon', 'expandIcon']),
52+
...pick(makeVDataTableGroupHeaderRowProps(), ['groupCollapseIcon', 'groupExpandIcon']),
5153
...makeDisplayProps(),
5254
}, 'VDataTableRows')
5355

@@ -72,6 +74,8 @@ export const VDataTableRows = genericComponent<new <T>(
7274
const { mobile } = useDisplay(props)
7375

7476
useRender(() => {
77+
const groupHeaderRowProps = pick(props, ['groupCollapseIcon', 'groupExpandIcon'])
78+
7579
if (props.loading && (!props.items.length || slots.loading)) {
7680
return (
7781
<tr
@@ -119,6 +123,7 @@ export const VDataTableRows = genericComponent<new <T>(
119123
key={ `group-header_${item.id}` }
120124
item={ item }
121125
{ ...getPrefixedEventHandlers(attrs, ':group-header', () => slotProps) }
126+
{ ...groupHeaderRowProps }
122127
v-slots={ slots }
123128
/>
124129
)
@@ -146,6 +151,8 @@ export const VDataTableRows = genericComponent<new <T>(
146151
index,
147152
item,
148153
cellProps: props.cellProps,
154+
collapseIcon: props.collapseIcon,
155+
expandIcon: props.expandIcon,
149156
mobile: mobile.value,
150157
},
151158
getPrefixedEventHandlers(attrs, ':row', () => slotProps),

packages/vuetify/src/iconsets/fa.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const aliases: IconAliases = {
4343
calendar: 'fas fa-calendar',
4444
treeviewCollapse: 'fas fa-caret-down',
4545
treeviewExpand: 'fas fa-caret-right',
46+
tableGroupExpand: 'fas fa-chevron-right',
47+
tableGroupCollapse: 'fas fa-chevron-down',
4648
eyeDropper: 'fas fa-eye-dropper',
4749
upload: 'fas fa-cloud-upload-alt',
4850
color: 'fas fa-palette',

packages/vuetify/src/iconsets/fa4.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const aliases: IconAliases = {
4646
calendar: 'fa-calendar',
4747
treeviewCollapse: 'fa-caret-down',
4848
treeviewExpand: 'fa-caret-right',
49+
tableGroupExpand: 'fa-chevron-right',
50+
tableGroupCollapse: 'fa-chevron-down',
4951
eyeDropper: 'fa-eye-dropper',
5052
upload: 'fa-cloud-upload',
5153
color: 'fa-paint-brush',

packages/vuetify/src/iconsets/md.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const aliases: IconAliases = {
4646
calendar: 'event',
4747
treeviewCollapse: 'arrow_drop_down',
4848
treeviewExpand: 'arrow_right',
49+
tableGroupCollapse: 'chevron_down',
50+
tableGroupExpand: 'chevron_right',
4951
eyeDropper: 'colorize',
5052
upload: 'cloud_upload',
5153
color: 'palette',

packages/vuetify/src/iconsets/mdi-svg.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ const aliases: IconAliases = {
4545
calendar: 'svg:M19,19H5V8H19M16,1V3H8V1H6V3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3H18V1M17,12H12V17H17V12Z',
4646
treeviewCollapse: 'svg:M7,10L12,15L17,10H7Z',
4747
treeviewExpand: 'svg:M10,17L15,12L10,7V17Z',
48+
tableGroupExpand: 'svg:M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z',
49+
tableGroupCollapse: 'svg:M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z',
4850
eyeDropper: 'svg:M19.35,11.72L17.22,13.85L15.81,12.43L8.1,20.14L3.5,22L2,20.5L3.86,15.9L11.57,8.19L10.15,6.78L12.28,4.65L19.35,11.72M16.76,3C17.93,1.83 19.83,1.83 21,3C22.17,4.17 22.17,6.07 21,7.24L19.08,9.16L14.84,4.92L16.76,3M5.56,17.03L4.5,19.5L6.97,18.44L14.4,11L13,9.6L5.56,17.03Z',
4951
upload: 'svg:M11 20H6.5q-2.28 0-3.89-1.57Q1 16.85 1 14.58q0-1.95 1.17-3.48q1.18-1.53 3.08-1.95q.63-2.3 2.5-3.72Q9.63 4 12 4q2.93 0 4.96 2.04Q19 8.07 19 11q1.73.2 2.86 1.5q1.14 1.28 1.14 3q0 1.88-1.31 3.19T18.5 20H13v-7.15l1.6 1.55L16 13l-4-4l-4 4l1.4 1.4l1.6-1.55Z',
5052
color: 'svg:M17.5 12a1.5 1.5 0 0 1-1.5-1.5A1.5 1.5 0 0 1 17.5 9a1.5 1.5 0 0 1 1.5 1.5a1.5 1.5 0 0 1-1.5 1.5m-3-4A1.5 1.5 0 0 1 13 6.5A1.5 1.5 0 0 1 14.5 5A1.5 1.5 0 0 1 16 6.5A1.5 1.5 0 0 1 14.5 8m-5 0A1.5 1.5 0 0 1 8 6.5A1.5 1.5 0 0 1 9.5 5A1.5 1.5 0 0 1 11 6.5A1.5 1.5 0 0 1 9.5 8m-3 4A1.5 1.5 0 0 1 5 10.5A1.5 1.5 0 0 1 6.5 9A1.5 1.5 0 0 1 8 10.5A1.5 1.5 0 0 1 6.5 12M12 3a9 9 0 0 0-9 9a9 9 0 0 0 9 9a1.5 1.5 0 0 0 1.5-1.5c0-.39-.15-.74-.39-1c-.23-.27-.38-.62-.38-1a1.5 1.5 0 0 1 1.5-1.5H16a5 5 0 0 0 5-5c0-4.42-4.03-8-9-8',

0 commit comments

Comments
 (0)