mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 12:14:41 +01:00
Merge branch 'v3' into feat/3880
This commit is contained in:
@@ -147,7 +147,8 @@ const test = ({ name, prose, content }) => {
|
||||
? undefined
|
||||
: `
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import ${upperName}, { type ${upperName}Props, type ${upperName}Slots } from '../../${content ? '../' : ''}src/runtime/components/${content ? 'content/' : ''}${upperName}.vue'
|
||||
import ${upperName} from '../../${content ? '../' : ''}src/runtime/components/${content ? 'content/' : ''}${upperName}.vue'
|
||||
import type { ${upperName}Props, ${upperName}Slots } from '../../${content ? '../' : ''}src/runtime/components/${content ? 'content/' : ''}${upperName}.vue'
|
||||
import ComponentRender from '../${content ? '../' : ''}component-render'
|
||||
|
||||
describe('${upperName}', () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<UBanner
|
||||
id="ui3-launch"
|
||||
title="Nuxt UI v3 is officially released!"
|
||||
icon="i-lucide-rocket"
|
||||
:actions="[
|
||||
{
|
||||
@@ -10,9 +11,5 @@
|
||||
}
|
||||
]"
|
||||
close
|
||||
>
|
||||
<template #title>
|
||||
<span class="font-semibold">Nuxt UI v3</span> is officially released.
|
||||
</template>
|
||||
</UBanner>
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { object, string, nonempty, refine, type Infer } from 'superstruct'
|
||||
import { object, string, nonempty, refine } from 'superstruct'
|
||||
import type { Infer } from 'superstruct'
|
||||
import type { FormSubmitEvent } from '@nuxt/ui'
|
||||
|
||||
const schema = object({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { object, string, type InferType } from 'yup'
|
||||
import { object, string } from 'yup'
|
||||
import type { InferType } from 'yup'
|
||||
import type { FormSubmitEvent } from '@nuxt/ui'
|
||||
|
||||
const schema = object({
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn, TableRow } 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'),
|
||||
footer: ({ column }) => {
|
||||
const total = column.getFacetedRowModel().rows.reduce((acc: number, row: TableRow<Payment>) => acc + Number.parseFloat(row.getValue('amount')), 0)
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(total)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, `Total: ${formatted}`)
|
||||
},
|
||||
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>
|
||||
@@ -1,7 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { h, resolveComponent } from 'vue'
|
||||
import type { TableColumn } from '@nuxt/ui'
|
||||
import { getGroupedRowModel, type GroupingOptions } from '@tanstack/vue-table'
|
||||
import { getGroupedRowModel } from '@tanstack/vue-table'
|
||||
import type { GroupingOptions } from '@tanstack/vue-table'
|
||||
|
||||
const UBadge = resolveComponent('UBadge')
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ Use the `columns` prop as an array of [ColumnDef](https://tanstack.com/table/lat
|
||||
|
||||
- `accessorKey`: [The key of the row object to use when extracting the value for the column.]{class="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-muted"}
|
||||
- `footer`: [The footer to display for the column. Works exactly like header, but is displayed under the table.]{class="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-muted"}
|
||||
- `meta`: [Extra properties for the column.]{class="text-muted"}
|
||||
- `class`:
|
||||
@@ -161,7 +162,7 @@ props:
|
||||
|
||||
### Sticky
|
||||
|
||||
Use the `sticky` prop to make the header sticky.
|
||||
Use the `sticky` prop to make the header or footer sticky.
|
||||
|
||||
::component-code
|
||||
---
|
||||
@@ -172,6 +173,10 @@ ignore:
|
||||
- class
|
||||
external:
|
||||
- data
|
||||
items:
|
||||
sticky:
|
||||
- true
|
||||
- false
|
||||
props:
|
||||
sticky: true
|
||||
data:
|
||||
@@ -372,6 +377,22 @@ class: '!p-0'
|
||||
This example is similar as the Popover [with following cursor example](/components/popover#with-following-cursor) and uses a [`refDebounced`](https://vueuse.org/shared/refDebounced/#refdebounced) to prevent the Popover from opening and closing too quickly when moving the cursor from one row to another.
|
||||
::
|
||||
|
||||
### With column footer :badge{label="Soon" class="align-text-top"}
|
||||
|
||||
You can add a `footer` property to the column definition to render a footer for the column.
|
||||
|
||||
::component-example
|
||||
---
|
||||
prettier: true
|
||||
collapse: true
|
||||
name: 'table-column-footer-example'
|
||||
highlights:
|
||||
- 94
|
||||
- 108
|
||||
class: '!p-0'
|
||||
---
|
||||
::
|
||||
|
||||
### 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).
|
||||
|
||||
@@ -14,24 +14,24 @@
|
||||
"@iconify-json/lucide": "^1.2.54",
|
||||
"@iconify-json/simple-icons": "^1.2.41",
|
||||
"@iconify-json/vscode-icons": "^1.2.23",
|
||||
"@nuxt/content": "^3.6.1",
|
||||
"@nuxt/content": "^3.6.2",
|
||||
"@nuxt/image": "^1.10.0",
|
||||
"@nuxt/ui": "workspace:*",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@3d48704",
|
||||
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@22fdc5e",
|
||||
"@nuxthub/core": "^0.9.0",
|
||||
"@nuxtjs/plausible": "^1.2.0",
|
||||
"@octokit/rest": "^22.0.0",
|
||||
"@rollup/plugin-yaml": "^4.1.2",
|
||||
"@vueuse/integrations": "^13.4.0",
|
||||
"@vueuse/nuxt": "^13.4.0",
|
||||
"@vueuse/integrations": "^13.5.0",
|
||||
"@vueuse/nuxt": "^13.5.0",
|
||||
"ai": "^4.3.16",
|
||||
"better-sqlite3": "^12.2.0",
|
||||
"capture-website": "^4.2.0",
|
||||
"joi": "^17.13.3",
|
||||
"maska": "^3.1.1",
|
||||
"motion-v": "^1.3.1",
|
||||
"maska": "^3.2.0",
|
||||
"motion-v": "^1.4.0",
|
||||
"nuxt": "^3.17.6",
|
||||
"nuxt-component-meta": "^0.12.0",
|
||||
"nuxt-component-meta": "^0.12.1",
|
||||
"nuxt-llms": "^0.1.3",
|
||||
"nuxt-og-image": "^5.1.8",
|
||||
"prettier": "^3.6.2",
|
||||
|
||||
16
package.json
16
package.json
@@ -124,8 +124,8 @@
|
||||
"@tailwindcss/vite": "^4.1.11",
|
||||
"@tanstack/vue-table": "^8.21.3",
|
||||
"@unhead/vue": "^2.0.11",
|
||||
"@vueuse/core": "^13.4.0",
|
||||
"@vueuse/integrations": "^13.4.0",
|
||||
"@vueuse/core": "^13.5.0",
|
||||
"@vueuse/integrations": "^13.5.0",
|
||||
"colortranslator": "^5.0.0",
|
||||
"consola": "^3.4.2",
|
||||
"defu": "^6.1.4",
|
||||
@@ -143,7 +143,7 @@
|
||||
"mlly": "^1.7.4",
|
||||
"ohash": "^2.0.11",
|
||||
"pathe": "^2.0.3",
|
||||
"reka-ui": "2.3.1",
|
||||
"reka-ui": "2.3.2",
|
||||
"scule": "^1.3.0",
|
||||
"tailwind-variants": "^1.0.0",
|
||||
"tailwindcss": "^4.1.11",
|
||||
@@ -152,22 +152,22 @@
|
||||
"unplugin-auto-import": "^19.3.0",
|
||||
"unplugin-vue-components": "^28.8.0",
|
||||
"vaul-vue": "0.4.1",
|
||||
"vue-component-type-helpers": "^2.2.10"
|
||||
"vue-component-type-helpers": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/eslint-config": "^1.4.1",
|
||||
"@nuxt/eslint-config": "^1.5.0",
|
||||
"@nuxt/module-builder": "^1.0.1",
|
||||
"@nuxt/test-utils": "^3.19.1",
|
||||
"@nuxt/test-utils": "^3.19.2",
|
||||
"@release-it/conventional-changelog": "^10.0.1",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"embla-carousel": "^8.6.0",
|
||||
"eslint": "^9.30.0",
|
||||
"eslint": "^9.30.1",
|
||||
"happy-dom": "^18.0.1",
|
||||
"nuxt": "^3.17.6",
|
||||
"release-it": "^19.0.3",
|
||||
"vitest": "^3.2.4",
|
||||
"vitest-environment-nuxt": "^1.0.1",
|
||||
"vue-tsc": "^2.2.10"
|
||||
"vue-tsc": "^3.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@inertiajs/vue3": "^2.0.7",
|
||||
|
||||
@@ -19,6 +19,6 @@
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^6.3.5",
|
||||
"vue-tsc": "^2.2.10"
|
||||
"vue-tsc": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,6 +242,16 @@ const columns: TableColumn<Payment>[] = [{
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
footer: ({ column }) => {
|
||||
const total = column.getFacetedRowModel().rows.reduce((acc: number, row: TableRow<Payment>) => acc + Number.parseFloat(row.getValue('amount')), 0)
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(total)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, `Total: ${formatted}`)
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.8.3",
|
||||
"vue-tsc": "^2.2.10"
|
||||
"vue-tsc": "^3.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"unimport": "4.1.1"
|
||||
|
||||
1162
pnpm-lock.yaml
generated
1162
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,12 @@
|
||||
"reka-ui",
|
||||
"vaul-vue"
|
||||
]
|
||||
}, {
|
||||
"groupName": "vue-tsc",
|
||||
"matchPackageNames": [
|
||||
"vue-tsc",
|
||||
"vue-component-type-helpers"
|
||||
]
|
||||
}, {
|
||||
"matchDepTypes": ["peerDependencies"],
|
||||
"enabled": false
|
||||
|
||||
@@ -3,7 +3,8 @@ import { normalize } from 'pathe'
|
||||
import { resolvePathSync } from 'mlly'
|
||||
import MagicString from 'magic-string'
|
||||
|
||||
import { runtimeDir, type NuxtUIOptions } from '../unplugin'
|
||||
import { runtimeDir } from '../unplugin'
|
||||
import type { NuxtUIOptions } from '../unplugin'
|
||||
|
||||
/**
|
||||
* This plugin normalises Nuxt environment (#imports) and `import.meta.client` within the Nuxt UI components.
|
||||
|
||||
@@ -4,7 +4,8 @@ import { genSafeVariableName } from 'knitwork'
|
||||
import MagicString from 'magic-string'
|
||||
import { resolvePathSync } from 'mlly'
|
||||
|
||||
import { runtimeDir, type NuxtUIOptions } from '../unplugin'
|
||||
import { runtimeDir } from '../unplugin'
|
||||
import type { NuxtUIOptions } from '../unplugin'
|
||||
|
||||
import type { UnpluginOptions } from 'unplugin'
|
||||
|
||||
|
||||
@@ -42,14 +42,15 @@ export interface ButtonSlots {
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type Ref, computed, ref, inject } from 'vue'
|
||||
import { computed, ref, inject } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
import { defu } from 'defu'
|
||||
import { useForwardProps } from 'reka-ui'
|
||||
import { useAppConfig } from '#imports'
|
||||
import { useComponentIcons } from '../composables/useComponentIcons'
|
||||
import { useButtonGroup } from '../composables/useButtonGroup'
|
||||
import { formLoadingInjectionKey } from '../composables/useFormField'
|
||||
import { omit } from '../utils'
|
||||
import { omit, mergeClasses } from '../utils'
|
||||
import { tv } from '../utils/tv'
|
||||
import { pickLinkProps } from '../utils/link'
|
||||
import UIcon from './Icon.vue'
|
||||
@@ -57,11 +58,7 @@ import UAvatar from './Avatar.vue'
|
||||
import ULink from './Link.vue'
|
||||
import ULinkBase from './LinkBase.vue'
|
||||
|
||||
const props = withDefaults(defineProps<ButtonProps>(), {
|
||||
active: undefined,
|
||||
activeClass: '',
|
||||
inactiveClass: ''
|
||||
})
|
||||
const props = defineProps<ButtonProps>()
|
||||
const slots = defineSlots<ButtonSlots>()
|
||||
|
||||
const appConfig = useAppConfig() as Button['AppConfig']
|
||||
@@ -96,10 +93,10 @@ const ui = computed(() => tv({
|
||||
variants: {
|
||||
active: {
|
||||
true: {
|
||||
base: props.activeClass
|
||||
base: mergeClasses(appConfig.ui?.button?.variants?.active?.true?.base, props.activeClass)
|
||||
},
|
||||
false: {
|
||||
base: props.inactiveClass
|
||||
base: mergeClasses(appConfig.ui?.button?.variants?.active?.false?.base, props.inactiveClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ import ULink from './Link.vue'
|
||||
import UAvatar from './Avatar.vue'
|
||||
import UIcon from './Icon.vue'
|
||||
import UKbd from './Kbd.vue'
|
||||
// eslint-disable-next-line import/no-self-import
|
||||
import UContextMenuContent from './ContextMenuContent.vue'
|
||||
|
||||
const props = defineProps<ContextMenuContentProps<T>>()
|
||||
|
||||
@@ -53,7 +53,6 @@ import ULink from './Link.vue'
|
||||
import UAvatar from './Avatar.vue'
|
||||
import UIcon from './Icon.vue'
|
||||
import UKbd from './Kbd.vue'
|
||||
// eslint-disable-next-line import/no-self-import
|
||||
import UDropdownMenuContent from './DropdownMenuContent.vue'
|
||||
|
||||
const props = defineProps<DropdownMenuContentProps<T>>()
|
||||
|
||||
@@ -47,7 +47,8 @@ export interface FormFieldSlots {
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, inject, provide, type Ref, useId } from 'vue'
|
||||
import { computed, ref, inject, provide, useId } from 'vue'
|
||||
import type { Ref } from 'vue'
|
||||
import { Primitive, Label } from 'reka-ui'
|
||||
import { useAppConfig } from '#imports'
|
||||
import { formFieldInjectionKey, inputIdInjectionKey } from '../composables/useFormField'
|
||||
|
||||
@@ -88,11 +88,12 @@ export interface LinkSlots {
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { defu } from 'defu'
|
||||
import { isEqual } from 'ohash/utils'
|
||||
import { useForwardProps } from 'reka-ui'
|
||||
import { defu } from 'defu'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { useRoute, useAppConfig } from '#imports'
|
||||
import { mergeClasses } from '../utils'
|
||||
import { tv } from '../utils/tv'
|
||||
import { isPartiallyEqual } from '../utils/link'
|
||||
import ULinkBase from './LinkBase.vue'
|
||||
@@ -103,9 +104,7 @@ const props = withDefaults(defineProps<LinkProps>(), {
|
||||
as: 'button',
|
||||
type: 'button',
|
||||
ariaCurrentValue: 'page',
|
||||
active: undefined,
|
||||
activeClass: '',
|
||||
inactiveClass: ''
|
||||
active: undefined
|
||||
})
|
||||
defineSlots<LinkSlots>()
|
||||
|
||||
@@ -119,8 +118,8 @@ const ui = computed(() => tv({
|
||||
...defu({
|
||||
variants: {
|
||||
active: {
|
||||
true: props.activeClass,
|
||||
false: props.inactiveClass
|
||||
true: mergeClasses(appConfig.ui?.link?.variants?.active?.true, props.activeClass),
|
||||
false: mergeClasses(appConfig.ui?.link?.variants?.active?.false, props.inactiveClass)
|
||||
}
|
||||
}
|
||||
}, appConfig.ui?.link || {})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useOverlay, type Overlay } from '../composables/useOverlay'
|
||||
import { useOverlay } from '../composables/useOverlay'
|
||||
import type { Overlay } from '../composables/useOverlay'
|
||||
|
||||
const { overlays, unmount, close } = useOverlay()
|
||||
|
||||
|
||||
@@ -83,10 +83,10 @@ export interface TableProps<T extends TableData = TableData> extends TableOption
|
||||
*/
|
||||
empty?: string
|
||||
/**
|
||||
* Whether the table should have a sticky header.
|
||||
* Whether the table should have a sticky header or footer. True for both, 'header' for header only, 'footer' for footer only.
|
||||
* @defaultValue false
|
||||
*/
|
||||
sticky?: boolean
|
||||
sticky?: boolean | 'header' | 'footer'
|
||||
/** Whether the table should be in loading state. */
|
||||
loading?: boolean
|
||||
/**
|
||||
@@ -172,6 +172,7 @@ export interface TableProps<T extends TableData = TableData> extends TableOption
|
||||
}
|
||||
|
||||
type DynamicHeaderSlots<T, K = keyof T> = Record<string, (props: HeaderContext<T, unknown>) => any> & Record<`${K extends string ? K : never}-header`, (props: HeaderContext<T, unknown>) => any>
|
||||
type DynamicFooterSlots<T, K = keyof T> = Record<string, (props: HeaderContext<T, unknown>) => any> & Record<`${K extends string ? K : never}-footer`, (props: HeaderContext<T, unknown>) => any>
|
||||
type DynamicCellSlots<T, K = keyof T> = Record<string, (props: CellContext<T, unknown>) => any> & Record<`${K extends string ? K : never}-cell`, (props: CellContext<T, unknown>) => any>
|
||||
|
||||
export type TableSlots<T extends TableData = TableData> = {
|
||||
@@ -181,7 +182,7 @@ export type TableSlots<T extends TableData = TableData> = {
|
||||
'caption': (props?: {}) => any
|
||||
'body-top': (props?: {}) => any
|
||||
'body-bottom': (props?: {}) => any
|
||||
} & DynamicHeaderSlots<T> & DynamicCellSlots<T>
|
||||
} & DynamicHeaderSlots<T> & DynamicFooterSlots<T> & DynamicCellSlots<T>
|
||||
|
||||
</script>
|
||||
|
||||
@@ -216,6 +217,22 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.table || {})
|
||||
loadingAnimation: props.loadingAnimation
|
||||
}))
|
||||
|
||||
const hasFooter = computed(() => {
|
||||
function hasFooterRecursive(columns: TableColumn<T>[]): boolean {
|
||||
for (const column of columns) {
|
||||
if ('footer' in column) {
|
||||
return true
|
||||
}
|
||||
if ('columns' in column && hasFooterRecursive(column.columns as TableColumn<T>[])) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return hasFooterRecursive(columns.value)
|
||||
})
|
||||
|
||||
const globalFilterState = defineModel<string>('globalFilter', { default: undefined })
|
||||
const columnFiltersState = defineModel<ColumnFiltersState>('columnFilters', { default: [] })
|
||||
const columnOrderState = defineModel<ColumnOrderState>('columnOrder', { default: [] })
|
||||
@@ -461,6 +478,30 @@ defineExpose({
|
||||
|
||||
<slot name="body-bottom" />
|
||||
</tbody>
|
||||
|
||||
<tfoot v-if="hasFooter" :class="ui.tfoot({ class: [props.ui?.tfoot] })">
|
||||
<tr :class="ui.separator({ class: [props.ui?.separator] })" />
|
||||
|
||||
<tr v-for="footerGroup in tableApi.getFooterGroups()" :key="footerGroup.id" :class="ui.tr({ class: [props.ui?.tr] })">
|
||||
<th
|
||||
v-for="header in footerGroup.headers"
|
||||
:key="header.id"
|
||||
:data-pinned="header.column.getIsPinned()"
|
||||
:colspan="header.colSpan > 1 ? header.colSpan : undefined"
|
||||
:class="ui.th({
|
||||
class: [
|
||||
props.ui?.th,
|
||||
typeof header.column.columnDef.meta?.class?.th === 'function' ? header.column.columnDef.meta.class.th(header) : header.column.columnDef.meta?.class?.th
|
||||
],
|
||||
pinned: !!header.column.getIsPinned()
|
||||
})"
|
||||
>
|
||||
<slot :name="`${header.id}-footer`" v-bind="header.getContext()">
|
||||
<FlexRender v-if="!header.isPlaceholder" :render="header.column.columnDef.footer" :props="header.getContext()" />
|
||||
</slot>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</Primitive>
|
||||
</template>
|
||||
|
||||
@@ -36,6 +36,8 @@ interface Shortcut {
|
||||
|
||||
const chainedShortcutRegex = /^[^-]+.*-.*[^-]+$/
|
||||
const combinedShortcutRegex = /^[^_]+.*_.*[^_]+$/
|
||||
// keyboard keys which can be combined with Shift modifier (in addition to alphabet keys)
|
||||
const shiftableKeys = ['arrowleft', 'arrowright', 'arrowup', 'arrowright', 'tab', 'escape', 'enter', 'backspace']
|
||||
|
||||
export function extractShortcuts(items: any[] | any[][]) {
|
||||
const shortcuts: Record<string, Handler> = {}
|
||||
@@ -76,7 +78,8 @@ export function defineShortcuts(config: MaybeRef<ShortcutsConfig>, options: Shor
|
||||
return
|
||||
}
|
||||
|
||||
const alphabeticalKey = /^[a-z]{1}$/i.test(e.key)
|
||||
const alphabetKey = /^[a-z]{1}$/i.test(e.key)
|
||||
const shiftableKey = shiftableKeys.includes(e.key.toLowerCase())
|
||||
|
||||
let chainedKey
|
||||
chainedInputs.value.push(e.key)
|
||||
@@ -109,9 +112,9 @@ export function defineShortcuts(config: MaybeRef<ShortcutsConfig>, options: Shor
|
||||
if (e.ctrlKey !== shortcut.ctrlKey) {
|
||||
continue
|
||||
}
|
||||
// shift modifier is only checked in combination with alphabetical keys
|
||||
// (shift with non-alphabetical keys would change the key)
|
||||
if (alphabeticalKey && e.shiftKey !== shortcut.shiftKey) {
|
||||
// shift modifier is only checked in combination with alphabet keys and some extra keys
|
||||
// (shift with special characters would change the key)
|
||||
if ((alphabetKey || shiftableKey) && e.shiftKey !== shortcut.shiftKey) {
|
||||
continue
|
||||
}
|
||||
// alt modifier changes the combined key anyways
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { inject, provide, computed, type ComputedRef, type InjectionKey } from 'vue'
|
||||
import { inject, provide, computed } from 'vue'
|
||||
import type { ComputedRef, InjectionKey } from 'vue'
|
||||
import type { AvatarGroupProps } from '../types'
|
||||
|
||||
export const avatarGroupInjectionKey: InjectionKey<ComputedRef<{ size: AvatarGroupProps['size'] }>> = Symbol('nuxt-ui.avatar-group')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { computed, toValue, type MaybeRefOrGetter } from 'vue'
|
||||
import { computed, toValue } from 'vue'
|
||||
import type { MaybeRefOrGetter } from 'vue'
|
||||
import { useAppConfig } from '#imports'
|
||||
import type { AvatarProps } from '../types'
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { inject, computed, type InjectionKey, type Ref, type ComputedRef, provide } from 'vue'
|
||||
import { type UseEventBusReturn, useDebounceFn } from '@vueuse/core'
|
||||
import { inject, computed, provide } from 'vue'
|
||||
import type { InjectionKey, Ref, ComputedRef } from 'vue'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
import type { UseEventBusReturn } from '@vueuse/core'
|
||||
import type { FormFieldProps } from '../types'
|
||||
import type { FormEvent, FormInputEvents, FormFieldInjectedOptions, FormInjectedOptions } from '../types/form'
|
||||
import type { GetObjectField } from '../types/utils'
|
||||
|
||||
@@ -3,9 +3,34 @@ import { reactive, markRaw, shallowReactive } from 'vue'
|
||||
import { createSharedComposable } from '@vueuse/core'
|
||||
import type { ComponentProps, ComponentEmit } from 'vue-component-type-helpers'
|
||||
|
||||
// Extracts the first argument of the close event
|
||||
type CloseEventArgType<T> = T extends (event: 'close', args_0: infer R) => void ? R : never
|
||||
|
||||
/**
|
||||
* This is a workaround for a design limitation in TypeScript.
|
||||
*
|
||||
* Conditional types only match the last function overload, not a union of all possible
|
||||
* parameter types. This workaround forces TypeScript to properly extract the 'close'
|
||||
* event argument type from component emits with multiple event signatures.
|
||||
*
|
||||
* @see https://github.com/microsoft/TypeScript/issues/32164
|
||||
*/
|
||||
type CloseEventArgType<T> = T extends {
|
||||
(event: 'close', arg_0: infer Arg, ...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
(...args: any[]): void
|
||||
} ? Arg : never
|
||||
export type OverlayOptions<OverlayAttrs = Record<string, any>> = {
|
||||
defaultOpen?: boolean
|
||||
props?: OverlayAttrs
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { inject, provide, computed, type Ref, type InjectionKey } from 'vue'
|
||||
import { inject, provide, computed } from 'vue'
|
||||
import type { Ref, InjectionKey } from 'vue'
|
||||
|
||||
export const portalTargetInjectionKey: InjectionKey<Ref<string | HTMLElement>> = Symbol('nuxt-ui.portal-target')
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ export interface Form<S extends FormSchema> {
|
||||
blurredFields: ReadonlySet<DeepReadonly<keyof FormData<S, false>>>
|
||||
}
|
||||
|
||||
export type FormSchema<I extends object = object, O extends object = I> =
|
||||
| YupObjectSchema<I>
|
||||
| JoiSchema<I>
|
||||
| SuperstructSchema<any, any>
|
||||
| StandardSchemaV1<I, O>
|
||||
export type FormSchema<I extends object = object, O extends object = I>
|
||||
= | YupObjectSchema<I>
|
||||
| JoiSchema<I>
|
||||
| SuperstructSchema<any, any>
|
||||
| StandardSchemaV1<I, O>
|
||||
|
||||
// Define a utility type to infer the input type based on the schema type
|
||||
export type InferInput<Schema> = Schema extends StandardSchemaV1 ? StandardSchemaV1.InferInput<Schema>
|
||||
@@ -83,10 +83,10 @@ export type FormInputEvent<T extends object> = {
|
||||
eager?: boolean
|
||||
}
|
||||
|
||||
export type FormEvent<T extends object> =
|
||||
| FormInputEvent<T>
|
||||
| FormChildAttachEvent
|
||||
| FormChildDetachEvent
|
||||
export type FormEvent<T extends object>
|
||||
= | FormInputEvent<T>
|
||||
| FormChildAttachEvent
|
||||
| FormChildDetachEvent
|
||||
|
||||
export interface FormInjectedOptions {
|
||||
disabled?: boolean
|
||||
|
||||
@@ -30,8 +30,8 @@ type ComponentSlots<T extends { slots?: Record<string, any> }> = Id<{
|
||||
[K in keyof T['slots']]?: ClassValue
|
||||
}>
|
||||
|
||||
type GetComponentAppConfig<A, U extends string, K extends string> =
|
||||
A extends Record<U, Record<K, any>> ? A[U][K] : {}
|
||||
type GetComponentAppConfig<A, U extends string, K extends string>
|
||||
= A extends Record<U, Record<K, any>> ? A[U][K] : {}
|
||||
|
||||
type ComponentAppConfig<
|
||||
T,
|
||||
|
||||
@@ -44,8 +44,8 @@ export type MergeTypes<T extends object> = {
|
||||
|
||||
export type GetItemKeys<I> = keyof Extract<NestedItem<I>, object>
|
||||
|
||||
export type GetItemValue<I, VK extends GetItemKeys<I> | undefined, T extends NestedItem<I> = NestedItem<I>> =
|
||||
T extends object
|
||||
export type GetItemValue<I, VK extends GetItemKeys<I> | undefined, T extends NestedItem<I> = NestedItem<I>>
|
||||
= T extends object
|
||||
? VK extends undefined
|
||||
? T
|
||||
: VK extends keyof T
|
||||
@@ -70,10 +70,10 @@ export type GetModelValueEmits<
|
||||
'update:modelValue': [payload: GetModelValue<T, VK, M>]
|
||||
}
|
||||
|
||||
export type StringOrVNode =
|
||||
| string
|
||||
| VNode
|
||||
| (() => VNode)
|
||||
export type StringOrVNode
|
||||
= | string
|
||||
| VNode
|
||||
| (() => VNode)
|
||||
|
||||
export type EmitsToProps<T> = {
|
||||
[K in keyof T as `on${Capitalize<string & K>}`]: T[K] extends [...args: infer Args]
|
||||
|
||||
@@ -85,3 +85,14 @@ export function compare<T>(value?: T, currentValue?: T, comparator?: string | ((
|
||||
export function isArrayOfArray<A>(item: A[] | A[][]): item is A[][] {
|
||||
return Array.isArray(item[0])
|
||||
}
|
||||
|
||||
export function mergeClasses(appConfigClass?: string | string[], propClass?: string) {
|
||||
if (!appConfigClass && !propClass) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return [
|
||||
...(Array.isArray(appConfigClass) ? appConfigClass : [appConfigClass]),
|
||||
propClass
|
||||
].filter(Boolean)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createTV, type defaultConfig } from 'tailwind-variants'
|
||||
import { createTV } from 'tailwind-variants'
|
||||
import type { defaultConfig } from 'tailwind-variants'
|
||||
import type { AppConfig } from '@nuxt/schema'
|
||||
import appConfig from '#build/app.config'
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
caption: 'sr-only',
|
||||
thead: 'relative',
|
||||
tbody: 'divide-y divide-default [&>tr]:data-[selectable=true]:hover:bg-elevated/50 [&>tr]:data-[selectable=true]:focus-visible:outline-primary',
|
||||
tfoot: 'relative',
|
||||
tr: 'data-[selected=true]:bg-elevated/50',
|
||||
th: 'px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0',
|
||||
td: 'p-4 text-sm text-muted whitespace-nowrap [&:has([role=checkbox])]:pe-0',
|
||||
@@ -23,7 +24,14 @@ export default (options: Required<ModuleOptions>) => ({
|
||||
},
|
||||
sticky: {
|
||||
true: {
|
||||
thead: 'sticky top-0 inset-x-0 bg-default/75 z-[1] backdrop-blur',
|
||||
tfoot: 'sticky bottom-0 inset-x-0 bg-default/75 z-[1] backdrop-blur'
|
||||
},
|
||||
header: {
|
||||
thead: 'sticky top-0 inset-x-0 bg-default/75 z-[1] backdrop-blur'
|
||||
},
|
||||
footer: {
|
||||
tfoot: 'sticky bottom-0 inset-x-0 bg-default/75 z-[1] backdrop-blur'
|
||||
}
|
||||
},
|
||||
loading: {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Accordion, { type AccordionProps, type AccordionSlots } from '../../src/runtime/components/Accordion.vue'
|
||||
import Accordion from '../../src/runtime/components/Accordion.vue'
|
||||
import type { AccordionProps, AccordionSlots } from '../../src/runtime/components/Accordion.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Accordion', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Alert, { type AlertProps, type AlertSlots } from '../../src/runtime/components/Alert.vue'
|
||||
import Alert from '../../src/runtime/components/Alert.vue'
|
||||
import type { AlertProps, AlertSlots } from '../../src/runtime/components/Alert.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/alert'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Avatar, { type AvatarProps, type AvatarSlots } from '../../src/runtime/components/Avatar.vue'
|
||||
import Avatar from '../../src/runtime/components/Avatar.vue'
|
||||
import type { AvatarProps, AvatarSlots } from '../../src/runtime/components/Avatar.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/avatar'
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Avatar from '../../src/runtime/components/Avatar.vue'
|
||||
import AvatarGroup, { type AvatarGroupProps, type AvatarGroupSlots } from '../../src/runtime/components/AvatarGroup.vue'
|
||||
import AvatarGroup from '../../src/runtime/components/AvatarGroup.vue'
|
||||
import type { AvatarGroupProps, AvatarGroupSlots } from '../../src/runtime/components/AvatarGroup.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/avatar-group'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Badge, { type BadgeProps, type BadgeSlots } from '../../src/runtime/components/Badge.vue'
|
||||
import Badge from '../../src/runtime/components/Badge.vue'
|
||||
import type { BadgeProps, BadgeSlots } from '../../src/runtime/components/Badge.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/badge'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Breadcrumb, { type BreadcrumbProps, type BreadcrumbSlots } from '../../src/runtime/components/Breadcrumb.vue'
|
||||
import Breadcrumb from '../../src/runtime/components/Breadcrumb.vue'
|
||||
import type { BreadcrumbProps, BreadcrumbSlots } from '../../src/runtime/components/Breadcrumb.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Breadcrumb', () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ref } from 'vue'
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import Button, { type ButtonProps, type ButtonSlots } from '../../src/runtime/components/Button.vue'
|
||||
import Button from '../../src/runtime/components/Button.vue'
|
||||
import type { ButtonProps, ButtonSlots } from '../../src/runtime/components/Button.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/button'
|
||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import ButtonGroup, { type ButtonGroupProps, type ButtonGroupSlots } from '../../src/runtime/components/ButtonGroup.vue'
|
||||
import ButtonGroup from '../../src/runtime/components/ButtonGroup.vue'
|
||||
import type { ButtonGroupProps, ButtonGroupSlots } from '../../src/runtime/components/ButtonGroup.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import { UInput, UButton } from '#components'
|
||||
import buttonTheme from '#build/ui/button'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, vi, afterAll, test } from 'vitest'
|
||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||
import Calendar, { type CalendarProps, type CalendarSlots } from '../../src/runtime/components/Calendar.vue'
|
||||
import Calendar from '../../src/runtime/components/Calendar.vue'
|
||||
import type { CalendarProps, CalendarSlots } from '../../src/runtime/components/Calendar.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/calendar'
|
||||
import { CalendarDate } from '@internationalized/date'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Card, { type CardProps, type CardSlots } from '../../src/runtime/components/Card.vue'
|
||||
import Card from '../../src/runtime/components/Card.vue'
|
||||
import type { CardProps, CardSlots } from '../../src/runtime/components/Card.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/card'
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Carousel, { type CarouselProps, type CarouselSlots } from '../../src/runtime/components/Carousel.vue'
|
||||
import Carousel from '../../src/runtime/components/Carousel.vue'
|
||||
import type { CarouselProps, CarouselSlots } from '../../src/runtime/components/Carousel.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
const CarouselWrapper = defineComponent({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import Checkbox, { type CheckboxProps, type CheckboxSlots } from '../../src/runtime/components/Checkbox.vue'
|
||||
import Checkbox from '../../src/runtime/components/Checkbox.vue'
|
||||
import type { CheckboxProps, CheckboxSlots } from '../../src/runtime/components/Checkbox.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/checkbox'
|
||||
import { renderForm } from '../utils/form'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import CheckboxGroup, { type CheckboxGroupProps, type CheckboxGroupSlots } from '../../src/runtime/components/CheckboxGroup.vue'
|
||||
import CheckboxGroup from '../../src/runtime/components/CheckboxGroup.vue'
|
||||
import type { CheckboxGroupProps, CheckboxGroupSlots } from '../../src/runtime/components/CheckboxGroup.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/checkbox-group'
|
||||
import themeCheckbox from '#build/ui/checkbox'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Chip, { type ChipProps, type ChipSlots } from '../../src/runtime/components/Chip.vue'
|
||||
import Chip from '../../src/runtime/components/Chip.vue'
|
||||
import type { ChipProps, ChipSlots } from '../../src/runtime/components/Chip.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/chip'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Collapsible, { type CollapsibleProps, type CollapsibleSlots } from '../../src/runtime/components/Collapsible.vue'
|
||||
import Collapsible from '../../src/runtime/components/Collapsible.vue'
|
||||
import type { CollapsibleProps, CollapsibleSlots } from '../../src/runtime/components/Collapsible.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Collapsible', () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||
import ColorPicker, { type ColorPickerProps } from '../../src/runtime/components/ColorPicker.vue'
|
||||
import ColorPicker from '../../src/runtime/components/ColorPicker.vue'
|
||||
import type { ColorPickerProps } from '../../src/runtime/components/ColorPicker.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/color-picker'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import CommandPalette, { type CommandPaletteProps, type CommandPaletteSlots } from '../../src/runtime/components/CommandPalette.vue'
|
||||
import CommandPalette from '../../src/runtime/components/CommandPalette.vue'
|
||||
import type { CommandPaletteProps, CommandPaletteSlots } from '../../src/runtime/components/CommandPalette.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('CommandPalette', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Container, { type ContainerProps, type ContainerSlots } from '../../src/runtime/components/Container.vue'
|
||||
import Container from '../../src/runtime/components/Container.vue'
|
||||
import type { ContainerProps, ContainerSlots } from '../../src/runtime/components/Container.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Container', () => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { h, defineComponent } from 'vue'
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import ContextMenu, { type ContextMenuProps, type ContextMenuSlots } from '../../src/runtime/components/ContextMenu.vue'
|
||||
import ContextMenu from '../../src/runtime/components/ContextMenu.vue'
|
||||
import type { ContextMenuProps, ContextMenuSlots } from '../../src/runtime/components/ContextMenu.vue'
|
||||
import theme from '#build/ui/context-menu'
|
||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||
import { expectSlotProps } from '../utils/types'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Drawer, { type DrawerProps, type DrawerSlots } from '../../src/runtime/components/Drawer.vue'
|
||||
import Drawer from '../../src/runtime/components/Drawer.vue'
|
||||
import type { DrawerProps, DrawerSlots } from '../../src/runtime/components/Drawer.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/drawer'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import DropdownMenu, { type DropdownMenuProps, type DropdownMenuSlots } from '../../src/runtime/components/DropdownMenu.vue'
|
||||
import DropdownMenu from '../../src/runtime/components/DropdownMenu.vue'
|
||||
import type { DropdownMenuProps, DropdownMenuSlots } from '../../src/runtime/components/DropdownMenu.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/dropdown-menu'
|
||||
import { expectSlotProps } from '../utils/types'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Input, { type InputProps, type InputSlots } from '../../src/runtime/components/Input.vue'
|
||||
import Input from '../../src/runtime/components/Input.vue'
|
||||
import type { InputProps, InputSlots } from '../../src/runtime/components/Input.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/input'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import InputMenu, { type InputMenuProps, type InputMenuSlots } from '../../src/runtime/components/InputMenu.vue'
|
||||
import InputMenu from '../../src/runtime/components/InputMenu.vue'
|
||||
import type { InputMenuProps, InputMenuSlots } from '../../src/runtime/components/InputMenu.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/input'
|
||||
import { renderForm } from '../utils/form'
|
||||
|
||||
@@ -2,7 +2,8 @@ import { describe, it, expect, test } from 'vitest'
|
||||
import { flushPromises } from '@vue/test-utils'
|
||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||
import { reactive } from 'vue'
|
||||
import InputNumber, { type InputNumberProps, type InputNumberSlots } from '../../src/runtime/components/InputNumber.vue'
|
||||
import InputNumber from '../../src/runtime/components/InputNumber.vue'
|
||||
import type { InputNumberProps, InputNumberSlots } from '../../src/runtime/components/InputNumber.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/input-number'
|
||||
import type { FormInputEvents } from '~/src/module'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import theme from '#build/ui/input'
|
||||
import InputTags, { type InputTagsProps, type InputTagsSlots } from '../../src/runtime/components/InputTags.vue'
|
||||
import InputTags from '../../src/runtime/components/InputTags.vue'
|
||||
import type { InputTagsProps, InputTagsSlots } from '../../src/runtime/components/InputTags.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('InputTags', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Kbd, { type KbdProps, type KbdSlots } from '../../src/runtime/components/Kbd.vue'
|
||||
import Kbd from '../../src/runtime/components/Kbd.vue'
|
||||
import type { KbdProps, KbdSlots } from '../../src/runtime/components/Kbd.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/kbd'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Modal, { type ModalProps, type ModalSlots } from '../../src/runtime/components/Modal.vue'
|
||||
import Modal from '../../src/runtime/components/Modal.vue'
|
||||
import type { ModalProps, ModalSlots } from '../../src/runtime/components/Modal.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Modal', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import NavigationMenu, { type NavigationMenuProps, type NavigationMenuSlots } from '../../src/runtime/components/NavigationMenu.vue'
|
||||
import NavigationMenu from '../../src/runtime/components/NavigationMenu.vue'
|
||||
import type { NavigationMenuProps, NavigationMenuSlots } from '../../src/runtime/components/NavigationMenu.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/navigation-menu'
|
||||
import { expectSlotProps } from '../utils/types'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Pagination, { type PaginationProps, type PaginationSlots } from '../../src/runtime/components/Pagination.vue'
|
||||
import Pagination from '../../src/runtime/components/Pagination.vue'
|
||||
import type { PaginationProps, PaginationSlots } from '../../src/runtime/components/Pagination.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/button'
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import PinInput, { type PinInputProps } from '../../src/runtime/components/PinInput.vue'
|
||||
import PinInput from '../../src/runtime/components/PinInput.vue'
|
||||
import type { PinInputProps } from '../../src/runtime/components/PinInput.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/pin-input'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Popover, { type PopoverProps, type PopoverSlots } from '../../src/runtime/components/Popover.vue'
|
||||
import Popover from '../../src/runtime/components/Popover.vue'
|
||||
import type { PopoverProps, PopoverSlots } from '../../src/runtime/components/Popover.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Popover', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Progress, { type ProgressProps, type ProgressSlots } from '../../src/runtime/components/Progress.vue'
|
||||
import Progress from '../../src/runtime/components/Progress.vue'
|
||||
import type { ProgressProps, ProgressSlots } from '../../src/runtime/components/Progress.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/progress'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import RadioGroup, { type RadioGroupProps, type RadioGroupSlots } from '../../src/runtime/components/RadioGroup.vue'
|
||||
import RadioGroup from '../../src/runtime/components/RadioGroup.vue'
|
||||
import type { RadioGroupProps, RadioGroupSlots } from '../../src/runtime/components/RadioGroup.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/radio-group'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import Select, { type SelectProps, type SelectSlots } from '../../src/runtime/components/Select.vue'
|
||||
import Select from '../../src/runtime/components/Select.vue'
|
||||
import type { SelectProps, SelectSlots } from '../../src/runtime/components/Select.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/input'
|
||||
import { renderForm } from '../utils/form'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import SelectMenu, { type SelectMenuProps, type SelectMenuSlots } from '../../src/runtime/components/SelectMenu.vue'
|
||||
import SelectMenu from '../../src/runtime/components/SelectMenu.vue'
|
||||
import type { SelectMenuProps, SelectMenuSlots } from '../../src/runtime/components/SelectMenu.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/input'
|
||||
import { renderForm } from '../utils/form'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Separator, { type SeparatorProps, type SeparatorSlots } from '../../src/runtime/components/Separator.vue'
|
||||
import Separator from '../../src/runtime/components/Separator.vue'
|
||||
import type { SeparatorProps, SeparatorSlots } from '../../src/runtime/components/Separator.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/separator'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Skeleton, { type SkeletonProps } from '../../src/runtime/components/Skeleton.vue'
|
||||
import Skeleton from '../../src/runtime/components/Skeleton.vue'
|
||||
import type { SkeletonProps } from '../../src/runtime/components/Skeleton.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Skeleton', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Slideover, { type SlideoverProps, type SlideoverSlots } from '../../src/runtime/components/Slideover.vue'
|
||||
import Slideover from '../../src/runtime/components/Slideover.vue'
|
||||
import type { SlideoverProps, SlideoverSlots } from '../../src/runtime/components/Slideover.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
describe('Slideover', () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import Slider, { type SliderProps } from '../../src/runtime/components/Slider.vue'
|
||||
import Slider from '../../src/runtime/components/Slider.vue'
|
||||
import type { SliderProps } from '../../src/runtime/components/Slider.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/slider'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Stepper, { type StepperProps, type StepperSlots } from '../../src/runtime/components/Stepper.vue'
|
||||
import Stepper from '../../src/runtime/components/Stepper.vue'
|
||||
import type { StepperProps, StepperSlots } from '../../src/runtime/components/Stepper.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/stepper'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import Switch, { type SwitchProps, type SwitchSlots } from '../../src/runtime/components/Switch.vue'
|
||||
import Switch from '../../src/runtime/components/Switch.vue'
|
||||
import type { SwitchProps, SwitchSlots } from '../../src/runtime/components/Switch.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/switch'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
|
||||
@@ -3,7 +3,8 @@ import { describe, it, expect } from 'vitest'
|
||||
import { flushPromises } from '@vue/test-utils'
|
||||
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
||||
import { UCheckbox, UButton, UBadge, UDropdownMenu } from '#components'
|
||||
import Table, { type TableProps, type TableSlots, type TableColumn } from '../../src/runtime/components/Table.vue'
|
||||
import Table from '../../src/runtime/components/Table.vue'
|
||||
import type { TableProps, TableSlots, TableColumn, TableRow } from '../../src/runtime/components/Table.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/table'
|
||||
|
||||
@@ -98,6 +99,16 @@ describe('Table', () => {
|
||||
}, {
|
||||
accessorKey: 'amount',
|
||||
header: () => h('div', { class: 'text-right' }, 'Amount'),
|
||||
footer: ({ column }) => {
|
||||
const total = column.getFacetedRowModel().rows.reduce((acc: number, row: TableRow<typeof data[number]>) => acc + Number.parseFloat(row.getValue('amount')), 0)
|
||||
|
||||
const formatted = new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(total)
|
||||
|
||||
return h('div', { class: 'text-right font-medium' }, `Total: ${formatted}`)
|
||||
},
|
||||
cell: ({ row }) => {
|
||||
const amount = Number.parseFloat(row.getValue('amount'))
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Tabs, { type TabsProps, type TabsSlots } from '../../src/runtime/components/Tabs.vue'
|
||||
import Tabs from '../../src/runtime/components/Tabs.vue'
|
||||
import type { TabsProps, TabsSlots } from '../../src/runtime/components/Tabs.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/tabs'
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Textarea, { type TextareaProps, type TextareaSlots } from '../../src/runtime/components/Textarea.vue'
|
||||
import Textarea from '../../src/runtime/components/Textarea.vue'
|
||||
import type { TextareaProps, TextareaSlots } from '../../src/runtime/components/Textarea.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/textarea'
|
||||
import { renderForm } from '../utils/form'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Timeline, { type TimelineProps, type TimelineSlots } from '../../src/runtime/components/Timeline.vue'
|
||||
import Timeline from '../../src/runtime/components/Timeline.vue'
|
||||
import type { TimelineProps, TimelineSlots } from '../../src/runtime/components/Timeline.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/timeline'
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import Toaster from '../../src/runtime/components/Toaster.vue'
|
||||
import Toast, { type ToastProps, type ToastSlots } from '../../src/runtime/components/Toast.vue'
|
||||
import Toast from '../../src/runtime/components/Toast.vue'
|
||||
import type { ToastProps, ToastSlots } from '../../src/runtime/components/Toast.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import { ClientOnly } from '#components'
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { TooltipProvider } from 'reka-ui'
|
||||
import Tooltip, { type TooltipProps, type TooltipSlots } from '../../src/runtime/components/Tooltip.vue'
|
||||
import Tooltip from '../../src/runtime/components/Tooltip.vue'
|
||||
import type { TooltipProps, TooltipSlots } from '../../src/runtime/components/Tooltip.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
|
||||
const TooltipWrapper = defineComponent({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, test } from 'vitest'
|
||||
import Tree, { type TreeProps, type TreeSlots, type TreeItem } from '../../src/runtime/components/Tree.vue'
|
||||
import Tree from '../../src/runtime/components/Tree.vue'
|
||||
import type { TreeProps, TreeSlots, TreeItem } from '../../src/runtime/components/Tree.vue'
|
||||
import ComponentRender from '../component-render'
|
||||
import theme from '#build/ui/tree'
|
||||
import { expectEmitPayloadType } from '../utils/types'
|
||||
|
||||
@@ -50,6 +50,7 @@ exports[`Table > renders with as correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</section>"
|
||||
`;
|
||||
@@ -104,6 +105,7 @@ exports[`Table > renders with body-bottom slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->Body bottom slot
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -157,6 +159,7 @@ exports[`Table > renders with body-top slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -211,6 +214,7 @@ exports[`Table > renders with caption correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -265,6 +269,7 @@ exports[`Table > renders with caption slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -319,6 +324,7 @@ exports[`Table > renders with cell slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -373,6 +379,7 @@ exports[`Table > renders with class correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -564,6 +571,32 @@ exports[`Table > renders with columns correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<tfoot class="relative">
|
||||
<tr class="absolute z-[1] left-0 w-full h-px bg-(--ui-border-accented)"></tr>
|
||||
<tr class="data-[selected=true]:bg-elevated/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<div class="text-right font-medium">Total: €2,990.00</div>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -618,6 +651,7 @@ exports[`Table > renders with data correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -635,6 +669,7 @@ exports[`Table > renders with empty correctly 1`] = `
|
||||
<td colspan="0" class="py-6 text-center text-sm text-muted">There is no data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -674,6 +709,32 @@ exports[`Table > renders with empty slot correctly 1`] = `
|
||||
<td colspan="7" class="py-6 text-center text-sm text-muted">Empty slot</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot class="relative">
|
||||
<tr class="absolute z-[1] left-0 w-full h-px bg-(--ui-border-accented)"></tr>
|
||||
<tr class="data-[selected=true]:bg-elevated/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<div class="text-right font-medium">Total: €0.00</div>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -728,6 +789,7 @@ exports[`Table > renders with expanded slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -782,6 +844,7 @@ exports[`Table > renders with header slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -836,6 +899,7 @@ exports[`Table > renders with loading animation carousel correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -890,6 +954,7 @@ exports[`Table > renders with loading animation carousel-inverse correctly 1`] =
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -944,6 +1009,7 @@ exports[`Table > renders with loading animation elastic correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -998,6 +1064,7 @@ exports[`Table > renders with loading animation swing correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1052,6 +1119,7 @@ exports[`Table > renders with loading color error correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1106,6 +1174,7 @@ exports[`Table > renders with loading color info correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1160,6 +1229,7 @@ exports[`Table > renders with loading color neutral correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1214,6 +1284,7 @@ exports[`Table > renders with loading color primary correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1268,6 +1339,7 @@ exports[`Table > renders with loading color secondary correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1322,6 +1394,7 @@ exports[`Table > renders with loading color success correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1376,6 +1449,7 @@ exports[`Table > renders with loading color warning correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1430,6 +1504,7 @@ exports[`Table > renders with loading correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1469,6 +1544,32 @@ exports[`Table > renders with loading slot correctly 1`] = `
|
||||
<td colspan="7" class="py-6 text-center">Loading slot</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot class="relative">
|
||||
<tr class="absolute z-[1] left-0 w-full h-px bg-(--ui-border-accented)"></tr>
|
||||
<tr class="data-[selected=true]:bg-elevated/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<div class="text-right font-medium">Total: €0.00</div>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1523,6 +1624,7 @@ exports[`Table > renders with sticky correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1577,6 +1679,7 @@ exports[`Table > renders with ui correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1594,6 +1697,7 @@ exports[`Table > renders without data correctly 1`] = `
|
||||
<td colspan="0" class="py-6 text-center text-sm text-muted">No data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
@@ -50,6 +50,7 @@ exports[`Table > renders with as correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</section>"
|
||||
`;
|
||||
@@ -104,6 +105,7 @@ exports[`Table > renders with body-bottom slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->Body bottom slot
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -157,6 +159,7 @@ exports[`Table > renders with body-top slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -211,6 +214,7 @@ exports[`Table > renders with caption correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -265,6 +269,7 @@ exports[`Table > renders with caption slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -319,6 +324,7 @@ exports[`Table > renders with cell slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -373,6 +379,7 @@ exports[`Table > renders with class correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -564,6 +571,32 @@ exports[`Table > renders with columns correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<tfoot class="relative">
|
||||
<tr class="absolute z-[1] left-0 w-full h-px bg-(--ui-border-accented)"></tr>
|
||||
<tr class="data-[selected=true]:bg-elevated/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<div class="text-right font-medium">Total: €2,990.00</div>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -618,6 +651,7 @@ exports[`Table > renders with data correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -635,6 +669,7 @@ exports[`Table > renders with empty correctly 1`] = `
|
||||
<td colspan="0" class="py-6 text-center text-sm text-muted">There is no data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -674,6 +709,32 @@ exports[`Table > renders with empty slot correctly 1`] = `
|
||||
<td colspan="7" class="py-6 text-center text-sm text-muted">Empty slot</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot class="relative">
|
||||
<tr class="absolute z-[1] left-0 w-full h-px bg-(--ui-border-accented)"></tr>
|
||||
<tr class="data-[selected=true]:bg-elevated/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<div class="text-right font-medium">Total: €0.00</div>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -728,6 +789,7 @@ exports[`Table > renders with expanded slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -782,6 +844,7 @@ exports[`Table > renders with header slot correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -836,6 +899,7 @@ exports[`Table > renders with loading animation carousel correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -890,6 +954,7 @@ exports[`Table > renders with loading animation carousel-inverse correctly 1`] =
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -944,6 +1009,7 @@ exports[`Table > renders with loading animation elastic correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -998,6 +1064,7 @@ exports[`Table > renders with loading animation swing correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1052,6 +1119,7 @@ exports[`Table > renders with loading color error correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1106,6 +1174,7 @@ exports[`Table > renders with loading color info correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1160,6 +1229,7 @@ exports[`Table > renders with loading color neutral correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1214,6 +1284,7 @@ exports[`Table > renders with loading color primary correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1268,6 +1339,7 @@ exports[`Table > renders with loading color secondary correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1322,6 +1394,7 @@ exports[`Table > renders with loading color success correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1376,6 +1449,7 @@ exports[`Table > renders with loading color warning correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1430,6 +1504,7 @@ exports[`Table > renders with loading correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1469,6 +1544,32 @@ exports[`Table > renders with loading slot correctly 1`] = `
|
||||
<td colspan="7" class="py-6 text-center">Loading slot</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot class="relative">
|
||||
<tr class="absolute z-[1] left-0 w-full h-px bg-(--ui-border-accented)"></tr>
|
||||
<tr class="data-[selected=true]:bg-elevated/50">
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<div class="text-right font-medium">Total: €0.00</div>
|
||||
</th>
|
||||
<th data-pinned="false" class="px-4 py-3.5 text-sm text-highlighted text-left rtl:text-right font-semibold [&:has([role=checkbox])]:pe-0">
|
||||
<!---->
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1523,6 +1624,7 @@ exports[`Table > renders with sticky correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1577,6 +1679,7 @@ exports[`Table > renders with ui correctly 1`] = `
|
||||
</tr>
|
||||
<!--v-if-->
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
@@ -1594,6 +1697,7 @@ exports[`Table > renders without data correctly 1`] = `
|
||||
<td colspan="0" class="py-6 text-center text-sm text-muted">No data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<!--v-if-->
|
||||
</table>
|
||||
</div>"
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user