Skip to content

Commit 6a6de8d

Browse files
feat(Empty): new component (#5200)
Co-authored-by: Benjamin Canac <[email protected]>
1 parent 724b152 commit 6a6de8d

File tree

16 files changed

+1229
-5
lines changed

16 files changed

+1229
-5
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<script setup lang="ts">
2+
import type { UserProps } from '@nuxt/ui'
3+
4+
const members: UserProps[] = [
5+
{
6+
name: 'Daniel Roe',
7+
description: 'danielroe',
8+
to: 'https://github.com/danielroe',
9+
target: '_blank',
10+
avatar: {
11+
src: 'https://github.com/danielroe.png',
12+
alt: 'danielroe'
13+
}
14+
},
15+
{
16+
name: 'Pooya Parsa',
17+
description: 'pi0',
18+
to: 'https://github.com/pi0',
19+
target: '_blank',
20+
avatar: {
21+
src: 'https://github.com/pi0.png',
22+
alt: 'pi0'
23+
}
24+
},
25+
{
26+
name: 'Sébastien Chopin',
27+
description: 'atinux',
28+
to: 'https://github.com/atinux',
29+
target: '_blank',
30+
avatar: {
31+
src: 'https://github.com/atinux.png',
32+
alt: 'atinux'
33+
}
34+
},
35+
{
36+
name: 'Benjamin Canac',
37+
description: 'benjamincanac',
38+
to: 'https://github.com/benjamincanac',
39+
target: '_blank',
40+
avatar: {
41+
src: 'https://github.com/benjamincanac.png',
42+
alt: 'benjamincanac'
43+
}
44+
}
45+
]
46+
</script>
47+
48+
<template>
49+
<UEmpty
50+
title="No team members"
51+
description="Invite your team to collaborate on this project."
52+
variant="naked"
53+
:actions="[{
54+
label: 'Invite members',
55+
icon: 'i-lucide-user-plus',
56+
color: 'neutral'
57+
}]"
58+
>
59+
<template #leading>
60+
<UAvatarGroup size="xl">
61+
<UAvatar src="https://github.com/nuxt.png" alt="Nuxt" />
62+
<UAvatar src="https://github.com/unjs.png" alt="Unjs" />
63+
</UAvatarGroup>
64+
</template>
65+
66+
<template #footer>
67+
<USeparator class="my-4" />
68+
69+
<div class="grid grid-cols-2 gap-4">
70+
<UPageCard
71+
v-for="(member, index) in members"
72+
:key="index"
73+
:to="member.to"
74+
:ui="{ container: 'sm:p-4' }"
75+
>
76+
<UUser
77+
:avatar="member.avatar"
78+
:name="member.name"
79+
:description="member.description"
80+
:ui="{ name: 'truncate' }"
81+
/>
82+
</UPageCard>
83+
</div>
84+
</template>
85+
</UEmpty>
86+
</template>
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
---
2+
title: Empty
3+
description: 'A component to display an empty state.'
4+
category: data
5+
links:
6+
- label: GitHub
7+
icon: i-simple-icons-github
8+
to: https://github.com/nuxt/ui/blob/v4/src/runtime/components/Empty.vue
9+
navigation.badge: Soon
10+
---
11+
12+
## Usage
13+
14+
::code-preview
15+
16+
:::u-empty
17+
---
18+
icon: i-lucide-file
19+
title: No projects found
20+
description: It looks like you haven't added any projects. Create one to get started.
21+
actions:
22+
- icon: i-lucide-plus
23+
label: Create new
24+
- icon: i-lucide-refresh-cw
25+
label: Refresh
26+
color: neutral
27+
variant: subtle
28+
---
29+
:::
30+
31+
::
32+
33+
### Title
34+
35+
Use the `title` prop to set the title of the empty state.
36+
37+
::component-code
38+
---
39+
props:
40+
title: No projects found
41+
---
42+
::
43+
44+
### Description
45+
46+
Use the `description` prop to set the description of the empty state.
47+
48+
::component-code
49+
---
50+
prettier: true
51+
ignore:
52+
- title
53+
props:
54+
title: No projects found
55+
description: It looks like you haven't added any projects. Create one to get started.
56+
---
57+
::
58+
59+
### Icon
60+
61+
Use the `icon` prop to set the icon of the empty state.
62+
63+
::component-code
64+
---
65+
prettier: true
66+
ignore:
67+
- title
68+
- description
69+
props:
70+
icon: i-lucide-file
71+
title: No projects found
72+
description: It looks like you haven't added any projects. Create one to get started.
73+
---
74+
::
75+
76+
### Avatar
77+
78+
Use the `avatar` prop to set the avatar of the empty state.
79+
80+
::component-code
81+
---
82+
prettier: true
83+
ignore:
84+
- icon
85+
- title
86+
- description
87+
props:
88+
avatar.src: 'https://github.com/nuxt.png'
89+
title: No projects found
90+
description: It looks like you haven't added any projects. Create one to get started.
91+
---
92+
::
93+
94+
### Actions
95+
96+
Use the `actions` prop to add some [Button](/docs/components/button) actions to the empty state.
97+
98+
::component-code
99+
---
100+
prettier: true
101+
ignore:
102+
- icon
103+
- title
104+
- description
105+
- actions
106+
props:
107+
icon: i-lucide-file
108+
title: No projects found
109+
description: It looks like you haven't added any projects. Create one to get started.
110+
actions:
111+
- icon: i-lucide-plus
112+
label: Create new
113+
- icon: i-lucide-refresh-cw
114+
label: Refresh
115+
color: neutral
116+
variant: subtle
117+
---
118+
::
119+
120+
### Variant
121+
122+
Use the `variant` prop to change the variant of the empty state.
123+
124+
::component-code
125+
---
126+
prettier: true
127+
ignore:
128+
- icon
129+
- title
130+
- description
131+
- actions
132+
props:
133+
variant: naked
134+
icon: i-lucide-bell
135+
title: No notifications
136+
description: You're all caught up. New notifications will appear here.
137+
actions:
138+
- icon: i-lucide-refresh-cw
139+
label: Refresh
140+
color: neutral
141+
variant: subtle
142+
---
143+
::
144+
145+
### Size
146+
147+
Use the `size` prop to change the size of the empty state.
148+
149+
::component-code
150+
---
151+
prettier: true
152+
ignore:
153+
- icon
154+
- title
155+
- description
156+
- actions
157+
props:
158+
size: xl
159+
icon: i-lucide-bell
160+
title: No notifications
161+
description: You're all caught up. New notifications will appear here.
162+
actions:
163+
- icon: i-lucide-refresh-cw
164+
label: Refresh
165+
color: neutral
166+
variant: subtle
167+
---
168+
::
169+
170+
## Examples
171+
172+
### With slots
173+
174+
Use the available slots to create a more complex empty state.
175+
176+
::component-example
177+
---
178+
collapse: true
179+
name: 'empty-slots-example'
180+
---
181+
::
182+
183+
## API
184+
185+
### Props
186+
187+
:component-props
188+
189+
### Slots
190+
191+
:component-slots
192+
193+
## Theme
194+
195+
:component-theme
196+
197+
## Changelog
198+
199+
:component-changelog

