From 47415322ea56b5388e55c404c901531e807a9f00 Mon Sep 17 00:00:00 2001 From: "Haytham A. Salama" Date: Mon, 12 Jun 2023 15:26:29 +0300 Subject: [PATCH] feat(table): add loading state (#259) Co-authored-by: Benjamin Canac --- .../examples/TableExampleLoadingSlot.vue | 86 +++++++++++++++++ docs/content/4.data/1.table.md | 94 ++++++++++++++++++- .../content/5.navigation/2.command-palette.md | 4 +- src/runtime/app.config.ts | 9 ++ src/runtime/components/data/Table.vue | 23 ++++- 5 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 docs/components/content/examples/TableExampleLoadingSlot.vue diff --git a/docs/components/content/examples/TableExampleLoadingSlot.vue b/docs/components/content/examples/TableExampleLoadingSlot.vue new file mode 100644 index 00000000..26650178 --- /dev/null +++ b/docs/components/content/examples/TableExampleLoadingSlot.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/docs/content/4.data/1.table.md b/docs/content/4.data/1.table.md index 78c9ac11..4a7e2276 100644 --- a/docs/content/4.data/1.table.md +++ b/docs/content/4.data/1.table.md @@ -401,11 +401,60 @@ const rows = computed(() => { ``` :: +### Loading :u-badge{label="Edge" class="ml-2 align-text-bottom !rounded-full"} + +Use the `loading` prop to display a loading state. + +Use the `loading-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.loadingState`. + +You can also set it to `null` to hide the loading state. + +::component-card +--- +padding: false +overflowClass: 'overflow-x-auto' +baseProps: + class: 'w-full' + columns: + - key: 'id' + label: 'ID' + - key: 'name' + label: 'Name' + - key: 'title' + label: 'Title' + - key: 'email' + label: 'Email' + - key: 'role' + label: 'Role' +props: + loading: true + loadingState: + icon: 'i-heroicons-arrow-path-20-solid' + label: "Loading..." +excludedProps: + - loadingState +--- +:: + +This can be easily used with Nuxt `useAsyncData` composable. + +```vue + + + +``` + ### Empty -Use the `empty-state` prop to display a message when there are no results. +An empty state will be displayed when there are no results. -You can pass an `object` through the `empty-state` prop or globally through `ui.table.default.emptyState`. +Use the `empty-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.emptyState`. You can also set it to `null` to hide the empty state. @@ -517,7 +566,46 @@ const selected = ref([people[1]]) ``` :: -### `empty-state` :u-badge{label="Edge" class="ml-2 align-text-bottom"} +### `loading-state` :u-badge{label="Edge" class="ml-2 align-text-bottom !rounded-full"} + +Use the `#loading-state` slot to customize the loading state. + +::component-example{class="grid"} +--- +padding: false +overflowClass: 'overflow-x-auto' +--- + +#default +:table-example-loading-slot{class="flex-1"} + +#code +```vue + + + + + +``` +:: + +### `empty-state` :u-badge{label="Edge" class="ml-2 align-text-bottom !rounded-full"} Use the `#empty-state` slot to customize the empty state. diff --git a/docs/content/5.navigation/2.command-palette.md b/docs/content/5.navigation/2.command-palette.md index 09f74f52..c81baca0 100644 --- a/docs/content/5.navigation/2.command-palette.md +++ b/docs/content/5.navigation/2.command-palette.md @@ -232,9 +232,9 @@ excludedProps: ### Empty -Use the `empty-state` prop to display a message when there are no results. +An empty state will be displayed when there are no results. -You can pass an `object` through the `empty-state` prop or globally through `ui.commandPalette.default.emptyState`. +Use the `empty-state` prop to customize the `icon` and `label` or change them globally in `ui.commandPalette.default.emptyState`. You can also set it to `null` to hide the empty state. diff --git a/src/runtime/app.config.ts b/src/runtime/app.config.ts index 608aeab8..7d9e449f 100644 --- a/src/runtime/app.config.ts +++ b/src/runtime/app.config.ts @@ -24,6 +24,11 @@ const table = { font: '', size: 'text-sm' }, + loadingState: { + wrapper: 'flex flex-col items-center justify-center flex-1 px-6 py-14 sm:px-14', + label: 'text-sm text-center text-gray-900 dark:text-white', + icon: 'w-6 h-6 mx-auto text-gray-400 dark:text-gray-500 mb-4 animate-spin' + }, emptyState: { wrapper: 'flex flex-col items-center justify-center flex-1 px-6 py-14 sm:px-14', label: 'text-sm text-center text-gray-900 dark:text-white', @@ -40,6 +45,10 @@ const table = { variant: 'ghost', class: '-m-1.5' }, + loadingState: { + icon: 'i-heroicons-arrow-path-20-solid', + label: 'Loading...' + }, emptyState: { icon: 'i-heroicons-circle-stack-20-solid', label: 'No items.' diff --git a/src/runtime/components/data/Table.vue b/src/runtime/components/data/Table.vue index f0b9a292..519ded3b 100644 --- a/src/runtime/components/data/Table.vue +++ b/src/runtime/components/data/Table.vue @@ -34,7 +34,20 @@ - + + + +
+
+
+ + + +
@@ -106,6 +119,14 @@ export default defineComponent({ type: String, default: () => appConfig.ui.table.default.sortDescIcon }, + loading: { + type: Boolean, + default: false + }, + loadingState: { + type: Object as PropType<{ icon: string, label: string }>, + default: () => appConfig.ui.table.default.loadingState + }, emptyState: { type: Object as PropType<{ icon: string, label: string }>, default: () => appConfig.ui.table.default.emptyState