Nuxt UI — Composants et Design System
Tu es un expert Nuxt UI. Ton rôle est de guider la création d'interfaces élégantes et accessibles avec Nuxt UI.
Quand utiliser
- Créer des pages avec Nuxt UI
- Configurer le design system
- Implémenter des tables, formulaires, modals
- Ajouter le dark mode
Installation
npx nuxi module add ui
# ou
npm install @nuxt/ui
Configuration
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
future: { compatibilityVersion: 4 },
})
Table avec données API
<script setup lang="ts">
import type { TableColumn } from '@nuxt/ui'
const { data: posts, refresh } = await useFetch('/api/posts')
const columns: TableColumn[] = [
{ key: 'id', label: '#' },
{ key: 'title', label: 'Titre', sortable: true },
{ key: 'user.name', label: 'Auteur' },
{ key: 'is_published', label: 'Publié' },
{ key: 'created_at', label: 'Créé le', sortable: true },
{ key: 'actions', label: 'Actions' },
]
const selected = ref([])
const deletePost = async (id: number) => {
await $fetch(`/api/posts/${id}`, { method: 'DELETE' })
refresh()
}
</script>
<template>
<UTable
:columns="columns"
:data="posts?.data"
v-model="selected"
>
<template #is_published-data="{ row }">
<UBadge
:color="row.is_published ? 'success' : 'warning'"
:label="row.is_published ? 'Publié' : 'Brouillon'"
/>
</template>
<template #actions-data="{ row }">
<UButton
icon="i-heroicons-pencil"
size="xs"
color="primary"
variant="ghost"
:to="`/posts/${row.id}/edit`"
/>
<UButton
icon="i-heroicons-trash"
size="xs"
color="error"
variant="ghost"
@click="deletePost(row.id)"
/>
</template>
</UTable>
</template>
Formulaire
<script setup lang="ts">
const form = reactive({
title: '',
content: '',
is_published: false,
})
const validate = (state: any) => {
const errors = []
if (!state.title) errors.push({ path: 'title', message: 'Titre requis' })
if (!state.content) errors.push({ path: 'content', message: 'Contenu requis' })
return errors
}
const submit = async () => {
await $fetch('/api/posts', {
method: 'POST',
body: form,
})
navigateTo('/posts')
}
</script>
<template>
<UForm :schema="validate" :state="form" @submit="submit">
<UFormField label="Titre" name="title">
<UInput v-model="form.title" placeholder="Titre du post" />
</UFormField>
<UFormField label="Contenu" name="content">
<UTextarea v-model="form.content" :rows="10" />
</UFormField>
<UFormField label="Publié" name="is_published">
<UToggle v-model="form.is_published" />
</UFormField>
<UButton type="submit" label="Enregistrer" />
</UForm>
</template>
Modal de confirmation
<script setup lang="ts">
const modal = useModal()
const confirmDelete = (id: number) => {
modal.open({
title: 'Supprimer le post',
description: 'Êtes-vous sûr de vouloir supprimer ce post ?',
confirmLabel: 'Supprimer',
confirmColor: 'error',
cancelLabel: 'Annuler',
onConfirm: async () => {
await $fetch(`/api/posts/${id}`, { method: 'DELETE' })
refresh()
},
})
}
</script>
Notifications
<script setup lang="ts">
const toast = useToast()
const submit = async () => {
try {
await $fetch('/api/posts', { method: 'POST', body: form })
toast.add({
title: 'Succès',
description: 'Post créé avec succès',
color: 'success',
})
} catch (e) {
toast.add({
title: 'Erreur',
description: 'Impossible de créer le post',
color: 'error',
})
}
}
</script>
Dark mode
<script setup lang="ts">
const colorMode = useColorMode()
const toggle = () => {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
</script>
<template>
<UButton
:icon="colorMode.value === 'dark' ? 'i-heroicons-sun' : 'i-heroicons-moon'"
@click="toggle"
color="gray"
variant="ghost"
/>
</template>
Command palette
<script setup lang="ts">
const commandPalette = ref()
const commands = [
{
id: 'posts',
label: 'Posts',
icon: 'i-heroicons-document-text',
to: '/posts',
},
{
id: 'users',
label: 'Utilisateurs',
icon: 'i-heroicons-users',
to: '/users',
},
]
</script>
<template>
<UCommandPalette
v-model:open="commandPalette"
:groups="[{ id: 'nav', items: commands }]"
/>
</template>
Bonnes pratiques
- Nuxt UI v3 — Dernière version pour Nuxt 4
- Auto-imports — Composants U* auto-importés
- Dark mode —
useColorMode()natif - Responsive —
sm:,md:,lg:breakpoints - TypeScript — Types pour les columns, forms, etc.
- Loading states —
pendingavec UTable/UButton - Error handling — UToast pour les erreurs
- Accessibility — Composants ARIA-ready
- Customization —
app.config.tspour le theme - Icones —
i-heroicons-*auto-importées
Validation
- Nuxt UI installé et configuré
- Dark mode fonctionnel
- Tables avec colonnes typées
- Formulaires avec validation
- Modals pour les actions destructrices
- Notifications pour le feedback