docs/content/docs/2.components/form.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ props:
159159

160160
Use the `nested` prop to nest multiple Form components and link their validation functions. In this case, validating the parent form will automatically validate all the other forms inside it.
161161

162-
Nested forms directly inherit their parent's state, so you dont need to define a separate state for them. You can use the `name` prop to target a nested attribute within the parent's state.
162+
Nested forms directly inherit their parent's state, so you don't need to define a separate state for them. You can use the `name` prop to target a nested attribute within the parent's state.
163163

164164
It can be used to dynamically add fields based on user's input:
165165

6.66 KB
Loading
6.63 KB
Loading

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@
106106
"lint": "eslint .",
107107
"lint:fix": "eslint . --fix",
108108
"typecheck": "vue-tsc --noEmit && nuxt typecheck playgrounds/nuxt && nuxt typecheck docs && cd playgrounds/vue && vue-tsc --noEmit",
109-
"test": "vitest",
110-
"test:vue": "vitest -c vitest.vue.config.ts",
109+
"test": "TZ=UTC vitest",
110+
"test:vue": "TZ=UTC vitest -c vitest.vue.config.ts",
111111
"release": "release-it"
112112
},
113113
"dependencies": {

playgrounds/nuxt/app/composables/useNavigation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const components = [
2727
'context-menu',
2828
'drawer',
2929
'dropdown-menu',
30+
'empty',
3031
'error',
3132
'field-group',
3233
'file-upload',
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script setup lang="ts">
2+
import theme from '#build/ui/empty'
3+
4+
const variants = Object.keys(theme.variants.variant)
5+
const sizes = Object.keys(theme.variants.size)
6+
7+
const attrs = reactive({
8+
variant: [theme.defaultVariants.variant],
9+
size: [theme.defaultVariants.size]
10+
})
11+
</script>
12+
13+
<template>
14+
<Navbar>
15+
<USelect v-model="attrs.variant" :items="variants" multiple placeholder="Variant" />
16+
<USelect v-model="attrs.size" :items="sizes" multiple placeholder="Size" />
17+
</Navbar>
18+
19+
<Matrix v-slot="props" :attrs="attrs">
20+
<UEmpty
21+
icon="i-lucide-file"
22+
title="No projects found"
23+
description="It looks like you haven't added any projects. Create one to get started."
24+
:actions="[{
25+
icon: 'i-lucide-plus',
26+
label: 'Create new'
27+
}, {
28+
icon: 'i-lucide-refresh-ccw',
29+
label: 'Refresh',
30+
color: 'neutral',
31+
variant: 'subtle'
32+
}]"
33+
v-bind="props"
34+
/>
35+
</Matrix>
36+
</template>

0 commit comments

Comments
 (0)