mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
feat(Table): implement component (#2364)
This commit is contained in:
@@ -32,6 +32,10 @@ const props = defineProps<{
|
||||
* @defaultValue false
|
||||
*/
|
||||
collapse?: boolean
|
||||
/**
|
||||
* A list of line numbers to highlight in the code block
|
||||
*/
|
||||
highlights?: number[]
|
||||
}>()
|
||||
|
||||
const route = useRoute()
|
||||
@@ -105,7 +109,7 @@ const code = computed(() => {
|
||||
`
|
||||
}
|
||||
|
||||
code += `\`\`\`vue`
|
||||
code += `\`\`\`vue${props.highlights?.length ? ` {${props.highlights.join('-')}}` : ''}`
|
||||
|
||||
if (props.external?.length) {
|
||||
code += `
|
||||
@@ -201,7 +205,8 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
|
||||
formatted = await $prettier.format(code.value, {
|
||||
trailingComma: 'none',
|
||||
semi: false,
|
||||
singleQuote: true
|
||||
singleQuote: true,
|
||||
printWidth: 100
|
||||
})
|
||||
} catch {
|
||||
formatted = code.value
|
||||
|
||||
@@ -22,13 +22,11 @@ const props = withDefaults(defineProps<{
|
||||
* @defaultValue true
|
||||
*/
|
||||
preview?: boolean
|
||||
|
||||
/**
|
||||
* Whether to show the source code
|
||||
* @defaultValue true
|
||||
*/
|
||||
source?: boolean
|
||||
|
||||
/**
|
||||
* A list of variable props to link to the component.
|
||||
*/
|
||||
@@ -40,6 +38,10 @@ const props = withDefaults(defineProps<{
|
||||
default: any
|
||||
multiple?: boolean
|
||||
}>
|
||||
/**
|
||||
* A list of line numbers to highlight in the code block
|
||||
*/
|
||||
highlights?: number[]
|
||||
}>(), {
|
||||
preview: true,
|
||||
source: true
|
||||
@@ -65,7 +67,7 @@ const code = computed(() => {
|
||||
`
|
||||
}
|
||||
|
||||
code += `\`\`\`vue${props.preview ? '' : ` [${data.pascalName}.vue]`}
|
||||
code += `\`\`\`vue ${props.preview ? '' : ` [${data.pascalName}.vue]`}${props.highlights?.length ? `{${props.highlights.join('-')}}` : ''}
|
||||
${data?.code ?? ''}
|
||||
\`\`\``
|
||||
|
||||
@@ -87,7 +89,8 @@ const { data: ast } = await useAsyncData(`component-example-${camelName}`, async
|
||||
formatted = await $prettier.format(code.value, {
|
||||
trailingComma: 'none',
|
||||
semi: false,
|
||||
singleQuote: true
|
||||
singleQuote: true,
|
||||
printWidth: 100
|
||||
})
|
||||
} catch {
|
||||
formatted = code.value
|
||||
@@ -113,7 +116,7 @@ const optionsValues = ref(props.options?.reduce((acc, option) => {
|
||||
|
||||
<template>
|
||||
<div class="my-5">
|
||||
<div v-if="preview">
|
||||
<template v-if="preview">
|
||||
<div class="border border-[var(--ui-color-neutral-200)] dark:border-[var(--ui-color-neutral-700)] relative z-[1]" :class="[{ 'border-b-0 rounded-t-[calc(var(--ui-radius)*1.5)]': props.source, 'rounded-[calc(var(--ui-radius)*1.5)]': !props.source }]">
|
||||
<div v-if="props.options?.length || !!slots.options" class="flex gap-4 p-4 border-b border-[var(--ui-color-neutral-200)] dark:border-[var(--ui-color-neutral-700)]">
|
||||
<slot name="options" />
|
||||
@@ -170,7 +173,7 @@ const optionsValues = ref(props.options?.reduce((acc, option) => {
|
||||
<component :is="camelName" v-bind="{ ...componentProps, ...optionsValues }" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<MDCRenderer v-if="ast && props.source" :body="ast.body" :data="ast.data" class="[&_pre]:!rounded-t-none [&_div.my-5]:!mt-0" />
|
||||
</div>
|
||||
|
||||
@@ -99,6 +99,7 @@ const metaProps: ComputedRef<ComponentMeta['props']> = computed(() => {
|
||||
|
||||
<MDC v-if="prop.description" :value="prop.description" class="text-[var(--ui-text-toned)] mt-1" />
|
||||
|
||||
<ComponentPropsLinks v-if="prop.tags?.length" :prop="prop" />
|
||||
<ComponentPropsSchema v-if="prop.schema" :prop="prop" :ignore="ignore" />
|
||||
</ProseTd>
|
||||
</ProseTr>
|
||||
|
||||
17
docs/app/components/content/ComponentPropsLinks.vue
Normal file
17
docs/app/components/content/ComponentPropsLinks.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import type { PropertyMeta } from 'vue-component-meta'
|
||||
|
||||
const props = defineProps<{
|
||||
prop: PropertyMeta
|
||||
}>()
|
||||
|
||||
const links = computed(() => props.prop.tags?.filter((tag: any) => tag.name === 'link'))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ProseUl v-if="links?.length">
|
||||
<ProseLi v-for="link in links" :key="link.name">
|
||||
<MDC :value="link.text ?? ''" class="my-1" />
|
||||
</ProseLi>
|
||||
</ProseUl>
|
||||
</template>
|
||||
@@ -28,6 +28,14 @@ function stripCompoundVariants(component?: any) {
|
||||
}
|
||||
}
|
||||
|
||||
if (compoundVariant.loadingColor) {
|
||||
if (!['primary', 'neutral'].includes(compoundVariant.loadingColor)) {
|
||||
strippedCompoundVariants.value = true
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
const table = useTemplateRef('table')
|
||||
|
||||
const columnFilters = ref([{
|
||||
id: 'email',
|
||||
value: 'james'
|
||||
}])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex px-4 py-3.5 border-b border-[var(--ui-border-accented)]">
|
||||
<UInput
|
||||
:model-value="(table?.tableApi?.getColumn('email')?.getFilterValue() as string)"
|
||||
class="max-w-sm"
|
||||
placeholder="Filter emails..."
|
||||
@update:model-value="table?.tableApi?.getColumn('email')?.setFilterValue($event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UTable
|
||||
ref="table"
|
||||
v-model:column-filters="columnFilters"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,114 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
import type { Column } from '@tanstack/vue-table'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
const UButton = resolveComponent('UButton')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '46000000000000000000000000000000000000000',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594000
|
||||
}, {
|
||||
id: '45990000000000000000000000000000000000000',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276000
|
||||
}, {
|
||||
id: '45980000000000000000000000000000000000000',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315000
|
||||
}, {
|
||||
id: '45970000000000000000000000000000000000000',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 5290000
|
||||
}, {
|
||||
id: '45960000000000000000000000000000000000000',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639000
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: ({ column }) => getHeader(column, 'ID', 'left'),
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: ({ column }) => getHeader(column, 'Date', 'left')
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: ({ column }) => getHeader(column, 'Status', 'left'),
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: ({ column }) => getHeader(column, 'Email', 'left')
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: ({ column }) => h('div', { class: 'text-right' }, getHeader(column, 'Amount', 'right')),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
function getHeader(column: Column<Payment>, label: string, position: 'left' | 'right') {
|
||||
const isPinned = column.getIsPinned()
|
||||
|
||||
return h(UButton, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
label,
|
||||
icon: isPinned ? 'i-heroicons-star-20-solid' : 'i-heroicons-star',
|
||||
class: '-mx-2.5',
|
||||
onClick() {
|
||||
column.pin(isPinned === position ? false : position)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const columnPinning = ref({
|
||||
left: [],
|
||||
right: ['amount']
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable
|
||||
v-model:column-pinning="columnPinning"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
class="flex-1"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,118 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
const UButton = resolveComponent('UButton')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: ({ column }) => {
|
||||
const isSorted = column.getIsSorted()
|
||||
|
||||
return h(UButton, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
label: 'Email',
|
||||
icon: isSorted ? (isSorted === 'asc' ? 'i-heroicons-bars-arrow-up-20-solid' : 'i-heroicons-bars-arrow-down-20-solid') : 'i-heroicons-arrows-up-down-20-solid',
|
||||
class: '-mx-2.5',
|
||||
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc')
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
const sorting = ref([{
|
||||
id: 'email',
|
||||
desc: false
|
||||
}])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable
|
||||
v-model:sorting="sorting"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
class="flex-1"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,150 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
import type { Column } from '@tanstack/vue-table'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
const UButton = resolveComponent('UButton')
|
||||
const UDropdownMenu = resolveComponent('UDropdownMenu')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: ({ column }) => getHeader(column, 'ID'),
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: ({ column }) => getHeader(column, 'Date'),
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: ({ column }) => getHeader(column, 'Status'),
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: ({ column }) => getHeader(column, 'Email')
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: ({ column }) => h('div', { class: 'text-right' }, getHeader(column, 'Amount')),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
function getHeader(column: Column<Payment>, label: string) {
|
||||
const isSorted = column.getIsSorted()
|
||||
|
||||
return h(UDropdownMenu, {
|
||||
content: {
|
||||
align: 'start'
|
||||
},
|
||||
items: [{
|
||||
label: 'Asc',
|
||||
type: 'checkbox',
|
||||
icon: 'i-heroicons-bars-arrow-up-20-solid',
|
||||
checked: isSorted === 'asc',
|
||||
onSelect: () => {
|
||||
if (isSorted === 'asc') {
|
||||
column.clearSorting()
|
||||
} else {
|
||||
column.toggleSorting(false)
|
||||
}
|
||||
}
|
||||
}, {
|
||||
label: 'Desc',
|
||||
icon: 'i-heroicons-bars-arrow-down-20-solid',
|
||||
type: 'checkbox',
|
||||
checked: isSorted === 'desc',
|
||||
onSelect: () => {
|
||||
if (isSorted === 'desc') {
|
||||
column.clearSorting()
|
||||
} else {
|
||||
column.toggleSorting(true)
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, () => h(UButton, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
label,
|
||||
icon: isSorted ? (isSorted === 'asc' ? 'i-heroicons-bars-arrow-up-20-solid' : 'i-heroicons-bars-arrow-down-20-solid') : 'i-heroicons-arrows-up-down-20-solid',
|
||||
class: '-mx-2.5 data-[state=open]:bg-[var(--ui-bg-elevated)]'
|
||||
}))
|
||||
}
|
||||
|
||||
const sorting = ref([{
|
||||
id: 'id',
|
||||
desc: false
|
||||
}])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable
|
||||
v-model:sorting="sorting"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
class="flex-1"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,134 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import { upperFirst } from 'scule'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
const table = useTemplateRef('table')
|
||||
|
||||
const columnVisibility = ref({
|
||||
id: false
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex justify-end px-4 py-3.5 border-b border-[var(--ui-border-accented)]">
|
||||
<UDropdownMenu
|
||||
:items="table?.tableApi?.getAllColumns().filter(column => column.getCanHide()).map(column => ({
|
||||
label: upperFirst(column.id),
|
||||
type: 'checkbox' as const,
|
||||
checked: column.getIsVisible(),
|
||||
onUpdateChecked(checked: boolean) {
|
||||
table?.tableApi?.getColumn(column.id)?.toggleVisibility(!!checked)
|
||||
},
|
||||
onSelect(e?: Event) {
|
||||
e?.preventDefault()
|
||||
}
|
||||
}))"
|
||||
:content="{ align: 'end' }"
|
||||
>
|
||||
<UButton
|
||||
label="Columns"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
trailing-icon="i-heroicons-chevron-down-20-solid"
|
||||
/>
|
||||
</UDropdownMenu>
|
||||
</div>
|
||||
|
||||
<UTable
|
||||
ref="table"
|
||||
v-model:column-visibility="columnVisibility"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,96 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable :data="data" :columns="columns" class="flex-1" />
|
||||
</template>
|
||||
319
docs/app/components/content/examples/table/TableExample.vue
Normal file
319
docs/app/components/content/examples/table/TableExample.vue
Normal file
@@ -0,0 +1,319 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import { upperFirst } from 'scule'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UButton = resolveComponent('UButton')
|
||||
const UCheckbox = resolveComponent('UCheckbox')
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
const UDropdownMenu = resolveComponent('UDropdownMenu')
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}, {
|
||||
id: '4595',
|
||||
date: '2024-03-10T13:40:00',
|
||||
status: 'refunded',
|
||||
email: 'ava.thomas@example.com',
|
||||
amount: 428
|
||||
}, {
|
||||
id: '4594',
|
||||
date: '2024-03-10T09:15:00',
|
||||
status: 'paid',
|
||||
email: 'michael.wilson@example.com',
|
||||
amount: 683
|
||||
}, {
|
||||
id: '4593',
|
||||
date: '2024-03-09T20:25:00',
|
||||
status: 'failed',
|
||||
email: 'olivia.taylor@example.com',
|
||||
amount: 947
|
||||
}, {
|
||||
id: '4592',
|
||||
date: '2024-03-09T18:45:00',
|
||||
status: 'paid',
|
||||
email: 'benjamin.jackson@example.com',
|
||||
amount: 851
|
||||
}, {
|
||||
id: '4591',
|
||||
date: '2024-03-09T16:05:00',
|
||||
status: 'paid',
|
||||
email: 'sophia.miller@example.com',
|
||||
amount: 762
|
||||
}, {
|
||||
id: '4590',
|
||||
date: '2024-03-09T14:20:00',
|
||||
status: 'paid',
|
||||
email: 'noah.clark@example.com',
|
||||
amount: 573
|
||||
}, {
|
||||
id: '4589',
|
||||
date: '2024-03-09T11:35:00',
|
||||
status: 'failed',
|
||||
email: 'isabella.lee@example.com',
|
||||
amount: 389
|
||||
}, {
|
||||
id: '4588',
|
||||
date: '2024-03-08T22:50:00',
|
||||
status: 'refunded',
|
||||
email: 'liam.walker@example.com',
|
||||
amount: 701
|
||||
}, {
|
||||
id: '4587',
|
||||
date: '2024-03-08T20:15:00',
|
||||
status: 'paid',
|
||||
email: 'charlotte.hall@example.com',
|
||||
amount: 856
|
||||
}, {
|
||||
id: '4586',
|
||||
date: '2024-03-08T17:40:00',
|
||||
status: 'paid',
|
||||
email: 'mason.young@example.com',
|
||||
amount: 492
|
||||
}, {
|
||||
id: '4585',
|
||||
date: '2024-03-08T14:55:00',
|
||||
status: 'failed',
|
||||
email: 'amelia.king@example.com',
|
||||
amount: 637
|
||||
}, {
|
||||
id: '4584',
|
||||
date: '2024-03-08T12:30:00',
|
||||
status: 'paid',
|
||||
email: 'elijah.wright@example.com',
|
||||
amount: 784
|
||||
}, {
|
||||
id: '4583',
|
||||
date: '2024-03-08T09:45:00',
|
||||
status: 'refunded',
|
||||
email: 'harper.scott@example.com',
|
||||
amount: 345
|
||||
}, {
|
||||
id: '4582',
|
||||
date: '2024-03-07T23:10:00',
|
||||
status: 'paid',
|
||||
email: 'evelyn.green@example.com',
|
||||
amount: 918
|
||||
}, {
|
||||
id: '4581',
|
||||
date: '2024-03-07T20:25:00',
|
||||
status: 'paid',
|
||||
email: 'logan.baker@example.com',
|
||||
amount: 567
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(UCheckbox, {
|
||||
'modelValue': table.getIsAllPageRowsSelected(),
|
||||
'indeterminate': table.getIsSomePageRowsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all'
|
||||
}),
|
||||
cell: ({ row }) => h(UCheckbox, {
|
||||
'modelValue': row.getIsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
|
||||
'ariaLabel': 'Select row'
|
||||
}),
|
||||
enableSorting: false,
|
||||
enableHiding: false
|
||||
}, {
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: ({ column }) => {
|
||||
const isSorted = column.getIsSorted()
|
||||
|
||||
return h(UButton, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
label: 'Email',
|
||||
icon: isSorted ? (isSorted === 'asc' ? 'i-heroicons-bars-arrow-up-20-solid' : 'i-heroicons-bars-arrow-down-20-solid') : 'i-heroicons-arrows-up-down-20-solid',
|
||||
class: '-mx-2.5',
|
||||
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc')
|
||||
})
|
||||
},
|
||||
cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email'))
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}, {
|
||||
id: 'actions',
|
||||
enableHiding: false,
|
||||
cell: ({ row }) => {
|
||||
const items = [{
|
||||
type: 'label',
|
||||
label: 'Actions'
|
||||
}, {
|
||||
label: 'Copy payment ID',
|
||||
onSelect() {
|
||||
navigator.clipboard.writeText(row.original.id)
|
||||
|
||||
toast.add({
|
||||
title: 'Payment ID copied to clipboard!',
|
||||
color: 'success',
|
||||
icon: 'i-heroicons-check-circle'
|
||||
})
|
||||
}
|
||||
}, {
|
||||
label: row.getIsExpanded() ? 'Collapse' : 'Expand',
|
||||
onSelect() {
|
||||
row.toggleExpanded()
|
||||
}
|
||||
}, {
|
||||
type: 'separator'
|
||||
}, {
|
||||
label: 'View customer'
|
||||
}, {
|
||||
label: 'View payment details'
|
||||
}]
|
||||
|
||||
return h('div', { class: 'text-right' }, h(UDropdownMenu, {
|
||||
content: {
|
||||
align: 'end'
|
||||
},
|
||||
items
|
||||
}, () => h(UButton, {
|
||||
icon: 'i-heroicons-ellipsis-vertical-20-solid',
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
class: 'ml-auto'
|
||||
})))
|
||||
}
|
||||
}]
|
||||
|
||||
const table = useTemplateRef('table')
|
||||
|
||||
function randomize() {
|
||||
data.value = [...data.value].sort(() => Math.random() - 0.5)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-1 divide-y divide-[var(--ui-border-accented)]">
|
||||
<div class="flex items-center gap-2 px-4 py-3.5">
|
||||
<UInput
|
||||
:model-value="(table?.tableApi?.getColumn('email')?.getFilterValue() as string)"
|
||||
class="max-w-sm"
|
||||
placeholder="Filter emails..."
|
||||
@update:model-value="table?.tableApi?.getColumn('email')?.setFilterValue($event)"
|
||||
/>
|
||||
|
||||
<UButton color="neutral" label="Randomize" @click="randomize" />
|
||||
|
||||
<UDropdownMenu
|
||||
:items="table?.tableApi?.getAllColumns().filter(column => column.getCanHide()).map(column => ({
|
||||
label: upperFirst(column.id),
|
||||
type: 'checkbox' as const,
|
||||
checked: column.getIsVisible(),
|
||||
onUpdateChecked(checked: boolean) {
|
||||
table?.tableApi?.getColumn(column.id)?.toggleVisibility(!!checked)
|
||||
},
|
||||
onSelect(e?: Event) {
|
||||
e?.preventDefault()
|
||||
}
|
||||
}))"
|
||||
:content="{ align: 'end' }"
|
||||
>
|
||||
<UButton
|
||||
label="Columns"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
trailing-icon="i-heroicons-chevron-down-20-solid"
|
||||
class="ml-auto"
|
||||
/>
|
||||
</UDropdownMenu>
|
||||
</div>
|
||||
|
||||
<UTable
|
||||
ref="table"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
sticky
|
||||
class="h-96"
|
||||
>
|
||||
<template #expanded="{ row }">
|
||||
<pre>{{ row.original }}</pre>
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
<div class="px-4 py-3.5 text-sm text-[var(--ui-text-muted)]">
|
||||
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
||||
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UAvatar = resolveComponent('UAvatar')
|
||||
|
||||
type User = {
|
||||
id: number
|
||||
name: string
|
||||
username: string
|
||||
email: string
|
||||
avatar: { src: string }
|
||||
company: { name: string }
|
||||
}
|
||||
|
||||
const { data, status } = await useFetch<User[]>('https://jsonplaceholder.typicode.com/users', {
|
||||
transform: (data) => {
|
||||
return data?.map(user => ({
|
||||
...user,
|
||||
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
|
||||
})) || []
|
||||
},
|
||||
lazy: true
|
||||
})
|
||||
|
||||
const columns: TableColumn<User>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: 'ID'
|
||||
}, {
|
||||
accessorKey: 'name',
|
||||
header: 'Name',
|
||||
cell: ({ row }) => {
|
||||
return h('div', { class: 'flex items-center gap-3' }, [
|
||||
h(UAvatar, {
|
||||
...row.original.avatar,
|
||||
size: 'lg'
|
||||
}),
|
||||
h('div', undefined, [
|
||||
h('p', { class: 'font-medium text-[var(--ui-text-highlighted)]' }, row.original.name),
|
||||
h('p', { class: '' }, `@${row.original.username}`)
|
||||
])
|
||||
])
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'company',
|
||||
header: 'Company',
|
||||
cell: ({ row }) => row.original.company.name
|
||||
}]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable :data="data" :columns="columns" :loading="status === 'pending'" class="flex-1" />
|
||||
</template>
|
||||
@@ -0,0 +1,115 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
const table = useTemplateRef('table')
|
||||
|
||||
const globalFilter = ref('45')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex px-4 py-3.5 border-b border-[var(--ui-border-accented)]">
|
||||
<UInput
|
||||
v-model="globalFilter"
|
||||
class="max-w-sm"
|
||||
placeholder="Filter..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UTable
|
||||
ref="table"
|
||||
v-model:global-filter="globalFilter"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,140 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
import type { Row } from '@tanstack/vue-table'
|
||||
|
||||
const UButton = resolveComponent('UButton')
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
const UDropdownMenu = resolveComponent('UDropdownMenu')
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}, {
|
||||
id: 'actions',
|
||||
cell: ({ row }) => {
|
||||
return h('div', { class: 'text-right' }, h(UDropdownMenu, {
|
||||
content: {
|
||||
align: 'end'
|
||||
},
|
||||
items: getRowItems(row)
|
||||
}, () => h(UButton, {
|
||||
icon: 'i-heroicons-ellipsis-vertical-20-solid',
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
class: 'ml-auto'
|
||||
})))
|
||||
}
|
||||
}]
|
||||
|
||||
function getRowItems(row: Row<Payment>) {
|
||||
return [{
|
||||
type: 'label',
|
||||
label: 'Actions'
|
||||
}, {
|
||||
label: 'Copy payment ID',
|
||||
onSelect() {
|
||||
navigator.clipboard.writeText(row.original.id)
|
||||
|
||||
toast.add({
|
||||
title: 'Payment ID copied to clipboard!',
|
||||
color: 'success',
|
||||
icon: 'i-heroicons-check-circle'
|
||||
})
|
||||
}
|
||||
}, {
|
||||
type: 'separator'
|
||||
}, {
|
||||
label: 'View customer'
|
||||
}, {
|
||||
label: 'View payment details'
|
||||
}]
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable :data="data" :columns="columns" class="flex-1" />
|
||||
</template>
|
||||
@@ -0,0 +1,121 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UButton = resolveComponent('UButton')
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
id: 'expand',
|
||||
cell: ({ row }) => h(UButton, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
icon: 'i-heroicons-chevron-down-20-solid',
|
||||
square: true,
|
||||
ui: {
|
||||
leadingIcon: ['transition-transform', row.getIsExpanded() ? 'duration-200 rotate-180' : '']
|
||||
},
|
||||
onClick: () => row.toggleExpanded()
|
||||
})
|
||||
}, {
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
const expanded = ref({ 1: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable
|
||||
v-model:expanded="expanded"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
:ui="{ tr: 'data-[expanded=true]:bg-[var(--ui-bg-elevated)]/50' }"
|
||||
class="flex-1"
|
||||
>
|
||||
<template #expanded="{ row }">
|
||||
<pre>{{ row.original }}</pre>
|
||||
</template>
|
||||
</UTable>
|
||||
</template>
|
||||
@@ -0,0 +1,122 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UCheckbox = resolveComponent('UCheckbox')
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(UCheckbox, {
|
||||
'modelValue': table.getIsAllPageRowsSelected(),
|
||||
'indeterminate': table.getIsSomePageRowsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all'
|
||||
}),
|
||||
cell: ({ row }) => h(UCheckbox, {
|
||||
'modelValue': row.getIsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
|
||||
'ariaLabel': 'Select row'
|
||||
})
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: 'Email'
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}]
|
||||
|
||||
const table = useTemplateRef('table')
|
||||
|
||||
const rowSelection = ref({ 1: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-1">
|
||||
<UTable
|
||||
ref="table"
|
||||
v-model:row-selection="rowSelection"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
/>
|
||||
|
||||
<div class="px-4 py-3.5 border-t border-[var(--ui-border-accented)] text-sm text-[var(--ui-text-muted)]">
|
||||
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
||||
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -75,10 +75,24 @@ const communityLinks = computed(() => [{
|
||||
|
||||
<template>
|
||||
<UPage v-if="page">
|
||||
<UPageHeader :title="page.title" :links="page.links" :headline="headline">
|
||||
<UPageHeader :title="page.title" :headline="headline">
|
||||
<template #description>
|
||||
<MDC v-if="page.description" :value="page.description" unwrap="p" />
|
||||
</template>
|
||||
|
||||
<template #links>
|
||||
<UButton
|
||||
v-for="link in page.links"
|
||||
:key="link.label"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
v-bind="link"
|
||||
>
|
||||
<template v-if="link.avatar" #leading>
|
||||
<UAvatar v-bind="link.avatar" size="2xs" />
|
||||
</template>
|
||||
</UButton>
|
||||
</template>
|
||||
</UPageHeader>
|
||||
|
||||
<UPageBody>
|
||||
|
||||
@@ -251,10 +251,6 @@ This will give you access to the following:
|
||||
| `emblaRef`{lang="ts-type"} | `Ref<HTMLElement \| null>`{lang="ts-type"} |
|
||||
| `emblaApi`{lang="ts-type"} | [`Ref<EmblaCarouselType \| null>`{lang="ts-type"}](https://www.embla-carousel.com/api/methods/#typescript) |
|
||||
|
||||
::note{to="https://vuejs.org/api/composition-api-helpers.html#usetemplateref" target="_blank"}
|
||||
You can use `useTemplateRef` to get the component instance.
|
||||
::
|
||||
|
||||
## Theme
|
||||
|
||||
:component-theme
|
||||
|
||||
@@ -1,21 +1,406 @@
|
||||
---
|
||||
description: A responsive table element to display data in rows and columns.
|
||||
links:
|
||||
- label: TanStack Table
|
||||
avatar:
|
||||
src: https://github.com/tanstack.png
|
||||
to: https://tanstack.com/table/latest
|
||||
- label: GitHub
|
||||
icon: i-simple-icons-github
|
||||
to: https://github.com/nuxt/ui/tree/v3/src/runtime/components/Table.vue
|
||||
navigation:
|
||||
badge:
|
||||
label: Todo
|
||||
color: neutral
|
||||
disabled: true
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
The Table component is built on top of [TanStack Table](https://tanstack.com/table/latest) and is powered by the [useVueTable](https://tanstack.com/table/latest/docs/framework/vue/vue-table#usevuetable) composable to provide a flexible and fully type-safe API.
|
||||
|
||||
::note
|
||||
Some features of **TanStack Table** are not supported yet, we'll add more over time.
|
||||
::
|
||||
|
||||
::component-example
|
||||
---
|
||||
source: false
|
||||
name: 'table-example'
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/tree/v3/docs/app/components/content/examples/table/TableExample.vue"}
|
||||
This example demonstrates the most common use case of the `Table` component. Check out the source code on GitHub.
|
||||
::
|
||||
|
||||
### Data
|
||||
|
||||
Use the `data` prop as an array of objects, the columns will be generated based on the keys of the objects.
|
||||
|
||||
::component-code
|
||||
---
|
||||
collapse: true
|
||||
class: '!p-0'
|
||||
ignore:
|
||||
- data
|
||||
- class
|
||||
external:
|
||||
- data
|
||||
props:
|
||||
data:
|
||||
- id: '4600'
|
||||
date: '2024-03-11T15:30:00'
|
||||
status: 'paid'
|
||||
email: 'james.anderson@example.com'
|
||||
amount: 594
|
||||
- id: '4599'
|
||||
date: '2024-03-11T10:10:00'
|
||||
status: 'failed'
|
||||
email: 'mia.white@example.com'
|
||||
amount: 276
|
||||
- id: '4598'
|
||||
date: '2024-03-11T08:50:00'
|
||||
status: 'refunded'
|
||||
email: 'william.brown@example.com'
|
||||
amount: 315
|
||||
- id: '4597'
|
||||
date: '2024-03-10T19:45:00'
|
||||
status: 'paid'
|
||||
email: 'emma.davis@example.com'
|
||||
amount: 529
|
||||
- id: '4596'
|
||||
date: '2024-03-10T15:55:00'
|
||||
status: 'paid'
|
||||
email: 'ethan.harris@example.com'
|
||||
amount: 639
|
||||
class: 'flex-1'
|
||||
---
|
||||
::
|
||||
|
||||
### Columns
|
||||
|
||||
Use the `columns` prop as an array of [ColumnDef](https://tanstack.com/table/latest/docs/api/core/column-def) objects with properties like:
|
||||
|
||||
- `accessorKey`: [The key of the row object to use when extracting the value for the column.]{class="text-[var(--ui-text-muted)]"}
|
||||
- `header`: [The header to display for the column. If a string is passed, it can be used as a default for the column ID. If a function is passed, it will be passed a props object for the header and should return the rendered header value (the exact type depends on the adapter being used).]{class="text-[var(--ui-text-muted)]"}
|
||||
- `cell`: [The cell to display each row for the column. If a function is passed, it will be passed a props object for the cell and should return the rendered cell value (the exact type depends on the adapter being used).]{class="text-[var(--ui-text-muted)]"}
|
||||
|
||||
In order to render components or other HTML elements, you will need to use the Vue [`h` function](https://vuejs.org/api/render-function.html#h) inside the `header` and `cell` props. This is different from other components that use slots but allows for more flexibility.
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
class: '!p-0'
|
||||
name: 'table-columns-example'
|
||||
highlights:
|
||||
- 53
|
||||
- 105
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
When rendering components with the `h` function, you can utilize the `resolveComponent` function to dynamically resolve and reference components.
|
||||
::
|
||||
|
||||
### Loading
|
||||
|
||||
Use the `loading` prop to display a loading state, the `loading-color` prop to change its color and the `loading-animation` prop to change its animation.
|
||||
|
||||
::component-code
|
||||
---
|
||||
collapse: true
|
||||
class: '!p-0'
|
||||
ignore:
|
||||
- data
|
||||
- class
|
||||
external:
|
||||
- data
|
||||
props:
|
||||
loading: true
|
||||
loadingColor: primary
|
||||
loadingAnimation: carousel
|
||||
data:
|
||||
- id: '4600'
|
||||
date: '2024-03-11T15:30:00'
|
||||
status: 'paid'
|
||||
email: 'james.anderson@example.com'
|
||||
amount: 594
|
||||
- id: '4599'
|
||||
date: '2024-03-11T10:10:00'
|
||||
status: 'failed'
|
||||
email: 'mia.white@example.com'
|
||||
amount: 276
|
||||
- id: '4598'
|
||||
date: '2024-03-11T08:50:00'
|
||||
status: 'refunded'
|
||||
email: 'william.brown@example.com'
|
||||
amount: 315
|
||||
- id: '4597'
|
||||
date: '2024-03-10T19:45:00'
|
||||
status: 'paid'
|
||||
email: 'emma.davis@example.com'
|
||||
amount: 529
|
||||
- id: '4596'
|
||||
date: '2024-03-10T15:55:00'
|
||||
status: 'paid'
|
||||
email: 'ethan.harris@example.com'
|
||||
amount: 639
|
||||
class: 'flex-1'
|
||||
---
|
||||
::
|
||||
|
||||
### Sticky
|
||||
|
||||
Use the `sticky` prop to make the header sticky.
|
||||
|
||||
::component-code
|
||||
---
|
||||
collapse: true
|
||||
class: '!p-0'
|
||||
ignore:
|
||||
- data
|
||||
- class
|
||||
external:
|
||||
- data
|
||||
props:
|
||||
sticky: true
|
||||
data:
|
||||
- id: '4600'
|
||||
date: '2024-03-11T15:30:00'
|
||||
status: 'paid'
|
||||
email: 'james.anderson@example.com'
|
||||
amount: 594
|
||||
- id: '4599'
|
||||
date: '2024-03-11T10:10:00'
|
||||
status: 'failed'
|
||||
email: 'mia.white@example.com'
|
||||
amount: 276
|
||||
- id: '4598'
|
||||
date: '2024-03-11T08:50:00'
|
||||
status: 'refunded'
|
||||
email: 'william.brown@example.com'
|
||||
amount: 315
|
||||
- id: '4597'
|
||||
date: '2024-03-10T19:45:00'
|
||||
status: 'paid'
|
||||
email: 'emma.davis@example.com'
|
||||
amount: 529
|
||||
- id: '4596'
|
||||
date: '2024-03-10T15:55:00'
|
||||
status: 'paid'
|
||||
email: 'ethan.harris@example.com'
|
||||
amount: 639
|
||||
- id: '4595'
|
||||
date: '2024-03-10T15:55:00'
|
||||
status: 'paid'
|
||||
email: 'ethan.harris@example.com'
|
||||
amount: 639
|
||||
- id: '4594'
|
||||
date: '2024-03-10T15:55:00'
|
||||
status: 'paid'
|
||||
email: 'ethan.harris@example.com'
|
||||
amount: 639
|
||||
class: 'flex-1 max-h-[312px]'
|
||||
---
|
||||
::
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- ## API
|
||||
### With row actions
|
||||
|
||||
You can add a new column that renders a [DropdownMenu](/components/dropdown-menu) component inside the `cell` to render row actions.
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-row-actions-example'
|
||||
highlights:
|
||||
- 110
|
||||
- 134
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
### With expandable rows
|
||||
|
||||
You can add a new column that renders a [Button](/components/button) component inside the `cell` to toggle the expandable state of a row using the TanStack Table [Expanding APIs](https://tanstack.com/table/latest/docs/api/features/expanding).
|
||||
|
||||
::caution
|
||||
You need to define the `#expanded` slot to render the expanded content which will receive the row as a parameter.
|
||||
::
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-row-expandable-example'
|
||||
highlights:
|
||||
- 55
|
||||
- 71
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can use the `expanded` prop to control the expandable state of the rows (can be binded with `v-model`).
|
||||
::
|
||||
|
||||
::note
|
||||
You could also add this action to the [DropdownMenu](/components/dropdown-menu) component inside the `actions` column.
|
||||
::
|
||||
|
||||
### With row selection
|
||||
|
||||
You can add a new column that renders a [Checkbox](/components/checkbox) component inside the `header` and `cell` to select rows using the TanStack Table [Row Selection APIs](https://tanstack.com/table/latest/docs/api/features/row-selection).
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-row-selection-example'
|
||||
highlights:
|
||||
- 55
|
||||
- 70
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can use the `row-selection` prop to control the selection state of the rows (can be binded with `v-model`).
|
||||
::
|
||||
|
||||
### With column sorting
|
||||
|
||||
You can update a column `header` to render a [Button](/components/button) component inside the `header` to toggle the sorting state using the TanStack Table [Sorting APIs](https://tanstack.com/table/latest/docs/api/features/sorting).
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-column-sorting-example'
|
||||
highlights:
|
||||
- 90
|
||||
- 105
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can use the `sorting` prop to control the sorting state of the columns (can be binded with `v-model`).
|
||||
::
|
||||
|
||||
You can also create a reusable component to make any column header sortable.
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-column-sorting-reusable-example'
|
||||
highlights:
|
||||
- 110
|
||||
- 161
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::note
|
||||
In this example, we use a function to define the column header but you can also create an actual component.
|
||||
::
|
||||
|
||||
### With column pinning
|
||||
|
||||
You can update a column `header` to render a [Button](/components/button) component inside the `header` to toggle the pinning state using the TanStack Table [Pinning APIs](https://tanstack.com/table/latest/docs/api/features/row-pinning).
|
||||
|
||||
::note
|
||||
A pinned column will become sticky on the left or right side of the table.
|
||||
::
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-column-pinning-example'
|
||||
highlights:
|
||||
- 100
|
||||
- 113
|
||||
class: '!p-0 overflow-clip'
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can use the `column-pinning` prop to control the pinning state of the columns (can be binded with `v-model`).
|
||||
::
|
||||
|
||||
### With column visibility
|
||||
|
||||
You can add use [DropdownMenu](/components/dropdown-menu) component to toggle the visibility of the columns using the TanStack Table [Column Visibility APIs](https://tanstack.com/table/latest/docs/api/features/column-visibility).
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-column-visibility-example'
|
||||
highlights:
|
||||
- 135
|
||||
- 142
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can use the `column-visibility` prop to control the visibility state of the columns (can be binded with `v-model`).
|
||||
::
|
||||
|
||||
### With column filters
|
||||
|
||||
You can use an [Input](/components/input) component to filter per column the rows using the TanStack Table [Column Filtering APIs](https://tanstack.com/table/latest/docs/api/features/column-filtering).
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-column-filters-example'
|
||||
highlights:
|
||||
- 135
|
||||
- 142
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can use the `column-filters` prop to control the filters state of the columns (can be binded with `v-model`).
|
||||
::
|
||||
|
||||
### With global filter
|
||||
|
||||
You can use an [Input](/components/input) component to filter the rows using the TanStack Table [Global Filtering APIs](https://tanstack.com/table/latest/docs/api/features/global-filtering).
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-global-filter-example'
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
::tip
|
||||
You can use the `global-filter` prop to control the global filter state (can be binded with `v-model`).
|
||||
::
|
||||
|
||||
### With fetched data
|
||||
|
||||
You can fetch data from an API and use them in the Table.
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-fetch-example'
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
@@ -25,10 +410,26 @@ navigation:
|
||||
|
||||
:component-slots
|
||||
|
||||
### Emits
|
||||
### Expose
|
||||
|
||||
:component-emits
|
||||
You can access the typed component instance using [`useTemplateRef`](https://vuejs.org/api/composition-api-helpers.html#usetemplateref).
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
const table = useTemplateRef('table')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UTable ref="table" />
|
||||
</template>
|
||||
```
|
||||
|
||||
This will give you access to the following:
|
||||
|
||||
| Name | Type |
|
||||
| ---- | ---- |
|
||||
| `tableApi`{lang="ts-type"} | [`Ref<Table \| null>`{lang="ts-type"}](https://tanstack.com/table/latest/docs/api/core/table#table-api) |
|
||||
|
||||
## Theme
|
||||
|
||||
:component-theme -->
|
||||
:component-theme
|
||||
|
||||
@@ -179,6 +179,7 @@ export default defineNuxtConfig({
|
||||
'USlider',
|
||||
'USlideover',
|
||||
'USwitch',
|
||||
'UTable',
|
||||
'UTabs',
|
||||
'UTextarea',
|
||||
'UTooltip'
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"@nuxt/content": "^2.13.4",
|
||||
"@nuxt/image": "^1.8.1",
|
||||
"@nuxt/ui": "latest",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@041ca1f",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@5c9e5b4",
|
||||
"@nuxthub/core": "^0.7.33",
|
||||
"@nuxtjs/plausible": "^1.0.3",
|
||||
"@octokit/rest": "^21.0.2",
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
"@nuxtjs/color-mode": "^3.5.1",
|
||||
"@tailwindcss/postcss": "4.0.0-alpha.28",
|
||||
"@tailwindcss/vite": "4.0.0-alpha.28",
|
||||
"@tanstack/vue-table": "^8.20.5",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"@vueuse/integrations": "^11.1.0",
|
||||
"defu": "^6.1.4",
|
||||
|
||||
@@ -42,6 +42,7 @@ const components = [
|
||||
'slider',
|
||||
'switch',
|
||||
'tabs',
|
||||
'table',
|
||||
'textarea',
|
||||
'toast',
|
||||
'tooltip'
|
||||
|
||||
354
playground/app/pages/components/table.vue
Normal file
354
playground/app/pages/components/table.vue
Normal file
@@ -0,0 +1,354 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import { upperFirst } from 'scule'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
|
||||
const UButton = resolveComponent('UButton')
|
||||
const UCheckbox = resolveComponent('UCheckbox')
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
const UDropdownMenu = resolveComponent('UDropdownMenu')
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
type Payment = {
|
||||
id: string
|
||||
date: string
|
||||
status: 'paid' | 'failed' | 'refunded'
|
||||
email: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
const table = useTemplateRef('table')
|
||||
|
||||
const data = ref<Payment[]>([{
|
||||
id: '4600',
|
||||
date: '2024-03-11T15:30:00',
|
||||
status: 'paid',
|
||||
email: 'james.anderson@example.com',
|
||||
amount: 594
|
||||
}, {
|
||||
id: '4599',
|
||||
date: '2024-03-11T10:10:00',
|
||||
status: 'failed',
|
||||
email: 'mia.white@example.com',
|
||||
amount: 276
|
||||
}, {
|
||||
id: '4598',
|
||||
date: '2024-03-11T08:50:00',
|
||||
status: 'refunded',
|
||||
email: 'william.brown@example.com',
|
||||
amount: 315
|
||||
}, {
|
||||
id: '4597',
|
||||
date: '2024-03-10T19:45:00',
|
||||
status: 'paid',
|
||||
email: 'emma.davis@example.com',
|
||||
amount: 529
|
||||
}, {
|
||||
id: '4596',
|
||||
date: '2024-03-10T15:55:00',
|
||||
status: 'paid',
|
||||
email: 'ethan.harris@example.com',
|
||||
amount: 639
|
||||
}, {
|
||||
id: '4595',
|
||||
date: '2024-03-10T13:40:00',
|
||||
status: 'refunded',
|
||||
email: 'ava.thomas@example.com',
|
||||
amount: 428
|
||||
}, {
|
||||
id: '4594',
|
||||
date: '2024-03-10T09:15:00',
|
||||
status: 'paid',
|
||||
email: 'michael.wilson@example.com',
|
||||
amount: 683
|
||||
}, {
|
||||
id: '4593',
|
||||
date: '2024-03-09T20:25:00',
|
||||
status: 'failed',
|
||||
email: 'olivia.taylor@example.com',
|
||||
amount: 947
|
||||
}, {
|
||||
id: '4592',
|
||||
date: '2024-03-09T18:45:00',
|
||||
status: 'paid',
|
||||
email: 'benjamin.jackson@example.com',
|
||||
amount: 851
|
||||
}, {
|
||||
id: '4591',
|
||||
date: '2024-03-09T16:05:00',
|
||||
status: 'paid',
|
||||
email: 'sophia.miller@example.com',
|
||||
amount: 762
|
||||
}, {
|
||||
id: '4590',
|
||||
date: '2024-03-09T14:20:00',
|
||||
status: 'paid',
|
||||
email: 'noah.clark@example.com',
|
||||
amount: 573
|
||||
}, {
|
||||
id: '4589',
|
||||
date: '2024-03-09T11:35:00',
|
||||
status: 'failed',
|
||||
email: 'isabella.lee@example.com',
|
||||
amount: 389
|
||||
}, {
|
||||
id: '4588',
|
||||
date: '2024-03-08T22:50:00',
|
||||
status: 'refunded',
|
||||
email: 'liam.walker@example.com',
|
||||
amount: 701
|
||||
}, {
|
||||
id: '4587',
|
||||
date: '2024-03-08T20:15:00',
|
||||
status: 'paid',
|
||||
email: 'charlotte.hall@example.com',
|
||||
amount: 856
|
||||
}, {
|
||||
id: '4586',
|
||||
date: '2024-03-08T17:40:00',
|
||||
status: 'paid',
|
||||
email: 'mason.young@example.com',
|
||||
amount: 492
|
||||
}, {
|
||||
id: '4585',
|
||||
date: '2024-03-08T14:55:00',
|
||||
status: 'failed',
|
||||
email: 'amelia.king@example.com',
|
||||
amount: 637
|
||||
}, {
|
||||
id: '4584',
|
||||
date: '2024-03-08T12:30:00',
|
||||
status: 'paid',
|
||||
email: 'elijah.wright@example.com',
|
||||
amount: 784
|
||||
}, {
|
||||
id: '4583',
|
||||
date: '2024-03-08T09:45:00',
|
||||
status: 'refunded',
|
||||
email: 'harper.scott@example.com',
|
||||
amount: 345
|
||||
}, {
|
||||
id: '4582',
|
||||
date: '2024-03-07T23:10:00',
|
||||
status: 'paid',
|
||||
email: 'evelyn.green@example.com',
|
||||
amount: 918
|
||||
}, {
|
||||
id: '4581',
|
||||
date: '2024-03-07T20:25:00',
|
||||
status: 'paid',
|
||||
email: 'logan.baker@example.com',
|
||||
amount: 567
|
||||
}])
|
||||
|
||||
const columns: TableColumn<Payment>[] = [{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(UCheckbox, {
|
||||
'modelValue': table.getIsAllPageRowsSelected(),
|
||||
'indeterminate': table.getIsSomePageRowsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all'
|
||||
}),
|
||||
cell: ({ row }) => h(UCheckbox, {
|
||||
'modelValue': row.getIsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
|
||||
'ariaLabel': 'Select row'
|
||||
}),
|
||||
enableSorting: false,
|
||||
enableHiding: false
|
||||
}, {
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: ({ column }) => {
|
||||
const isSorted = column.getIsSorted()
|
||||
|
||||
return h(UButton, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
label: 'Email',
|
||||
icon: isSorted ? (isSorted === 'asc' ? 'i-heroicons-bars-arrow-up-20-solid' : 'i-heroicons-bars-arrow-down-20-solid') : 'i-heroicons-arrows-up-down-20-solid',
|
||||
class: '-mx-2.5',
|
||||
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc')
|
||||
})
|
||||
},
|
||||
cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email'))
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}, {
|
||||
id: 'actions',
|
||||
enableHiding: false,
|
||||
cell: ({ row }) => {
|
||||
const items = [{
|
||||
type: 'label',
|
||||
label: 'Actions'
|
||||
}, {
|
||||
label: 'Copy payment ID',
|
||||
onSelect() {
|
||||
navigator.clipboard.writeText(row.original.id)
|
||||
|
||||
toast.add({
|
||||
title: 'Payment ID copied to clipboard!',
|
||||
color: 'success',
|
||||
icon: 'i-heroicons-check-circle'
|
||||
})
|
||||
}
|
||||
}, {
|
||||
label: row.getIsExpanded() ? 'Collapse' : 'Expand',
|
||||
onSelect() {
|
||||
row.toggleExpanded()
|
||||
}
|
||||
}, {
|
||||
type: 'separator'
|
||||
}, {
|
||||
label: 'View customer'
|
||||
}, {
|
||||
label: 'View payment details'
|
||||
}]
|
||||
|
||||
return h('div', { class: 'text-right' }, h(UDropdownMenu, {
|
||||
content: {
|
||||
align: 'end'
|
||||
},
|
||||
items
|
||||
}, () => h(UButton, {
|
||||
icon: 'i-heroicons-ellipsis-vertical-20-solid',
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
class: 'ml-auto'
|
||||
})))
|
||||
}
|
||||
}]
|
||||
|
||||
const loading = ref(true)
|
||||
const columnPinning = ref({
|
||||
left: ['id'],
|
||||
right: ['actions']
|
||||
})
|
||||
|
||||
function randomize() {
|
||||
data.value = [...data.value].sort(() => Math.random() - 0.5)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1300)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full flex flex-col flex-1 gap-4 w-full -my-8">
|
||||
<div class="flex gap-2 items-center">
|
||||
<UInput
|
||||
:model-value="(table?.tableApi?.getColumn('email')?.getFilterValue() as string)"
|
||||
class="max-w-sm"
|
||||
placeholder="Filter emails..."
|
||||
@update:model-value="table?.tableApi?.getColumn('email')?.setFilterValue($event)"
|
||||
/>
|
||||
|
||||
<UButton color="neutral" label="Randomize" @click="randomize" />
|
||||
|
||||
<UDropdownMenu
|
||||
:items="table?.tableApi?.getAllColumns().filter(column => column.getCanHide()).map(column => ({
|
||||
label: upperFirst(column.id),
|
||||
type: 'checkbox' as const,
|
||||
checked: column.getIsVisible(),
|
||||
onUpdateChecked(checked: boolean) {
|
||||
table?.tableApi?.getColumn(column.id)?.toggleVisibility(!!checked)
|
||||
},
|
||||
onSelect(e?: Event) {
|
||||
e?.preventDefault()
|
||||
}
|
||||
}))"
|
||||
:content="{ align: 'end' }"
|
||||
>
|
||||
<UButton
|
||||
label="Columns"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
trailing-icon="i-heroicons-chevron-down-20-solid"
|
||||
class="ml-auto"
|
||||
/>
|
||||
</UDropdownMenu>
|
||||
</div>
|
||||
|
||||
<UTable
|
||||
ref="table"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
:column-pinning="columnPinning"
|
||||
:loading="loading"
|
||||
sticky
|
||||
class="border border-[var(--ui-border-accented)] rounded-[var(--ui-radius)] flex-1"
|
||||
>
|
||||
<template #expanded="{ row }">
|
||||
<pre>{{ row.original }}</pre>
|
||||
</template>
|
||||
</UTable>
|
||||
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div class="text-sm text-[var(--ui-text-muted)]">
|
||||
{{ table?.tableApi?.getFilteredSelectedRowModel().rows.length || 0 }} of
|
||||
{{ table?.tableApi?.getFilteredRowModel().rows.length || 0 }} row(s) selected.
|
||||
</div>
|
||||
|
||||
<!-- <div class="flex items-center gap-1.5">
|
||||
<UButton
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
:disabled="!table?.tableApi?.getCanPreviousPage()"
|
||||
@click="table?.tableApi?.previousPage()"
|
||||
>
|
||||
Prev
|
||||
</UButton>
|
||||
<UButton
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
:disabled="!table?.tableApi?.getCanNextPage()"
|
||||
@click="table?.tableApi?.nextPage()"
|
||||
>
|
||||
Next
|
||||
</UButton>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
@@ -34,6 +34,9 @@ importers:
|
||||
'@tailwindcss/vite':
|
||||
specifier: 4.0.0-alpha.28
|
||||
version: 4.0.0-alpha.28(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.27.0)(terser@5.36.0))
|
||||
'@tanstack/vue-table':
|
||||
specifier: ^8.20.5
|
||||
version: 8.20.5(vue@3.5.12(typescript@5.6.3))
|
||||
'@vueuse/core':
|
||||
specifier: ^11.1.0
|
||||
version: 11.1.0(vue@3.5.12(typescript@5.6.3))
|
||||
@@ -183,8 +186,8 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:..
|
||||
'@nuxt/ui-pro':
|
||||
specifier: https://pkg.pr.new/@nuxt/ui-pro@041ca1f
|
||||
version: https://pkg.pr.new/@nuxt/ui-pro@041ca1f(magicast@0.3.5)(rollup@4.24.0)(typescript@5.6.3)(vue@3.5.12(typescript@5.6.3))
|
||||
specifier: https://pkg.pr.new/@nuxt/ui-pro@5c9e5b4
|
||||
version: https://pkg.pr.new/@nuxt/ui-pro@5c9e5b4(magicast@0.3.5)(rollup@4.24.0)(typescript@5.6.3)(vue@3.5.12(typescript@5.6.3))
|
||||
'@nuxthub/core':
|
||||
specifier: ^0.7.33
|
||||
version: 0.7.34(ioredis@5.4.1)(magicast@0.3.5)(rollup@4.24.0)(vite@5.4.9(@types/node@22.7.7)(lightningcss@1.27.0)(terser@5.36.0))
|
||||
@@ -1613,9 +1616,9 @@ packages:
|
||||
vitest:
|
||||
optional: true
|
||||
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@041ca1f':
|
||||
resolution: {tarball: https://pkg.pr.new/@nuxt/ui-pro@041ca1f}
|
||||
version: 2.0.0-alpha.6
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@5c9e5b4':
|
||||
resolution: {tarball: https://pkg.pr.new/@nuxt/ui-pro@5c9e5b4}
|
||||
version: 3.0.0-alpha.6
|
||||
peerDependencies:
|
||||
typescript: ^5.6.3
|
||||
|
||||
@@ -2222,9 +2225,19 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^5.2.0
|
||||
|
||||
'@tanstack/table-core@8.20.5':
|
||||
resolution: {integrity: sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@tanstack/virtual-core@3.10.8':
|
||||
resolution: {integrity: sha512-PBu00mtt95jbKFi6Llk9aik8bnR3tR/oQP1o3TSi+iG//+Q2RTIzCEgKkHG8BB86kxMNW6O8wku+Lmi+QFR6jA==}
|
||||
|
||||
'@tanstack/vue-table@8.20.5':
|
||||
resolution: {integrity: sha512-2xixT3BEgSDw+jOSqPt6ylO/eutDI107t2WdFMVYIZZ45UmTHLySqNriNs0+dMaKR56K5z3t+97P6VuVnI2L+Q==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
vue: '>=3.2'
|
||||
|
||||
'@tanstack/vue-virtual@3.10.8':
|
||||
resolution: {integrity: sha512-DB5QA8c/LfqOqIUCpSs3RdOTVroRRdqeHMqBkYrcashSZtOzIv8xbiqHgg7RYxDfkH5F3Y+e0MkuuyGNDVB0BQ==}
|
||||
peerDependencies:
|
||||
@@ -8344,7 +8357,7 @@ snapshots:
|
||||
- supports-color
|
||||
- webpack-sources
|
||||
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@041ca1f(magicast@0.3.5)(rollup@4.24.0)(typescript@5.6.3)(vue@3.5.12(typescript@5.6.3))':
|
||||
'@nuxt/ui-pro@https://pkg.pr.new/@nuxt/ui-pro@5c9e5b4(magicast@0.3.5)(rollup@4.24.0)(typescript@5.6.3)(vue@3.5.12(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@nuxt/kit': 3.13.2(magicast@0.3.5)(rollup@4.24.0)
|
||||
'@nuxt/schema': 3.13.2(rollup@4.24.0)
|
||||
@@ -9050,8 +9063,15 @@ snapshots:
|
||||
tailwindcss: 4.0.0-alpha.28
|
||||
vite: 5.4.9(@types/node@22.7.7)(lightningcss@1.27.0)(terser@5.36.0)
|
||||
|
||||
'@tanstack/table-core@8.20.5': {}
|
||||
|
||||
'@tanstack/virtual-core@3.10.8': {}
|
||||
|
||||
'@tanstack/vue-table@8.20.5(vue@3.5.12(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@tanstack/table-core': 8.20.5
|
||||
vue: 3.5.12(typescript@5.6.3)
|
||||
|
||||
'@tanstack/vue-virtual@3.10.8(vue@3.5.12(typescript@5.6.3))':
|
||||
dependencies:
|
||||
'@tanstack/virtual-core': 3.10.8
|
||||
|
||||
@@ -10,40 +10,40 @@ export interface ModuleOptions {
|
||||
/**
|
||||
* Prefix for components
|
||||
* @defaultValue `U`
|
||||
* @see https://ui3.nuxt.dev/getting-started/installation#prefix
|
||||
* @link https://ui3.nuxt.dev/getting-started/installation#prefix
|
||||
*/
|
||||
prefix?: string
|
||||
|
||||
/**
|
||||
* Enable or disable `@nuxt/fonts` module
|
||||
* @defaultValue `true`
|
||||
* @see https://ui3.nuxt.dev/getting-started/installation#fonts
|
||||
* @link https://ui3.nuxt.dev/getting-started/installation#fonts
|
||||
*/
|
||||
fonts?: boolean
|
||||
|
||||
/**
|
||||
* Enable or disable `@nuxtjs/color-mode` module
|
||||
* @defaultValue `true`
|
||||
* @see https://ui3.nuxt.dev/getting-started/installation#colormode
|
||||
* @link https://ui3.nuxt.dev/getting-started/installation#colormode
|
||||
*/
|
||||
colorMode?: boolean
|
||||
|
||||
/**
|
||||
* Customize how the theme is generated
|
||||
* @see https://ui3.nuxt.dev/getting-started/theme
|
||||
* @link https://ui3.nuxt.dev/getting-started/theme
|
||||
*/
|
||||
theme?: {
|
||||
/**
|
||||
* Define the color aliases available for components
|
||||
* @defaultValue `['primary', 'secondary', 'success', 'info', 'warning', 'error']`
|
||||
* @see https://ui3.nuxt.dev/getting-started/installation#themecolors
|
||||
* @link https://ui3.nuxt.dev/getting-started/installation#themecolors
|
||||
*/
|
||||
colors?: string[]
|
||||
|
||||
/**
|
||||
* Enable or disable transitions on components
|
||||
* @defaultValue `true`
|
||||
* @see https://ui3.nuxt.dev/getting-started/installation#themetransitions
|
||||
* @link https://ui3.nuxt.dev/getting-started/installation#themetransitions
|
||||
*/
|
||||
transitions?: boolean
|
||||
}
|
||||
|
||||
@@ -55,32 +55,32 @@ export interface CarouselProps<T> extends Omit<EmblaOptionsType, 'axis' | 'conta
|
||||
items?: T[]
|
||||
/**
|
||||
* Enable Autoplay plugin
|
||||
* @see https://www.embla-carousel.com/plugins/autoplay/
|
||||
* @link https://www.embla-carousel.com/plugins/autoplay/
|
||||
*/
|
||||
autoplay?: boolean | AutoplayOptionsType
|
||||
/**
|
||||
* Enable Auto Scroll plugin
|
||||
* @see https://www.embla-carousel.com/plugins/auto-scroll/
|
||||
* @link https://www.embla-carousel.com/plugins/auto-scroll/
|
||||
*/
|
||||
autoScroll?: boolean | AutoScrollOptionsType
|
||||
/**
|
||||
* Enable Auto Height plugin
|
||||
* @see https://www.embla-carousel.com/plugins/auto-height/
|
||||
* @link https://www.embla-carousel.com/plugins/auto-height/
|
||||
*/
|
||||
autoHeight?: boolean | AutoHeightOptionsType
|
||||
/**
|
||||
* Enable Class Names plugin
|
||||
* @see https://www.embla-carousel.com/plugins/class-names/
|
||||
* @link https://www.embla-carousel.com/plugins/class-names/
|
||||
*/
|
||||
classNames?: boolean | ClassNamesOptionsType
|
||||
/**
|
||||
* Enable Fade plugin
|
||||
* @see https://www.embla-carousel.com/plugins/fade/
|
||||
* @link https://www.embla-carousel.com/plugins/fade/
|
||||
*/
|
||||
fade?: boolean | FadeOptionsType
|
||||
/**
|
||||
* Enable Wheel Gestures plugin
|
||||
* @see https://www.embla-carousel.com/plugins/wheel-gestures/
|
||||
* @link https://www.embla-carousel.com/plugins/wheel-gestures/
|
||||
*/
|
||||
wheelGestures?: boolean | WheelGesturesPluginOptions
|
||||
class?: any
|
||||
|
||||
232
src/runtime/components/Table.vue
Normal file
232
src/runtime/components/Table.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<!-- eslint-disable vue/block-tag-newline -->
|
||||
<script lang="ts">
|
||||
import type { Ref } from 'vue'
|
||||
import { tv, type VariantProps } from 'tailwind-variants'
|
||||
import type { AppConfig } from '@nuxt/schema'
|
||||
import type {
|
||||
Row,
|
||||
ColumnDef,
|
||||
ColumnFiltersState,
|
||||
ColumnPinningState,
|
||||
RowSelectionState,
|
||||
SortingState,
|
||||
ExpandedState,
|
||||
VisibilityState,
|
||||
GlobalFilterOptions,
|
||||
ColumnFiltersOptions,
|
||||
ColumnPinningOptions,
|
||||
VisibilityOptions,
|
||||
ExpandedOptions,
|
||||
SortingOptions,
|
||||
RowSelectionOptions,
|
||||
Updater
|
||||
} from '@tanstack/vue-table'
|
||||
import _appConfig from '#build/app.config'
|
||||
import theme from '#build/ui/table'
|
||||
|
||||
const appConfig = _appConfig as AppConfig & { ui: { table: Partial<typeof theme> } }
|
||||
|
||||
const table = tv({ extend: tv(theme), ...(appConfig.ui?.table || {}) })
|
||||
|
||||
type TableVariants = VariantProps<typeof table>
|
||||
|
||||
export type TableColumn<T> = ColumnDef<T>
|
||||
|
||||
export interface TableData {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface TableProps<T> {
|
||||
data?: T[]
|
||||
columns?: TableColumn<T>[]
|
||||
/**
|
||||
* Whether the table should have a sticky header.
|
||||
* @defaultValue false
|
||||
*/
|
||||
sticky?: boolean
|
||||
/** Whether the table should be in loading state. */
|
||||
loading?: boolean
|
||||
loadingColor?: TableVariants['loadingColor']
|
||||
loadingAnimation?: TableVariants['loadingAnimation']
|
||||
/**
|
||||
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/global-filtering#table-options)
|
||||
* @link [Guide](https://tanstack.com/table/v8/docs/guide/global-filtering)
|
||||
*/
|
||||
globalFilterOptions?: Omit<GlobalFilterOptions<T>, 'onGlobalFilterChange'>
|
||||
/**
|
||||
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-filtering#table-options)
|
||||
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-filtering)
|
||||
*/
|
||||
columnFiltersOptions?: Omit<ColumnFiltersOptions<T>, 'getFilteredRowModel' | 'onColumnFiltersChange'>
|
||||
/**
|
||||
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-pinning#table-options)
|
||||
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-pinning)
|
||||
*/
|
||||
columnPinningOptions?: Omit<ColumnPinningOptions, 'onColumnPinningChange'>
|
||||
/**
|
||||
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/column-visibility#table-options)
|
||||
* @link [Guide](https://tanstack.com/table/v8/docs/guide/column-visibility)
|
||||
*/
|
||||
visibilityOptions?: Omit<VisibilityOptions, 'onColumnVisibilityChange'>
|
||||
/**
|
||||
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/sorting#table-options)
|
||||
* @link [Guide](https://tanstack.com/table/v8/docs/guide/sorting)
|
||||
*/
|
||||
sortingOptions?: Omit<SortingOptions<T>, 'getSortedRowModel' | 'onSortingChange'>
|
||||
/**
|
||||
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/expanding#table-options)
|
||||
* @link [Guide](https://tanstack.com/table/v8/docs/guide/expanding)
|
||||
*/
|
||||
expandedOptions?: Omit<ExpandedOptions<T>, 'getExpandedRowModel' | 'onExpandedChange'>
|
||||
/**
|
||||
* @link [API Docs](https://tanstack.com/table/v8/docs/api/features/row-selection#table-options)
|
||||
* @link [Guide](https://tanstack.com/table/v8/docs/guide/row-selection)
|
||||
*/
|
||||
rowSelectionOptions?: Omit<RowSelectionOptions<T>, 'onRowSelectionChange'>
|
||||
class?: any
|
||||
ui?: Partial<typeof table.slots>
|
||||
}
|
||||
|
||||
export interface TableSlots<T> {
|
||||
expanded(props: { row: Row<T> }): any
|
||||
empty(props?: {}): any
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script setup lang="ts" generic="T extends TableData">
|
||||
import { computed } from 'vue'
|
||||
import {
|
||||
FlexRender,
|
||||
getCoreRowModel,
|
||||
getFilteredRowModel,
|
||||
getSortedRowModel,
|
||||
getExpandedRowModel,
|
||||
useVueTable
|
||||
} from '@tanstack/vue-table'
|
||||
import { upperFirst } from 'scule'
|
||||
|
||||
const props = defineProps<TableProps<T>>()
|
||||
defineSlots<TableSlots<T>>()
|
||||
|
||||
const data = computed(() => props.data ?? [])
|
||||
const columns = computed<TableColumn<T>[]>(() => props.columns ?? Object.keys(data.value[0] ?? {}).map((accessorKey: string) => ({ accessorKey, header: upperFirst(accessorKey) })))
|
||||
|
||||
const ui = computed(() => table({
|
||||
sticky: props.sticky,
|
||||
loading: props.loading,
|
||||
loadingColor: props.loadingColor,
|
||||
loadingAnimation: props.loadingAnimation
|
||||
}))
|
||||
|
||||
const globalFilterState = defineModel<string>('globalFilter', { default: undefined })
|
||||
const columnFiltersState = defineModel<ColumnFiltersState>('columnFilters', { default: [] })
|
||||
const columnVisibilityState = defineModel<VisibilityState>('columnVisibility', { default: {} })
|
||||
const columnPinningState = defineModel<ColumnPinningState>('columnPinning', { default: {} })
|
||||
const rowSelectionState = defineModel<RowSelectionState>('rowSelection', { default: {} })
|
||||
const sortingState = defineModel<SortingState>('sorting', { default: [] })
|
||||
const expandedState = defineModel<ExpandedState>('expanded', { default: {} })
|
||||
|
||||
const tableApi = useVueTable({
|
||||
data,
|
||||
columns: columns.value,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
...(props.globalFilterOptions || {}),
|
||||
onGlobalFilterChange: updaterOrValue => valueUpdater(updaterOrValue, globalFilterState),
|
||||
...(props.columnFiltersOptions || {}),
|
||||
getFilteredRowModel: getFilteredRowModel(),
|
||||
onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFiltersState),
|
||||
...(props.visibilityOptions || {}),
|
||||
onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibilityState),
|
||||
...(props.columnPinningOptions || {}),
|
||||
onColumnPinningChange: updaterOrValue => valueUpdater(updaterOrValue, columnPinningState),
|
||||
...(props.rowSelectionOptions || {}),
|
||||
onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelectionState),
|
||||
...(props.sortingOptions || {}),
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sortingState),
|
||||
...(props.expandedOptions || {}),
|
||||
getExpandedRowModel: getExpandedRowModel(),
|
||||
onExpandedChange: updaterOrValue => valueUpdater(updaterOrValue, expandedState),
|
||||
state: {
|
||||
get globalFilter() {
|
||||
return globalFilterState.value
|
||||
},
|
||||
get columnFilters() {
|
||||
return columnFiltersState.value
|
||||
},
|
||||
get columnVisibility() {
|
||||
return columnVisibilityState.value
|
||||
},
|
||||
get columnPinning() {
|
||||
return columnPinningState.value
|
||||
},
|
||||
get expanded() {
|
||||
return expandedState.value
|
||||
},
|
||||
get rowSelection() {
|
||||
return rowSelectionState.value
|
||||
},
|
||||
get sorting() {
|
||||
return sortingState.value
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
|
||||
ref.value = typeof updaterOrValue === 'function' ? updaterOrValue(ref.value) : updaterOrValue
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
tableApi
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="ui.root({ class: [props.class, props.ui?.root] })">
|
||||
<table :class="ui.base({ class: [props.ui?.base] })">
|
||||
<thead :class="ui.thead({ class: [props.ui?.thead] })">
|
||||
<tr v-for="headerGroup in tableApi.getHeaderGroups()" :key="headerGroup.id" :class="ui.tr({ class: [props.ui?.tr] })">
|
||||
<th
|
||||
v-for="header in headerGroup.headers"
|
||||
:key="header.id"
|
||||
:data-pinned="header.column.getIsPinned()"
|
||||
:class="ui.th({ class: [props.ui?.th], pinned: !!header.column.getIsPinned() })"
|
||||
>
|
||||
<FlexRender v-if="!header.isPlaceholder" :render="header.column.columnDef.header" :props="header.getContext()" />
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody :class="ui.tbody({ class: [props.ui?.tbody] })">
|
||||
<template v-if="tableApi.getRowModel().rows?.length">
|
||||
<template v-for="row in tableApi.getRowModel().rows" :key="row.id">
|
||||
<tr :data-selected="row.getIsSelected()" :data-expanded="row.getIsExpanded()" :class="ui.tr({ class: [props.ui?.tr] })">
|
||||
<td
|
||||
v-for="cell in row.getVisibleCells()"
|
||||
:key="cell.id"
|
||||
:data-pinned="cell.column.getIsPinned()"
|
||||
:class="ui.td({ class: [props.ui?.td], pinned: !!cell.column.getIsPinned() })"
|
||||
>
|
||||
<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="row.getIsExpanded()" :class="ui.tr({ class: [props.ui?.tr] })">
|
||||
<td :colspan="row.getAllCells().length" :class="ui.td({ class: [props.ui?.td] })">
|
||||
<slot name="expanded" :row="row" />
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<tr v-else :class="ui.tr({ class: [props.ui?.tr] })">
|
||||
<td :colspan="columns?.length" :class="ui.empty({ class: props.ui?.empty })">
|
||||
<slot name="empty">
|
||||
No results
|
||||
</slot>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ref, inject } from 'vue'
|
||||
import type { ShallowRef, Component, InjectionKey } from 'vue'
|
||||
import type { ComponentProps } from 'vue-component-type-helpers'
|
||||
import { createSharedComposable } from '@vueuse/core'
|
||||
import type { ModalProps } from '../types'
|
||||
import type { ComponentProps } from '../types/component'
|
||||
|
||||
export interface ModalState {
|
||||
component: Component | string
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ref, inject } from 'vue'
|
||||
import type { ShallowRef, Component, InjectionKey } from 'vue'
|
||||
import type { ComponentProps } from 'vue-component-type-helpers'
|
||||
import { createSharedComposable } from '@vueuse/core'
|
||||
import type { SlideoverProps } from '../types'
|
||||
import type { ComponentProps } from '../types/component'
|
||||
|
||||
export interface SlideoverState {
|
||||
component: Component | string
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
export type ComponentProps<T> =
|
||||
T extends new () => { $props: infer P } ? NonNullable<P> :
|
||||
T extends (props: infer P, ...args: any) => any ? P :
|
||||
Record<string, never>
|
||||
|
||||
export type ComponentSlots<T> =
|
||||
T extends new () => { $slots: infer S } ? NonNullable<S> :
|
||||
T extends (props: any, ctx: { slots: infer S, attrs: any, emit: any }, ...args: any) => any ? NonNullable<S> :
|
||||
Record<string, never>
|
||||
|
||||
export type ComponentEmit<T> =
|
||||
T extends new () => { $emit: infer E } ? NonNullable<E> :
|
||||
T extends (props: any, ctx: { slots: any, attrs: any, emit: infer E }, ...args: any) => any ? NonNullable<E> :
|
||||
Record<string, never>
|
||||
@@ -35,6 +35,7 @@ export * from '../components/Skeleton.vue'
|
||||
export * from '../components/Slideover.vue'
|
||||
export * from '../components/Slider.vue'
|
||||
export * from '../components/Switch.vue'
|
||||
export * from '../components/Table.vue'
|
||||
export * from '../components/Tabs.vue'
|
||||
export * from '../components/Textarea.vue'
|
||||
export * from '../components/Toast.vue'
|
||||
|
||||
@@ -8,7 +8,7 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
content: 'relative overflow-hidden',
|
||||
viewport: 'divide-y divide-[var(--ui-border)] scroll-py-1',
|
||||
group: 'p-1 isolate',
|
||||
empty: 'py-6 text-center text-sm',
|
||||
empty: 'py-6 text-center text-sm text-[var(--ui-text-muted)]',
|
||||
label: 'px-2 py-1.5 text-xs font-semibold text-[var(--ui-text-highlighted)]',
|
||||
item: ['group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50', options.theme.transitions && 'transition-colors before:transition-colors'],
|
||||
itemLeadingIcon: ['shrink-0 size-5 text-[var(--ui-text-dimmed)] group-data-highlighted:text-[var(--ui-text)]', options.theme.transitions && 'transition-colors'],
|
||||
|
||||
@@ -35,6 +35,7 @@ export { default as skeleton } from './skeleton'
|
||||
export { default as slideover } from './slideover'
|
||||
export { default as slider } from './slider'
|
||||
export { default as switch } from './switch'
|
||||
export { default as table } from './table'
|
||||
export { default as tabs } from './tabs'
|
||||
export { default as textarea } from './textarea'
|
||||
export { default as toast } from './toast'
|
||||
|
||||
83
src/theme/table.ts
Normal file
83
src/theme/table.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import type { ModuleOptions } from '../module'
|
||||
|
||||
export default (options: Required<ModuleOptions>) => ({
|
||||
slots: {
|
||||
root: 'relative overflow-auto',
|
||||
base: 'min-w-full overflow-clip',
|
||||
thead: 'relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)]',
|
||||
tbody: 'divide-y divide-[var(--ui-border)]',
|
||||
tr: 'data-[selected=true]:bg-[var(--ui-bg-elevated)]/50',
|
||||
th: 'px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0',
|
||||
td: 'p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0',
|
||||
empty: 'py-6 text-center text-sm text-[var(--ui-text-muted)]'
|
||||
},
|
||||
variants: {
|
||||
pinned: {
|
||||
true: {
|
||||
th: 'sticky bg-[var(--ui-bg)]/75 data-[pinned=left]:left-0 data-[pinned=right]:right-0',
|
||||
td: 'sticky bg-[var(--ui-bg)]/75 data-[pinned=left]:left-0 data-[pinned=right]:right-0'
|
||||
}
|
||||
},
|
||||
sticky: {
|
||||
true: {
|
||||
thead: 'sticky top-0 inset-x-0 bg-[var(--ui-bg)]/75 z-[1] backdrop-blur'
|
||||
}
|
||||
},
|
||||
loading: {
|
||||
true: {
|
||||
thead: 'after:absolute after:bottom-0 after:inset-x-0 after:h-px'
|
||||
}
|
||||
},
|
||||
loadingAnimation: {
|
||||
'carousel': '',
|
||||
'carousel-inverse': '',
|
||||
'swing': '',
|
||||
'elastic': ''
|
||||
},
|
||||
loadingColor: {
|
||||
...Object.fromEntries((options.theme.colors || []).map((color: string) => [color, ''])),
|
||||
neutral: ''
|
||||
}
|
||||
},
|
||||
compoundVariants: [...(options.theme.colors || []).map((loadingColor: string) => ({
|
||||
loading: true,
|
||||
loadingColor,
|
||||
class: {
|
||||
thead: `after:bg-[var(--ui-${loadingColor})]`
|
||||
}
|
||||
})), {
|
||||
loading: true,
|
||||
loadingColor: 'neutral',
|
||||
class: {
|
||||
thead: 'after:bg-[var(--ui-bg-inverted)]'
|
||||
}
|
||||
}, {
|
||||
loading: true,
|
||||
loadingAnimation: 'carousel',
|
||||
class: {
|
||||
thead: 'after:animate-[carousel_2s_ease-in-out_infinite]'
|
||||
}
|
||||
}, {
|
||||
loading: true,
|
||||
loadingAnimation: 'carousel-inverse',
|
||||
class: {
|
||||
thead: 'after:animate-[carousel-inverse_2s_ease-in-out_infinite]'
|
||||
}
|
||||
}, {
|
||||
loading: true,
|
||||
loadingAnimation: 'swing',
|
||||
class: {
|
||||
thead: 'after:animate-[swing_2s_ease-in-out_infinite]'
|
||||
}
|
||||
}, {
|
||||
loading: true,
|
||||
loadingAnimation: 'elastic',
|
||||
class: {
|
||||
thead: 'after:animate-[elastic_2s_ease-in-out_infinite]'
|
||||
}
|
||||
}],
|
||||
defaultVariants: {
|
||||
loadingColor: 'primary',
|
||||
loadingAnimation: 'carousel'
|
||||
}
|
||||
})
|
||||
@@ -62,6 +62,7 @@ describe('CommandPalette', () => {
|
||||
it.each([
|
||||
// Props
|
||||
['with groups', { props }],
|
||||
['without results', {}],
|
||||
['with modelValue', { props: { ...props, modelValue: groups[2].items[0] } }],
|
||||
['with defaultValue', { props: { ...props, defaultValue: groups[2].items[0] } }],
|
||||
['with labelKey', { props: { ...props, labelKey: 'icon' } }],
|
||||
@@ -69,7 +70,7 @@ describe('CommandPalette', () => {
|
||||
['with disabled', { props: { ...props, disabled: true } }],
|
||||
['with icon', { props: { ...props, icon: 'i-heroicons-command-line' } }],
|
||||
['with loading', { props: { ...props, loading: true } }],
|
||||
['with loadingIcon', { props: { loading: true, loadingIcon: 'i-heroicons-sparkles' } }],
|
||||
['with loadingIcon', { props: { ...props, loading: true, loadingIcon: 'i-heroicons-sparkles' } }],
|
||||
['with selectedIcon', { props: { ...props, selectedIcon: 'i-heroicons-check-badge', modelValue: groups[2].items[0] } }],
|
||||
['with close', { props: { ...props, close: true } }],
|
||||
['with closeIcon', { props: { ...props, close: true, closeIcon: 'i-heroicons-trash' } }],
|
||||
|
||||
164
test/components/Table.spec.ts
Normal file
164
test/components/Table.spec.ts
Normal file
@@ -0,0 +1,164 @@
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Table, { type TableProps, type TableSlots, type TableColumn } from '../../src/runtime/components/Table.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/table'
|
||||
|
||||
describe('Table', () => {
|
||||
const loadingColors = Object.keys(theme.variants.loadingColor) as any
|
||||
const loadingAnimations = Object.keys(theme.variants.loadingAnimation) as any
|
||||
|
||||
const UButton = resolveComponent('UButton')
|
||||
const UCheckbox = resolveComponent('UCheckbox')
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
const UDropdownMenu = resolveComponent('UDropdownMenu')
|
||||
|
||||
const data = [{
|
||||
id: 'm5gr84i9',
|
||||
amount: 316,
|
||||
status: 'success',
|
||||
email: 'ken99@yahoo.com'
|
||||
}, {
|
||||
id: '3u1reuv4',
|
||||
amount: 242,
|
||||
status: 'success',
|
||||
email: 'Abe45@gmail.com'
|
||||
}, {
|
||||
id: 'derv1ws0',
|
||||
amount: 837,
|
||||
status: 'processing',
|
||||
email: 'Monserrat44@gmail.com'
|
||||
}, {
|
||||
id: '5kma53ae',
|
||||
amount: 874,
|
||||
status: 'success',
|
||||
email: 'Silas22@gmail.com'
|
||||
}, {
|
||||
id: 'bhqecj4p',
|
||||
amount: 721,
|
||||
status: 'failed',
|
||||
email: 'carmella@hotmail.com'
|
||||
}]
|
||||
|
||||
const columns: TableColumn<typeof data[number]>[] = [{
|
||||
id: 'select',
|
||||
header: ({ table }) => h(UCheckbox, {
|
||||
'modelValue': table.getIsAllPageRowsSelected(),
|
||||
'indeterminate': table.getIsSomePageRowsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
|
||||
'ariaLabel': 'Select all'
|
||||
}),
|
||||
cell: ({ row }) => h(UCheckbox, {
|
||||
'modelValue': row.getIsSelected(),
|
||||
'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
|
||||
'ariaLabel': 'Select row'
|
||||
}),
|
||||
enableSorting: false,
|
||||
enableHiding: false
|
||||
}, {
|
||||
accessorKey: 'id',
|
||||
header: '#',
|
||||
cell: ({ row }) => `#${row.getValue('id')}`
|
||||
}, {
|
||||
accessorKey: 'date',
|
||||
header: 'Date',
|
||||
cell: ({ row }) => {
|
||||
return new Date(row.getValue('date')).toLocaleString('en-US', {
|
||||
day: 'numeric',
|
||||
month: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false
|
||||
})
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: ({ row }) => {
|
||||
const color = ({
|
||||
paid: 'success' as const,
|
||||
failed: 'error' as const,
|
||||
refunded: 'neutral' as const
|
||||
})[row.getValue('status') as string]
|
||||
|
||||
return h(UBadge, { class: 'capitalize', variant: 'subtle', color }, () => row.getValue('status'))
|
||||
}
|
||||
}, {
|
||||
accessorKey: 'email',
|
||||
header: ({ column }) => {
|
||||
const isSorted = column.getIsSorted()
|
||||
|
||||
return h(UButton, {
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
label: 'Email',
|
||||
icon: isSorted ? (isSorted === 'asc' ? 'i-heroicons-bars-arrow-up-20-solid' : 'i-heroicons-bars-arrow-down-20-solid') : 'i-heroicons-arrows-up-down-20-solid',
|
||||
class: '-mx-2.5',
|
||||
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc')
|
||||
})
|
||||
},
|
||||
cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email'))
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(amount)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, formatted)
|
||||
}
|
||||
}, {
|
||||
id: 'actions',
|
||||
enableHiding: false,
|
||||
cell: ({ row }) => {
|
||||
const items = [{
|
||||
type: 'label',
|
||||
label: 'Actions'
|
||||
}, {
|
||||
label: 'Copy payment ID'
|
||||
}, {
|
||||
label: row.getIsExpanded() ? 'Collapse' : 'Expand'
|
||||
}, {
|
||||
type: 'separator'
|
||||
}, {
|
||||
label: 'View customer'
|
||||
}, {
|
||||
label: 'View payment details'
|
||||
}]
|
||||
|
||||
return h('div', { class: 'text-right' }, h(UDropdownMenu, {
|
||||
content: {
|
||||
align: 'end'
|
||||
},
|
||||
items
|
||||
}, () => h(UButton, {
|
||||
icon: 'i-heroicons-ellipsis-vertical-20-solid',
|
||||
color: 'neutral',
|
||||
variant: 'ghost',
|
||||
class: 'ml-auto'
|
||||
})))
|
||||
}
|
||||
}]
|
||||
|
||||
const props = { data }
|
||||
|
||||
it.each([
|
||||
// Props
|
||||
['with data', { props }],
|
||||
['without results', {}],
|
||||
['with columns', { props: { ...props, columns } }],
|
||||
['with sticky', { props: { ...props, sticky: true } }],
|
||||
['with loading', { props: { ...props, loading: true } }],
|
||||
...loadingColors.map((loadingColor: string) => [`with loading color ${loadingColor}`, { props: { ...props, loading: true, loadingColor } }]),
|
||||
...loadingAnimations.map((loadingAnimation: string) => [`with loading animation ${loadingAnimation}`, { props: { ...props, loading: true, loadingAnimation } }]),
|
||||
['with class', { props: { ...props, class: 'absolute' } }],
|
||||
['with ui', { props: { ...props, ui: { base: 'table-auto' } } }]
|
||||
])('renders %s correctly', async (nameOrHtml: string, options: { props?: TableProps<typeof data[number]>, slots?: Partial<TableSlots<typeof data[number]>> }) => {
|
||||
const html = await ComponentRender(nameOrHtml, options, Table)
|
||||
expect(html).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
@@ -984,13 +984,45 @@ exports[`CommandPalette > renders with loading correctly 1`] = `
|
||||
|
||||
exports[`CommandPalette > renders with loadingIcon correctly 1`] = `
|
||||
"<div style="pointer-events: auto;" dir="ltr" class="flex flex-col min-h-0 min-w-0 divide-y divide-[var(--ui-border)]">
|
||||
<div class="relative inline-flex items-center [&>input]:h-12"><input type="text" placeholder="Type a command or search..." class="w-full rounded-[calc(var(--ui-radius)*1.5)] border-0 placeholder:text-[var(--ui-text-dimmed)] focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors px-3 py-2 text-sm gap-2 text-[var(--ui-text-highlighted)] pl-10" autocomplete="false" aria-expanded="true" aria-controls="" aria-disabled="false" aria-autocomplete="list" role="combobox" value=""><span class="absolute inset-y-0 start-0 flex items-center pl-3"><span class="iconify i-heroicons:sparkles shrink-0 text-[var(--ui-text-dimmed)] size-5 animate-spin" aria-hidden="true"></span></span>
|
||||
<div class="relative inline-flex items-center [&>input]:h-12"><input type="text" placeholder="Type a command or search..." class="w-full rounded-[calc(var(--ui-radius)*1.5)] border-0 placeholder:text-[var(--ui-text-dimmed)] focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors px-3 py-2 text-sm gap-2 text-[var(--ui-text-highlighted)] pl-10" autocomplete="false" aria-expanded="true" aria-disabled="false" aria-autocomplete="list" role="combobox" aria-controls="radix-vue-combobox-content-v-0-0-0" aria-activedescendant="radix-vue-combobox-option-v-0-0-3" value=""><span class="absolute inset-y-0 start-0 flex items-center pl-3"><span class="iconify i-heroicons:sparkles shrink-0 text-[var(--ui-text-dimmed)] size-5 animate-spin" aria-hidden="true"></span></span>
|
||||
<!--v-if-->
|
||||
</div>
|
||||
<!--teleport start-->
|
||||
<div id="radix-vue-combobox-content-v-0-0-0" role="listbox" data-state="open" style="display: flex; flex-direction: column; outline-color: none; outline-style: none; outline-width: initial;" class="relative overflow-hidden">
|
||||
<div class="py-6 text-center text-sm">No results</div>
|
||||
<div class="divide-y divide-[var(--ui-border)] scroll-py-1" data-radix-combobox-viewport="" role="presentation" style="position: relative; flex-grow: 1; flex-shrink: 1; flex-basis: 0%; overflow: auto;"></div>
|
||||
<!---->
|
||||
<div class="divide-y divide-[var(--ui-border)] scroll-py-1" data-radix-combobox-viewport="" role="presentation" style="position: relative; flex-grow: 1; flex-shrink: 1; flex-basis: 0%; overflow: auto;">
|
||||
<div role="group" aria-labelledby="radix-vue-combobox-group-v-0-0-1" class="p-1 isolate">
|
||||
<!--v-if-->
|
||||
<div id="radix-vue-combobox-option-v-0-0-3" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-2" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item="" data-highlighted=""><span class="iconify i-heroicons:document-plus shrink-0 size-5 text-[var(--ui-text-dimmed)] group-data-highlighted:text-[var(--ui-text)] transition-colors" aria-hidden="true"></span><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Add new file</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Create a new file in the current directory or workspace.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">⌃</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">N</kbd></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div id="radix-vue-combobox-option-v-0-0-5" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-4" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item=""><span class="iconify i-heroicons:folder-plus shrink-0 size-5 text-[var(--ui-text-dimmed)] group-data-highlighted:text-[var(--ui-text)] transition-colors" aria-hidden="true"></span><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Add new folder</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Create a new folder in the current directory or workspace.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">⌃</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">F</kbd></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div id="radix-vue-combobox-option-v-0-0-7" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-6" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item=""><span class="iconify i-heroicons:hashtag shrink-0 size-5 text-[var(--ui-text-dimmed)] group-data-highlighted:text-[var(--ui-text)] transition-colors" aria-hidden="true"></span><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Add hashtag</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Add a hashtag to the current item.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">⌃</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">H</kbd></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
<div id="radix-vue-combobox-option-v-0-0-9" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-8" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item=""><span class="iconify i-heroicons:tag shrink-0 size-5 text-[var(--ui-text-dimmed)] group-data-highlighted:text-[var(--ui-text)] transition-colors" aria-hidden="true"></span><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Add label</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">Add a label to the current item.</span></span><span class="ms-auto inline-flex gap-1.5 items-center"><span class="hidden lg:inline-flex items-center shrink-0 gap-0.5"><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">⌃</kbd><kbd class="inline-flex items-center justify-center px-1 rounded-[var(--ui-radius)] font-medium font-sans bg-[var(--ui-bg)] text-[var(--ui-text-highlighted)] ring ring-inset ring-[var(--ui-border-accented)] h-5 min-w-[20px] text-[11px]">L</kbd></span>
|
||||
<!----></span>
|
||||
</div>
|
||||
</div>
|
||||
<div role="group" aria-labelledby="radix-vue-combobox-group-v-0-0-10" class="p-1 isolate">
|
||||
<div id="radix-vue-combobox-group-v-0-0-10" class="px-2 py-1.5 text-xs font-semibold text-[var(--ui-text-highlighted)]">Labels</div>
|
||||
<div id="radix-vue-combobox-option-v-0-0-12" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-11" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item="">
|
||||
<div class="relative inline-flex items-center justify-center shrink-0 size-5"><span class="rounded-full ring ring-[var(--ui-bg)] flex items-center justify-center text-[var(--ui-bg)] font-medium whitespace-nowrap bg-[var(--ui-error)] h-[8px] min-w-[8px] text-[8px] top-0 right-0"></span></div><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">bug</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]"></span></span><span class="ms-auto inline-flex gap-1.5 items-center"><!--v-if--><!----></span>
|
||||
</div>
|
||||
<div id="radix-vue-combobox-option-v-0-0-14" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-13" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item="">
|
||||
<div class="relative inline-flex items-center justify-center shrink-0 size-5"><span class="rounded-full ring ring-[var(--ui-bg)] flex items-center justify-center text-[var(--ui-bg)] font-medium whitespace-nowrap bg-[var(--ui-success)] h-[8px] min-w-[8px] text-[8px] top-0 right-0"></span></div><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">feature</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]"></span></span><span class="ms-auto inline-flex gap-1.5 items-center"><!--v-if--><!----></span>
|
||||
</div>
|
||||
<div id="radix-vue-combobox-option-v-0-0-16" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-15" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item="">
|
||||
<div class="relative inline-flex items-center justify-center shrink-0 size-5"><span class="rounded-full ring ring-[var(--ui-bg)] flex items-center justify-center text-[var(--ui-bg)] font-medium whitespace-nowrap bg-[var(--ui-info)] h-[8px] min-w-[8px] text-[8px] top-0 right-0"></span></div><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">enhancement</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]"></span></span><span class="ms-auto inline-flex gap-1.5 items-center"><!--v-if--><!----></span>
|
||||
</div>
|
||||
</div>
|
||||
<div role="group" aria-labelledby="radix-vue-combobox-group-v-0-0-17" class="p-1 isolate">
|
||||
<div id="radix-vue-combobox-group-v-0-0-17" class="px-2 py-1.5 text-xs font-semibold text-[var(--ui-text-highlighted)]">Users</div>
|
||||
<div id="radix-vue-combobox-option-v-0-0-19" role="option" tabindex="-1" aria-labelledby="radix-vue-combobox-item-v-0-0-18" aria-selected="false" data-state="unchecked" class="group relative w-full flex items-center gap-2 px-2 py-1.5 text-sm select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-[calc(var(--ui-radius)*1.5)] data-disabled:cursor-not-allowed data-disabled:opacity-75 text-[var(--ui-text)] data-highlighted:text-[var(--ui-text-highlighted)] data-highlighted:before:bg-[var(--ui-bg-elevated)]/50 transition-colors before:transition-colors" data-radix-vue-combobox-item=""><span class="inline-flex items-center justify-center select-none overflow-hidden rounded-full align-middle bg-[var(--ui-bg-elevated)] size-5 text-[10px] shrink-0"><img role="img" src="https://github.com/benjamincanac.png" class="h-full w-full rounded-[inherit] object-cover" style="display: none;"><span class="font-medium leading-none text-[var(--ui-text-muted)] truncate"></span></span><span class="truncate space-x-1"><!--v-if--><span class="text-[var(--ui-text-highlighted)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]">benjamincanac</span><span class="text-[var(--ui-text-dimmed)] [&>mark]:text-[var(--ui-bg)] [&>mark]:bg-[var(--ui-primary)]"></span></span><span class="ms-auto inline-flex gap-1.5 items-center"><!--v-if--><!----></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
/* Hide scrollbars cross-browser and enable momentum scroll for touch devices */
|
||||
[data-radix-combobox-viewport] {
|
||||
@@ -1244,3 +1276,30 @@ exports[`CommandPalette > renders with ui correctly 1`] = `
|
||||
<!---->
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`CommandPalette > renders without results correctly 1`] = `
|
||||
"<div style="pointer-events: auto;" dir="ltr" class="flex flex-col min-h-0 min-w-0 divide-y divide-[var(--ui-border)]">
|
||||
<div class="relative inline-flex items-center [&>input]:h-12"><input type="text" placeholder="Type a command or search..." class="w-full rounded-[calc(var(--ui-radius)*1.5)] border-0 placeholder:text-[var(--ui-text-dimmed)] focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors px-3 py-2 text-sm gap-2 text-[var(--ui-text-highlighted)] pl-10" autocomplete="false" aria-expanded="true" aria-controls="" aria-disabled="false" aria-autocomplete="list" role="combobox" value=""><span class="absolute inset-y-0 start-0 flex items-center pl-3"><span class="iconify i-heroicons:magnifying-glass-20-solid shrink-0 text-[var(--ui-text-dimmed)] size-5" aria-hidden="true"></span></span>
|
||||
<!--v-if-->
|
||||
</div>
|
||||
<!--teleport start-->
|
||||
<div id="radix-vue-combobox-content-v-0-0-0" role="listbox" data-state="open" style="display: flex; flex-direction: column; outline-color: none; outline-style: none; outline-width: initial;" class="relative overflow-hidden">
|
||||
<div class="py-6 text-center text-sm text-[var(--ui-text-muted)]">No results</div>
|
||||
<div class="divide-y divide-[var(--ui-border)] scroll-py-1" data-radix-combobox-viewport="" role="presentation" style="position: relative; flex-grow: 1; flex-shrink: 1; flex-basis: 0%; overflow: auto;"></div>
|
||||
<style>
|
||||
/* Hide scrollbars cross-browser and enable momentum scroll for touch devices */
|
||||
[data-radix-combobox-viewport] {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
[data-radix-combobox-viewport]::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
<!--teleport end-->
|
||||
<!---->
|
||||
</div>"
|
||||
`;
|
||||
|
||||
986
test/components/__snapshots__/Table.spec.ts.snap
Normal file
986
test/components/__snapshots__/Table.spec.ts.snap
Normal file
@@ -0,0 +1,986 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Table > renders with class correctly 1`] = `
|
||||
"<div class="overflow-auto absolute">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with columns correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">
|
||||
<ucheckbox modelvalue="false" indeterminate="false" arialabel="Select all"></ucheckbox>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">#</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Date</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">
|
||||
<ubutton color="neutral" variant="ghost" label="Email" icon="i-heroicons-arrows-up-down-20-solid" class="-mx-2.5"></ubutton>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right">Amount</div>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">
|
||||
<!---->
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ucheckbox modelvalue="false" arialabel="Select row"></ucheckbox>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">#m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Invalid Date</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ubadge class="capitalize" variant="subtle"></ubadge>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="lowercase">ken99@yahoo.com</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right font-medium">€316.00</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right">
|
||||
<udropdownmenu content="[object Object]" items="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"></udropdownmenu>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ucheckbox modelvalue="false" arialabel="Select row"></ucheckbox>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">#3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Invalid Date</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ubadge class="capitalize" variant="subtle"></ubadge>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="lowercase">Abe45@gmail.com</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right font-medium">€242.00</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right">
|
||||
<udropdownmenu content="[object Object]" items="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"></udropdownmenu>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ucheckbox modelvalue="false" arialabel="Select row"></ucheckbox>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">#derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Invalid Date</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ubadge class="capitalize" variant="subtle"></ubadge>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="lowercase">Monserrat44@gmail.com</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right font-medium">€837.00</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right">
|
||||
<udropdownmenu content="[object Object]" items="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"></udropdownmenu>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ucheckbox modelvalue="false" arialabel="Select row"></ucheckbox>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">#5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Invalid Date</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ubadge class="capitalize" variant="subtle"></ubadge>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="lowercase">Silas22@gmail.com</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right font-medium">€874.00</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right">
|
||||
<udropdownmenu content="[object Object]" items="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"></udropdownmenu>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ucheckbox modelvalue="false" arialabel="Select row"></ucheckbox>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">#bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Invalid Date</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<ubadge class="capitalize" variant="subtle" color="error"></ubadge>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="lowercase">carmella@hotmail.com</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right font-medium">€721.00</div>
|
||||
</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">
|
||||
<div class="text-right">
|
||||
<udropdownmenu content="[object Object]" items="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"></udropdownmenu>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with data correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading animation carousel correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-primary)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading animation carousel-inverse correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-primary)] after:animate-[carousel-inverse_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading animation elastic correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-primary)] after:animate-[elastic_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading animation swing correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-primary)] after:animate-[swing_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading color error correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-error)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading color info correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-info)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading color neutral correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-bg-inverted)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading color primary correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-primary)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading color secondary correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-secondary)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading color success correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-success)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading color warning correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-warning)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with loading correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] after:absolute after:bottom-0 after:inset-x-0 after:h-px after:bg-[var(--ui-primary)] after:animate-[carousel_2s_ease-in-out_infinite]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with sticky correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="[&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)] sticky top-0 inset-x-0 bg-[var(--ui-bg)]/75 z-[1] backdrop-blur">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders with ui correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip table-auto">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Id</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Amount</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Status</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-[var(--ui-text-highlighted)] text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pr-0">Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">m5gr84i9</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">316</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">ken99@yahoo.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">3u1reuv4</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">242</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Abe45@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">derv1ws0</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">837</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">processing</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Monserrat44@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">5kma53ae</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">874</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">success</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">Silas22@gmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
<tr data-selected="false" data-expanded="false" class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">bhqecj4p</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">721</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">failed</td>
|
||||
<td data-pinned="false" class="p-4 text-sm text-[var(--ui-text-muted)] whitespace-nowrap [&:has([role=checkbox])]:pr-0">carmella@hotmail.com</td>
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
exports[`Table > renders without results correctly 1`] = `
|
||||
"<div class="relative overflow-auto">
|
||||
<table class="min-w-full overflow-clip">
|
||||
<thead class="relative [&>tr]:after:absolute [&>tr]:after:inset-x-0 [&>tr]:after:bottom-0 [&>tr]:after:h-px [&>tr]:after:bg-[var(--ui-border-accented)]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50"></tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-[var(--ui-border)]">
|
||||
<tr class="data-[selected=true]:bg-[var(--ui-bg-elevated)]/50">
|
||||
<td colspan="0" class="py-6 text-center text-sm text-[var(--ui-text-muted)]"> No results </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
Reference in New Issue
Block a user