From 9f4d88e0aa7ec8cbbdae3fccd372d8c5e81d7ad0 Mon Sep 17 00:00:00 2001 From: Italo Date: Sat, 14 Oct 2023 14:18:49 -0300 Subject: [PATCH] feat(Table): add `v-model:sort` prop (#803) Co-authored-by: Benjamin Canac --- .../examples/TableExampleReactiveSorting.vue | 69 +++++++++++++++++++ docs/content/4.data/1.table.md | 40 ++++++++++- src/runtime/components/data/Table.vue | 8 ++- src/runtime/components/forms/Input.vue | 2 +- 4 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 docs/components/content/examples/TableExampleReactiveSorting.vue diff --git a/docs/components/content/examples/TableExampleReactiveSorting.vue b/docs/components/content/examples/TableExampleReactiveSorting.vue new file mode 100644 index 00000000..b8a22c01 --- /dev/null +++ b/docs/components/content/examples/TableExampleReactiveSorting.vue @@ -0,0 +1,69 @@ + + + diff --git a/docs/content/4.data/1.table.md b/docs/content/4.data/1.table.md index 1c37952c..78d304b3 100644 --- a/docs/content/4.data/1.table.md +++ b/docs/content/4.data/1.table.md @@ -66,7 +66,7 @@ componentProps: --- :: -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 may specify the default direction of each column through the `direction` property. It can be either `asc` or `desc`, but it will default to `asc`. You can specify a default sort for the table through the `sort` prop. It's an object with the following properties: @@ -156,6 +156,44 @@ Use the `sort-desc-icon` prop to set a different icon or change it globally in ` You can also customize the entire header cell, read more in the [Slots](#slots) section. :: +#### Reactive sorting :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"} + +Sometimes you will want to fetch new data depending on the sorted column and direction. You can use the `v-model:sort` to automatically update the `ref` reactive element every time the sorting changes on the Table. You may also use `@update:sort` to call your own function with the sorting data. + +For example, we can take advantage of `useLazyRefresh` computed URL to automatically fetch the data depending on the sorting column and direction every time the `sort` reactive element changes. + +```vue + + + +``` + +The initial value of `sort` will be respected as the initial sort column and direction, as well as each column default sorting direction. + +::component-example{class="grid"} +--- +padding: false +overflowClass: 'overflow-x-auto' +component: 'table-example-reactive-sorting' +componentProps: + class: 'flex-1' +--- +:: + ### Selectable Use a `v-model` to make the table selectable. The `v-model` will be an array of the selected rows. diff --git a/src/runtime/components/data/Table.vue b/src/runtime/components/data/Table.vue index 59453b30..85c06b6c 100644 --- a/src/runtime/components/data/Table.vue +++ b/src/runtime/components/data/Table.vue @@ -152,7 +152,7 @@ export default defineComponent({ default: undefined } }, - emits: ['update:modelValue'], + emits: ['update:modelValue', 'update:sort'], setup (props, { emit, attrs: $attrs }) { const { ui, attrs } = useUI('table', toRef(props, 'ui'), config, toRef(props, 'class')) @@ -160,6 +160,8 @@ export default defineComponent({ const sort = ref(defu({}, props.sort, { column: null, direction: 'asc' })) + const defaultSort = { column: sort.value.column, direction: null } + const rows = computed(() => { if (!sort.value?.column) { return props.rows @@ -225,13 +227,15 @@ export default defineComponent({ const direction = !column.direction || column.direction === 'asc' ? 'desc' : 'asc' if (sort.value.direction === direction) { - sort.value = defu({}, props.sort, { column: null, direction: 'asc' }) + sort.value = defu({}, defaultSort, { column: null, direction: 'asc' }) } else { sort.value.direction = sort.value.direction === 'asc' ? 'desc' : 'asc' } } else { sort.value = { column: column.key, direction: column.direction || 'asc' } } + + emit('update:sort', sort.value) } function onSelect (row) { diff --git a/src/runtime/components/forms/Input.vue b/src/runtime/components/forms/Input.vue index fdaadad9..8f77e253 100644 --- a/src/runtime/components/forms/Input.vue +++ b/src/runtime/components/forms/Input.vue @@ -87,7 +87,7 @@ export default defineComponent({ }, autofocusDelay: { type: Number, - default: 100, + default: 100 }, icon: { type: String,