Tutorials
Vue tutorial
Vue 3 single-file components with typed props, defineModel two-way binding, and v-bind="$attrs" pass-through.
What you'll build
A small contact form — labelled input, submit button, v-model binding, real keyboard and screen-reader behaviour — first bare, then
styled, in about 10 minutes.
Before you start
You need git, Node 22 or later, and pnpm 10 or later. Any Vue 3 project works — Nuxt, Vite, or plain Vue.
Step 1 — Get the code
git clone https://github.com/LilyDesignSystem/lily-design-system-vue-headless
cd lily-design-system-vue-headless
pnpm install
pnpm test # vitest + @testing-library/vue
pnpm run storybook # browse all 490 components Components are flat files in components/ — Button.vue, TextInput.vue — each with its test,
story, and docs alongside. Copy the files you need, or vendor the repo.
Step 2 — Your first component
<script setup>
import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>
<template>
<Button @click="save">Save</Button>
</template> Renders <button class="button" type="button">. Props
mirror the other frameworks: type, disabled, pressed, label, plus attribute fall-through for
everything else.
Step 3 — Compose a small form
<script setup>
import { ref } from "vue";
import Form from ".../components/Form.vue";
import Field from ".../components/Field.vue";
import Label from ".../components/Label.vue";
import TextInput from ".../components/TextInput.vue";
import Button from ".../components/Button.vue";
const name = ref("");
</script>
<template>
<Form @submit="handleSubmit">
<Field>
<Label for="name">Full name</Label>
<TextInput id="name" label="Full name" v-model="name" required />
</Field>
<Button type="submit">Save</Button>
</Form>
</template> TextInput uses defineModel, so plain v-model works out of the box.
Check your work: run the app and the form looks plain — exactly as intended: styling is still ahead. Press Tab: focus moves through every control, the label is announced, and submit works. The behaviour is done; the look is yours, and it's next.
Step 4 — Style it
Style the class hooks — .button, .text-input, .label, .field — in your stylesheet, or link a
ready-made theme in index.html / nuxt.config:
<link rel="stylesheet" href="/themes/nord.css" /> Step 5 — See it all working
The Nuxt example app is the full catalog styled and demoed, with Playwright e2e and an axe-core baseline:
git clone https://github.com/LilyDesignSystem/lily-design-system-vue-nuxt-examples
cd lily-design-system-vue-nuxt-examples
pnpm install && pnpm run dev Next steps
- Theming — runtime switching with the Vue theme-select helper.
- Preference helpers — language and text size.
- Component catalog — props, ARIA, and keyboard per component.
Questions along the way? The help page is full of answers — and if a step could be clearer, tell us and we'll gladly improve the tutorial.