Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(components): improve generic types #3331

Open
wants to merge 112 commits into
base: v3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
1f606ee
docs(ComponentCode): support type imports
sandros94 Feb 16, 2025
7030a58
up
sandros94 Feb 16, 2025
cacd27c
up
sandros94 Feb 16, 2025
93f8de1
refactor(Accordion): default type generics
sandros94 Feb 16, 2025
7533f76
docs(Accordion): add type imports
sandros94 Feb 16, 2025
324718c
refactor(Breadcrumb): types and default generic
sandros94 Feb 16, 2025
ad7f711
docs(Breadcrumb): add type imports
sandros94 Feb 16, 2025
84c122c
docs(ButtonGroup): add type imports
sandros94 Feb 16, 2025
667b6ce
up
sandros94 Feb 16, 2025
9b8b007
up
sandros94 Feb 16, 2025
ac3517f
up
sandros94 Feb 16, 2025
859e034
refactor(Calendar): type generics and defaults
sandros94 Feb 16, 2025
3608bcd
refactor(Carousel): generics and default types
sandros94 Feb 16, 2025
5203359
fix(CommandPalette): generics and default types
sandros94 Feb 16, 2025
6f24639
docs(CommandPalette): add type imports
sandros94 Feb 16, 2025
e6222bb
up
sandros94 Feb 16, 2025
b796336
refactor(ContextMenu): generics and default types
sandros94 Feb 16, 2025
8d36ce4
docs(ContextMenu): add type imports
sandros94 Feb 16, 2025
cc059a9
up
sandros94 Feb 16, 2025
1faf6ca
refactor(DropdownMenu): generics and default types
sandros94 Feb 16, 2025
54e535e
docs(DropdownMenu): add type imports
sandros94 Feb 16, 2025
4f3adaa
fix(NavigationMenu): generics and default types
sandros94 Feb 16, 2025
6876efe
docs(NavigationMenu): add type imports
sandros94 Feb 16, 2025
c3b2380
refactor(RadioGroup): generic and default types
sandros94 Feb 16, 2025
6e55648
docs(RadioGroup): add type imports
sandros94 Feb 16, 2025
d3c2fae
fix(NavigationMenu): nested array types
sandros94 Feb 16, 2025
f7fc963
up
sandros94 Feb 16, 2025
83b24e0
up
sandros94 Feb 16, 2025
dc80d77
fix(CommandPalette): items types
sandros94 Feb 17, 2025
4b13341
Revert "fix(CommandPalette): items types"
sandros94 Feb 17, 2025
d830e37
up
sandros94 Feb 17, 2025
9a26405
fix(ContextMenu): nested array types
sandros94 Feb 17, 2025
a1f9a89
up
sandros94 Feb 17, 2025
d834e75
fix(DropdownMenu): nested array types
sandros94 Feb 17, 2025
627594a
up
sandros94 Feb 17, 2025
98cb6c6
revert: `CommandPalette`
sandros94 Feb 17, 2025
e7991e9
up
sandros94 Feb 17, 2025
d46adcb
fix(InputMenu): nested array types
sandros94 Feb 17, 2025
f382bd7
up
sandros94 Feb 17, 2025
146fe04
up
sandros94 Feb 17, 2025
c726ac7
fix(InputMenu): `value-key` and `model-value`
sandros94 Feb 17, 2025
5997809
fix(Select): nested array and dynamic types
sandros94 Feb 18, 2025
1320626
docs(Select): add types to examples
sandros94 Feb 18, 2025
890a8b3
docs(InputMenu): add types to examples
sandros94 Feb 18, 2025
eafaebc
up
sandros94 Feb 18, 2025
c58def5
up
sandros94 Feb 18, 2025
59e2221
fix(SelectMenu): nested array and dynamic types
sandros94 Feb 18, 2025
8325181
docs(SelectMenu): add types to examples
sandros94 Feb 18, 2025
dfd6681
up
sandros94 Feb 18, 2025
8bc0574
refactor(Stepper): type defaults
sandros94 Feb 18, 2025
dc5e402
docs(Stepper): add type imports
sandros94 Feb 18, 2025
e2be436
refactor(Tabs): type generics and defaults
sandros94 Feb 18, 2025
428e7d5
docs(Tabs): add type imports
sandros94 Feb 18, 2025
438ee88
Merge branch 'v3' into refactor-types
sandros94 Feb 18, 2025
46f5c6d
Merge branch 'v3' into refactor-types
sandros94 Feb 18, 2025
63756e5
Merge branch 'v3' into refactor-types
sandros94 Feb 21, 2025
e22fa6c
fix(DropdownMenu): dynamic values typing
sandros94 Feb 21, 2025
a0a008e
up
sandros94 Feb 22, 2025
f8df24a
up
sandros94 Feb 22, 2025
7744a44
Merge branch 'v3' into refactor-types
sandros94 Feb 25, 2025
3fd75cc
refactor: simplify type utils
sandros94 Feb 25, 2025
342278b
Merge branch 'v3' into refactor-types
sandros94 Feb 27, 2025
0f26858
up
sandros94 Feb 27, 2025
60e8b0a
fix: dynamic slots
sandros94 Feb 27, 2025
83f4010
fix(Tree): dynamic types
sandros94 Feb 27, 2025
4d76c46
test: fix typing
sandros94 Feb 27, 2025
de9f6ab
up
sandros94 Feb 27, 2025
48f06c5
revert(partially): dynamic slot typing
sandros94 Feb 27, 2025
f4050a8
up
sandros94 Feb 27, 2025
b5ff285
Merge branch 'v3' into refactor-types
sandros94 Feb 28, 2025
c6144fd
fix: `DynamicSlots` named slots
sandros94 Feb 28, 2025
dea97bf
fix(typescript): default to `value` key for some components
sandros94 Mar 1, 2025
4011a8a
test(Tree): add type tests
sandros94 Mar 1, 2025
ce3b7f7
test(Select): update tests to follow default value for `valueKey`
sandros94 Mar 1, 2025
211e053
fix(Stepper): slot type cast
sandros94 Mar 1, 2025
ca75373
up
sandros94 Mar 1, 2025
5f86d7d
up
sandros94 Mar 1, 2025
6c56e9f
up
sandros94 Mar 2, 2025
d3a3796
fix(typescript): DynamicSlots typing for nested arrays
sandros94 Mar 2, 2025
56220e9
Merge branch 'v3' into refactor-types
sandros94 Mar 2, 2025
75cfac7
fix: correctly type `ui` prop in slots
sandros94 Mar 20, 2025
d2d5696
chore(deps): update `vaul-vue`
benjamincanac Mar 20, 2025
7d97c6f
up
sandros94 Mar 20, 2025
263b3da
up
sandros94 Mar 20, 2025
19f8d4b
Merge branch 'v3' into refactor-types
sandros94 Mar 20, 2025
7aa60d6
type(Drawer): force prop type
sandros94 Mar 20, 2025
0ca1deb
Merge branch 'v3' into refactor-types
benjamincanac Mar 20, 2025
e429777
fix(Calendar):: bad typing cascading upstream
sandros94 Mar 20, 2025
0c1a9a6
fix(Calendar): more type fixes
sandros94 Mar 21, 2025
f519ea2
chore(package): disable docs typecheck for now
benjamincanac Mar 21, 2025
ffcd335
fix calendar
benjamincanac Mar 21, 2025
617551c
type: enforce boolean type on `multiple`
sandros94 Mar 21, 2025
1ab1af5
Merge branch 'v3' into refactor-types
benjamincanac Mar 21, 2025
859185f
up
benjamincanac Mar 21, 2025
5cb2101
fix(InputMenu|Select|SelectMenu): `value` item key
sandros94 Mar 21, 2025
50236e3
up
sandros94 Mar 21, 2025
5711132
up
sandros94 Mar 21, 2025
75eee60
fix(Stepper): `currentStep` conditional slots
sandros94 Mar 21, 2025
0dbaae0
up
sandros94 Mar 21, 2025
00315f6
Revert "up"
sandros94 Mar 21, 2025
09dc2ca
Revert "fix(Stepper): `currentStep` conditional slots"
sandros94 Mar 21, 2025
0e829c1
fix(Stepper): `currentStep` conditional name slot
sandros94 Mar 21, 2025
2564b17
Merge branch 'v3' into refactor-types
benjamincanac Mar 21, 2025
a9aff12
chore(package): put back docs typecheck
benjamincanac Mar 21, 2025
33ca724
chore(deps): update `@nuxt/ui-pro`
benjamincanac Mar 21, 2025
b8bf1a0
docs(tabs): remove test
benjamincanac Mar 21, 2025
cd0f8d1
fix: component default generics
sandros94 Mar 21, 2025
c4f89c3
type(components): allow arbitrary data
sandros94 Mar 21, 2025
e104a5d
up
sandros94 Mar 21, 2025
9ad1d11
up
benjamincanac Mar 22, 2025
38bb890
fix(Stepper): only use `slot` for slot's name
sandros94 Mar 22, 2025
f278747
docs(DropdownMenu): update examples
sandros94 Mar 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions docs/app/components/content/ComponentCode.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<!-- eslint-disable no-useless-escape -->
<script setup lang="ts">
import type { ChipProps } from '@nuxt/ui'
import json5 from 'json5'
import { upperFirst, camelCase, kebabCase } from 'scule'
import { hash } from 'ohash'
Expand Down Expand Up @@ -53,6 +54,8 @@ const props = defineProps<{
hide?: string[]
/** List of props to externalize in script setup */
external?: string[]
/** The types of the externalized props */
externalTypes?: string[]
/** List of props to use with `v-model` */
model?: string[]
/** List of props to cast from code and selection */
Expand Down Expand Up @@ -209,11 +212,21 @@ ${props.slots?.default}
code += `
<script setup lang="ts">
`
for (const key of props.external) {
if (props.externalTypes?.length) {
const removeArrayBrackets = (type: string): string => type.endsWith('[]') ? removeArrayBrackets(type.slice(0, -2)) : type

const types = props.externalTypes.map(type => removeArrayBrackets(type))
code += `import type { ${types.join(', ')} } from '@nuxt/ui${props.pro ? '-pro' : ''}'

`
}

for (const [i, key] of props.external.entries()) {
const cast = props.cast?.[key]
const value = cast ? castMap[cast]!.template(componentProps[key]) : json5.stringify(componentProps[key], null, 2)?.replace(/,([ |\t\n]+[}|\]])/g, '$1')
const type = props.externalTypes?.[i] ? `<${props.externalTypes[i]}>` : ''

code += `const ${key === 'modelValue' ? 'value' : key} = ref(${value})
code += `const ${key === 'modelValue' ? 'value' : key} = ref${type}(${value})
`
}
code += `<\/script>
Expand Down Expand Up @@ -346,7 +359,7 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${hash({ props:
inset
standalone
:color="(modelValue as any)"
:size="ui.itemLeadingChipSize()"
:size="(ui.itemLeadingChipSize() as ChipProps['size'])"
class="size-2"
/>
</template>
Expand Down
3 changes: 2 additions & 1 deletion docs/app/components/content/ComponentExample.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script setup lang="ts">
import type { ChipProps } from '@nuxt/ui'
import { camelCase } from 'scule'
import { useElementSize } from '@vueuse/core'
import { get, set } from '#ui/utils'
Expand Down Expand Up @@ -185,7 +186,7 @@ const urlSearchParams = computed(() => {
inset
standalone
:color="(modelValue as any)"
:size="ui.itemLeadingChipSize()"
:size="(ui.itemLeadingChipSize() as ChipProps['size'])"
class="size-2"
/>
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script setup lang="ts">
const items = [
import type { AccordionItem } from '@nuxt/ui'

const items: AccordionItem[] = [
{
label: 'Icons',
icon: 'i-lucide-smile'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script setup lang="ts">
const items = [
import type { AccordionItem } from '@nuxt/ui'

const items: AccordionItem[] = [
{
label: 'Icons',
icon: 'i-lucide-smile'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup lang="ts">
import type { AccordionItem } from '@nuxt/ui'

const items = [
{
label: 'Icons',
Expand All @@ -8,15 +10,15 @@ const items = [
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
slot: 'colors',
slot: 'colors' as const,
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
]
] satisfies AccordionItem[]
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script setup lang="ts">
const items = [
import type { AccordionItem } from '@nuxt/ui'

const items: AccordionItem[] = [
{
label: 'Icons',
icon: 'i-lucide-smile',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<script setup lang="ts">
import type { BreadcrumbItem } from '@nuxt/ui'

const items = [{
label: 'Home',
to: '/'
}, {
slot: 'dropdown',
slot: 'dropdown' as const,
icon: 'i-lucide-ellipsis',
children: [{
label: 'Documentation'
Expand All @@ -18,7 +20,7 @@ const items = [{
}, {
label: 'Breadcrumb',
to: '/components/breadcrumb'
}]
}] satisfies BreadcrumbItem[]
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script setup lang="ts">
const items = [{
import type { BreadcrumbItem } from '@nuxt/ui'

const items: BreadcrumbItem[] = [{
label: 'Home',
to: '/'
}, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script setup lang="ts">
const items = [{
import type { DropdownMenuItem } from '@nuxt/ui'

const items: DropdownMenuItem[] = [{
label: 'Team',
icon: 'i-lucide-users'
}, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const groups = [{
label: 'Billing',
icon: 'i-lucide-credit-card',
kbds: ['meta', 'B'],
slot: 'billing'
slot: 'billing' as const
},
{
label: 'Notifications',
Expand All @@ -25,7 +25,7 @@ const groups = [{
}, {
id: 'users',
label: 'Users',
slot: 'users',
slot: 'users' as const,
items: [
{
label: 'Benjamin Canac',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const showSidebar = ref(true)
const showToolbar = ref(false)

const items = computed(() => [{
const items = computed<ContextMenuItem[]>(() => [{
label: 'View',
type: 'label' as const
}, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script setup lang="ts">
const items = [
import type { ContextMenuItem } from '@nuxt/ui'

const items: ContextMenuItem[][] = [
[
{
label: 'View',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script setup lang="ts">
import type { ContextMenuItem } from '@nuxt/ui'

const loading = ref(true)

const items = [{
const items: ContextMenuItem[] = [{
label: 'Refresh the Page',
slot: 'refresh'
}, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'

const showBookmarks = ref(true)
const showHistory = ref(false)
const showDownloads = ref(false)
Expand Down Expand Up @@ -36,7 +38,7 @@ const items = computed(() => [{
onUpdateChecked(checked: boolean) {
showDownloads.value = checked
}
}])
}] satisfies DropdownMenuItem[])
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'

const items = [
[
{
Expand All @@ -21,15 +23,11 @@ const items = [
icon: 'i-lucide-trash'
}
]
]
] satisfies DropdownMenuItem[][]
</script>

<template>
<UDropdownMenu :items="items" :ui="{ content: 'w-48' }">
<UButton label="Open" color="neutral" variant="outline" icon="i-lucide-menu" />

<template #profile-trailing>
<UIcon name="i-lucide-badge-check" class="shrink-0 size-5 text-(--ui-primary)" />
</template>
</UDropdownMenu>
</template>
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<script setup lang="ts">
const items = [{
label: 'Profile',
icon: 'i-lucide-user',
slot: 'profile'
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}]
import type { DropdownMenuItem } from '@nuxt/ui'

const items = [
{
label: 'Profile',
icon: 'i-lucide-user',
slot: 'profile' as const
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}
] satisfies DropdownMenuItem[]
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<script setup lang="ts">
import type { DropdownMenuItem } from '@nuxt/ui'

const open = ref(false)

defineShortcuts({
o: () => open.value = !open.value
})

const items = [{
label: 'Profile',
icon: 'i-lucide-user'
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}]
const items = [
{
label: 'Profile',
icon: 'i-lucide-user'
}, {
label: 'Billing',
icon: 'i-lucide-credit-card'
}, {
label: 'Settings',
icon: 'i-lucide-cog'
}
] satisfies DropdownMenuItem[]
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function onOpen() {

<template>
<UInputMenu
:items="countries || []"
:items="countries"
:loading="status === 'pending'"
label-key="name"
:search-input="{ icon: 'i-lucide-search' }"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
<script setup lang="ts">
import type { AvatarProps } from '@nuxt/ui'

const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
key: 'typicode-users',
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
}))
},
lazy: true
})
</script>

<template>
<UInputMenu
:items="users || []"
:items="users"
:loading="status === 'pending'"
icon="i-lucide-user"
placeholder="Select user"
Expand All @@ -23,7 +25,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.leadingAvatarSize()"
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
:class="ui.leadingAvatar()"
/>
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup lang="ts">
import type { AvatarProps } from '@nuxt/ui'

const { data: users, status } = await useFetch('https://jsonplaceholder.typicode.com/users', {
key: 'typicode-users-email',
transform: (data: { id: number, name: string, email: string }[]) => {
Expand All @@ -7,15 +9,15 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
email: user.email,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` }
})) || []
}))
},
lazy: true
})
</script>

<template>
<UInputMenu
:items="users || []"
:items="users"
:loading="status === 'pending'"
:filter-fields="['label', 'email']"
icon="i-lucide-user"
Expand All @@ -26,7 +28,7 @@ const { data: users, status } = await useFetch('https://jsonplaceholder.typicode
<UAvatar
v-if="modelValue"
v-bind="modelValue.avatar"
:size="ui.leadingAvatarSize()"
:size="(ui.leadingAvatarSize() as AvatarProps['size'])"
:class="ui.leadingAvatar()"
/>
</template>
Expand Down
Loading
Loading