feat(Table): display progress bar when loading (#1362)

This commit is contained in:
Benjamin Canac
2024-02-15 12:37:44 +01:00
committed by GitHub
parent 04ef47376d
commit 3fe35217cb
3 changed files with 31 additions and 8 deletions

View File

@@ -302,11 +302,11 @@ componentProps:
### Loading ### Loading
Use the `loading` prop to display a loading state. Use the `loading` prop to indicate that data is currently loading with an indeterminate [Progress](/components/progress#indeterminate) bar.
Use the `loading-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.loadingState`. You can use the `progress` prop to customize the `color` and `animation` of the progress bar or change them globally in `ui.table.default.progress` (you can set it to `null` to hide the progress bar).
You can also set it to `null` to hide the loading state. If there is no rows provided, a loading state will also be displayed. You can use the `loading-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.loadingState` (you can set it to `null` to hide the loading state).
::component-card ::component-card
--- ---
@@ -330,8 +330,12 @@ props:
loadingState: loadingState:
icon: 'i-heroicons-arrow-path-20-solid' icon: 'i-heroicons-arrow-path-20-solid'
label: "Loading..." label: "Loading..."
progress:
color: 'primary'
animation: 'carousel'
excludedProps: excludedProps:
- loadingState - loadingState
- progress
--- ---
:: ::

View File

@@ -20,9 +20,15 @@
</slot> </slot>
</th> </th>
</tr> </tr>
<tr v-if="loading && progress">
<td :colspan="0" :class="ui.progress.wrapper">
<UProgress v-bind="{ ...(ui.default.progress || {}), ...progress }" size="2xs" />
</td>
</tr>
</thead> </thead>
<tbody :class="ui.tbody"> <tbody :class="ui.tbody">
<tr v-if="loadingState && loading"> <tr v-if="loadingState && loading && !rows.length">
<td :colspan="columns.length + (modelValue ? 1 : 0)"> <td :colspan="columns.length + (modelValue ? 1 : 0)">
<slot name="loading-state"> <slot name="loading-state">
<div :class="ui.loadingState.wrapper"> <div :class="ui.loadingState.wrapper">
@@ -72,12 +78,13 @@ import type { PropType } from 'vue'
import { upperFirst } from 'scule' import { upperFirst } from 'scule'
import { defu } from 'defu' import { defu } from 'defu'
import { useVModel } from '@vueuse/core' import { useVModel } from '@vueuse/core'
import UButton from '../elements/Button.vue'
import UIcon from '../elements/Icon.vue' import UIcon from '../elements/Icon.vue'
import UButton from '../elements/Button.vue'
import UProgress from '../elements/Progress.vue'
import UCheckbox from '../forms/Checkbox.vue' import UCheckbox from '../forms/Checkbox.vue'
import { useUI } from '../../composables/useUI' import { useUI } from '../../composables/useUI'
import { mergeConfig, get } from '../../utils' import { mergeConfig, get } from '../../utils'
import type { Strategy, Button } from '../../types' import type { Strategy, Button, ProgressColor, ProgressAnimation } from '../../types'
// @ts-expect-error // @ts-expect-error
import appConfig from '#build/app.config' import appConfig from '#build/app.config'
import { table } from '#ui/ui.config' import { table } from '#ui/ui.config'
@@ -102,8 +109,9 @@ function defaultSort (a: any, b: any, direction: 'asc' | 'desc') {
export default defineComponent({ export default defineComponent({
components: { components: {
UButton,
UIcon, UIcon,
UButton,
UProgress,
UCheckbox UCheckbox
}, },
inheritAttrs: false, inheritAttrs: false,
@@ -160,6 +168,10 @@ export default defineComponent({
type: Object as PropType<{ icon: string, label: string }>, type: Object as PropType<{ icon: string, label: string }>,
default: () => config.default.emptyState default: () => config.default.emptyState
}, },
progress: {
type: Object as PropType<{ color: ProgressColor, animation: ProgressAnimation }>,
default: () => config.default.progress
},
class: { class: {
type: [String, Object, Array] as PropType<any>, type: [String, Object, Array] as PropType<any>,
default: () => '' default: () => ''

View File

@@ -2,7 +2,7 @@ export default {
wrapper: 'relative overflow-x-auto', wrapper: 'relative overflow-x-auto',
base: 'min-w-full table-fixed', base: 'min-w-full table-fixed',
divide: 'divide-y divide-gray-300 dark:divide-gray-700', divide: 'divide-y divide-gray-300 dark:divide-gray-700',
thead: '', thead: 'relative',
tbody: 'divide-y divide-gray-200 dark:divide-gray-800', tbody: 'divide-y divide-gray-200 dark:divide-gray-800',
tr: { tr: {
base: '', base: '',
@@ -36,6 +36,9 @@ export default {
label: 'text-sm text-center text-gray-900 dark:text-white', 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' icon: 'w-6 h-6 mx-auto text-gray-400 dark:text-gray-500 mb-4'
}, },
progress: {
wrapper: 'absolute inset-x-0 -bottom-[0.5px] p-0'
},
default: { default: {
sortAscIcon: 'i-heroicons-bars-arrow-up-20-solid', sortAscIcon: 'i-heroicons-bars-arrow-up-20-solid',
sortDescIcon: 'i-heroicons-bars-arrow-down-20-solid', sortDescIcon: 'i-heroicons-bars-arrow-down-20-solid',
@@ -47,6 +50,10 @@ export default {
variant: 'ghost' as const, variant: 'ghost' as const,
class: '-m-1.5' class: '-m-1.5'
}, },
progress: {
color: 'primary' as const,
animation: 'carousel' as const
},
loadingState: { loadingState: {
icon: 'i-heroicons-arrow-path-20-solid', icon: 'i-heroicons-arrow-path-20-solid',
label: 'Loading...' label: 'Loading...'