mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
chore(Table): handle default sort and default column direction
This commit is contained in:
@@ -13,7 +13,8 @@ const columns = [{
|
||||
}, {
|
||||
key: 'email',
|
||||
label: 'Email',
|
||||
sortable: true
|
||||
sortable: true,
|
||||
direction: 'desc'
|
||||
}, {
|
||||
key: 'role',
|
||||
label: 'Role'
|
||||
@@ -59,5 +60,5 @@ const people = [{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable :columns="columns" :rows="people" />
|
||||
<UTable :columns="columns" :rows="people" :sort="{ column: 'title' }" />
|
||||
</template>
|
||||
|
||||
@@ -70,6 +70,7 @@ Use the `columns` prop to configure which columns to display. It's an array of o
|
||||
- `label` - The label to display in the table header. Can be changed through the `column-attribute` prop.
|
||||
- `key` - The field to display from the row data.
|
||||
- `sortable` - Whether the column is sortable. Defaults to `false`.
|
||||
- `direction` - The sort direction to use on first click. Defaults to `asc`.
|
||||
|
||||
::component-example
|
||||
---
|
||||
@@ -181,7 +182,8 @@ const columns = [{
|
||||
}, {
|
||||
key: 'email',
|
||||
label: 'Email',
|
||||
sortable: true
|
||||
sortable: true,
|
||||
direction: 'desc'
|
||||
}, {
|
||||
key: 'role',
|
||||
label: 'Role'
|
||||
@@ -191,11 +193,18 @@ const people = [...]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable :columns="columns" :rows="people" />
|
||||
<UTable :columns="columns" :rows="people" :sort="{ column: 'title' }" />
|
||||
</template>
|
||||
```
|
||||
::
|
||||
|
||||
You can specify the default direction of each column through the `direction` property. It can be either `asc` or `desc` and defaults to `asc`.
|
||||
|
||||
You can specify a default sort for the table through the `sort` prop. It's an object with the following properties:
|
||||
|
||||
- `column` - The column to sort by.
|
||||
- `direction` - The sort direction. Can be either `asc` or `desc` and defaults to `asc`.
|
||||
|
||||
Use the `sort-button` prop to customize the sort button in the header. You can pass all the props of the [Button](/elements/button) component to customize it through this prop or globally through `ui.table.default.sortButton`. Its icon defaults to `i-heroicons-arrows-up-down-20-solid`.
|
||||
|
||||
::component-card
|
||||
@@ -358,7 +367,7 @@ The `sort` property is an object with the following properties:
|
||||
- `field` - The field to sort by.
|
||||
- `direction` - The direction to sort by. Can be `asc` or `desc`.
|
||||
|
||||
The `on-sort` property is a function that you can call to sort the table. It accepts a string with the field to sort by and an optional string with the direction to sort by. If the direction is not provided, it will toggle between `asc` and `desc`.
|
||||
The `on-sort` property is a function that you can call to sort the table and accepts the column as parameter.
|
||||
|
||||
::alert{icon="i-heroicons-light-bulb"}
|
||||
Even though you can customize the sort button as mentioned in the [Sortable](#sortable) section, you can use this slot to completely override its behavior, with a custom dropdown for example.
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
<UButton
|
||||
v-if="column.sortable"
|
||||
v-bind="sortButton"
|
||||
:icon="(!sort.field || sort.field !== column.key) ? sortButton.icon : sort.direction === 'asc' ? sortAscIcon : sortDescIcon"
|
||||
:icon="(!sort.column || sort.column !== column.key) ? sortButton.icon : sort.direction === 'asc' ? sortAscIcon : sortDescIcon"
|
||||
:label="column[columnAttribute]"
|
||||
@click="onSort(column.key)"
|
||||
@click="onSort(column)"
|
||||
/>
|
||||
<span v-else>{{ column[columnAttribute] }}</span>
|
||||
</slot>
|
||||
@@ -77,6 +77,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: 'label'
|
||||
},
|
||||
sort: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
sortButton: {
|
||||
type: Object as PropType<Partial<Button>>,
|
||||
default: () => appConfig.ui.table.default.sortButton
|
||||
@@ -101,18 +105,18 @@ export default defineComponent({
|
||||
|
||||
const ui = computed<Partial<typeof appConfig.ui.table>>(() => defu({}, props.ui, appConfig.ui.table))
|
||||
|
||||
const sort = ref({ field: null, direction: null })
|
||||
|
||||
const columns = computed(() => props.columns ?? Object.keys(props.rows[0] ?? {}).map((key) => ({ key, label: capitalize(key), sortable: false })))
|
||||
|
||||
const sort = ref(defu({}, props.sort, { column: null, direction: 'asc' }))
|
||||
|
||||
const rows = computed(() => {
|
||||
if (!sort.value?.field) {
|
||||
if (!sort.value?.column) {
|
||||
return props.rows
|
||||
}
|
||||
|
||||
const { field, direction } = sort.value
|
||||
const { column, direction } = sort.value
|
||||
|
||||
return orderBy(props.rows, field, direction)
|
||||
return orderBy(props.rows, column, direction)
|
||||
})
|
||||
|
||||
const selected = computed({
|
||||
@@ -142,17 +146,18 @@ export default defineComponent({
|
||||
return selected.value.some((item) => compare(toRaw(item), toRaw(row)))
|
||||
}
|
||||
|
||||
function onSort (field: string, direction?: 'asc' | 'desc') {
|
||||
if (sort.value.field === field) {
|
||||
sort.value.direction = direction || sort.value.direction === 'asc' ? 'desc' : 'asc'
|
||||
function onSort (column) {
|
||||
if (sort.value.column === column.key) {
|
||||
sort.value.direction = sort.value.direction === 'asc' ? 'desc' : 'asc'
|
||||
} else {
|
||||
sort.value = { field, direction: direction || 'asc' }
|
||||
sort.value = { column: column.key, direction: column.direction || 'asc' }
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// eslint-disable-next-line vue/no-dupe-keys
|
||||
ui,
|
||||
// eslint-disable-next-line vue/no-dupe-keys
|
||||
sort,
|
||||
// eslint-disable-next-line vue/no-dupe-keys
|
||||
columns,
|
||||
|
||||
Reference in New Issue
Block a user