docs(deps): update @nuxt/content and move content/ outside of app/

This commit is contained in:
Benjamin Canac
2024-06-20 10:39:10 +02:00
parent 11ef256db7
commit 0b8bfa887b
52 changed files with 61 additions and 89 deletions

View File

@@ -0,0 +1,266 @@
---
title: Installation
description: 'Learn how to install and configure Nuxt UI in your application.'
---
## Setup
1. Install `@nuxt/ui` dependency to your project:
::code-group
```bash [pnpm]
pnpm add @nuxt/ui
```
```bash [yarn]
yarn add @nuxt/ui
```
```bash [npm]
npm install @nuxt/ui
```
```bash [bun]
bun add @nuxt/ui
```
::
2. Add it to your `modules` section in your `nuxt.config`:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxt/ui']
})
```
That's it! You can now use all the components and composables in your Nuxt app ✨
## Modules
Nuxt UI will automatically install the [@nuxtjs/tailwindcss](https://tailwindcss.nuxtjs.org/), [@nuxtjs/color-mode](https://color-mode.nuxtjs.org/) and [nuxt-icon](https://github.com/nuxt-modules/icon) modules for you.
::callout{icon="i-heroicons-exclamation-triangle"}
You should remove them from your `modules` and `dependencies` if you've previously installed them.
::
### `@nuxtjs/tailwindcss`
This module is pre-configured and will automatically load the following plugins:
- [@tailwindcss/forms](https://github.com/tailwindlabs/tailwindcss-forms)
- [@tailwindcss/typography](https://github.com/tailwindlabs/tailwindcss-typography)
- [@tailwindcss/aspect-ratio](https://github.com/tailwindlabs/tailwindcss-aspect-ratio)
- [@tailwindcss/container-queries](https://github.com/tailwindlabs/tailwindcss-container-queries)
- [@headlessui/tailwindcss](https://github.com/tailwindlabs/headlessui/tree/main/packages/%40headlessui-vue)
Note that the `@tailwindcss/aspect-ratio` plugin disables the default aspect ratio utilities:
- `aspect-auto`
- `aspect-square`
- `aspect-video`
You can re-enable them by adding the following to your `tailwind.config.ts`:
```ts [tailwind.config.ts]
import type { Config } from 'tailwindcss'
export default <Partial<Config>>{
theme: {
extend: {
aspectRatio: {
auto: 'auto',
square: '1 / 1',
video: '16 / 9'
}
}
}
}
```
### `@nuxtjs/color-mode`
This module is installed to provide dark mode support out of the box thanks to the Tailwind CSS dark mode `class` strategy.
::callout{icon="i-heroicons-light-bulb"}
You can read more about this in the [Theming](/getting-started/theming#dark-mode) section.
::
### `nuxt-icon`
This module is installed when using the `dynamic` prop on the `Icon` component or globally through the `ui.icons.dynamic` option in your `app.config.ts`.
::callout{icon="i-heroicons-light-bulb"}
You can read more about this in the [Theming](/getting-started/theming#dynamic-icons) section and on the [Icon](/components/icon) component page.
::
## TypeScript
This module is written in TypeScript and provides typings for all the components and composables. You can look at the [source code](https://github.com/nuxt/ui/tree/dev/src/runtime/types) to see all the available types.
::callout{icon="i-heroicons-light-bulb" to="https://nuxt.com/docs/guide/concepts/typescript" target="_blank"}
You can read more about TypeScript on the official Nuxt documentation.
::
You can use those types in your own components by importing them from `#ui/types`, for example when defining wrapper components:
```vue
<template>
<UBreadcrumb :links="links">
<template #icon="{ link }">
<UIcon :name="link.icon" />
</template>
</UBreadcrumb>
</template>
<script setup lang="ts">
import type { BreadcrumbLink } from '#ui/types'
export interface Props {
links: BreadcrumbLink[]
}
defineProps<Props>()
</script>
```
You don't have to use TypeScript yourself, but doing so will give you access to prop validation and autocomplete.
We've managed to provide dynamic typings on props such as `color`, `size`, `variant`, etc. based on your custom config. For example, you'll be suggested the `custom` color and the `subtle` variant when using the `Button` component with an `app.config.ts` as such:
```ts [app.config.ts]
export default defineAppConfig({
ui: {
button: {
color: {
custom: {
subtle: '...'
}
}
}
}
})
```
::callout{icon="i-heroicons-light-bulb"}
You can read more about components configuration in the [Theming](/getting-started/theming#appconfigts) section.
::
## IntelliSense
If you're using VSCode, you can install the [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) extension to get autocompletion for the classes.
You can read more on how to set it up on the [@nuxtjs/tailwindcss](https://tailwindcss.nuxtjs.org/tailwind/editor-support) module documentation, but to summarize, you'll need to add the following to your `.vscode/settings.json`:
```json [.vscode/settings.json]
{
"files.associations": {
"*.css": "tailwindcss"
},
"editor.quickSuggestions": {
"strings": true
}
}
```
You can write your `tailwind.config` in TypeScript as such:
```ts [tailwind.config.ts]
import type { Config } from 'tailwindcss'
export default <Partial<Config>> {
content: [
'docs/content/**/*.md'
]
}
```
If you do so, you'll need to add the following to your `.vscode/settings.json`:
```json [.vscode/settings.json]
{
"tailwindCSS.experimental.configFile": "tailwind.config.ts"
}
```
Note, the extension won't work when writing classes in your `app.config.ts` by default.
Also, you might want IntelliSense on objects in your SFC by prefixing with `/*ui*/`.
To enable these two features, you can add the following to your `.vscode/settings.json`:
```json [.vscode/settings.json]
{
"tailwindCSS.experimental.classRegex": [
["ui:\\s*{([^)]*)\\s*}", "[\"'`]([^\"'`]*).*?[\"'`]"],
["/\\*\\s?ui\\s?\\*/\\s*{([^;]*)}", ":\\s*[\"'`]([^\"'`]*).*?[\"'`]"]
]
}
```
An example SFC using IntelliSense (note the `/*ui*/` prefix, also works with `ref()`):
```vue [example.vue]
<template>
<UCard :ui="ui" />
</template>
<script setup lang="ts">
const ui = /* ui */ {
background: 'bg-white dark:bg-slate-900'
}
</script>
```
You can also add the following to your `.vscode/settings.json` to enable IntelliSense when using the `ui` prop:
```json [.vscode/settings.json]
{
"tailwindCSS.classAttributes": [
"class",
"className",
"ngClass",
"ui"
]
}
```
## Options
| Key | Default | Description |
|-----------------------|-----------------|-------------------------------------------------------------------------------------------------------------|
| `prefix` | `u` | Define the prefix of the imported components. |
| `global` | `false` | Expose components globally. |
| `icons` | `['heroicons']` | Icon collections to load. |
| `safelistColors` | `['primary']` | Force safelisting of colors to need be purged. |
| `disableGlobalStyles` | `false` | Disable [global CSS styles](https://github.com/nuxt/ui/blob/dev/src/runtime/ui.css) injected by the module. |
Configure options in your `nuxt.config.ts` as such:
```ts [nuxt.config.ts]
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
ui: {
global: true,
icons: ['mdi', 'simple-icons']
}
})
```
## Edge
To use the latest updates pushed on the [`dev`](https://github.com/nuxt/ui/tree/dev) branch, you can use `@nuxt/ui-edge`.
Update your `package.json` to the following:
```diff [package.json]
{
"devDependencies": {
- "@nuxt/ui": "^2.11.0"
+ "@nuxt/ui": "npm:@nuxt/ui-edge@latest"
}
}
```
Then run `pnpm install`, `yarn install` or `npm install`.

View File

@@ -0,0 +1,184 @@
---
description: 'Learn how to customize the look and feel of the components.'
---
This module relies on Nuxt [App Config](https://nuxt.com/docs/guide/directory-structure/app-config#app-config-file) file to customize the look and feel of the components at runtime with HMR (hot-module-replacement).
## Colors
### Configuration
Components are based on a `primary` and a `gray` color. You can change them in your `app.config.ts`.
```ts [app.config.ts]
export default defineAppConfig({
ui: {
primary: 'green',
gray: 'cool'
}
})
```
::callout{icon="i-heroicons-light-bulb"}
Try to change the `primary` and `gray` colors by clicking on the :u-icon{name="i-heroicons-swatch-20-solid" class="w-4 h-4 align-middle text-primary-500 dark:text-primary-400"} button in the header.
::
As this module uses Tailwind CSS under the hood, you can use any of the [Tailwind CSS colors](https://tailwindcss.com/docs/customizing-colors#color-palette-reference) or your own custom colors. By default, the `primary` color is `green` and the `gray` color is `cool`.
When [using custom colors](https://tailwindcss.com/docs/customizing-colors#using-custom-colors) or [adding additional colors](https://tailwindcss.com/docs/customizing-colors#adding-additional-colors) through the `extend` key in your `tailwind.config.ts`, you'll need to make sure to define all the shades from `50` to `950` as most of them are used in the components config defined in [`ui.config/`](https://github.com/nuxt/ui/tree/dev/src/runtime/ui.config) directory. You can [generate your colors](https://tailwindcss.com/docs/customizing-colors#generating-colors) using tools such as https://uicolors.app/ for example.
```ts [tailwind.config.ts]
import type { Config } from 'tailwindcss'
import defaultTheme from 'tailwindcss/defaultTheme'
export default <Partial<Config>>{
theme: {
extend: {
colors: {
green: {
50: '#EFFDF5',
100: '#D9FBE8',
200: '#B3F5D1',
300: '#75EDAE',
400: '#00DC82',
500: '#00C16A',
600: '#00A155',
700: '#007F45',
800: '#016538',
900: '#0A5331',
950: '#052e16'
}
}
}
}
}
```
### CSS Variables
To provide dynamic colors that can be changed at runtime, this module uses CSS variables. As Tailwind CSS already has a `gray` color, the module automatically renames it to `cool` to avoid conflicts (`coolGray` was renamed to `gray` when Tailwind CSS v3.0 was released).
Likewise, you can't define a `primary` color in your `tailwind.config.ts` as it would conflict with the `primary` color defined by the module.
::callout{icon="i-heroicons-light-bulb"}
We'd advise you to use those colors in your components and pages, e.g. `text-primary-500 dark:text-primary-400`, `bg-gray-100 dark:bg-gray-900`, etc. so your app automatically adapts when changing your `app.config.ts`.
::
The `primary` color also has a `DEFAULT` shade that changes based on the theme. It is `500` in light mode and `400` in dark mode. You can use as a shortcut in your components and pages, e.g. `text-primary`, `bg-primary`, `focus-visible:ring-primary`, etc.
## Components
### `app.config.ts`
You can find the config of each component in the [`ui.config/`](https://github.com/nuxt/ui/tree/dev/src/runtime/ui.config) directory. You can override those classes in your own `app.config.ts`.
```ts [app.config.ts]
export default defineAppConfig({
ui: {
container: {
constrained: 'max-w-5xl'
}
}
})
```
Thanks to [tailwind-merge](https://github.com/dcastil/tailwind-merge), the `app.config.ts` is smartly merged with the default config. This means you don't have to rewrite everything.
You can change this behavior by setting `strategy` to `override` in your `app.config.ts`:
```ts [app.config.ts]
export default defineAppConfig({
ui: {
strategy: 'override',
button: {
color: {
white: {
solid: 'bg-white dark:bg-gray-900'
}
}
}
}
})
```
### `ui` prop
Each component has a `ui` prop that allows you to customize everything specifically.
```vue
<template>
<UContainer :ui="{ constrained: 'max-w-2xl' }">
<slot />
</UContainer>
</template>
```
::callout{icon="i-heroicons-light-bulb"}
You can find the default classes for each component under the `Config` section.
::
Thanks to [tailwind-merge](https://github.com/dcastil/tailwind-merge), the `ui` prop is smartly merged with the config. This means you don't have to rewrite everything.
For example, the default preset of the `FormGroup` component looks like this:
```json
{
"label": {
"base": "block font-medium text-gray-700 dark:text-gray-200"
}
}
```
To change the font of the `label`, you only need to write:
```vue
<UFormGroup name="email" label="Email" :ui="{ label: { base: 'font-semibold' } }" />
```
This will smartly replace the `font-medium` by `font-semibold` and prevent any class duplication and any class priority issue.
You can change this behavior by setting `strategy` to `override` inside the `ui` prop:
```vue
<UButton
to="https://github.com/nuxt/ui"
:ui="{
strategy: 'override',
color: {
white: {
solid: 'bg-white dark:bg-gray-900'
}
}
}"
/>
```
### `class` attribute
You can also use the `class` attribute to add classes to the component.
```vue
<template>
<UButton label="Button" class="rounded-full" />
</template>
```
Again, with [tailwind-merge](https://github.com/dcastil/tailwind-merge), this will smartly merge the classes with the `ui` prop and the config.
### Default values
Some component props like `size`, `color`, `variant`, etc. have a default value that you can override in your `app.config.ts`.
```ts [app.config.ts]
export default defineAppConfig({
ui: {
button: {
default: {
size: 'md',
color: 'gray',
variant: 'ghost'
}
}
}
})
```

View File

@@ -0,0 +1,195 @@
---
description: ''
---
You can use any icon (100,000+) from [Iconify](https://iconify.design/).
Some components have an `icon` prop that allows you to add an icon to the component.
```vue
<template>
<UButton icon="i-heroicons-magnifying-glass" />
</template>
```
You can also use the [Icon](/components/icon) component to add an icon anywhere in your app by following this pattern: `i-{collection_name}-{icon_name}`.
```vue
<template>
<UIcon name="i-heroicons-moon" />
</template>
```
### Collections
By default, the module uses [Heroicons](https://heroicons.com/) but you can change it from the module options in your `nuxt.config.ts`.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
ui: {
icons: ['mdi', 'simple-icons']
}
})
```
::callout{icon="i-heroicons-light-bulb"}
Search the icon you want to use on https://icones.js.org built by [@antfu](https://github.com/antfu).
::
Thanks to [@egoist/tailwindcss-icons](https://github.com/egoist/tailwindcss-icons) plugin, only the icons you use in your app will be bundled in your CSS. However, you need to install the icon collections you specified in the `ui.icons` key:
::code-group
```bash [pnpm]
pnpm i @iconify-json/{collection_name}
```
```bash [yarn]
yarn add @iconify-json/{collection_name}
```
```bash [npm]
npm install @iconify-json/{collection_name}
```
::
If you choose to use the full `@iconify/json` icon collection (50MB), you can specifiy `icons: 'all'` or `icons: {}` in your `nuxt.config.ts` to use any icon in your app.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
ui: {
icons: {}
}
})
```
### Custom config
If you have specific needs, like using a custom icon collection, you can use the `icons` option in your `nuxt.config.ts` as an object to override the config of the [@egoist/tailwindcss-icons](https://github.com/egoist/tailwindcss-icons#plugin-options) plugin.
```ts [nuxt.config.ts]
import { getIconCollections } from '@egoist/tailwindcss-icons'
export default defineNuxtConfig({
ui: {
icons: {
// might solve stretch bug on generate, see https://github.com/egoist/tailwindcss-icons/issues/23
extraProperties: {
'mask-size': 'contain',
'mask-position': 'center'
},
collections: {
foo: {
icons: {
'arrow-left': {
// svg body
body: '<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18" />',
// svg width and height, optional
width: 24,
height: 24
}
}
},
...getIconCollections(['heroicons', 'simple-icons'])
}
}
}
})
```
### Dynamic icons
The `Icon` component also has a `dynamic` prop to use the [nuxt-icon](https://github.com/nuxt-modules/icon/) module instead of the [@egoist/tailwindcss-icons](https://github.com/egoist/tailwindcss-icons#plugin-options) plugin.
Read more about this in the [Icon](/components/icon#dynamic) component page.
### Defaults
You can easily replace all the default icons of the components in your `app.config.ts`.
```ts [app.config.ts]
export default defineAppConfig({
ui: {
button: {
default: {
loadingIcon: 'i-octicon-sync-24'
}
},
input: {
default: {
loadingIcon: 'i-octicon-sync-24'
}
},
select: {
default: {
loadingIcon: 'i-octicon-sync-24',
trailingIcon: 'i-octicon-chevron-down-24'
}
},
selectMenu: {
default: {
selectedIcon: 'i-octicon-check-24'
}
},
notification: {
default: {
closeButton: {
icon: 'i-octicon-x-24'
}
}
},
commandPalette: {
default: {
icon: 'i-octicon-search-24',
loadingIcon: 'i-octicon-sync-24',
selectedIcon: 'i-octicon-check-24',
emptyState: {
icon: 'i-octicon-search-24'
}
}
},
table: {
default: {
sortAscIcon: 'i-octicon-sort-asc-24',
sortDescIcon: 'i-octicon-sort-desc-24',
sortButton: {
icon: 'i-octicon-arrow-switch-24'
},
loadingState: {
icon: 'i-octicon-sync-24'
},
emptyState: {
icon: 'i-octicon-database-24'
}
}
},
pagination: {
default: {
firstButton: {
icon: 'i-octicon-chevron-left-24'
},
prevButton: {
icon: 'i-octicon-arrow-left-24'
},
nextButton: {
icon: 'i-octicon-arrow-right-24'
},
lastButton: {
icon: 'i-octicon-chevron-right-24'
}
}
},
accordion: {
default: {
openIcon: 'i-octicon-chevron-down-24'
}
},
breadcrumb: {
default: {
divider: 'i-octicon-chevron-right-24'
}
}
}
})
```

View File

@@ -0,0 +1,58 @@
---
title: 'Dark mode'
description: ''
---
All the components are styled with dark mode in mind.
Thanks to [Tailwind CSS dark mode](https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually) class strategy and the [@nuxtjs/color-mode](https://github.com/nuxt-modules/color-mode) module, you literally have nothing to do.
You can disable dark mode by setting the `preference` to `light` instead of `system` in your `nuxt.config.ts`.
```ts [nuxt.config.ts]
export default defineNuxtConfig({
colorMode: {
preference: 'light'
}
})
```
::callout{icon="i-heroicons-light-bulb"}
If you're stuck in dark mode even after changing this setting, you might need to remove the `nuxt-color-mode` entry from your browser's local storage.
::
You can easily build a color mode button by using the `useColorMode` composable from `@nuxtjs/color-mode`.
::component-example
#default
:color-mode-button
#code
```vue
<script setup lang="ts">
const colorMode = useColorMode()
const isDark = computed({
get () {
return colorMode.value === 'dark'
},
set () {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
</script>
<template>
<ClientOnly>
<UButton
:icon="isDark ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
color="gray"
variant="ghost"
aria-label="Theme"
@click="isDark = !isDark"
/>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>
</template>
```
::

View File

@@ -0,0 +1,141 @@
---
description: 'Learn how to display and define keyboard shortcuts in your app.'
---
Some components like [Dropdown](/components/dropdown), [Command Palette](/components/command-palette) and [Tooltip](/components/tooltip) support the display of keyboard shortcuts.
```vue
<UDropdown :items="[[{ label: 'Edit', shortcuts: ['E'] }]]" />
```
Shortcuts are displayed and styled through the [Kbd](/components/kbd) component.
```vue
<template>
<div class="flex items-center gap-0.5">
<UKbd></UKbd>
<UKbd>K</UKbd>
</div>
</template>
```
::callout{icon="i-heroicons-light-bulb"}
You will have a preview of how shortcuts are rendered in each component page.
::
## `defineShortcuts`
This module provides a `defineShortcuts` composable that allows you to define keyboard shortcuts in your app really easily.
```vue
<template>
<UModal v-model="isOpen" />
</template>
<script setup lang="ts">
const isOpen = ref(false)
defineShortcuts({
meta_k: {
usingInput: true,
handler: () => {
isOpen.value = !isOpen.value
}
}
})
</script>
```
Shortcuts keys are written as the literal keyboard key value. Combinations are made with `_` separator. Chained shortcuts are made with `-` separator.
Modifiers are also available:
- `meta`: acts as `Command` for MacOS and `Control` for others
- `ctrl`: acts as `Control`
- `shift`: acts as `Shift` and is only necessary for alphabetic keys
Examples of keys:
- `escape`: will trigger by hitting `Esc`
- `meta_k`: will trigger by hitting `⌘` and `K` at the same time on MacOS, and `Ctrl` and `K` on Windows and Linux
- `ctrl_k`: will trigger by hitting `Ctrl` and `K` at the same time on MacOS, Windows and Linux
- `shift_e`: will trigger by hitting `Shift` and `E` at the same time on MacOS, Windows and Linux
- `?`: will trigger by hitting `?` on some keyboard layouts, or for example `Shift` and `/`, which results in `?` on US Mac keyboards
- `g-d`: will trigger by hitting `g` then `d` with a maximum delay of 800ms by default
- `arrowleft`: will trigger by hitting `←` (also: `arrowright`, `arrowup`, `arrowdown`)
::callout{icon="i-heroicons-light-bulb"}
For a complete list of available shortcut keys, refer to the [`KeyboardEvent`](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values) API docs. Note the `KeyboardEvent.key` has to be written in lowercase.
::
### `usingInput`
Prop: `usingInput?: string | boolean`
By default, `usingInput` is `false`, meaning it will only trigger when no input is focused. When set to `true`, the shortcut will also trigger when any input is focused.
For a more advanced behavior, `usingInput` can be set to the name of an input, so it only triggers when focusing this specific input.
```vue
<template>
<UInput v-model="query" name="queryInput" />
</template>
<script setup lang="ts">
const query = ref('')
defineShortcuts({
enter: {
usingInput: 'queryInput',
handler: () => {
// TODO
}
}
})
</script>
```
_`enter` shortcut will only trigger when `queryInput` is focused._
### `whenever`
Prop: `whenever?: WatchSource<boolean>[]`
`whenever` allows to add constraints on the shortcut triggering behavior. This array can contain `Ref<boolean>`, `ComputedRef<boolean>` or `() => boolean`.
```ts
defineShortcuts({
meta_k: {
usingInput: true,
handler: () => { isOpen.value = !isOpen.value }
},
escape: {
usingInput: true,
whenever: [isOpen],
handler: () => { isOpen.value = false }
}
})
```
_`escape` shortcut will only trigger when `isOpen` is `true`._
### Simple shortcut
In case the shortcut does not need any config, it can be written as a function.
```ts
defineShortcuts({
'?': () => openHelpModal()
})
```
## `useShortcuts`
To display shortcuts in your app according to the user's OS, you can use the `useShortcuts` composable.
```vue
<script setup lang="ts">
const { metaSymbol } = useShortcuts()
</script>
<template>
<UKbd>{{ metaSymbol }}</UKbd>
</template>
```
_`metaSymbol` will display either `⌘` on MacOS or `Ctrl` on any other OS_

View File

@@ -0,0 +1,178 @@
---
title: Contributing
description: Learn how to contribute to Nuxt UI.
navigation: false
---
Nuxt UI thrives thanks to its fantastic community ❤️, which contributes by submitting issues, creating pull requests, and offering valuable feedback.
Before reporting a bug or reporting a feature, please make sure that you have read through our documentation and existing [issues](https://github.com/nuxt/ui/issues).
## Submitting a Pull Request (PR)
### 1. Before You Start
Check if there's an existing issue describing the problem or feature request you're working on. If there is, please leave a comment on the issue to let us know you're working on it.
If there isn't, open a new issue to discuss the problem or feature.
### 2. Local Development Setup
To begin local development, follow these steps:
1. Clone the `nuxt/ui` repository to your local machine:
```sh
git clone https://github.com/nuxt/ui.git
```
2. Enable [Corepack](https://github.com/nodejs/corepack):
```sh
corepack enable
```
3. Install dependencies:
```sh
pnpm install
```
4. Generate type stubs:
```sh
pnpm run dev:prepare
```
5. Configure your local development environment:
- To work on the **documentation** located in the `docs` folder, run:
```sh
pnpm run dev
```
- To test the components using **playground**, run:
```sh
pnpm run play
```
#### IDE Setup
We recommend using VS Code along with the ESLint extension. You can enable auto-fix and formatting when saving your code. Here's how:
```json
{
"editor.codeActionsOnSave": {
"source.fixAll": false,
"source.fixAll.eslint": true
}
}
```
You can also use the `lint` command:
```sh
pnpm run lint # check for linting errors
pnpm run lint:fix # fix linting errors
```
#### No Prettier
Since ESLint is already configured to format the code, there's no need for duplicating functionality with Prettier.
If you have Prettier installed in your editor, we recommend disabling it to avoid conflicts.
#### Type Checking
We use TypeScript for type checking. You can use the `typecheck` command to check for type errors:
```sh
pnpm run typecheck
```
### 3. Commit Conventions
We use [Conventional Commits](https://www.conventionalcommits.org/) for commit messages, which allows a changelog to be auto-generated based on the commits. Please read the [guide](https://www.conventionalcommits.org/en/v1.0.0/#summary) through if you aren't familiar with it already.
#### Note
- `fix` and `feat` are for actual code changes (that might affect logic). For typo or document changes, use `docs` or `chore` instead:
~~`fix: typo`~~ -> `docs: fix typo`
- If you are working on a specific component, ensure that you specify the main scope of your commit in brackets. e.g.
```
feat(Alert): new component
chore(Table): improve accessibility
```
### 4. Making a Pull Request
- Follow along the [instructions](https://github.com/nuxt/ui/blob/main/.github/PULL_REQUEST_TEMPLATE.md?plain=1) provided when creating a PR
- Ensure your PR's title adheres to the [Conventional Commits](https://www.conventionalcommits.org/) since it will be used once the code is merged.
- Multiple commits are fine; no need to rebase or force push. We'll use `Squash and Merge` when merging.
- Ensure linting and make tests manually before submitting the PR. Avoid making unrelated changes.
### 5. After You've Made a Pull Request
We'll review it promptly. If assigned to a maintainer, they'll review it carefully. Ignore the red text; it's for tracking purposes.
## Project Structure
In this project, you'll find a variety of folders and files that serve different purposes. Here's an overview of the main ones:
- **Documentation - `docs`** :
The documentation is located in the `docs` folder. It's a Nuxt app that uses the `@nuxt/content` module to generate the documentation pages from Markdown files. Here's a breakdown of its structure:
```
docs/
├── components/
│ ├── examples/ # Components used in documentation as examples
│ └── themes/ # Components used in the examples page in the theming section
├── content/ # Documentation, separated into categories according to component types
│ ├── 1.getting-started/
│ │ ├── 1.index.md
│ │ ├── 2.installation.md
│ │ ├── ... etc
│ ├── 2.elements/ # The category of components, which are elements
│ │ ├── 1.accordion.md # Docs for a single component (i.e., accordion)
│ │ ├── 2.alert.md
│ │ ├── ... etc
└── ... etc
```
- **Components - `src`** :
The components are located in the `src` folder. It's separated into categories according to component types. Here's a breakdown of its structure:
```
src/
├── runtime/
│ ├── composables/ # Composable functions used in components
│ ├── components/ # Components folder, separated into categories according to component types
│ │ ├── data/ # The category of components, which are data related
│ │ │ ├── table.vue/ # Table component
│ │ │ ├── elements/ # Elements category
│ │ │ │ ├── ...etc/
│ │ │ └── ... etc/
│ │ ├── plugins/ # Plugins used in components
│ │ ├── utils/ # Utility functions used on the components page (e.g., lodash)
│ │ ├── types/ # Types used in components
│ │ │ ├── accordion.d.ts/ # [componentName].d.ts type used for single component
│ │ │ ├── avatar.d.ts/
│ │ │ └── ... etc/
│ │ ├── ui.config.ts/ # Configuration file used to apply styles to every component
├── colors.ts/ # Everything related to color functions (e.g., safelistByComponent, generateSafelist)
└── ... etc/ # Other files and folders
```
## Thanks
Thank you again for being interested in this project! You are awesome! ❤️

View File

@@ -0,0 +1 @@
title: Getting Started

View File

@@ -0,0 +1,10 @@
---
title: App
description: Starting point for your Nuxt UI app.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Accordion.vue
---
## Usage

View File

@@ -0,0 +1,168 @@
---
description: Display togglable accordion panels.
links:
- label: Disclosure
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/disclosure'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Accordion.vue
---
## Usage
Pass an array to the `items` prop of the Accordion component. Each item can have any property from the [Button](/components/button) component such as `label`, `icon`, `color`, `variant`, `size`, etc. but also:
- `slot` - A key to customize the item with a slot.
- `content` - The content to display in the panel by default.
- `disabled` - Determines whether the item is disabled or not.
- `defaultOpen` - Determines whether the item is initially open or closed.
- `closeOthers` - Determines whether the item click close others or not. **It only works with multiple mode**.
:component-example{component="accordion-example-basic"}
### Style
You can also pass any prop from the [Button](/components/button) component directly to the Accordion component to style the buttons.
::component-card
---
baseProps:
items:
- label: '1. What is Nuxt UI?'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: '2. Getting Started'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: '3. Theming'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: '4. Components'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
props:
color: 'primary'
variant: 'soft'
size: 'sm'
options:
- name: color
restriction: included
values:
- gray
- white
- black
- name: variant
restriction: included
values:
- solid
- outline
- ghost
- soft
- link
- name: size
restriction: included
values:
- 2xs
- xs
- sm
- md
- lg
- xl
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `open-icon` and `close-icon` props by using this pattern: `i-{collection_name}-{icon_name}` or change it globally in `ui.accordion.default.openIcon` and `ui.accordion.default.closeIcon`.
You can also set them to `null` to hide the icons.
::component-card
---
baseProps:
items:
- label: '1. What is Nuxt UI?'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: '2. Getting Started'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: '3. Theming'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: '4. Components'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
props:
openIcon: 'i-heroicons-plus'
closeIcon: 'i-heroicons-minus'
excludedProps:
- openIcon
- closeIcon
---
::
### Multiple
Use the `multiple` prop to to allow multiple elements to be opened at the same time.
::component-card
---
baseProps:
items:
- label: 'What is Nuxt UI?'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: 'Getting Started'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: 'Theming'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: 'Components'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
props:
multiple: true
excludedProps:
- defaultOpen
---
::
### Open
Use the `default-open` prop to open all items by default. Works better when the `multiple` prop is set to `true`.
::component-card
---
baseProps:
items:
- label: 'What is Nuxt UI?'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: 'Getting Started'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: 'Theming'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
- label: 'Components'
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
props:
defaultOpen: true
multiple: true
excludedProps:
- defaultOpen
- multiple
---
::
## Slots
You can use slots to customize the buttons and items content of the Accordion.
### `default`
Use the `#default` slot to customize the trigger buttons. You will have access to the `item`, `index`, `open` properties and `close` method in the slot scope.
:component-example{component="accordion-example-default-slot"}
### `item`
Use the `#item` slot to customize the items content or pass a `slot` property to customize a specific item. You will have access to the `item`, `index`, `open` properties and `close` method in the slot scope.
:component-example{component="accordion-example-item-slot"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,184 @@
---
description: Display an alert element to draw attention.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Alert.vue
---
## Usage
Pass a `title` to your Alert.
::component-card
---
props:
title: 'Heads up!'
---
::
### Description
You can add a `description` in addition of the `title`.
::component-card
---
baseProps:
title: 'Heads up!'
props:
description: 'You can add components to your app using the cli.'
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}` or change it globally in `ui.alert.default.icon`.
::component-card
---
baseProps:
title: 'Heads up!'
props:
icon: 'i-heroicons-command-line'
description: 'You can add components to your app using the cli.'
excludedProps:
- icon
---
::
### Avatar
Use the [avatar](/components/avatar) prop as an `object` and configure it with any of its props.
::component-card
---
baseProps:
title: 'Heads up!'
props:
description: 'You can add components to your app using the cli.'
avatar:
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
excludedProps:
- avatar
---
::
### Style
Use the `color` and `variant` props to change the visual style of the Alert.
- `color` can be any color from the `ui.colors` object or `white` (default).
- `variant` can be `solid` (default), `outline`, `soft` or `subtle`.
::component-card
---
baseProps:
title: 'Heads up!'
description: 'You can add components to your app using the cli.'
props:
icon: 'i-heroicons-command-line'
color: 'primary'
variant: 'solid'
options:
- name: color
restriction: included
values:
- white
excludedProps:
- icon
---
::
### Close
Use the `close-button` prop to hide or customize the close button on the Alert.
You can pass all the props of the [Button](/components/button) component to customize it through the `close-button` prop or globally through `ui.alert.default.closeButton`.
It defaults to `null` which means no close button will be displayed. A `close` event will be emitted when the close button is clicked.
::component-card
---
baseProps:
title: 'Heads up!'
props:
closeButton:
icon: 'i-heroicons-x-mark-20-solid'
color: 'gray'
variant: 'link'
padded: false
excludedProps:
- closeButton
---
::
### Actions
Use the `actions` prop to add actions to the Alert.
Like for `closeButton`, you can pass all the props of the [Button](/components/button) component plus a `click` function in the action but also customize the default style for the actions globally through `ui.alert.default.actionButton`.
::component-card
---
baseProps:
title: 'Heads up!'
props:
actions:
- label: Action 1
- variant: 'ghost'
color: 'gray'
label: Action 2
excludedProps:
- actions
---
::
Actions will render differently whether you have a `description` set.
::component-card
---
baseProps:
title: 'Heads up!'
description: 'You can add components to your app using the cli.'
props:
actions:
- variant: 'solid'
color: 'primary'
label: Action 1
- variant: 'outline'
color: 'primary'
label: Action 2
excludedProps:
- actions
---
::
## Slots
### `title` / `description`
Use the `#title` and `#description` slots to customize the Alert.
This can be handy when you want to display HTML content. To achieve this, you can define those slots and use the `v-html` directive.
:component-example{component="alert-example-html"}
### `icon` :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
Use the `#icon` slot to customize the displayed icon.
:component-example{component="alert-example-icon"}
### `avatar` :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
Use the `#avatar` slot to customize the displayable avatar.
:component-example{component="alert-example-avatar"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,122 @@
---
description: Display an image that represents a resource or a group of resources.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Avatar.vue
---
## Usage
::component-card
---
props:
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
alt: 'Avatar'
---
::
### Size
Use the `size` prop to change the size of the Avatar.
::component-card
---
props:
size: 'sm'
baseProps:
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
alt: 'Avatar'
---
::
### Chip
Use the `chip-color`, `chip-text` and `chip-position` props to display a chip on the Avatar.
::component-card
---
props:
chipColor: 'primary'
chipText: ''
chipPosition: 'top-right'
size : 'sm'
options:
- name: 'chipColor'
restriction: 'included'
values:
- 'gray'
baseProps:
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
alt: 'Avatar'
---
::
### Placeholder
If there is an error loading the `src` of the avatar or `src` is null / false a background placeholder will be displayed, customizable in `ui.avatar.background`.
#### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}` or change it globally in `ui.avatar.default.icon` to display an icon on top of the background.
::component-card
---
props:
icon: 'i-heroicons-photo'
size: 'sm'
excludedProps:
- icon
---
::
#### Alt
Otherwise, a placeholder will be displayed with the initials of the `alt` prop, customizable in `ui.avatar.placeholder`.
::component-card
---
props:
alt: 'Benjamin Canac'
size: 'sm'
---
::
## Group
To stack avatars as a group, use the `AvatarGroup` component.
- To limit the amount of avatars to show, use the `max` prop. It'll truncate the avatars and show a "+X" label (where X is the remaining avatars)
- To size all the avatars equally, pass the `size` prop
- To adjust the spacing or the ring between avatars, customize with `ui.avatarGroup.margin` or `ui.avatarGroup.ring`
::component-card{slug="UAvatarGroup"}
---
props:
size: 'sm'
max: 2
code: |
<UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" alt="benjamincanac" />
<UAvatar src="https://avatars.githubusercontent.com/u/904724?v=4" alt="Atinux" />
<UAvatar src="https://avatars.githubusercontent.com/u/7547335?v=4" alt="smarroufin" />
---
#default
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" alt="Avatar"}
:u-avatar{src="https://avatars.githubusercontent.com/u/904724?v=4" alt="Avatar"}
:u-avatar{src="https://avatars.githubusercontent.com/u/7547335?v=4" alt="Avatar"}
::
## Props
::tabs
:component-props{label="Avatar"}
:component-props{label="AvatarGroup" slug="UAvatarGroup"}
::
## Config
::tabs
:component-preset{label="Avatar"}
:component-preset{label="AvatarGroup" slug="AvatarGroup"}
::

View File

@@ -0,0 +1,150 @@
---
description: Display a short text to represent a status or a category.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Badge.vue
---
## Usage
Use the default slot to set the text of the Badge.
::component-card
---
code: Badge
---
Badge
::
You can also use the `label` prop:
::component-card
---
props:
label: Badge
---
::
### Style
Use the `color` and `variant` props to change the visual style of the Badge.
- `variant` can be `solid` (default), `outline`, `soft` or `subtle`.
::component-card
---
props:
color: 'primary'
variant: 'solid'
code: Badge
---
Badge
::
Besides all the colors from the `ui.colors` object, you can also use the `white` and `black` colors with their pre-defined variants.
#### White
::component-card
---
props:
color: 'white'
variant: 'solid'
options:
- name: variant
restriction: expected
values:
- solid
excludedProps:
- color
code: Badge
---
Badge
::
#### Gray
::component-card
---
props:
color: 'gray'
variant: 'solid'
options:
- name: variant
restriction: expected
values:
- solid
excludedProps:
- color
code: Badge
---
Badge
::
#### Black
::component-card
---
props:
color: 'black'
variant: 'solid'
options:
- name: variant
restriction: only
values:
- solid
excludedProps:
- color
code: Badge
---
Badge
::
### Size
Use the `size` prop to change the size of the Badge.
::component-card
---
props:
size: 'sm'
code: Badge
---
Badge
::
### Rounded
To customize the border radius of the Badge, you can use the `ui` prop.
::component-card
---
props:
ui:
rounded: 'rounded-full'
excludedProps:
- ui
code: Badge
---
Badge
::
::callout{icon="i-heroicons-light-bulb"}
You can customize the whole [preset](#preset) by using the `ui` prop.
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,72 @@
---
title: Breadcrumb
description: A list of links that indicate the current page's location within a navigational hierarchy.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/Breadcrumb.vue
---
## Usage
Pass an array to the `links` prop of the Breadcrumb component. Each link can have the following properties:
- `label` - The label of the link.
- `labelClass` - The class of the link label.
- `icon` - The icon of the link.
- `iconClass` - The class of the link icon.
You can also pass any property from the [NuxtLink](https://nuxt.com/docs/api/components/nuxt-link#props) component such as `to`, `exact`, etc.
:component-example{component="breadcrumb-example-basic"}
::callout{icon="i-heroicons-light-bulb"}
A `span` will be rendered instead of a link when the `to` property is not defined.
::
## Divider
Use the `divider` prop to customize the divider between each link, it can be **an icon or a string**. You can change it globally in `ui.breadcrumb.default.divider`. Defaults to `i-heroicons-chevron-right-20-solid`.
You can set the prop to `null` to hide the divider. Additionally, you can customize it using the [`divider`](#divider-1) slot.
::component-card
---
baseProps:
links:
- label: Home
to: /
- label: Navigation
- label: Breadcrumb
props:
divider: '/'
---
::
## Slots
### `default`
Use the `#default` slot to customize the link label. You will have access to the `link`, `index` and `isActive` properties in the slot scope.
:component-example{component="breadcrumb-example-default-slot"}
### `icon`
Use the `#icon` slot to customize the link icon. You will have access to the `link`, `index` and `isActive` properties in the slot scope.
:component-example{component="breadcrumb-example-icon-slot"}
### `divider`
Use the `divider` slot to customize the divider of the Breadcrumb.
:component-example{component="breadcrumb-example-divider-slot"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,384 @@
---
description: Create a button with icon or link capabilities.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Button.vue
---
## Usage
Use the default slot to set the text of the Button.
::component-card
---
code: Button
---
Button
::
You can also use the `label` prop.
::component-card
---
props:
label: Button
---
::
### Style
Use the `color` and `variant` props to change the visual style of the Button.
::component-card
---
props:
color: 'primary'
variant: 'solid'
code: Button
---
Button
::
Besides all the colors from the `ui.colors` object, you can also use the `white`, `gray` and `black` colors with their pre-defined variants.
#### White
::component-card
---
backgroundClass: 'bg-gray-50 dark:bg-gray-800'
props:
color: 'white'
variant: 'solid'
options:
- name: variant
restriction: expected
values:
- solid
- ghost
excludedProps:
- color
code: Button
---
Button
::
#### Gray
::component-card
---
props:
color: 'gray'
variant: 'solid'
options:
- name: variant
restriction: expected
values:
- solid
- ghost
- link
excludedProps:
- color
code: Button
---
Button
::
#### Black
::component-card
---
props:
color: 'black'
variant: 'solid'
options:
- name: variant
restriction: expected
values:
- solid
- link
excludedProps:
- color
code: Button
---
Button
::
### Size
Use the `size` prop to change the size of the Button.
::component-card
---
props:
size: 'sm'
code: Button
---
Button
::
### Rounded
To customize the border radius of the Button, you can use the `ui` prop.
::component-card
---
props:
ui:
rounded: 'rounded-full'
excludedProps:
- ui
code: Button
---
Button
::
::callout{icon="i-heroicons-light-bulb"}
You can customize the whole [preset](#preset) by using the `ui` prop.
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}`.
Use the `leading` and `trailing` props to set the icon position or the `leading-icon` and `trailing-icon` props to set a different icon for each position.
::component-card
---
props:
icon: 'i-heroicons-pencil-square'
size: 'sm'
color: 'primary'
variant: 'solid'
label: Button
trailing: false
excludedProps:
- icon
- label
---
::
The `label` as prop or slot is optional so you can use the Button as an icon-only button.
::component-card
---
props:
icon: 'i-heroicons-pencil-square'
size: 'sm'
color: 'primary'
square: true
variant: 'solid'
excludedProps:
- icon
- square
---
::
### Disabled
Use the `disabled` prop to disable the Button.
::component-card
---
props:
disabled: true
code: Button
---
Button
::
### Loading
Use the `loading` prop to show a loading icon and disable the Button.
Use the `loading-icon` prop to set a different icon or change it globally in `ui.button.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-card
---
props:
loading: true
code: Button
---
Button
::
### Block
Use the `block` prop to make the Button fill the width of its container.
::component-card
---
props:
block: true
code: Button
---
Button
::
### Link
Use the `to` prop to make the Button a link.
::component-card
---
props:
to: 'https://volta.net'
target: '_blank'
code: Button
---
Button
::
You can also pass any property from the [NuxtLink](https://nuxt.com/docs/api/components/nuxt-link#props) component such as `target`, `exact`, etc.
### Padded
Use the `padded` prop to remove the padding of the Button.
::component-card
---
props:
padded: false
baseProps:
color: 'gray'
variant: 'link'
icon: 'i-heroicons-x-mark-20-solid'
---
::
### Square
Use the `square` prop to force the Button to have the same padding horizontally and vertically.
::component-card
---
props:
square: true
baseProps:
label: 'Button'
color: 'gray'
variant: 'solid'
---
::
### Truncate
Use the `truncate` prop to truncate the label of the Button.
::component-card
---
props:
truncate: true
class: 'w-20'
label: 'Button with a long text'
excludedProps:
- class
---
::
## Group
To stack buttons as a group, use the `ButtonGroup` component.
- To size all the buttons equally, pass the `size` prop
- To change the orientation of the buttons, set the `orientation` prop to `vertical`
- To adjust the rounded or the shadow around buttons, customize with `ui.buttonGroup.rounded` or `ui.buttonGroup.shadow`
::component-card{slug="UButtonGroup"}
---
props:
size: 'sm'
orientation: 'horizontal'
code: |
<UButton label="Action" color="white" />
<UButton icon="i-heroicons-chevron-down-20-solid" color="gray" />
---
#default
:u-button{label="Action" color="white"}
:u-button{icon="i-heroicons-chevron-down-20-solid" color="gray"}
::
This can also work with an [Input](/components/input) component for example:
::component-card{slug="UButtonGroup"}
---
props:
size: 'sm'
orientation: 'horizontal'
code: |
<UInput />
<UButton icon="i-heroicons-clipboard-document" color="gray" />
---
#default
:u-input
:u-button{icon="i-heroicons-clipboard-document" color="gray"}
::
## Slots
### `leading`
Use the `#leading` slot to set the content of the leading icon.
::component-card
---
slots:
leading: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="2xs" />
baseProps:
color: 'gray'
props:
label: Button
color: 'gray'
excludedProps:
- color
---
#leading
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" size="2xs"}
::
### `trailing`
Use the `#trailing` slot to set the content of the trailing icon.
::component-card
---
slots:
trailing: <UIcon name="i-heroicons-arrow-right-20-solid" class="w-5 h-5" />
props:
label: Button
color: 'gray'
excludedProps:
- color
---
#trailing
:u-icon{name="i-heroicons-arrow-right-20-solid" class="w-5 h-5"}
::
## Props
::tabs
:component-props{label="Button"}
:component-props{label="ButtonGroup" slug="UButtonGroup"}
::
## Config
::tabs
:component-preset{label="Button"}
:component-preset{label="ButtonGroup" slug="ButtonGroup"}
::

View File

@@ -0,0 +1,35 @@
---
description: Display a card for content with a header, body and footer.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Card.vue
---
## Usage
::component-example
---
component: 'card-example'
componentProps:
class: 'w-full'
---
::
## Slots
### `header`
Use the `#header` slot to fill the header.
### `footer`
Use the `#footer` slot to fill the footer.
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,165 @@
---
description: Display images or content in a scrollable area.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Carousel.vue
disabled: true
badge: Coming soon
---
## Usage
Drag with your mouse, scroll with your mouse wheel or use the navigation arrows to navigate.
Pass an array to the `items` prop and use the default slot to display the content of each item.
:component-example{component="carousel-example"}
### Snap
The carousel will snap the item to the center (`snap-center`). You can use the `snap` utility classes to change this behavior using the `ui` prop:
#### Snap to start
::component-example
---
component: 'carousel-example-snap-start'
---
#code
```vue
<template>
<UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'snap-start' }">
<img :src="item" width="200" height="300">
</UCarousel>
</template>
```
::
#### Snap to end
::component-example
---
component: 'carousel-example-snap-end'
---
#code
```vue
<template>
<UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'snap-end' }">
<img :src="item" width="200" height="300">
</UCarousel>
</template>
```
::
::callout{icon="i-heroicons-light-bulb" to="https://tailwindcss.com/docs/scroll-snap-align" target="_blank"}
Learn more about the `scroll-snap-align` property on the Tailwind CSS documentation.
::
### Size
Each item will take its own size by default in the carousel. You can use the `basis` / `width` utility classes to change this behavior using the `ui` prop:
:component-example{component="carousel-example-size"}
In this example, we used `basis-1/3` to display 3 items at a time but you can also use this to make the carousel full width using `basis-full` and display only one item at a time:
:component-example{component="carousel-example-size-full"}
You can also set a width on the container to center the carousel:
:component-example{component="carousel-example-size-center"}
::callout{icon="i-heroicons-light-bulb" to="https://tailwindcss.com/docs/flex-basis" target="_blank"}
Learn more about the `flex-basis` property on the Tailwind CSS documentation.
::
## Navigation
### Arrows
Use the `arrows` prop to enable prev and next buttons, they will be automatically disabled when the carousel reaches the first or last item.
:component-example{component="carousel-example-arrows"}
You can also customize the prev and next buttons using the `prev-button` and `next-button` props:
:component-example{component="carousel-example-arrows-center"}
In this example, we move the buttons outside of the carousel container. You can also change this globally in `ui.carousel.default.prevButton` and `ui.carousel.default.nextButton`.
### Indicators
Use the `indicators` prop to display a list of buttons at the bottom of the carousel to navigate between items.
:component-example{component="carousel-example-indicators"}
The number of indicators will be automatically generated based on the number of items:
:component-example{component="carousel-example-indicators-size"}
## Autoplay :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
You can easily implement an autoplay behavior using the exposed [API](#api) through a template ref.
:component-example{component="carousel-example-autoplay"}
## Slots
### `default`
You can put anything inside the default slot, not only images. You will have access to the `item` and `index` properties in the slot scope.
:component-example{component="carousel-example-slots-default"}
### `prev` / `next`
With the `arrows` prop enabled, use the `#prev` and `#next` slots to set the content of the previous and next buttons. You will have access to the `disabled` property and `on-click` method in the slot scope.
:component-example{component="carousel-example-slots-prev-next"}
::callout{icon="i-heroicons-light-bulb"}
You can customize the position of the buttons through `ui.arrows.wrapper`.
::
### `indicator`
With the `indicators` prop enabled, use the `#indicator` slot to set the content of the indicators. You will have access to the `active`, `page` properties and `on-click` method in the slot scope.
:component-example{component="carousel-example-slots-indicator"}
::callout{icon="i-heroicons-light-bulb"}
You can customize the position of the buttons through `ui.indicators.wrapper`.
::
## Props
:component-props
## API
When accessing the component via a template ref, you can use the following:
::field-group
::field{name="page" type="number"}
The current page.
::
::field{name="pages" type="number"}
The total number of pages.
::
::field{name="select (page)"}
Go to a specific page.
::
::field{name="next ()"}
Go to the next page.
::
::field{name="prev ()"}
Go to the previous page.
::
::
## Config
:component-preset

View File

@@ -0,0 +1,96 @@
---
description: Display a checkbox field.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Checkbox.vue
---
## Usage
Use a `v-model` to make the Checkbox reactive.
:component-example{component="checkbox-example"}
### Label
Use the `label` prop to display a label on the right.
::component-card
---
props:
label: 'Label'
---
::
### Style
Use the `color` prop to change the style of the Checkbox.
::component-card
---
baseProps:
label: 'Label'
props:
color: 'primary'
---
::
### Required
Use the `required` prop to display a red star next to the label of the Checkbox.
::component-card
---
props:
label: 'Label'
required: true
---
::
### Help
Use the `help` prop to display some text under the Checkbox.
::component-card
---
props:
label: 'Label'
help: 'Please check this box'
---
::
### Disabled
Use the `disabled` prop to disable the Checkbox.
::component-card
---
props:
disabled: true
---
::
## Slots
### `label`
Use the `#label` slot to override the content of the label.
::component-card
---
slots:
label: <span class="italic">Label</span>
---
#label
[Label]{.italic}
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,132 @@
---
description: Display a chip indicator on any component.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Chip.vue
---
## Usage
Wrap any component with the `Chip` component to display a chip indicator.
::component-card
---
code: >-
<UButton icon="i-heroicons-inbox" color="gray" />
---
#default
:u-button{icon="i-heroicons-inbox" color="gray"}
::
### Size
Use the `size` prop to change the size of the chip.
::component-card
---
props:
size: '2xl'
code: >-
<UButton icon="i-heroicons-inbox" color="gray" />
---
#default
:u-button{icon="i-heroicons-inbox" color="gray"}
::
### Color
Use the `color` prop to change the color of the chip.
::component-card
---
props:
color: 'red'
code: >-
<UButton icon="i-heroicons-inbox" color="gray" />
---
#default
:u-button{icon="i-heroicons-inbox" color="gray"}
::
### Position
Use the `position` prop to change the position of the chip.
::component-card
---
props:
position: 'bottom-right'
code: >-
<UButton icon="i-heroicons-inbox" color="gray" />
---
#default
:u-button{icon="i-heroicons-inbox" color="gray"}
::
### Text
Use the `text` prop to display text in the chip.
::component-card
---
props:
text: '3'
size: '2xl'
excludedProps:
- size
code: >-
<UButton icon="i-heroicons-inbox" color="gray" />
---
#default
:u-button{icon="i-heroicons-inbox" color="gray"}
::
### Show
Use the `show` prop to conditionally display the chip.
:component-example{component="chip-example-show"}
### Inset
Use the `inset` prop to display the chip inside the component. This is useful when dealing with rounded components.
::component-card
---
props:
inset: true
code: >-
<UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" alt="Avatar" />
---
#default
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" alt="Avatar"}
::
## Slots
### `content`
Use the `#content` slot to fully customize the chip.
:component-example{component="chip-example-content-slot"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,17 @@
---
description: A container lets you center and constrain the width of your content.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Container.vue
---
## Usage
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,295 @@
---
title: CommandPalette
description: Add a customizable command palette to your app.
links:
- label: 'Combobox'
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/combobox'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/CommandPalette.vue
---
## Usage
Use a `v-model` to display a searchable and selectable list of commands.
::component-example
---
padding: false
component: 'command-palette-example-basic'
componentProps:
class: 'h-[257px]'
---
::
You can put a `CommandPalette` anywhere you want but it's most commonly used inside of a modal.
:component-example{component="command-palette-example-modal"}
You can pass multiple groups of commands to the component. Each group will be separated by a divider and will display a label.
Without a `v-model`, you can also listen on `@update:model-value` to navigate to a link or do something else when a command is clicked.
::component-example
---
padding: false
component: 'command-palette-example-groups'
componentProps:
class: 'h-[274px]'
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}`.
Use the `selected-icon` prop to set a different icon or change it globally in `ui.commandPalette.default.selectedIcon`. Defaults to `i-heroicons-check-20-solid`.
::component-card
---
padding: false
baseProps:
emptyState: null
props:
icon: 'i-heroicons-command-line'
excludedProps:
- icon
---
::
### Loading
Use the `loading` prop to show a loading icon.
Use the `loading-icon` prop to set a different icon or change it globally in `ui.commandPalette.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-card
---
padding: false
baseProps:
emptyState: null
props:
loading: true
excludedProps:
- icon
---
::
### Placeholder
Use the `placeholder` prop to change the input placeholder
::component-card
---
padding: false
baseProps:
emptyState: null
props:
placeholder: 'Type a command...'
excludedProps:
- icon
---
::
### Close
Use the `close-button` prop to display a close button on the right side of the input.
You can pass all the props of the [Button](/components/button) component to customize it through the `close-button` prop or globally through `ui.commandPalette.default.closeButton`.
::component-card
---
padding: false
baseProps:
emptyState: null
props:
closeButton:
icon: 'i-heroicons-x-mark-20-solid'
color: 'gray'
variant: 'link'
padded: false
excludedProps:
- closeButton
---
::
### Empty
An empty state will be displayed when there are no results.
Use the `empty-state` prop to customize the `icon` and `label` or change them globally in `ui.commandPalette.default.emptyState`.
You can also set it to `null` to hide the empty state.
::component-card
---
padding: false
baseProps:
placeholder: 'Type something to see the empty label change'
props:
emptyState:
icon: 'i-heroicons-magnifying-glass-20-solid'
label: "We couldn't find any items."
queryLabel: "We couldn't find any items with that term. Please try again."
excludedProps:
- emptyState
---
::
## Full-text search
The CommandPalette component takes care of the full-text search for you with [Fuse.js](https://fusejs.io). You can pass all the options of Fuse.js through the `fuse` prop.
When searching for a command, the component will look for a `label` property on the command by default. You can customize this behavior by overriding the `command-attribute` prop. This will also affect the display of the command.
You can also highlight the matches in the command by setting the `fuse.fuseOptions.includeMatches` to `true`. The CommandPalette component automatically takes care of the highlighting for you.
```vue
<template>
<UCommandPalette
command-attribute="title"
:fuse="{
fuseOptions: {
ignoreLocation: true,
includeMatches: true,
threshold: 0,
keys: ['title', 'description', 'children.children.value', 'children.children.children.value']
},
resultLimit: 10
}"
/>
</template>
```
::callout{icon="i-heroicons-light-bulb"}
Try it yourself in this documentation's search by pressing :shortcut{value="meta"} :shortcut{value="K" class="ml-1"}.
::
## Async search
You can also pass an `async` function to the `search` property of a group to perform an async search. The function will receive the query as its first argument and should return an array of commands.
::component-example
---
padding: false
component: 'command-palette-example-async'
componentProps:
class: 'h-[274px]'
---
::
::callout{icon="i-heroicons-light-bulb"}
The `loading` state will automatically be enabled when a `search` function is loading. You can disable this behavior by setting the `loading-icon` prop to `null` or globally in `ui.commandPalette.default.loadingIcon`.
::
## Filter search
You can also pass a function to the `filter` property of a group to filter displayed commands after the search happened. The function will receive the query as its first argument, the array of commands as second argument and should return an array of commands.
::component-example
---
padding: false
component: 'command-palette-example-filter'
componentProps:
class: 'h-[274px]'
---
::
## Slots
### `<group>-icon`
Use the `#<group>-icon` slot to override the left command content which display by default the `icon`, `avatar` and `chip`.
### `<group>-command`
Use the `#<group>-command` slot to override the command content which display by default the `prefix`, `suffix` and `label` (customizable through the `command-attribute` prop).
### `<group>-active`
Use the `#<group>-active` slot to override the right command content (when hovered) which display by default the `active` field of the group if provided.
### `<group>-inactive`
Use the `#<group>-inactive` slot to override the right command content (when not hovered) which display by default the `inactive` field of the group if provided or the `shortcuts` of the command.
::callout{icon="i-heroicons-light-bulb"}
The 4 slots above will have access to the `group`, `command`, `active` and `selected` properties in the slot scope.
::
### `empty-state`
Use the `#empty-state` slot to customize the empty state.
::component-example
---
padding: false
component: 'command-palette-example-empty-slot'
componentProps:
class: 'flex-1'
---
::
## Props
:component-props
## API
When accessing the component via a template ref, you can use the following:
::field-group
::field{name="query" type="string"}
The current query.
::
::field{name="updateQuery (query)"}
Updates the current query.
::
::field{name="results" type="ComputedRef<Fuse.FuseResult<Command>[]>"}
The results exposed by [useFuse](https://vueuse.org/integrations/useFuse/#usefuse).
::
::field{name="comboboxApi"}
The Combobox [API](https://github.com/tailwindlabs/headlessui/blob/main/packages/%40headlessui-vue/src/components/combobox/combobox.ts#L384) exposed by Headless UI.
::
::
## Config
:component-preset
## Example
Here are a few examples illustrating how you can customize the appearance of the `CommandPalette` component by utilizing its `ui` prop.
### Algolia
::component-example
---
padding: false
component: 'command-palette-example-theme-algolia'
componentProps:
class: 'max-h-[480px] rounded-md'
hiddenCode: true
---
::
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/CommandPaletteExampleThemeAlgolia.vue#L23" target="_blank"}
Take a look at the component!
::
### Raycast
::component-example
---
padding: false
component: 'command-palette-example-theme-raycast'
componentProps:
class: 'max-h-[480px] rounded-md'
hiddenCode: true
---
::
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/CommandPaletteExampleThemeRaycast.vue#L30" target="_blank"}
Take a look at the component!
::

View File

@@ -0,0 +1,25 @@
---
description: A container lets you center and constrain the width of your content.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Container.vue
---
## Usage
::component-example
---
component: 'container-example'
componentProps:
class: 'w-full'
---
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,36 @@
---
title: ContextMenu
description: Display a menu that appears on right click.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/ContextMenu.vue
---
## Usage
:component-example{component="context-menu-example"}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="context-menu-example-arrow"}
### Placement
:component-example{component="context-menu-example-placement"}
### Offset
:component-example{component="context-menu-example-offset"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,73 @@
---
description: Display a list of actions in a dropdown menu.
links:
- label: Menu
icon: i-simple-icons-headlessui
to: https://headlessui.com/vue/menu
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Dropdown.vue
---
## Usage
Pass an array of arrays to the `items` prop of the Dropdown component. Each array represents a group of items. Each item can have the following properties:
- `label` - The label of the item.
- `labelClass` - The class of the item label.
- `icon` - The icon of the item.
- `iconClass` - The class of the item icon.
- `avatar` - The avatar of the item. You can pass all the props of the [Avatar](/components/avatar) component.
- `shortcuts` - The shortcuts of the item.
- `slot` - The slot of the item.
- `disabled` - Whether the item is disabled.
- `class` - The class of the item.
- `click` - The click handler of the item.
You can also pass any property from the [NuxtLink](https://nuxt.com/docs/api/components/nuxt-link#props) component such as `to`, `exact`, etc.
:component-example{component="dropdown-example-basic"}
### Mode
Use the `mode` prop to switch between `click` and `hover` modes.
:component-example{component="dropdown-example-mode"}
### Manual
Use a `v-model:open` to manually control the state. In this example, press :shortcut{value="O"} to toggle the dropdown.
:component-example{component="dropdown-example-open"}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="dropdown-example-arrow"}
### Placement
:component-example{component="dropdown-example-placement"}
### Offset
:component-example{component="dropdown-example-offset"}
## Slots
### `item`
Use the `#item` slot to customize the items content or pass a `slot` property to customize a specific item. You will have access to the `item` property in the slot scope.
:component-example{component="dropdown-example-slot"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,270 @@
---
title: FormGroup
description: Display a label and additional informations around a form element.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/FormGroup.vue
---
## Usage
Use the FormGroup component around an [Input](/components/input), [Textarea](/components/textarea), [Select](/components/select) or a [SelectMenu](/components/select-menu) with a `label`. The `<label>` will automatically be associated with the form element so it gets focused on click.
::component-card
---
props:
label: 'Email'
code: >-
<UInput placeholder="you@example.com" icon="i-heroicons-envelope" />
---
#default
:u-input{placeholder="you@example.com" icon="i-heroicons-envelope"}
::
### Required
Use the `required` prop to indicate that the form element is required.
::component-card
---
props:
label: 'Email'
required: true
code: >-
<UInput placeholder="you@example.com" icon="i-heroicons-envelope" />
---
#default
:u-input{placeholder="you@example.com" icon="i-heroicons-envelope"}
::
### Description
Use the `description` prop to display a description below the label.
::component-card
---
props:
label: 'Email'
description: "We'll only use this for spam."
code: >-
<UInput placeholder="you@example.com" icon="i-heroicons-envelope" />
---
#default
:u-input{placeholder="you@example.com" icon="i-heroicons-envelope"}
::
### Hint
Use the `hint` prop to display a hint above the form element.
::component-card
---
props:
label: 'Email'
hint: 'Optional'
code: >-
<UInput placeholder="you@example.com" icon="i-heroicons-envelope" />
---
#default
:u-input{placeholder="you@example.com" icon="i-heroicons-envelope"}
::
### Help
Use the `help` prop to display an help message below the form element.
::component-card
---
props:
label: 'Email'
help: 'We will never share your email with anyone else.'
code: >-
<UInput placeholder="you@example.com" icon="i-heroicons-envelope" />
---
#default
:u-input{placeholder="you@example.com" icon="i-heroicons-envelope"}
::
### Error
Use the `error` prop to display an error message below the form element.
When used together with the `help` prop, the `error` prop will take precedence.
:component-example{component="form-group-error-example"}
::callout{icon="i-heroicons-light-bulb"}
The `error` prop will automatically set the `color` prop of the form element to `red`.
::
You can also use the `error` prop as a boolean to mark the form element as invalid.
::component-card
---
props:
label: 'Email'
error: true
excludedProps:
- ui
- error
- label
code: >-
<UInput placeholder="you@example.com" />
---
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
::callout{icon="i-heroicons-light-bulb" to="/components/form"}
Learn more about form validation in the `Form` component.
::
### Size
Use the `size` prop to change the size of the label and the form element.
::component-card
---
props:
size: 'xl'
label: 'Email'
hint: 'Optional'
description: "We'll only use this for spam."
help: 'We will never share your email with anyone else.'
excludedProps:
- label
- hint
- description
- help
code: >-
<UInput placeholder="you@example.com" icon="i-heroicons-envelope" />
---
#default
:u-input{placeholder="you@example.com" icon="i-heroicons-envelope"}
::
::callout{icon="i-heroicons-exclamation-triangle"}
This will only work with form elements that support the `size` prop.
::
### Eager Validation
By default, validation is only triggered after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the `eager-validation` prop to `true`
:component-example{component="form-group-eager-validation-example"}
## Slots
### `label`
Use the `#label` slot to set the custom content for label.
::component-card
---
slots:
label: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
---
#label
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" class="mr-2 inline-flex"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `description`
Use the `#description` slot to set the custom content for description.
::component-card
---
slots:
description: Write only valid email address <UIcon name="i-heroicons-arrow-right-20-solid" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
props:
label: 'Email'
---
#description
Write only valid email address :u-icon{name="i-heroicons-information-circle" class="align-middle"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `hint`
Use the `#hint` slot to set the custom content for hint.
::component-card
---
slots:
hint: <UIcon name="i-heroicons-arrow-right-20-solid" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
props:
label: 'Step 1'
---
#hint
:u-icon{name="i-heroicons-arrow-right-20-solid"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `help`
Use the `#help` slot to set the custom content for help.
::component-card
---
slots:
help: Here are some examples <UIcon name="i-heroicons-information-circle" />
default: <UInput model-value="benjamincanac" placeholder="you@example.com" />
props:
label: 'Email'
---
#help
Here are some examples :u-icon{name="i-heroicons-information-circle" class="align-middle"}
#default
:u-input{model-value="benjamincanac" placeholder="you@example.com"}
::
### `error`
Use the `#error` slot to set the custom content for error.
::component-example
---
component: 'form-group-error-slot-example'
componentProps:
class: 'w-60'
---
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,230 @@
---
description: Collect and validate form data.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Form.vue
---
## Usage
Use the Form component to validate form data using schema libraries such as [Yup](https://github.com/jquense/yup), [Zod](https://github.com/colinhacks/zod), [Joi](https://github.com/hapijs/joi), [Valibot](https://valibot.dev/), or your own validation logic.
It works with the [FormGroup](/components/input) component to display error messages around form elements automatically.
The form component requires two props:
- `state` - a reactive object holding the form's state.
- `schema` - a schema object from [Yup](#yup), [Zod](#zod), [Joi](#joi), or [Valibot](#valibot).
::callout{icon="i-heroicons-light-bulb"}
Note that **no validation library is included** by default, so ensure you **install the one you need**.
::
::tabs
::component-example{label="Yup"}
---
component: 'form-example-yup'
componentProps:
class: 'w-60'
---
::
::component-example{label="Zod"}
---
component: 'form-example-zod'
componentProps:
class: 'w-60'
---
::
::component-example{label="Joi"}
---
component: 'form-example-joi'
componentProps:
class: 'w-60'
---
::
::component-example{label="Valibot"}
---
component: 'form-example-valibot'
componentProps:
class: 'w-60'
---
::
::
## Custom validation
Use the `validate` prop to apply your own validation logic.
The validation function must return a list of errors with the following attributes:
- `message` - Error message for display.
- `path` - Path to the form element corresponding to the `name` attribute.
::callout{icon="i-heroicons-light-bulb"}
Note: this can be used alongside the `schema` prop to handle complex use cases.
::
::component-example
---
component: 'form-example-basic'
componentProps:
class: 'w-60'
---
::
This can also be used to integrate with other validation libraries. Here is an example with [Vuelidate](https://github.com/vuelidate/vuelidate):
```vue
<script setup lang="ts">
import useVuelidate from '@vuelidate/core'
const props = defineProps({
rules: { type: Object, required: true },
model: { type: Object, required: true }
})
const form = ref();
const v = useVuelidate(props.rules, props.model)
async function validateWithVuelidate() {
v.value.$touch()
await v.value.$validate()
return v.value.$errors.map((error) => ({
message: error.$message,
path: error.$propertyPath,
}))
}
defineExpose({
validate: async () => {
await form.value.validate()
}
})
</script>
<template>
<UForm ref="form" :model="model" :validate="validateWithVuelidate">
<slot />
</UForm>
</template>
```
## Backend validation
You can manually set errors after form submission if required. To do this, simply use the `form.setErrors` function to set the errors as needed.
```vue
<script setup lang="ts">
import type { FormError, FormSubmitEvent } from '#ui/types'
const state = reactive({
email: undefined,
password: undefined
})
const form = ref()
async function onSubmit (event: FormSubmitEvent<any>) {
form.value.clear()
try {
const response = await $fetch('...')
// ...
} catch (err) {
if (err.statusCode === 422) {
form.value.setErrors(err.data.errors.map((err) => ({
// Map validation errors to { path: string, message: string }
message: err.message,
path: err.path,
})))
}
}
}
</script>
<template>
<UForm ref="form" :state="state" @submit="onSubmit">
<UFormGroup label="Email" name="email">
<UInput v-model="state.email" />
</UFormGroup>
<UFormGroup label="Password" name="password">
<UInput v-model="state.password" type="password" />
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>
```
## Input events
The Form component automatically triggers validation upon `submit`, `input`, `blur` or `change` events.
This ensures that any errors are displayed as soon as the user interacts with the form elements. You can control when validation happens this using the `validate-on` prop.
::callout{icon="i-heroicons-light-bulb"}
Note that the `input` event is not triggered until after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the [`eager-validation`](/components/form-group#eager-validation) prop on [`FormGroup`](/components/form-group) to `true`.
::
::component-example
---
component: 'form-example-elements'
componentProps:
class: 'w-60'
hiddenCode: true
---
::
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/FormExampleElements.vue" target="_blank"}
Take a look at the component!
::
## Error event
You can listen to the `@error` event to handle errors. This event is triggered when the form is validated and contains an array of `FormError` objects with the following fields:
- `id` - the identifier of the form element.
- `path` - the path to the form element matching the `name`.
- `message` - the error message to display.
Here is an example of how to focus the first form element with an error:
::component-example
---
component: 'form-example-on-error'
componentProps:
class: 'w-60'
---
::
## Props
:component-props
## API
When accessing the component via a template ref, you can use the following:
::field-group
::field{name="submit ()" type="Promise<void>"}
Triggers form submission.
::
::field{name="validate (path?: string | string[], opts: { silent?: boolean })" type="Promise<T>"}
Triggers form validation. Will raise any errors unless `opts.silent` is set to true.
::
::field{name="clear (path?: string)"}
Clears form errors associated with a specific path. If no path is provided, clears all form errors.
::
::field{name="getErrors (path?: string)" type="FormError[]"}
Retrieves form errors associated with a specific path. If no path is provided, returns all form errors.
::
::field{name="setErrors (errors: FormError[], path?: string)"}
Sets form errors for a given path. If no path is provided, overrides all errors.
::
::field{name="errors" type="Ref<FormError[]>"}
A reference to the array containing validation errors. Use this to access or manipulate the error information.
::
::

View File

@@ -0,0 +1,56 @@
---
description: Display any icon (100,000+) from Iconify.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Icon.vue
---
## Usage
Use the `name` prop by following this pattern: `i-{collection_name}-{icon_name}`. You can search any icon from [Iconify](https://iconify.design/) using https://icones.js.org.
::component-card
---
props:
name: 'i-heroicons-light-bulb'
---
::
::callout{icon="i-heroicons-exclamation-triangle"}
You won't be able to use all icons in the `name` prop here as icons are bundled using [egoist/tailwindcss-icons](https://github.com/egoist/tailwindcss-icons).
::
::callout{icon="i-heroicons-light-bulb"}
Don't forget to install and specify the icon collections you need in your `nuxt.config.ts`, read more about this in [Theming](/getting-started/theming#icons).
::
### Dynamic
You can use the `dynamic` prop to enable dynamic icon loading. This will use [`nuxt-icon`](https://github.com/nuxt-modules/icon) instead and allow you to use any icon from [Iconify](https://iconify.design/) as well as the `{collection_name}:{icon_name}` pattern.
This can be quite useful when using [dynamic class names](https://tailwindcss.com/docs/content-configuration#dynamic-class-names) or for icons that are not bundled by default (fetched from a database for example).
::component-card
---
props:
name: 'i-ph-rocket-launch'
dynamic: true
---
::
You can also change the default behavior of the `dynamic` prop by setting the `ui.icons.dynamic` option in your `app.config.ts`.
```ts [app.config.ts]
export default defineAppConfig({
ui: {
icons: {
dynamic: true
}
}
})
```
## Props
:component-props

View File

@@ -0,0 +1,208 @@
---
title: InputMenu
description: Display an autocomplete input with real-time suggestions.
links:
- label: 'Combobox'
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/combobox'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/InputMenu.vue
---
## Usage
The `InputMenu` component renders by default an [Input](/components/input) component and is based on the `ui.input` preset. You can use most of the `Input` props to configure the display such as [color](/components/input#style), [variant](/components/input#style), [size](/components/input#size), [placeholder](/components/input#placeholder), [icon](/components/input#icon), [disabled](/components/input#disabled), etc.
You can use the `ui` prop like the `Input` component to override the default config. The `uiMenu` prop can be used to override the default menu config.
Pass an array of strings or objects to the `options` prop to display in the menu.
::component-example
---
component: 'input-menu-example-basic'
componentProps:
class: 'w-full lg:w-48'
---
::
::callout{icon="i-heroicons-exclamation-triangle"}
This component does not support multiple values. Use the [SelectMenu](/components/select-menu#multiple) component instead.
::
### Objects
You can pass an array of objects to `options` and either compare on the whole object or use the `by` prop to compare on a specific key. You can configure which field will be used to display the label through the `option-attribute` prop that defaults to `label`.
::component-example
---
component: 'input-menu-example-objects'
componentProps:
class: 'w-full lg:w-48'
---
::
Use the `search-attributes` prop with an array of property names to search on each option object. Nested attributes can be accessed using `dot.notation`. When the property value is an array or object, these are cast to string so these can be searched within.
::component-example
---
component: 'input-menu-example-search-attributes'
componentProps:
class: 'w-full lg:w-48'
---
::
If you only want to select a single object property rather than the whole object as value, you can set the `value-attribute` property. This prop defaults to `null`.
::component-example
---
component: 'input-menu-example-objects-value-attribute'
componentProps:
class: 'w-full lg:w-48'
---
::
### Icon
The `InputMenu` has a button on the right to toggle the menu. Use the `trailing-icon` prop to set a different icon or change it globally in `ui.inputMenu.default.trailingIcon`. Defaults to `i-heroicons-chevron-down-20-solid`.
::component-card
---
baseProps:
class: 'w-full lg:w-48'
placeholder: 'Select a person'
options: ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
props:
trailingIcon: 'i-heroicons-chevron-up-down-20-solid'
excludedProps:
- trailingIcon
---
::
Use the `selected-icon` prop to set a different icon or change it globally in `ui.inputMenu.default.selectedIcon`. Defaults to `i-heroicons-check-20-solid`.
::component-card
---
baseProps:
class: 'w-full lg:w-48'
placeholder: 'Select a person'
options: ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
props:
selectedIcon: 'i-heroicons-hand-thumb-up-solid'
excludedProps:
- selectedIcon
---
::
::callout{icon="i-heroicons-light-bulb"}
Learn how to customize icons from the [Input](/components/input#icon) component.
::
## Searchable
### Attributes
Use the `search-attributes` prop with an array of property names to search on each option object. Nested attributes can be accessed using `dot.notation`. When the property value is an array or object, these are cast to string so these can be searched within.
::component-example
---
component: 'input-menu-example-search-attributes'
componentProps:
class: 'w-full lg:w-48'
---
::
### Control the query
Use a `v-model:query` to control the search query.
::component-example
---
component: 'input-menu-example-search-query'
componentProps:
class: 'w-full lg:w-48'
---
::
### Async search
Pass a function to the `search` prop to customize the search behavior and filter options according to your needs. The function will receive the query as its first argument and should return an array.
Use the `debounce` prop to adjust the delay of the function.
::component-example
---
component: 'input-menu-example-search-async'
componentProps:
class: 'w-full lg:w-48'
---
::
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="input-menu-example-popper-arrow"}
### Placement
:component-example{component="input-menu-example-popper-placement"}
### Offset
:component-example{component="input-menu-example-popper-offset"}
## Slots
### `option`
Use the `#option` slot to customize the option content. You will have access to the `option`, `active` and `selected` properties in the slot scope.
::component-example
---
component: 'input-menu-example-option-slot'
componentProps:
class: 'w-full lg:w-48'
---
::
### `option-empty`
Use the `#option-empty` slot to customize the content displayed when the `searchable` prop is `true` and there is no options. You will have access to the `query` property in the slot scope.
::component-example
---
component: 'input-menu-example-option-empty-slot'
componentProps:
class: 'w-full lg:w-48'
---
::
### `empty`
Use the `#empty` slot to customize the content displayed when there is no options. Defaults to `No options.`.
::component-example
---
component: 'input-menu-example-empty-slot'
componentProps:
class: 'w-full lg:w-48'
---
::
## Props
:component-props
## Config
::callout{icon="i-heroicons-light-bulb"}
Use the `ui` prop to override the input config and the `uiMenu` prop to override the menu config.
::
::tabs{:selectedIndex="1"}
:component-preset{label="Input (ui)" slug="Input"}
:component-preset{label="InputMenu (uiMenu)"}
::

View File

@@ -0,0 +1,222 @@
---
description: Display an input field.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Input.vue
---
## Usage
Use a `v-model` to make the Input reactive.
:component-example{component="input-example"}
### Style
Use the `color` and `variant` props to change the visual style of the Input.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
color: 'primary'
variant: 'outline'
---
::
Besides all the colors from the `ui.colors` object, you can also use the `white` (default) and `gray` colors with their pre-defined variants.
#### White
::component-card
---
baseProps:
placeholder: 'Search...'
props:
color: 'white'
variant: 'outline'
excludedProps:
- color
---
::
#### Gray
::component-card
---
baseProps:
placeholder: 'Search...'
props:
color: 'gray'
variant: 'outline'
excludedProps:
- color
---
::
### Size
Use the `size` prop to change the size of the Input.
::component-card
---
props:
size: 'sm'
---
::
### Type
Use the `type` prop to change the input type, the default `type` is set to `text`, you can check all the available types at [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types).
Some types have been implemented in their own components, such as [Checkbox](/components/checkbox), [Radio](/components/radio-group), etc. and others have been styled like `file` for example. :u-badge{label="New" class="!rounded-full" variant="subtle"}
::component-card
---
props:
type: 'file'
size: sm
options:
- name: type
restriction: included
values:
- file
- password
- number
---
::
### Placeholder
Use the `placeholder` prop to set a placeholder text.
::component-card
---
props:
placeholder: 'Search...'
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}`.
Use the `leading` and `trailing` props to set the icon position or the `leading-icon` and `trailing-icon` props to set a different icon for each position.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
icon: 'i-heroicons-magnifying-glass-20-solid'
size: 'sm'
color: 'white'
trailing: false
options:
- name: color
restriction: included
values:
- white
- gray
excludedProps:
- icon
---
::
### Disabled
Use the `disabled` prop to disable the Input.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
disabled: true
---
::
### Loading
Use the `loading` prop to show a loading icon and disable the Input.
Use the `loading-icon` prop to set a different icon or change it globally in `ui.input.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-card
---
baseProps:
placeholder: 'Searching...'
props:
loading: true
icon: 'i-heroicons-magnifying-glass-20-solid'
excludedProps:
- icon
---
::
### Padded
Use the `padded` prop to remove the padding of the Input.
::component-card
---
props:
padded: false
baseProps:
placeholder: 'Search...'
variant: 'none'
class: 'w-full'
---
::
## Slots
### `leading`
Use the `#leading` slot to set the content of the leading icon.
::component-card
---
slots:
leading: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="2xs" />
baseProps:
placeholder: 'Search...'
---
#leading
:u-avatar{src="https://avatars.githubusercontent.com/u/739984?v=4" size="2xs"}
::
### `trailing`
Use the `#trailing` slot to set the content of the trailing icon.
::component-card
---
slots:
trailing: <span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
baseProps:
placeholder: 'Search...'
---
#trailing
[EUR]{class="text-gray-500 dark:text-gray-400 text-xs"}
::
You can for example create a clearable Input by injecting a [Button](/components/button) in the `trailing` slot that displays when some text is entered.
:component-example{component="input-example-clearable"}
::callout{icon="i-heroicons-exclamation-triangle-20-solid"}
As leading and trailing icons are wrapped around a `pointer-events-none` class, if you inject a clickable element in the slot, you need to remove this class to make it clickable by adding `:ui="{ icon: { trailing: { pointer: '' } } }"` to the Input.
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,57 @@
---
title: 'Keyboard Key'
description: Display a keyboard key in a text block.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Kbd.vue
navigation:
title: 'Kbd'
---
## Usage
Use the default slot to set the text of the Kbd.
::component-card
---
code: K
---
K
::
You can also use the `value` prop:
::component-card
---
props:
value: K
---
::
As explained in the [Shortcuts](/getting-started/shortcuts) page, you can use the `metaSymbol` property of the `useShortcuts` composable to display the meta key according to the user's OS.
:component-example{component="kbd-example"}
### Size
Use the `size` prop to change the size of the Kbd.
::component-card
---
props:
size: 'sm'
code: 'U'
---
U
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,50 @@
---
title: 'Link'
description: Render a NuxtLink but with superpowers.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Link.vue
---
## Usage
The Link component is a wrapper around [`<NuxtLink>`](https://nuxt.com/docs/api/components/nuxt-link) through the [`custom`](https://router.vuejs.org/api/interfaces/RouterLinkProps.html#Properties-custom) prop that provides a few extra props:
- `inactive-class` prop to set a class when the link is inactive, `active-class` is used when active.
- `exact` prop to style with `active-class` when the link is active and the route is exactly the same as the current route.
- `exact-query` and `exact-hash` props to style with `active-class` when the link is active and the query or hash is exactly the same as the current query or hash.
The incentive behind this is to provide the same API as NuxtLink back in Nuxt 2 / Vue 2. You can read more about it in the Vue Router [migration from Vue 2](https://router.vuejs.org/guide/migration/#removal-of-the-exact-prop-in-router-link) guide.
::component-card
---
props:
to: /components/link
activeClass: 'text-primary'
inactiveClass: 'text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200'
code: ' Link '
---
Link
::
It also renders an `<a>` tag when a `to` prop is provided, otherwise it defaults to rendering a `<button>` tag. The default behavior can be customized using the `as` prop.
It is used underneath by the [Button](/components/button), [Dropdown](/components/dropdown) and [VerticalNavigation](/components/vertical-navigation) components.
## IntelliSense
If you're using VSCode and wish to get autocompletion for the classes `active-class` and `inactive-class`, you can add the following settings to your `.vscode/settings.json`:
```json [.vscode/settings.json]
{
"tailwindCSS.classAttributes": [
"active-class",
"inactive-class"
],
}
```
## Props
:component-props

View File

@@ -0,0 +1,179 @@
---
title: 'Meter'
description: Display a gauge meter that fills or depletes.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Meter.vue
badge: Coming soon
---
## Usage
Use the `value` prop from `0` to `100` to set a value for the meter bar.
::component-card
---
props:
value: 25
---
::
::callout{icon="i-heroicons-light-bulb"}
Check out the [Range](/components/range) component for inputs
::
### Min & Max
By default, `min` is `0` and `max` is `100`. You can change either of these using their respective props, even for negative numbers.
::component-card
---
props:
value: -25
min: -50
max: 50
---
::
### Indicator
You may show a percentage indicator on top of the meter using the `indicator` prop.
::component-card
---
props:
value: 35
indicator: true
---
::
### Label
Add a label below the meter using the `label` prop.
::component-card
---
baseProps:
value: 86
props:
label: Disk usage
---
::
### Icon
You may also add an icon to the start label using the `icon` prop.
::component-card
---
baseProps:
value: 86
label: Disk usage
props:
icon: i-heroicons-server
excludedProps:
- icon
---
::
### Size
Change the size of the meter bar using the `size` prop.
::component-card
---
baseProps:
value: 75.4
props:
size: 'md'
indicator: true
label: CPU Load
---
::
### Style
The `color` prop changes the visual style of the meter bar. The `color` can be any color from the `ui.colors` object.
::component-card
---
baseProps:
value: 80
indicator: true
label: Memory usage
props:
color: 'primary'
---
::
## Group
To group multiple meters into a group, adding all values, use the `MeterGroup` component.
- To change the overall minimum and maximum value, pass the `min` and `max` props respectively.
- To change size of all meters, use the `size` prop.
- To show an indicator for the overall amount, set the `indicator` prop or slot.
- To change the color of each meter, use the `color` prop.
- To show a label for each meter, use the `label` prop on each meter.
- To change the icon for each meter, use the `icon` prop.
::component-card{slug="UMeterGroup"}
---
baseProps:
icon: i-heroicons-minus
props:
min: 0
max: 128
size: 'md'
indicator: true
code: |
<UMeter :value="24" color="gray" label="System" />
<UMeter :value="8" color="red" label="Apps" />
<UMeter :value="12" color="yellow" label="Documents" />
<UMeter :value="42" color="green" label="Multimedia" />
<!-- Total: 86 -->
---
#default
:u-meter{:value="24" color="gray" label="System"}
:u-meter{:value="8" color="red" label="Apps"}
:u-meter{:value="12" color="yellow" label="Documents"}
:u-meter{:value="42" color="green" label="Multimedia"}
::
::callout{icon="i-heroicons-exclamation-triangle"}
When the Meters are grouped, their individual indicators and label slots are stripped away.
::
A Meter group can also be used with an [indicator slot](#indicator-1), and even individual meter icons.
:component-example{component="meter-group-example-slots"}
## Slots
### `indicator`
Use the `#indicator` slot to change the indicator shown at the top of the bar. It receives the current meter percent.
:component-example{component="meter-slot-indicator-example"}
### `label`
The `label` slot can be used to change how the label below the meter bar is shown. It receives the current meter percent.
:component-example{component="meter-slot-label-example"}
## Props
::tabs
:component-props{label="Meter"}
:component-props{label="MeterGroup" slug="UMeterGroup"}
::
## Config
::tabs
:component-preset{label="Meter"}
:component-preset{label="MeterGroup" slug="MeterGroup"}
::

View File

@@ -0,0 +1,90 @@
---
description: Display a modal within your application.
links:
- label: 'Dialog'
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/dialog'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Modal.vue
---
## Usage
Use a `v-model` to control the Modal state.
:component-example{component="modal-example-basic"}
You can put a [Card](/components/card) component inside your Modal to handle forms and take advantage of `header` and `footer` slots:
:component-example{component="modal-example-card"}
### Disable overlay
Set the `overlay` prop to `false` to disable it.
:component-example{component="modal-example-disable-overlay"}
### Disable transition
Set the `transition` prop to `false` to disable it.
:component-example{component="modal-example-disable-transition"}
### Prevent close
Use the `prevent-close` prop to disable the outside click alongside the `esc` keyboard shortcut. A `close-prevented` event will be emitted when the user tries to close the modal.
:component-example{component="modal-example-prevent-close"}
You can still handle the `esc` shortcut yourself by using our [defineShortcuts](/getting-started/shortcuts#defineshortcuts) composable.
```vue
<script setup lang="ts">
const isOpen = ref(false)
defineShortcuts({
escape: {
usingInput: true,
whenever: [isOpen],
handler: () => { isOpen.value = false }
}
})
</script>
```
### Fullscreen
Set the `fullscreen` prop to `true` to enable it.
:component-example{component="modal-example-fullscreen"}
### Control programmatically :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
First of all, add the `Modals` component to your app, preferably inside `app.vue`.
```vue [app.vue]
<template>
<div>
<UContainer>
<NuxtPage />
</UContainer>
<UModals />
</div>
</template>
```
Then, you can use the `useModal` composable to control your modals within your app.
:component-example{component="modal-example-composable"}
Additionally, you can close the modal within the modal component by calling `modal.close()`.
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,62 @@
---
title: HorizontalNavigation
description: Display a list of horizontal links.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/HorizontalNavigation.vue
---
## Usage
Pass an array to the `links` prop of the HorizontalNavigation component. Each link can have the following properties:
- `label` - The label of the link.
- `labelClass` - The class of the link label.
- `icon` - The icon of the link.
- `iconClass` - The class of the link icon.
- `avatar` - The avatar of the link. You can pass all the props of the [Avatar](/components/avatar) component.
- `badge` - A badge to display next to the label. You can pass all the props of the [Badge](/components/badge) component.
- `click` - The click handler of the link.
You can also pass any property from the [NuxtLink](https://nuxt.com/docs/api/components/nuxt-link#props) component such as `to`, `exact`, etc.
:component-example{component="horizontal-navigation-example"}
## Sections
Group your navigation links into distinct sections, they will be displayed apart thanks to a `justify-between` flexbox layout.
You can do this by passing an array of arrays to the `links` prop of the HorizontalNavigation component.
:component-example{component="horizontal-navigation-example-sections"}
## Slots
You can use slots to customize links display.
### `default`
Use the `#default` slot to customize the link label. You will have access to the `link` and `isActive` properties in the slot scope.
:component-example{component="horizontal-navigation-example-default-slot"}
### `avatar`
Use the `#avatar` slot to customize the link avatar. You will have access to the `link` and `isActive` properties in the slot scope.
### `icon`
Use the `#icon` slot to customize the link icon. You will have access to the `link` and `isActive` properties in the slot scope.
### `badge`
Use the `#badge` slot to customize the link badge. You will have access to the `link` and `isActive` properties in the slot scope.
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,302 @@
---
description: Display a toast notification in your app.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Notification.vue
---
## Usage
First of all, add the `Notifications` component to your app, preferably inside `app.vue`.
```vue [app.vue]
<template>
<div>
<UContainer>
<NuxtPage />
</UContainer>
<UNotifications />
</div>
</template>
```
This component will render the notifications at the bottom right of the screen by default. You can configure its behavior in the `app.config.ts` through `ui.notifications`:
```ts [app.config.ts]
export default defineAppConfig({
ui: {
notifications: {
// Show toasts at the top right of the screen
position: 'top-0 bottom-auto'
}
}
})
```
Then, you can use the `useToast` composable to add notifications to your app:
:component-example{component="notification-example-basic"}
When using `toast.add`, this will push a new notification to the stack displayed in `<UNotifications />`. All the props of the `Notification` component can be passed to `toast.add`.
```vue
<script setup lang="ts">
const toast = useToast()
onMounted(() => {
toast.add({
id: 'update_downloaded',
title: 'Update downloaded.',
description: 'It will be installed on restart. Restart now?',
icon: 'i-octicon-desktop-download-24',
timeout: 0,
actions: [{
label: 'Restart',
click: () => {
}
}]
})
})
</script>
```
You can also use the `Notification` component directly in your app as an alert for example.
### Title
Pass a `title` to your Notification.
::component-card
---
baseProps:
id: 1
timeout: 0
props:
title: 'Notification'
---
::
### Description
You can add a `description` in addition of the `title`.
::component-card
---
baseProps:
id: 2
timeout: 0
title: 'Notification'
props:
description: 'This is a notification.'
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}` or change it globally in `ui.notification.default.icon`.
::component-card
---
baseProps:
id: 3
timeout: 0
title: 'Notification'
props:
icon: 'i-heroicons-check-circle'
description: 'This is a notification.'
excludedProps:
- icon
---
::
### Avatar
Use the [avatar](/components/avatar) prop as an `object` and configure it with any of its props.
::component-card
---
baseProps:
id: 4
timeout: 0
title: 'Notification'
props:
description: 'This is a notification.'
avatar:
src: 'https://avatars.githubusercontent.com/u/739984?v=4'
excludedProps:
- avatar
---
::
### Timeout
Use the `timeout` prop to configure how long the Notification will remain. The default value is `5000`, set it to `0` to disable the timeout.
You will see a progress bar at the bottom of the Notification which will indicate the remaining time. When hovering the Notification, the progress bar will be paused.
::component-card
---
baseProps:
id: 5
title: 'Notification'
description: 'This is a notification.'
props:
timeout: 60000
---
::
### Style
Use the `color` prop to change the progress and icon color of the Notification.
::component-card
---
baseProps:
id: 6
title: 'Notification'
description: 'This is a notification.'
timeout: 600000
props:
icon: 'i-heroicons-check-badge'
color: 'primary'
options:
- name: color
restriction: included
values:
- gray
excludedProps:
- icon
---
::
### Click
Use the `click` prop to execute a function when the Notification is clicked.
:component-example{component="notification-example-click"}
### Callback
Use the `callback` prop to execute a function when the Notification expires.
:component-example{component="notification-example-callback"}
### Close
Use the `close-button` prop to hide or customize the close button on the Notification.
You can pass all the props of the [Button](/components/button) component to customize it through the `close-button` prop or globally through `ui.notification.default.closeButton`.
::component-card
---
baseProps:
id: 7
title: 'Notification'
timeout: 0
props:
closeButton:
icon: 'i-heroicons-archive-box-x-mark'
color: 'primary'
variant: 'outline'
padded: true
size: '2xs'
ui:
rounded: 'rounded-full'
excludedProps:
- closeButton
---
::
### Actions
Use the `actions` prop to add actions to the Notification.
:component-example{component="notification-example-actions"}
Like for `closeButton`, you can pass all the props of the [Button](/components/button) component inside the action or globally through `ui.notification.default.actionButton`.
::component-card
---
baseProps:
id: 8
title: 'Notification'
timeout: 0
props:
actions:
- label: Action 1
- variant: 'solid'
color: 'gray'
label: Action 2
excludedProps:
- actions
---
::
Actions will render differently whether you have a `description` set.
::component-card
---
baseProps:
id: 9
title: 'Notification'
description: 'This is a notification.'
timeout: 0
props:
actions:
- variant: 'solid'
color: 'primary'
label: Action 1
- variant: 'outline'
color: 'primary'
label: Action 2
excludedProps:
- actions
---
::
## Slots
### `title` / `description`
Use the `#title` and `#description` slots to customize the Notification.
This can be handy when you want to display HTML content. To achieve this, you can define those slots in the top-level `<UNotifications />` component in your `app.vue` and use the `v-html` directive.
```vue [app.vue]
<template>
<UNotifications>
<template #title="{ title }">
<span v-html="title" />
</template>
<template #description="{ description }">
<span v-html="description" />
</template>
</UNotifications>
</template>
```
This way, you can use HTML tags in the `title` and `description` props when using `useToast`.
:component-example{component="notification-example-html"}
::callout{icon="i-heroicons-light-bulb"}
Slots defined in the `<UNotifications />` component are automatically passed down to the `Notification` children.
::
## Props
::tabs
:component-props{label="Notification"}
:component-props{label="Notifications" slug="UNotifications"}
::
## Config
::tabs
:component-preset{label="Notification"}
:component-preset{label="Notifications" slug="Notifications"}
::

View File

@@ -0,0 +1,157 @@
---
description: Add a pagination to handle pages.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/Pagination.vue
---
## Usage
Use a `v-model` to get a reactive page alongside a `total` which represents the total of items. You can also use the `page-count` prop to define the number of items per page which defaults to `10`.
:component-example{component="pagination-example-basic"}
### Max
Use the `max` prop to set a maximum of displayed pages. Defaults to `7`, being the minimum.
::component-card
---
baseProps:
modelValue: 1
props:
max: 5
pageCount: 5
total: 100
excludedProps:
- pageCount
- total
---
::
### Size
Use the `size` prop to change the size of the buttons.
::component-card
---
baseProps:
modelValue: 1
total: 100
showLast: true
showFirst: true
props:
size: 'sm'
---
::
### Disabled
Use the `disabled` prop to disable all the buttons.
::component-card
---
baseProps:
modelValue: 1
total: 100
showLast: true
showFirst: true
props:
disabled: true
---
::
### Active / Inactive
Use the `active-button` and `inactive-button` props to customize the active and inactive buttons of the Pagination.
::component-card
---
baseProps:
modelValue: 1
total: 100
props:
activeButton:
variant: 'outline'
inactiveButton:
color: 'gray'
excludedProps:
- activeButton
- inactiveButton
---
::
### Prev / Next
Use the `prev-button` and `next-button` props to customize the prev and next buttons of the Pagination.
::component-card
---
baseProps:
modelValue: 1
total: 100
props:
prevButton:
icon: 'i-heroicons-arrow-small-left-20-solid'
label: Prev
color: 'gray'
nextButton:
icon: 'i-heroicons-arrow-small-right-20-solid'
trailing: true
label: Next
color: 'gray'
excludedProps:
- prevButton
- nextButton
---
::
### First / Last
Use the `first-button` and `last-button` props to customize the first and last buttons of the Pagination.
::component-card
---
baseProps:
modelValue: 1
total: 100
showFirst: true
showLast: true
props:
firstButton:
icon: 'i-heroicons-arrow-small-left-20-solid'
label: First
color: 'gray'
lastButton:
icon: 'i-heroicons-arrow-small-right-20-solid'
trailing: true
label: Last
color: 'gray'
excludedProps:
- firstButton
- lastButton
---
::
## Slots
### `prev` / `next`
Use the `#prev` and `#next` slots to set the content of the previous and next buttons.
:component-example{component="pagination-example-prev-next-slots"}
### `first` / `last`
Use the `#first` and `#last` slots to set the content of the first and last buttons.
:component-example{component="pagination-example-first-last-slots"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,62 @@
---
description: Display a non-modal dialog that floats around a trigger element.
links:
- label: 'Popover'
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/popover'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Popover.vue
---
## Usage
:component-example{component="popover-example"}
### Mode
Use the `mode` prop to switch between `click` and `hover` modes.
:component-example{component="popover-example-mode"}
### Manual
Use a `v-model:open` to manually control the state. In this example, press :shortcut{value="O"} to toggle the popover.
:component-example{component="popover-example-open"}
### Overlay
:component-example{component="popover-example-overlay"}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="popover-example-arrow"}
### Placement
:component-example{component="popover-example-placement"}
### Offset
:component-example{component="popover-example-offset"}
## Slots
### `panel`
Use the `#panel` slot to fill the content of the panel. You will have access to the `open` property and the `close` method in the slot scope.
:component-example{component="popover-example-slot"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,151 @@
---
title: 'Progress'
description: Show a horizontal bar to indicate task progression.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Progress.vue
---
## Usage
Pass an integer as the `value` from `0` to `100` to the Progress bar component.
::component-card
---
props:
value: 70
---
::
::callout{icon="i-heroicons-light-bulb"}
Check out the [Range](/components/range) component for forms.
::
### Max
You may also set the `max` number to set the maximum progress value, which will be relative to 100% percent.
::component-card
---
props:
value: 2
max: 5
options:
- name: max
restriction: only
values:
- 3
- 4
- 5
- 6
- 7
---
::
### Steps
You can set an array of named steps in the `max` prop to show the active step, at the same time it sets the maximum value.
The first step is always shown at `0%`, making the last `100%`.
::component-card
---
props:
value: 0
max:
- Waiting to start
- Cloning...
- Migrating...
- Deployed!
excludedProps:
- max
---
::
### Progress indicator
You can add a numeric indicator, which will show the percent on top the progress track.
::component-card
---
props:
value: 20
indicator: true
---
::
### Indeterminate
By not setting a `value`, or setting it as `null`, the progress bar becomes _indeterminate_. The bar will be animated as a carousel, but you can change it using the `animation` prop for an inverse carousel, a swinging bar or an elastic bar.
::component-card
---
baseProps:
value: null
props:
animation: 'carousel'
options:
- name: animation
restriction: only
values:
- 'carousel'
- 'carousel-inverse'
- 'swing'
- 'elastic'
---
::
### Size
Use the `size` prop to change the size of the progress bar.
::component-card
---
baseProps:
value: 70
props:
size: 'md'
indicator: false
excludedProps:
- value
---
::
### Style
Use the `color` prop to change the visual style of the Progress bar. The `color` can be any color from the `ui.colors` object.
::component-card
---
baseProps:
value: 70
props:
color: 'primary'
indicator: false
excludedProps:
- modelValue
---
::
## Slots
### `indicator`
You can use the `#indicator` slot to show a custom indicator above the progress bar. It receives the current `percent` of progress.
:component-example{component="progress-example-slot-indicator"}
### `step-<index>`
Use the `#step-<index>` to alter the HTML being shown for each step.
:component-example{component="progress-example-slot-step"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,172 @@
---
title: RadioGroup
description: Display a set of radio buttons.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/RadioGroup.vue
---
## Usage
Use a `v-model` to make the RadioGroup reactive.
:component-example{component="radio-group-example"}
Alternatively, you can use individual Radio components:
:component-example{component="radio-example"}
::callout{icon="i-heroicons-light-bulb"}
If using the RadioGroup component, you can customize the Radio options by using the `uiRadio` prop.
::
### Legend
Use the `legend` prop to add a legend to the RadioGroup.
::component-card
---
baseProps:
options: [{ value: 'email', label: 'Email' }, { value: 'sms', label: 'Phone (SMS)' }, { value: 'push', label: 'Push notification' }]
modelValue: 'sms'
props:
legend: 'Legend'
---
::
### Style
Use the `color` prop to change the style of the RadioGroup.
::component-card
---
baseProps:
options: [{ value: 'email', label: 'Email' }, { value: 'sms', label: 'Phone (SMS)' }, { value: 'push', label: 'Push notification' }]
modelValue: 'sms'
props:
color: 'primary'
---
::
::callout{icon="i-heroicons-light-bulb"}
This prop also work on the Radio component.
::
### Orientation
You can change the orientation of the divider by setting the `orientation` prop to `horizontal` or `vertical`. Defaults to `vertical`.
::component-card
---
baseProps:
options: [{ value: 'email', label: 'Email' }, { value: 'sms', label: 'Phone (SMS)' }, { value: 'push', label: 'Push notification' }]
modelValue: 'sms'
props:
orientation: 'horizontal'
---
::
### Disabled
Use the `disabled` prop to disable the RadioGroup.
::component-card
---
baseProps:
options: [{ value: 'email', label: 'Email' }, { value: 'sms', label: 'Phone (SMS)' }, { value: 'push', label: 'Push notification', disabled: true }]
modelValue: 'sms'
props:
disabled: true
---
::
::callout{icon="i-heroicons-light-bulb"}
This prop also work on the Radio component and you can set the `disabled` field in the `options` to disable a specific Radio.
::
### Label
Use the `label` prop to display a label on the right of the Radio.
::component-card{slug="URadio"}
---
props:
label: 'Label'
---
::
### Required
Use the `required` prop to display a red star next to the label of the Radio.
::component-card{slug="URadio"}
---
props:
label: 'Label'
required: true
---
::
### Help
Use the `help` prop to display some text under the Radio.
::component-card{slug="URadio"}
---
props:
label: 'Label'
help: 'Please choose one'
---
::
## Slots
### `label`
Use the `#label` slot to override the label of each option.
:component-example{component="radio-group-label-example"}
Alternatively, you can do the same with individual Radio:
::component-card{slug="URadio"}
---
slots:
label: <span class="italic">Label</span>
---
#label
[Label]{.italic}
::
### `legend`
Use the `#legend` slot to override the content of the legend.
::component-card
---
baseProps:
options: [{ value: 'email', label: 'Email' }, { value: 'sms', label: 'Phone (SMS)' }, { value: 'push', label: 'Push notification' }]
modelValue: 'sms'
slots:
legend: <span class="italic">Legend</span>
---
#legend
[Legend]{.italic}
::
## Props
::tabs
:component-props{label="Radio" slug="URadio"}
:component-props{label="RadioGroup"}
::
## Config
::tabs
:component-preset{label="Radio" slug="Radio"}
:component-preset{label="RadioGroup"}
::

View File

@@ -0,0 +1,79 @@
---
description: Display a range field
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Range.vue
---
## Usage
Use a `v-model` to make the Range reactive.
:component-example{component="range-example"}
### Style
Use the `color` prop to change the visual style of the Range.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
color: 'primary'
---
::
### Size
Use the `size` prop to change the size of the Range.
::component-card
---
props:
size: 'md'
---
::
### Disabled
Use the `disabled` prop to disable the Range.
::component-card
---
props:
disabled: true
---
::
### Min and Max
Use the `min` and `max` prop to configure the Range.
::component-card
---
props:
min: 0
max: 100
---
::
### Step
Use the `step` prop to change the step increment.
::component-card
---
props:
step: 20
---
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,288 @@
---
title: SelectMenu
description: Display a select menu with advanced features.
links:
- label: 'Listbox'
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/listbox'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/SelectMenu.vue
---
## Usage
The `SelectMenu` component renders by default a [Select](/components/select) component and is based on the `ui.select` preset. You can use most of the `Select` props to configure the display if you don't want to override the default slot such as [color](/components/select#style), [variant](/components/select#style), [size](/components/select#size), [placeholder](/components/select#placeholder), [icon](/components/select#icon), [disabled](/components/select#disabled), etc.
You can use the `ui` prop like the `Select` component to override the default config. The `uiMenu` prop can be used to override the default menu config.
Like the `Select` component, you can use the `options` prop to pass an array of strings or objects.
::component-example
---
component: 'select-menu-example-basic'
componentProps:
class: 'w-full lg:w-48'
---
::
### Multiple
You can use the `multiple` prop to select multiple values.
::component-example
---
component: 'select-menu-example-multiple'
componentProps:
class: 'w-full lg:w-48'
---
::
### Objects
You can pass an array of objects to `options` and either compare on the whole object or use the `by` prop to compare on a specific key. You can configure which field will be used to display the label through the `option-attribute` prop that defaults to `label`.
::component-example
---
component: 'select-menu-example-objects'
componentProps:
class: 'w-full lg:w-48'
---
::
If you only want to select a single object property rather than the whole object as value, you can set the `value-attribute` property. This prop defaults to `null`.The value of the `value-attribute` field in options must be unique.
::component-example
---
component: 'select-menu-example-objects-value-attribute'
componentProps:
class: 'w-full lg:w-48'
---
::
### Icon
Use the `selected-icon` prop to set a different icon or change it globally in `ui.selectMenu.default.selectedIcon`. Defaults to `i-heroicons-check-20-solid`.
::component-card
---
baseProps:
class: 'w-full lg:w-48'
placeholder: 'Select a person'
options: ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
props:
selectedIcon: 'i-heroicons-hand-thumb-up-solid'
excludedProps:
- selectedIcon
---
::
::callout{icon="i-heroicons-light-bulb"}
Learn how to customize icons from the [Select](/components/select#icon) component.
::
## Searchable
Use the `searchable` prop to enable search.
Use the `searchable-placeholder` prop to set a different placeholder.
This will use Headless UI [Combobox](https://headlessui.com/vue/combobox) component instead of [Listbox](https://headlessui.com/vue/listbox).
::component-card
---
baseProps:
class: 'w-full lg:w-48'
placeholder: 'Select a person'
options: ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
props:
searchable: true
searchablePlaceholder: 'Search a person...'
---
::
### Attributes
Use the `search-attributes` prop with an array of property names to search on each option object. Nested attributes can be accessed using `dot.notation`. When the property value is an array or object, these are cast to string so these can be searched within.
::component-example
---
component: 'select-menu-example-search-attributes'
componentProps:
class: 'w-full lg:w-48'
---
::
### Clear on close
By default, the search query will be kept after the menu is closed. To clear it on close, set the `clear-search-on-close` prop.
You can also configure this globally through the `ui.selectMenu.default.clearSearchOnClose` config. Defaults to `false`.
::component-card
---
baseProps:
class: 'w-full lg:w-48'
placeholder: 'Select a person'
searchable: true
searchablePlaceholder: 'Search a person...'
options: ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
props:
clearSearchOnClose: true
---
::
### Control the query
Use a `v-model:query` to control the search query.
::component-example
---
component: 'select-menu-example-search-query'
componentProps:
class: 'w-full lg:w-48'
---
::
### Async search
Pass a function to the `searchable` prop to customize the search behavior and filter options according to your needs. The function will receive the query as its first argument and should return an array.
Use the `debounce` prop to adjust the delay of the function.
::component-example
---
component: 'select-menu-example-search-async'
componentProps:
class: 'w-full lg:w-48'
---
::
## Creatable
Use the `creatable` prop to enable the creation of new options when the search doesn't return any results (only works with `searchable`).
Try to search for something that doesn't exist in the example below.
::component-example
---
component: 'select-menu-example-creatable'
componentProps:
class: 'w-full lg:w-48'
---
::
However, if you want to create options despite search query (apart from exact match), you can set the `show-create-option-when` prop to `'always'`.
You can also configure this globally through the `ui.selectMenu.default.showCreateOptionWhen` config. Defaults to `empty`.
Try to search for something that exists in the example below, but not an exact match.
::component-example
---
component: 'select-menu-example-creatable-always'
componentProps:
class: 'w-full lg:w-48'
---
::
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="select-menu-example-arrow"}
### Placement
:component-example{component="select-menu-example-placement"}
### Offset
:component-example{component="select-menu-example-offset"}
## Slots
### `label`
You can override the `#label` slot and handle the display yourself.
::component-example
---
component: 'select-menu-example-multiple-slot'
componentProps:
class: 'w-full lg:w-48'
---
::
### `default`
You can also override the `#default` slot entirely.
::component-example
---
component: 'select-menu-example-button'
componentProps:
class: 'w-full lg:w-48'
---
::
### `option`
Use the `#option` slot to customize the option content. You will have access to the `option`, `active` and `selected` properties in the slot scope.
::component-example
---
component: 'select-menu-example-option-slot'
componentProps:
class: 'w-full lg:w-48'
---
::
### `option-empty`
Use the `#option-empty` slot to customize the content displayed when the `searchable` prop is `true` and there is no options. You will have access to the `query` property in the slot scope.
::component-example
---
component: 'select-menu-example-option-empty-slot'
componentProps:
class: 'w-full lg:w-48'
---
::
### `option-create`
Use the `#option-create` slot to customize the content displayed when the `creatable` prop is `true` and there is no options. You will have access to the `query` property in the slot scope.
::callout{icon="i-heroicons-light-bulb"}
An example is available in the [Creatable](#creatable) section.
::
### `empty`
Use the `#empty` slot to customize the content displayed when there is no options. Defaults to `No options.`.
::component-example
---
component: 'select-menu-example-empty-slot'
componentProps:
class: 'w-full lg:w-48'
---
::
## Props
:component-props
## Config
::callout{icon="i-heroicons-light-bulb"}
Use the `ui` prop to override the select config and the `uiMenu` prop to override the menu config.
::
::tabs{:selectedIndex="1"}
:component-preset{label="Select (ui)" slug="Select"}
:component-preset{label="SelectMenu (uiMenu)"}
::

View File

@@ -0,0 +1,241 @@
---
description: Display a select field.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Select.vue
---
## Usage
The Select component is a wrapper around the native `<select>` HTML element. For more advanced use cases like searching or multiple selection, consider using the [SelectMenu](/components/select-menu) component.
Use a `v-model` to make the Select reactive alongside the `options` prop to pass an array of strings or objects.
:component-example{component="select-example"}
When using objects, you can configure which field will be used for display through the `option-attribute` prop that defaults to `label` and which field will be used for comparison through the `value-attribute` prop that defaults to `value`.
Adding a `disabled` key to the objects will control the disabled state of the option.
:component-example{component="select-example-objects"}
### Style
Use the `color` and `variant` props to change the visual style of the Select.
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
props:
color: 'primary'
variant: 'outline'
---
::
Besides all the colors from the `ui.colors` object, you can also use the `white` (default) and `gray` colors with their pre-defined variants.
#### White
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
props:
color: 'white'
variant: 'outline'
excludedProps:
- color
---
::
#### Gray
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
props:
color: 'gray'
variant: 'outline'
excludedProps:
- color
---
::
### Size
Use the `size` prop to change the size of the Select.
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
props:
size: 'sm'
---
::
### Placeholder
Use the `placeholder` prop to set a placeholder text.
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
props:
placeholder: 'Search...'
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}`.
Use the `trailing-icon` prop to set a different icon or change it globally in `ui.select.default.trailingIcon`. Defaults to `i-heroicons-chevron-down-20-solid`.
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
placeholder: 'Search...'
props:
icon: 'i-heroicons-magnifying-glass-20-solid'
color: 'white'
size: 'sm'
options:
- name: color
restriction: included
values:
- white
- gray
excludedProps:
- icon
---
::
### Disabled
Use the `disabled` prop to disable the Select.
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
placeholder: 'Search...'
props:
disabled: true
---
::
Add a `disabled` key with a truthy value to the `options` array of object to disable a single option.
### Loading
Use the `loading` prop to show a loading icon and disable the Input.
Use the `loading-icon` prop to set a different icon or change it globally in `ui.select.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-card
---
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
placeholder: 'Search...'
props:
loading: true
icon: 'i-heroicons-magnifying-glass-20-solid'
excludedProps:
- icon
---
::
### Padded
Use the `padded` prop to remove the padding of the Select.
::component-card
---
props:
padded: false
baseProps:
placeholder: 'Search...'
options:
- 'United States'
- 'Canada'
- 'Mexico'
variant: 'none'
class: 'w-full'
---
::
## Slots
### `leading`
Use the `#leading` slot to set the content of the leading icon.
::component-card
---
slots:
leading: <UIcon name="i-heroicons-flag" class="w-5 h-5" />
baseProps:
options:
- 'United States'
- 'Canada'
- 'Mexico'
placeholder: 'Search...'
---
#leading
:u-icon{name="i-heroicons-flag" class="w-5 h-5"}
::
### `trailing`
Use the `#trailing` slot to set the content of the trailing icon.
::component-card
---
slots:
trailing: <UIcon name="i-heroicons-arrows-up-down-20-solid" class="w-5 h-5" />
baseProps:
placeholder: 'Search...'
---
#trailing
:u-icon{name="i-heroicons-arrows-up-down-20-solid" class="w-5 h-5"}
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,113 @@
---
description: Display a separator between content.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Divider.vue
---
## Usage
You can pass `label`, `icon` or `avatar` to the divider component.
### Label
::component-card
---
props:
label: OR
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `icon` prop by using this pattern: `i-{collection_name}-{icon_name}`.
::component-card
---
props:
icon: 'i-simple-icons-github'
excludedProps:
- icon
---
::
### Avatar
Use the [avatar](/components/avatar) prop as an `object` and configure it with any of its props.
::component-card
---
props:
avatar:
src: https://avatars.githubusercontent.com/u/739984?v=4
excludedProps:
- avatar
---
::
### Orientation
You can change the orientation of the divider by setting the `orientation` prop to `horizontal` or `vertical`. Defaults to `horizontal`.
:component-example{component="divider-example-orientation"}
### Type
You can change the type of the divider by setting the `type` prop to `solid`, `dotted` or `dashed`. Defaults to `solid`.
::component-card{class="w-full"}
---
props:
label: Nuxt UI
type: dashed
excludedProps:
- label
---
::
### Size :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
Use the `size` prop to change the size of the divider.
::component-card
---
props:
label: Nuxt UI
size: sm
excludedProps:
- label
---
::
### Color
You can change the color of the content by using the `ui` prop
::component-card
---
props:
label: Nuxt UI
ui:
label: text-primary-500 dark:text-primary-400
excludedProps:
- label
- ui
---
::
## Slots
### `default`
Use the `default` slot to add content to the divider.
:component-example{component="divider-example-default-slot"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,21 @@
---
description: Display a placeholder while content is loading.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/layout/Skeleton.vue
---
## Usage
Use to show a placeholder while content is loading.
:component-example{component="skeleton-example"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,80 @@
---
description: Display a dialog that slides in from the edge of the screen.
links:
- label: 'Dialog'
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/dialog'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Slideover.vue
---
## Usage
Use a `v-model` to control the Slideover state.
:component-example{component="slideover-example-basic"}
You can put a [Card](/components/card) component inside your Slideover to handle forms and take advantage of `header` and `footer` slots:
:component-example{component="slideover-example-card"}
### Disable overlay
Set the `overlay` prop to `false` to disable it.
:component-example{component="slideover-example-disable-overlay"}
### Disable transition
Set the `transition` prop to `false` to disable it.
:component-example{component="slideover-example-disable-transition"}
### Prevent close
Use the `prevent-close` prop to disable the outside click alongside the `esc` keyboard shortcut. A `close-prevented` event will be emitted when the user tries to close the slideover.
:component-example{component="slideover-example-prevent-close"}
You can still handle the `esc` shortcut yourself by using our [defineShortcuts](/getting-started/shortcuts#defineshortcuts) composable.
```vue
<script setup lang="ts">
const isOpen = ref(false)
defineShortcuts({
escape: {
usingInput: true,
whenever: [isOpen],
handler: () => { isOpen.value = false }
}
})
</script>
```
### Control programmatically :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
First of all, add the `USlideovers` component to your app, preferably inside `app.vue`.
```vue [app.vue]
<template>
<div>
<UContainer>
<NuxtPage />
</UContainer>
<USlideovers />
</div>
</template>
```
Then, you can use the `useSlideover` composable to control your slideovers within your app.
:component-example{component="slideover-example-composable"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,478 @@
---
description: 'Display data in a table.'
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/data/Table.vue
---
## Usage
Use the `rows` prop to set the data to display in the table. By default, the table will display all the fields of the rows.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-basic'
componentProps:
class: 'flex-1'
---
::
### Columns
Use the `columns` prop to configure which columns to display. It's an array of objects with the following properties:
- `label` - The label to display in the table header. Can be changed through the `column-attribute` prop.
- `key` - The field to display from the row data.
- `sortable` - Whether the column is sortable. Defaults to `false`.
- `direction` - The sort direction to use on first click. Defaults to `asc`.
- `class` - The class to apply to the column cells.
- `sort` - Pass your own `sort` function. Defaults to a simple _greater than_ / _less than_ comparison.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-columns'
componentProps:
class: 'flex-1'
---
::
You can easily use the [SelectMenu](/components/select-menu) component to change the columns to display.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-columns-selectable'
componentProps:
class: 'flex-1'
---
::
You can apply styles to `tr` and `td` elements by passing a `class` to rows.
Also, you can apply styles to `th` elements by passing a `class` to columns.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-style'
componentProps:
class: 'w-full'
---
::
### Sortable
You can make the columns sortable by setting the `sortable` property to `true` in the column configuration.
You may specify the default direction of each column through the `direction` property. It can be either `asc` or `desc`, but it will default to `asc`.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-columns-sortable'
componentProps:
class: 'flex-1'
---
::
#### Default sorting
You can specify a default sort for the table through the `sort` prop. It's an object with the following properties:
- `column` - The column to sort by.
- `direction` - The sort direction. Can be either `asc` or `desc` and defaults to `asc`.
This will set the default sort and will work even if no column is set as `sortable`.
```vue
<script setup lang="ts">
const sort = ref({
column: 'name',
direction: 'desc'
})
const columns = [{
label: 'Name',
key: 'name',
sortable: true
}]
const people = [{
id: 1,
name: 'Lindsay Walton',
title: 'Front-end Developer',
email: 'lindsay.walton@example.com',
role: 'Member'
}, {
id: 2,
name: 'Courtney Henry',
title: 'Designer',
email: 'courtney.henry@example.com',
role: 'Admin'
}]
</script>
<template>
<UTable :sort="sort" :columns="columns" :rows="people" />
</template>
```
#### Reactive sorting
You can use a `v-model:sort` to make the sorting reactive. You may also use `@update:sort` to call your own function with the sorting data.
When fetching data from an API, we can take advantage of the [`useFetch`](https://nuxt.com/docs/api/composables/use-fetch) or [`useAsyncData`](https://nuxt.com/docs/api/composables/use-async-data) composables to fetch the data based on the sorting column and direction every time the `sort` reactive element changes.
When doing so, you might want to set the `sort-mode` prop to `manual` to disable the automatic sorting and return the rows as is.
```vue
<script setup lang="ts">
// Ensure it uses `ref` instead of `reactive`.
const sort = ref({
column: 'name',
direction: 'desc'
})
const columns = [{
label: 'Name',
key: 'name',
sortable: true
}]
const { data, pending } = await useLazyFetch(() => `/api/users?orderBy=${sort.value.column}&order=${sort.value.direction}`)
</script>
<template>
<UTable v-model:sort="sort" :loading="pending" :columns="columns" :rows="data" sort-mode="manual" />
</template>
```
::callout{icon="i-heroicons-light-bulb" to="https://nuxt.com/docs/api/composables/use-fetch#params" target="_blank"}
We pass a function to `useLazyFetch` here to make the url reactive but you can use the `query` / `params` options alongside `watch`.
::
#### Custom sorting
Use the `sort-button` prop to customize the sort button in the header. You can pass all the props of the [Button](/components/button) component to customize it through this prop or globally through `ui.table.default.sortButton`. Its icon defaults to `i-heroicons-arrows-up-down-20-solid`.
::component-card{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
baseProps:
class: 'w-full'
columns:
- key: 'id'
label: 'ID'
- key: 'name'
label: 'Name'
sortable: true
- key: 'title'
label: 'Title'
sortable: true
- key: 'email'
label: 'Email'
sortable: true
- key: 'role'
label: 'Role'
rows:
- id: 1
name: 'Lindsay Walton'
title: 'Front-end Developer'
email: 'lindsay.walton@example.com'
role: 'Member'
- id: 2
name: 'Courtney Henry'
title: 'Designer'
email: 'courtney.henry@example.com'
role: 'Admin'
- id: 3
name: 'Tom Cook'
title: 'Director of Product'
email: 'tom.cook@example.com'
role: 'Member'
- id: 4
name: 'Whitney Francis'
title: 'Copywriter'
email: 'whitney.francis@example.com'
role: 'Admin'
- id: 5
name: 'Leonard Krasner'
title: 'Senior Designer'
email: 'leonard.krasner@example.com'
role: 'Owner'
- id: 6
name: 'Floyd Miles'
title: 'Principal Designer'
email: 'floyd.miles@example.com'
role: 'Member'
props:
sortAscIcon: 'i-heroicons-arrow-up-20-solid'
sortDescIcon: 'i-heroicons-arrow-down-20-solid'
sortButton:
icon: 'i-heroicons-sparkles-20-solid'
color: 'primary'
variant: 'outline'
size: '2xs'
square: false
ui:
rounded: 'rounded-full'
excludedProps:
- sortButton
- sortAscIcon
- sortDescIcon
---
::
Use the `sort-asc-icon` prop to set a different icon or change it globally in `ui.table.default.sortAscIcon`. Defaults to `i-heroicons-bars-arrow-up-20-solid`.
Use the `sort-desc-icon` prop to set a different icon or change it globally in `ui.table.default.sortDescIcon`. Defaults to `i-heroicons-bars-arrow-down-20-solid`.
::callout{icon="i-heroicons-light-bulb"}
You can also customize the entire header cell, read more in the [Slots](#slots) section.
::
### Selectable
Use a `v-model` to make the table selectable. The `v-model` will be an array of the selected rows.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-selectable'
componentProps:
class: 'flex-1'
---
::
::callout{icon="i-heroicons-light-bulb"}
You can use the `by` prop to compare objects by a field instead of comparing object instances. We've replicated the behavior of Headless UI [Combobox](https://headlessui.com/vue/combobox#binding-objects-as-values).
::
You can also add a `select` listener on your Table to make the rows clickable. The function will receive the row as the first argument.
You can use this to navigate to a page, open a modal or even to select the row manually.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-clickable'
componentProps:
class: 'flex-1'
---
::
### Searchable
You can easily use the [Input](/components/input) component to filter the rows.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-searchable'
componentProps:
class: 'flex-1'
---
::
### Paginable
You can easily use the [Pagination](/components/pagination) component to paginate the rows.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-paginable'
componentProps:
class: 'flex-1'
---
::
### Loading
Use the `loading` prop to indicate that data is currently loading with an indeterminate [Progress](/components/progress#indeterminate) bar.
You can use the `progress` prop to customize the `color` and `animation` of the progress bar or change them globally in `ui.table.default.progress` (you can set it to `null` to hide the progress bar).
If there is no rows provided, a loading state will also be displayed. You can use the `loading-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.loadingState` (you can set it to `null` to hide the loading state).
::component-card
---
extraClass: 'overflow-hidden'
padding: false
baseProps:
class: 'w-full'
columns:
- key: 'id'
label: 'ID'
- key: 'name'
label: 'Name'
- key: 'title'
label: 'Title'
- key: 'email'
label: 'Email'
- key: 'role'
label: 'Role'
props:
loading: true
loadingState:
icon: 'i-heroicons-arrow-path-20-solid'
label: "Loading..."
progress:
color: 'primary'
animation: 'carousel'
excludedProps:
- loadingState
- progress
---
::
This can be easily used with Nuxt `useAsyncData` composable.
```vue
<script setup lang="ts">
const columns = [...]
const { pending, data: people } = await useLazyAsyncData('people', () => $fetch('/api/people'))
</script>
<template>
<UTable :rows="people" :columns="columns" :loading="pending" />
</template>
```
### Empty
An empty state will be displayed when there are no results.
Use the `empty-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.emptyState`.
You can also set it to `null` to hide the empty state.
::component-card
---
extraClass: 'overflow-hidden'
padding: false
baseProps:
class: 'w-full'
columns:
- key: 'id'
label: 'ID'
- key: 'name'
label: 'Name'
- key: 'title'
label: 'Title'
- key: 'email'
label: 'Email'
- key: 'role'
label: 'Role'
props:
emptyState:
icon: 'i-heroicons-circle-stack-20-solid'
label: "No items."
excludedProps:
- emptyState
---
::
## Slots
You can use slots to customize the header and data cells of the table.
### `<column>-header`
Use the `#<column>-header` slot to customize the header cell of a column. You will have access to the `column`, `sort` and `on-sort` properties in the slot scope.
The `sort` property is an object with the following properties:
- `field` - The field to sort by.
- `direction` - The direction to sort by. Can be `asc` or `desc`.
The `on-sort` property is a function that you can call to sort the table and accepts the column as parameter.
::callout{icon="i-heroicons-light-bulb"}
Even though you can customize the sort button as mentioned in the [Sortable](#sortable) section, you can use this slot to completely override its behavior, with a custom dropdown for example.
::
### `<column>-data`
Use the `#<column>-data` slot to customize the data cell of a column. You will have access to the `row`, `column` and `getRowData` properties in the slot scope.
You can for example create an extra column for actions with a [Dropdown](/components/dropdown) component inside or change the color of the rows based on a selection.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-slots'
componentProps:
class: 'flex-1'
---
::
### `loading-state`
Use the `#loading-state` slot to customize the loading state.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-loading-slot'
componentProps:
class: 'flex-1'
---
::
### `empty-state`
Use the `#empty-state` slot to customize the empty state.
::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-empty-slot'
componentProps:
class: 'flex-1'
---
::
## Props
:component-props
## Config
:component-preset
## Example
Here is an example of a Table component with all its features implemented.
::component-example
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-advanced'
componentProps:
class: 'flex-1'
hiddenCode: true
---
::
::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/TableExampleAdvanced.vue" target="_blank"}
Take a look at the component!
::

View File

@@ -0,0 +1,108 @@
---
description: A set of tab panels that are displayed one at a time.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/Tabs.vue
---
## Usage
Pass an array to the `items` prop of the Tabs component. Each item can have the following properties:
- `label` - The label of the item.
- `slot` - A key to customize the item with a slot.
- `content` - The content to display in the panel by default.
- `disabled` - Determines whether the item is disabled or not.
::component-example
---
component: 'tabs-example-basic'
componentProps:
class: 'w-full'
---
::
### Vertical
You can change the orientation of the tabs by setting the `orientation` prop to `vertical`.
::component-example
---
component: 'tabs-example-vertical'
componentProps:
class: 'w-full'
---
::
### Default index
You can set the default index of the tabs by setting the `default-index` prop.
::component-example
---
component: 'tabs-example-index'
componentProps:
class: 'w-full'
---
::
::callout{icon="i-heroicons-exclamation-triangle"}
This will have no effect if you are using a `v-model` to control the selected index.
::
### Listen to changes
You can listen to changes by using the `@change` event. The event will emit the index of the selected item.
::component-example
---
component: 'tabs-example-change'
componentProps:
class: 'w-full'
---
::
### Control the selected index
Use a `v-model` to control the selected index.
::component-example
---
component: 'tabs-example-v-model'
componentProps:
class: 'w-full'
---
::
::callout{icon="i-heroicons-information-circle"}
In this example, we are binding tabs to the route query. Refresh the page to see the selected tab change.
::
## Slots
You can use slots to customize the buttons and items content of the Accordion.
### `default`
Use the `#default` slot to customize the content of the trigger buttons. You will have access to the `item`, `index`, `selected` and `disabled` in the slot scope.
:component-example{component="tabs-example-default-slot"}
### `item`
Use the `#item` slot to customize the items content. You will have access to the `item`, `index` and `selected` properties in the slot scope.
:component-example{component="tabs-example-item-slot"}
You can also pass a `slot` property to customize a specific item.
:component-example{component="tabs-example-item-custom-slot"}
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,169 @@
---
description: Display a textarea field.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Textarea.vue
---
## Usage
Use a `v-model` to make the Textarea reactive.
:component-example{component="textarea-example"}
### Style
Use the `color` and `variant` props to change the visual style of the Textarea.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
color: 'primary'
variant: 'outline'
---
::
Besides all the colors from the `ui.colors` object, you can also use the `white` (default) and `gray` colors with their pre-defined variants.
#### White
::component-card
---
baseProps:
placeholder: 'Search...'
props:
color: 'white'
variant: 'outline'
excludedProps:
- color
---
::
#### Gray
::component-card
---
baseProps:
placeholder: 'Search...'
props:
color: 'gray'
variant: 'outline'
excludedProps:
- color
---
::
### Size
Use the `size` prop to change the size of the Textarea.
::component-card
---
baseProps:
props:
size: 'sm'
---
::
### Placeholder
Use the `placeholder` prop to set a placeholder text.
::component-card
---
props:
placeholder: 'Search...'
---
::
### Rows
Use the `rows` prop to set the number of rows of the Textarea.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
rows: 1
---
::
### Disabled
Use the `disabled` prop to disable the Textarea.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
disabled: true
---
::
### Autoresize
Use the `autoresize` prop to enable the autoresize. Writing more lines than the `rows` prop will make the Textarea grow up.
::component-card
---
baseProps:
placeholder: 'Search...'
modelValue: 'Here is an autoresize Textarea, write new lines to make the Textarea grow up...'
props:
autoresize: true
---
::
Use the `maxrows` prop to set a maximum number of rows when autoresizing. If set to `0`, the Textarea will infinitely grow up. :u-badge{label="New" class="!rounded-full" variant="subtle"}
::component-card
---
baseProps:
placeholder: 'Search...'
modelValue: 'Here is an autoresize Textarea, write new lines to make the Textarea grow up at a maximum of 5 rows...'
props:
autoresize: true
maxrows: 5
---
::
### Resize
Use the `resize` prop to enable the resize control.
::component-card
---
baseProps:
placeholder: 'Search...'
props:
resize: true
---
::
### Padded
Use the `padded` prop to remove the padding of the Textarea.
::component-card
---
props:
padded: false
baseProps:
placeholder: 'Search...'
variant: 'none'
class: 'w-full'
---
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,86 @@
---
description: Display a toggle field.
links:
- label: 'Switch'
icon: i-simple-icons-headlessui
to: 'https://headlessui.com/vue/switch'
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/forms/Toggle.vue
---
## Usage
Use a `v-model` to make the Toggle reactive.
:component-example{component="toggle-example"}
### Style
Use the `color` prop to change the style of the Toggle.
::component-card
---
props:
color: 'primary'
---
::
### Size
Use the `size` prop to change the size of the Toggle.
::component-card
---
props:
size: 'md'
---
::
### Icon
Use any icon from [Iconify](https://icones.js.org) by setting the `on-icon` and `off-icon` props by using this pattern: `i-{collection_name}-{icon_name}` or change it globally in `ui.toggle.default.onIcon` and `ui.toggle.default.offIcon`.
::component-card
---
props:
onIcon: 'i-heroicons-check-20-solid'
offIcon: 'i-heroicons-x-mark-20-solid'
excludedProps:
- onIcon
- offIcon
---
::
### Loading :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
Use the `loading` prop to show a loading icon and disable the Toggle.
Use the `loading-icon` prop to set a different icon or change it globally in `ui.toggle.default.loadingIcon`. Defaults to `i-heroicons-arrow-path-20-solid`.
::component-card
---
props:
loading: true
---
::
### Disabled
Use the `disabled` prop to disable the Toggle.
::component-card
---
props:
disabled: true
---
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,51 @@
---
description: Display content that appears on hover next to an element.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/overlays/Tooltip.vue
---
## Usage
:component-example{component="tooltip-example"}
## Popper
Use the `popper` prop to customize the popper instance.
### Arrow
:component-example{component="tooltip-example-arrow"}
### Placement
:component-example{component="tooltip-example-placement"}
### Offset
:component-example{component="tooltip-example-offset"}
## Slots
### `text`
Use the `#text` slot to override the content of the text.
::component-card
---
slots:
text: <span class="italic">Hello World!</span>
---
#text
[Hello World!]{.italic}
::
## Props
:component-props
## Config
:component-preset

View File

@@ -0,0 +1,72 @@
---
title: VerticalNavigation
description: Display a list of vertical links.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/navigation/VerticalNavigation.vue
---
## Usage
Pass an array to the `links` prop of the VerticalNavigation component. Each link can have the following properties:
- `label` - The label of the link.
- `labelClass` - The class of the link label.
- `icon` - The icon of the link.
- `iconClass` - The class of the link icon.
- `avatar` - The avatar of the link. You can pass all the props of the [Avatar](/components/avatar) component.
- `badge` - A badge to display next to the label. You can pass all the props of the [Badge](/components/badge) component.
- `click` - The click handler of the link.
You can also pass any property from the [NuxtLink](https://nuxt.com/docs/api/components/nuxt-link#props) component such as `to`, `exact`, etc.
:component-example{component="vertical-navigation-example"}
## Sections
Group your navigation links into distinct sections, separated by a divider. You can do this by passing an array of arrays to the `links` prop of the VerticalNavigation component.
:component-example{component="vertical-navigation-example-sections"}
## Slots
You can use slots to customize links display.
### `default`
Use the `#default` slot to customize the link label. You will have access to the `link` and `isActive` properties in the slot scope.
:component-example{component="vertical-navigation-example-default-slot"}
### `avatar`
Use the `#avatar` slot to customize the link avatar. You will have access to the `link` and `isActive` properties in the slot scope.
:component-example{component="vertical-navigation-example-avatar-slot"}
### `icon`
Use the `#icon` slot to customize the link icon. You will have access to the `link` and `isActive` properties in the slot scope.
:component-example{component="vertical-navigation-example-icon-slot"}
### `badge`
Use the `#badge` slot to customize the link badge. You will have access to the `link` and `isActive` properties in the slot scope.
:component-example{component="vertical-navigation-example-badge-slot"}
## Props
:component-props
## Config
:component-preset
## Example
Here is an example illustrating how you can customize the appearance of the `VerticalNavigation` component by utilizing its `ui` prop.
:component-example{component="vertical-navigation-example-theme-tailwind"}