Components
Small building blocks. Everything else you see in this playground ( Button , Card , Badge , Avatar …) is Nuxt UI , registered without the U prefix.
Source in the kit: components/Loader.vue · Empty.vue · Image.vue · Log/
Loader and Empty
examples/components/LoaderEmpty.vue<template>
<div class="space-y-4">
<div class="flex gap-2">
<Button
label="Loading"
size="sm"
:variant="state === 'loading' ? 'solid' : 'outline'"
@click="state = 'loading'"
/>
<Button
label="Empty"
size="sm"
:variant="state === 'empty' ? 'solid' : 'outline'"
@click="state = 'empty'"
/>
<Button
label="Data"
size="sm"
:variant="state === 'data' ? 'solid' : 'outline'"
@click="state = 'data'"
/>
</div>
<div class="min-h-40 rounded-lg border border-gray-200 p-4">
<!-- Loader shows a spinner while `loading`, then its default slot -->
<Loader :loading="state === 'loading'">
<!-- Empty's text comes from core.messages.common.empty; `message` and `icon` override it -->
<Empty
v-if="state === 'empty'"
message="No invoices yet"
icon="ph:receipt"
/>
<p v-else>3 invoices</p>
</Loader>
</div>
</div>
</template>
<script lang="ts" setup>
const state = ref<'loading' | 'empty' | 'data'>('loading')
</script>Image
examples/components/ImageStates.vue<template>
<div class="grid grid-cols-2 gap-4 md:grid-cols-3">
<figure>
<Image
src="https://placehold.co/320x200/png"
class="h-32 w-full rounded-lg object-cover"
/>
<figcaption class="mt-1 text-xs text-gray-500">Loads: spinner first, then the picture</figcaption>
</figure>
<figure>
<div class="h-32 w-full rounded-lg bg-gray-50">
<Image src="https://example.invalid/missing.png" />
</div>
<figcaption class="mt-1 text-xs text-gray-500">Fails: error icon instead of a broken image</figcaption>
</figure>
<figure>
<div class="h-32 w-full rounded-lg bg-gray-50">
<Image src="https://example.invalid/missing.png">
<template #error>
<div class="flex h-full items-center justify-center text-sm text-gray-400">No photo</div>
</template>
</Image>
</div>
<figcaption class="mt-1 text-xs text-gray-500">#error and #loading slots replace the defaults</figcaption>
</figure>
</div>
</template>Log: inspect values while developing
examples/components/LogDebug.vue Type above, then open the floating DevTools panel in the corner. Log is wrapped in DevOnly , so it is safe to leave in a page: production renders nothing.
<template>
<div class="space-y-3">
<FormFields :options="fields" />
<!-- Renders nothing here: in development the values appear in the DevTools window (bottom right) -->
<Log
title="Example form"
:data="form.values"
/>
<p class="text-sm text-gray-500">
Type above, then open the floating DevTools panel in the corner.
<code>Log</code>
is wrapped in
<code>DevOnly</code>
, so it is safe to leave in a page: production renders nothing.
</p>
</div>
</template>
<script lang="ts" setup>
const form = useForm({
initialValues: {
note: '',
},
})
const fields = createFormFields(() => [
{
type: INPUT_TYPES.TEXT,
props: {
name: 'note',
label: 'Note',
},
},
])
</script>