# Instalação > \[!NOTE] > See: /docs/getting-started/installation/vue > > Procurando pela versão **Vue**? ## Configuração ### Adicionar a um projeto Nuxt #### Instale o pacote do Nitro UI ```bash [pnpm] pnpm add @nitro/ui tailwindcss ``` ```bash [yarn] yarn add @nitro/ui tailwindcss ``` ```bash [npm] npm install @nitro/ui tailwindcss ``` ```bash [bun] bun add @nitro/ui tailwindcss ``` #### Adicione o módulo do Nitro UI no seu `nuxt.config.ts`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] export default defineNuxtConfig({ modules: ['@nitro/ui'] }) ``` > \[!NOTE] > > Não é necessário adicionar `@nuxt/icon`, `@nuxt/fonts` ou `@nuxtjs/color-mode` ao seu array `modules`, pois o Nitro UI os registra automaticamente. Você ainda pode configurar esses módulos no seu `nuxt.config.ts` usando as chaves `icon`, `fonts` e `colorMode`. #### Importe o Tailwind CSS e o Nitro UI no seu CSS ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; ``` ```ts [nuxt.config.ts] {3} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'] }) ``` > \[!TIP] > See: https\://nuxt.com/docs/getting-started/layers > > Ao usar [Nuxt Layers](https://nuxt.com/docs/getting-started/layers){rel=""nofollow""}, o módulo gera automaticamente diretivas [`@source`](https://tailwindcss.com/docs/functions-and-directives#source-directive){rel=""nofollow""} para cada diretório de layer, garantindo que o Tailwind CSS escaneie todos os arquivos-fonte dos seus layers em busca de classes utilitárias. > \[!NOTE] > > É recomendado instalar a extensão [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss){rel=""nofollow""} para o VSCode e adicionar as seguintes configurações: > > ```json [.vscode/settings.json] > { > "files.associations": { > "*.css": "tailwindcss" > }, > "editor.quickSuggestions": { > "strings": "on" > }, > "tailwindCSS.classAttributes": ["class", "ui"], > "tailwindCSS.classFunctions": ["defineAppConfig"] > } > ``` #### Envolva o seu app com o componente App ```vue [app.vue] ``` > \[!NOTE] > See: /docs/components/app > > O componente `App` fornece configurações globais e é necessário para que os componentes **Toast** e **Tooltip** funcionem, assim como os **overlays programáticos**. ### Usar um template Nuxt Comece com um dos nossos templates oficiais usando o botão `Use this template` no GitHub ou a CLI: ```bash [Starter] npm create nuxt@latest -- -t ui ``` ```bash [Landing] npm create nuxt@latest -- -t ui/landing ``` ```bash [Docs] npm create nuxt@latest -- -t ui/docs ``` ```bash [SaaS] npm create nuxt@latest -- -t ui/saas ``` ```bash [Dashboard] npm create nuxt@latest -- -t ui/dashboard ``` ```bash [Chat] npm create nuxt@latest -- -t ui/chat ``` ```bash [Portfolio] npm create nuxt@latest -- -t ui/portfolio ``` ```bash [Changelog] npm create nuxt@latest -- -t ui/changelog ``` ```bash [Editor] npm create nuxt@latest -- -t ui/editor ``` ## Opções Você pode personalizar o Nitro UI fornecendo opções no seu `nuxt.config.ts`. ### `prefix` Use a opção `prefix` para alterar o prefixo dos componentes. - Default: `N`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { prefix: 'Nuxt' } }) ``` ### `fonts` Use a opção `fonts` para habilitar ou desabilitar o módulo [`@nuxt/fonts`](https://github.com/nuxt/fonts){rel=""nofollow""}. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { fonts: false } }) ``` ### `colorMode` Use a opção `colorMode` para habilitar ou desabilitar o módulo [`@nuxt/color-mode`](https://github.com/nuxt-modules/color-mode){rel=""nofollow""}. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { colorMode: false } }) ``` ### `theme.colors` Use a opção `theme.colors` para definir os aliases de cor dinâmicos usados para gerar o tema dos componentes. - Default: `['primary', 'secondary', 'success', 'info', 'warning', 'error']`{.inline,language-ts-type,shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { colors: ['primary', 'error'] } } }) ``` > \[!TIP] > See: /docs/getting-started/theme/design-system#colors > > Saiba mais sobre personalização de cores e tematização na seção Tema. ### `theme.transitions` Use a opção `theme.transitions` para habilitar ou desabilitar as transições nos componentes. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { transitions: false } } }) ``` > \[!NOTE] > > Essa opção adiciona a classe `transition-colors` nos componentes com estados de hover ou ativo. ### `theme.unstyled` `4.9+` Use a opção `theme.unstyled` para remover todas as classes de tema padrão dos componentes, mantendo apenas sua estrutura e as classes que você fornece por meio de `class`, `ui` ou `app.config.ui`. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { unstyled: true } } }) ``` > \[!WARNING] > > Isso também remove classes **estruturais** (posicionamento, transições, flex/grid), não apenas as cosméticas. Componentes com muito layout, como `Modal`, `Drawer` ou `Calendar`, exigirão que você forneça novamente o layout deles, semelhante ao modo unstyled do PrimeVue. ### `theme.defaultVariants` Use a opção `theme.defaultVariants` para sobrescrever as variantes `color` e `size` padrão dos componentes. - Default: `{ color: 'primary', size: 'md' }`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-11} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { defaultVariants: { color: 'neutral', size: 'sm' } } } }) ``` ### `theme.prefix` `4.2+` Use a opção `theme.prefix` para configurar o mesmo prefixo que você definiu na importação do Tailwind CSS. Isso garante que os componentes do Nitro UI usem as classes utilitárias e variáveis CSS com o prefixo correto. ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { prefix: 'tw' } } }) ``` ```css [app/assets/css/main.css] {1} @import "tailwindcss" prefix(tw); @import "@nitro/ui"; ``` > \[!WARNING] > See: https\://fonts.nuxt.com/get-started/configuration#processcssvariables > > Você pode precisar habilitar `fonts.processCSSVariables` para usar a opção de prefixo com o módulo `@nuxt/fonts`: > > ```ts [nuxt.config.ts] {9-11} > export default defineNuxtConfig({ > modules: ['@nitro/ui'], > css: ['~/assets/css/main.css'], > ui: { > theme: { > prefix: 'tw' > } > }, > fonts: { > processCSSVariables: true > } > }) > ``` Isso adicionará automaticamente o prefixo a todas as classes utilitárias do Tailwind e variáveis CSS nos temas dos componentes do Nitro UI: ```html ``` > \[!NOTE] > See: https\://tailwindcss.com/docs/styling-with-utility-classes#using-the-prefix-option > > Saiba mais sobre o uso de um prefixo na documentação do Tailwind CSS. ### `prose` Use a opção `prose` para forçar a importação dos [componentes `Prose`](https://ui.nitro.news/docs/typography) do Nitro UI mesmo que o `@nuxtjs/mdc` ou o `@nuxt/content` não estejam instalados. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { prose: true } }) ``` ### `mdc` `Deprecated` Use a opção [`prose`](https://ui.nitro.news/#prose). ### `content` Use a opção `content` para forçar a importação dos componentes `` e `` do Nitro UI mesmo que o `@nuxt/content` não esteja instalado. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { content: true } }) ``` ### `experimental.componentDetection` `4.1+` Use a opção `experimental.componentDetection` para habilitar a detecção automática de componentes para tree-shaking. Esse recurso escaneia seu código-fonte para detectar quais componentes são realmente usados e gera apenas o CSS necessário para esses componentes (incluindo suas dependências). - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - Type: `boolean | string[]`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} **Enable automatic detection:** ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { experimental: { componentDetection: true } } }) ``` **Include additional components for dynamic usage:** ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { experimental: { componentDetection: ['Modal', 'Dropdown', 'Popover'] } } }) ``` > \[!NOTE] > > Ao fornecer um array de nomes de componentes, a detecção automática é habilitada e esses componentes (junto com suas dependências) têm inclusão garantida. Isso é útil para componentes dinâmicos como `` que não podem ser analisados estaticamente. ## Lançamentos contínuos O Nitro UI usa o [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new){rel=""nofollow""} para lançamentos de preview contínuos, dando aos desenvolvedores acesso instantâneo aos recursos mais recentes e correções de bugs sem esperar pelos lançamentos oficiais. Lançamentos de preview automáticos são criados para todos os commits e PRs na branch `v4`. Use-os substituindo a versão do seu pacote pelo hash específico do commit ou pelo número do PR. ```diff [package.json] { "dependencies": { - "@nitro/ui": "^4.0.0", + "@nitro/ui": "https://pkg.pr.new/@nitro/ui@4c96909", } } ``` > \[!NOTE] > > **pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes. # Instalação > \[!NOTE] > See: /docs/getting-started/installation/nuxt > > Procurando pela versão **Nuxt**? ## Configuração ### Adicionar a um projeto Vue #### Instale o pacote do Nitro UI ```bash [pnpm] pnpm add @nitro/ui tailwindcss ``` ```bash [yarn] yarn add @nitro/ui tailwindcss ``` ```bash [npm] npm install @nitro/ui tailwindcss ``` ```bash [bun] bun add @nitro/ui tailwindcss ``` #### Adicione o plugin Vite do Nitro UI no seu `vite.config.ts`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts (Vite)] {3,8} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui() ] }) ``` ```ts [vite.config.ts (Laravel Inertia)] {3,20-22} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' import laravel from 'laravel-vite-plugin' export default defineConfig({ plugins: [ laravel({ input: ['resources/js/app.ts'], refresh: true }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false } } }), ui({ router: 'inertia' }) ] }) ``` ```ts [vite.config.ts (AdonisJS Inertia)] {3,15-17} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' import adonisjs from '@adonisjs/vite/client' import inertia from '@adonisjs/inertia/client' export default defineConfig({ plugins: [ adonisjs({ entrypoints: ['inertia/app/app.ts'], reload: ['resources/views/**/*.edge'] }), inertia(), vue(), ui({ router: 'inertia' }) ] }) ``` > \[!TIP] > > O Nitro UI registra o `unplugin-auto-import` e o `unplugin-vue-components`, que geram os arquivos de declaração de tipos `auto-imports.d.ts` e `components.d.ts`. Você provavelmente vai querer colocá-los no gitignore e adicioná-los ao seu `tsconfig`. > > ```json [tsconfig.app.json] > { > "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "auto-imports.d.ts", "components.d.ts"] > } > ``` > > ```bash [.gitignore] > # Auto-generated type declarations > auto-imports.d.ts > components.d.ts > ``` > \[!TIP] > > Internamente, o Nitro UI depende de um alias personalizado para resolver os tipos do tema. Se você usa TypeScript, deve adicionar um alias ao seu `tsconfig` para habilitar o autocompletar no seu `vite.config.ts`. > > ```json [tsconfig.node.json] > { > "compilerOptions": { > "paths": { > "#build/ui": [ > "./node_modules/.nuxt-ui/ui" > ] > } > } > } > ``` > > ```json [tsconfig.app.json] > { > "compilerOptions": { > "paths": { > "#build/ui/*": [ > "./node_modules/.nuxt-ui/ui/*" > ] > } > } > } > ``` #### Use o plugin Vue do Nitro UI ```ts [src/main.ts (Vite)] {3,14} import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import ui from '@nitro/ui/vue-plugin' import App from './App.vue' const app = createApp(App) const router = createRouter({ routes: [], history: createWebHistory() }) app.use(router) app.use(ui) app.mount('#app') ``` ```ts [resources/js/app.ts (Laravel Inertia)] {3,19} import type { DefineComponent } from 'vue' import { createInertiaApp } from '@inertiajs/vue3' import ui from '@nitro/ui/vue-plugin' import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' import { createApp, h } from 'vue' const appName = import.meta.env.VITE_APP_NAME || 'Laravel x Nitro UI' createInertiaApp({ title: title => (title ? `${title} - ${appName}` : appName), resolve: name => resolvePageComponent( `./pages/${name}.vue`, import.meta.glob('./pages/**/*.vue') ), setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(ui) .mount(el) } }) ``` ```ts [inertia/app/app.ts (AdonisJS Inertia)] {3,19} import type { DefineComponent } from 'vue' import { createInertiaApp } from '@inertiajs/vue3' import ui from '@nitro/ui/vue-plugin' import { resolvePageComponent } from '@adonisjs/inertia/helpers' import { createApp, h } from 'vue' const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS x Nitro UI' createInertiaApp({ title: title => (title ? `${title} - ${appName}` : appName), resolve: name => resolvePageComponent( `../pages/${name}.vue`, import.meta.glob('../pages/**/*.vue') ), setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(ui) .mount(el) } }) ``` #### Importe o Tailwind CSS e o Nitro UI no seu CSS ```css [src/assets/css/main.css (Vite)] @import "tailwindcss"; @import "@nitro/ui"; ``` ```css [resources/css/app.css (Laravel Inertia)] @import "tailwindcss"; @import "@nitro/ui"; ``` ```css [inertia/css/app.css (AdonisJS Inertia)] @import "tailwindcss"; @import "@nitro/ui"; ``` > \[!TIP] > > Importe o arquivo CSS no seu ponto de entrada. > > ```ts [src/main.ts] {1} > import './assets/css/main.css' > > import { createApp } from 'vue' > import { createRouter, createWebHistory } from 'vue-router' > import ui from '@nitro/ui/vue-plugin' > import App from './App.vue' > > const app = createApp(App) > > const router = createRouter({ > routes: [], > history: createWebHistory() > }) > > app.use(router) > app.use(ui) > > app.mount('#app') > ``` > > ```ts [resources/js/app.ts (Laravel Inertia)] {1} > import '../css/app.css' > import type { DefineComponent } from 'vue' > import { createInertiaApp } from '@inertiajs/vue3' > import ui from '@nitro/ui/vue-plugin' > import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' > import { createApp, h } from 'vue' > > const appName = import.meta.env.VITE_APP_NAME || 'Laravel x Nitro UI' > > createInertiaApp({ > title: title => (title ? `${title} - ${appName}` : appName), > resolve: name => > resolvePageComponent( > `./pages/${name}.vue`, > import.meta.glob('./pages/**/*.vue') > ), > setup({ el, App, props, plugin }) { > createApp({ render: () => h(App, props) }) > .use(plugin) > .use(ui) > .mount(el) > } > }) > ``` > > ```ts [inertia/app/app.ts (AdonisJS Inertia)] {1} > import '../css/app.css' > import type { DefineComponent } from 'vue' > import { createInertiaApp } from '@inertiajs/vue3' > import ui from '@nitro/ui/vue-plugin' > import { resolvePageComponent } from '@adonisjs/inertia/helpers' > import { createApp, h } from 'vue' > > const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS x Nitro UI' > > createInertiaApp({ > title: title => (title ? `${title} - ${appName}` : appName), > resolve: name => > resolvePageComponent( > `../pages/${name}.vue`, > import.meta.glob('../pages/**/*.vue') > ), > setup({ el, App, props, plugin }) { > createApp({ render: () => h(App, props) }) > .use(plugin) > .use(ui) > .mount(el) > } > }) > ``` > \[!NOTE] > > É recomendado instalar a extensão [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss){rel=""nofollow""} para o VSCode e adicionar as seguintes configurações: > > ```json [.vscode/settings.json] > { > "files.associations": { > "*.css": "tailwindcss" > }, > "editor.quickSuggestions": { > "strings": "on" > }, > "tailwindCSS.classAttributes": ["class", "ui"], > "tailwindCSS.classFunctions": ["defineAppConfig"] > } > ``` #### Envolva o seu app com o componente App ```vue [src/App.vue (Vite)] ``` ```vue [resources/js/pages/index.vue (Laravel Inertia)] ``` ```vue [inertia/pages/index.vue (AdonisJS Inertia)] ``` > \[!NOTE] > See: /docs/components/app > > O componente `App` configura o config global e é necessário para **Toast**, **Tooltip** e **overlays programáticos**. #### Adicione a classe `isolate` ao seu container raiz ```html [index.html (Vite)] {9} Nitro UI
``` ```blade [resources/views/app.blade.php (Laravel Inertia)] {10} @inertiaHead @vite('resources/js/app.ts')
@inertia
``` ```edge [resources/views/inertia_layout.edge (AdonisJS Inertia)] {10} @inertiaHead() @vite(['inertia/app/app.ts', `inertia/pages/${page.component}.vue`]) @inertia({ class: 'isolate' }) ``` > \[!NOTE] > > Isso garante que os estilos fiquem restritos ao seu app e evita problemas com overlays e contextos de empilhamento. ## Opções Você pode personalizar o Nitro UI fornecendo opções no seu `vite.config.ts`. ### `prefix` Use a opção `prefix` para alterar o prefixo dos componentes. - Default: `N`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ prefix: 'Nuxt' }) ] }) ``` ### `ui` Use a opção `ui` para fornecer a configuração do Nitro UI. ```ts [vite.config.ts] {9-14} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ ui: { colors: { primary: 'green', neutral: 'slate' } } }) ] }) ``` ### `colorMode` Use a opção `colorMode` para habilitar ou desabilitar a integração de modo de cor do `@vueuse/core`. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ colorMode: false }) ] }) ``` ### `theme.colors` Use a opção `theme.colors` para definir os aliases de cor dinâmicos usados para gerar o tema dos componentes. - Default: `['primary', 'secondary', 'success', 'info', 'warning', 'error']`{.inline,language-ts-type,shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { colors: ['primary', 'error'] } }) ] }) ``` > \[!TIP] > See: /docs/getting-started/theme/design-system#colors > > Saiba mais sobre personalização de cores e tematização na seção Tema. ### `theme.transitions` Use a opção `theme.transitions` para habilitar ou desabilitar as transições nos componentes. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { transitions: false } }) ] }) ``` > \[!NOTE] > > Essa opção adiciona a classe `transition-colors` nos componentes com estados de hover ou ativo. ### `theme.unstyled` `4.9+` Use a opção `theme.unstyled` para remover todas as classes de tema padrão dos componentes, mantendo apenas sua estrutura e as classes que você fornece por meio de `class`, `ui` ou `app.config.ui`. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { unstyled: true } }) ] }) ``` > \[!WARNING] > > Isso também remove classes **estruturais** (posicionamento, transições, flex/grid), não apenas as cosméticas. Componentes com muito layout, como `Modal`, `Drawer` ou `Calendar`, exigirão que você forneça novamente o layout deles, semelhante ao modo unstyled do PrimeVue. ### `theme.defaultVariants` Use a opção `theme.defaultVariants` para sobrescrever as variantes `color` e `size` padrão dos componentes. - Default: `{ color: 'primary', size: 'md' }`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-14} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { defaultVariants: { color: 'neutral', size: 'sm' } } }) ] }) ``` ### `theme.prefix` `4.2+` Use a opção `theme.prefix` para configurar o mesmo prefixo que você definiu na importação do Tailwind CSS. Isso garante que os componentes do Nitro UI usem as classes utilitárias e variáveis CSS com o prefixo correto. ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { prefix: 'tw' } }) ] }) ``` ```css [src/assets/css/main.css] {1} @import "tailwindcss" prefix(tw); @import "@nitro/ui"; ``` Isso adicionará automaticamente o prefixo a todas as classes utilitárias do Tailwind e variáveis CSS nos temas dos componentes do Nitro UI: ```html ``` > \[!NOTE] > See: https\://tailwindcss.com/docs/styling-with-utility-classes#using-the-prefix-option > > Saiba mais sobre o uso de um prefixo na documentação do Tailwind CSS. ### `prose` Use a opção `prose` para habilitar os [componentes `Prose`](https://ui.nitro.news/docs/typography) do Nitro UI e o tema deles. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ prose: true }) ] }) ``` ### `autoImport` Use a opção `autoImport` para desabilitar a importação automática de composables ou para personalizar as opções do [`unplugin-auto-import`](https://github.com/unplugin/unplugin-auto-import){rel=""nofollow""}. - Default: `{}`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ autoImport: false }) ] }) ``` > \[!NOTE] > > Quando desabilitado, você ainda pode importar composables explicitamente de `@nitro/ui/composables`. ### `components` Use a opção `components` para desabilitar a importação automática de componentes ou para personalizar as opções do [`unplugin-vue-components`](https://github.com/unplugin/unplugin-vue-components){rel=""nofollow""}. - Default: `{}`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ components: false }) ] }) ``` > \[!NOTE] > > Quando desabilitado, você ainda pode importar componentes explicitamente, ex.: `import Button from '@nitro/ui/components/Button.vue'` ou `import ProseCode from '@nitro/ui/components/prose/Code.vue'`. ### `router` `4.3+` Use a opção `router` para configurar a integração de roteamento. Isso é útil para aplicações que não usam `vue-router`, como apps Electron, MPAs ou frameworks como [Inertia.js](https://inertiajs.com/){rel=""nofollow""} ou [Hybridly](https://hybridly.dev/){rel=""nofollow""}. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} | Value | Description | | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | | `true`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | Uses `vue-router` for navigation with `RouterLink` component. | | `false`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | Disables routing integration, links render as plain `` tags. | | `'inertia'`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | Uses Inertia.js for navigation with its `Link` component. | ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ router: false }) ] }) ``` > \[!TIP] > > Você pode fornecer uma lógica de navegação personalizada para frameworks como o **Hybridly** definindo `router: false` na configuração do Vite e passando uma função ao instalar o plugin do Vue: > > ```ts [src/main.ts] > import ui from '@nitro/ui/vue-plugin' > import { router } from 'hybridly' > > app.use(ui, { > router: (event, { href, external }) => { > if (external) { > return > } > > event.preventDefault() > > router.navigate({ url: href }) > } > }) > ``` > \[!NOTE] > > Quando definido como `false` ou `'inertia'`, o `vue-router` não é necessário como dependência. ### `scanPackages` `4.3+` Use a opção `scanPackages` para especificar pacotes npm adicionais que devem ser escaneados em busca de componentes que usam o Nitro UI. Isso é útil quando você tem uma biblioteca de componentes compartilhada que usa componentes do Nitro UI internamente. ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ scanPackages: ['@my-org/ui-components'] }) ] }) ``` > \[!NOTE] > > Por padrão, apenas o `@nitro/ui` é escaneado. Use esta opção quando seus pacotes externos contiverem componentes Vue que usam o Nitro UI. ### `root` `4.9+` Use a opção `root` para sobrescrever o diretório onde o Nitro UI gera seu diretório `.nuxt-ui` (que contém os templates do tema). Por padrão, ele usa o `root` do Vite, mas em configurações como [`electron-vite`](https://electron-vite.org/){rel=""nofollow""} o `root` do renderer aponta para um subdiretório (ex.: `src/renderer`), então os templates acabam em `src/renderer/node_modules/.nuxt-ui`, onde o Tailwind não os escaneia, fazendo com que classes de tema como `bg-default`, `ring-default` e `divide-default` fiquem ausentes. ```ts [electron.vite.config.ts] {12} import { defineConfig } from 'electron-vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ renderer: { root: 'src/renderer', plugins: [ vue(), ui({ root: __dirname }) ] } }) ``` > \[!NOTE] > > Aponte o `root` para a raiz do seu projeto para que o diretório `.nuxt-ui` gerado fique em um `node_modules` que o Tailwind escaneia. ## Lançamentos contínuos O Nitro UI usa o [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new){rel=""nofollow""} para lançamentos de preview contínuos, dando aos desenvolvedores acesso instantâneo aos recursos mais recentes e correções de bugs sem esperar pelos lançamentos oficiais. Lançamentos de preview automáticos são criados para todos os commits e PRs na branch `v4`. Use-os substituindo a versão do seu pacote pelo hash específico do commit ou pelo número do PR. ```diff [package.json] { "dependencies": { - "@nitro/ui": "^4.0.0", + "@nitro/ui": "https://pkg.pr.new/@nitro/ui@4c96909", } } ``` > \[!NOTE] > > **pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes. # Introdução ## O que é o Nitro UI? Uma biblioteca moderna de componentes de UI para Vue, construída sobre [Reka UI](https://reka-ui.com/){rel=""nofollow""}, [Tailwind CSS](https://tailwindcss.com/){rel=""nofollow""} e [Tailwind Variants](https://www.tailwind-variants.org/){rel=""nofollow""} para entregar aplicações bonitas e acessíveis com mais de 125 componentes prontos para produção. Funciona com Nuxt e com apps Vue puros (Vite, Inertia, SSR). Se você está construindo um projeto Vue com Tailwind CSS, o Nitro UI é uma ótima escolha padrão. Ele oferece componentes de alto nível e prontos para uso (tabelas de dados, formulários, overlays, navegação) e ainda permite personalização avançada quando necessário. **Experiência do desenvolvedor em primeiro lugar** Intuitive APIs, excellent TypeScript support, auto-completion, and comprehensive docs. **Bonito por padrão** Um design moderno e limpo por padrão, com um tema que você pode adaptar em minutos. **Acessível por padrão** Compatível com WAI-ARIA, com navegação por teclado, gerenciamento de foco e suporte a leitores de tela. **Pronto para produção** Mais de 125 componentes testados em produção, incluindo tabelas de dados, formulários, overlays e navegação, usados por milhares de aplicações. ## Tecnologias principais ### Reka UI O Nitro UI é construído sobre o [Reka UI](https://reka-ui.com/){rel=""nofollow""} como base para os componentes: - **WAI-ARIA Compliance**: Follows [WAI-ARIA authoring practices](https://reka-ui.com/docs/overview/accessibility){rel=""nofollow""} with proper semantics and roles - **Keyboard Navigation**: Built-in keyboard support for complex components like tabs and dialogs - **Focus Management**: Intelligent focus handling that moves focus based on user interactions - **Accessible Labels**: Abstractions to simplify labeling controls for screen readers ### Tailwind CSS Nitro UI integrates the latest [Tailwind CSS](https://tailwindcss.com/){rel=""nofollow""}, bringing significant improvements: - **5x Faster Builds**: Full builds up to 5x faster, incremental builds over 100x faster - **Unified Toolchain**: Built-in import handling, vendor prefixing, and syntax transforms - **CSS-first Configuration**: Customize and extend directly in CSS instead of JavaScript - **Modern Web Features**: Container queries, cascade layers, wide-gamut colors, and more ### Tailwind Variants O Nitro UI aproveita o [Tailwind Variants](https://www.tailwind-variants.org/){rel=""nofollow""} para oferecer um design system poderoso: - **Dynamic Styling**: Flexible component variants with a powerful API - **Type Safety**: Full TypeScript support with auto-completion - **Conflict Resolution**: Efficient merging of conflicting styles ## Principais recursos ### Integração com o ecossistema O Nitro UI é compatível com SSR e se integra perfeitamente ao ecossistema Nuxt (esses recursos também funcionam no Vue com configuração adicional): - [**Icons**](https://ui.nitro.news/docs/getting-started/integrations/icons): Access 200,000+ icons from Iconify - [**Fonts**](https://ui.nitro.news/docs/getting-started/integrations/fonts): Plug-and-play web font optimization and configuration - [**Color Mode**](https://ui.nitro.news/docs/getting-started/integrations/color-mode): Dark and Light mode with auto detection - [**i18n**](https://ui.nitro.news/docs/getting-started/integrations/i18n): Internationalize your components with 50+ languages - [**Content**](https://ui.nitro.news/docs/getting-started/integrations/content): Beautiful typography out of the box ### Compatibilidade com Vue (Nuxt opcional) O Nitro UI funciona com qualquer projeto Vue, não apenas Nuxt. Basta adicionar os plugins do Vite e do Vue à sua configuração: - **Auto-imports**: Components and composables are automatically imported and available globally - **Design System**: Full theming support with customizable colors, sizes, variants, and more - **Developer Experience**: Complete TypeScript support with IntelliSense and auto-completion > \[!TIP] > See: /docs/getting-started/installation/vue > > Aprenda a instalar e configurar o Nitro UI em um projeto Vue no **guia de instalação para Vue**. ### Suporte a TypeScript O Nitro UI oferece uma integração completa com TypeScript para uma experiência de desenvolvimento superior: - **Auto-completion**: For all component props, slots, and events - **Generic Components**: Using [Vue Generics](https://vuejs.org/api/sfc-script-setup.html#generics){rel=""nofollow""} - **Type-safe Theming**: In `app.config.ts` - **IntelliSense**: Throughout your entire codebase ## Perguntas frequentes **Q: Is Nitro UI free to use?** Sim! O Nitro UI é totalmente gratuito e de código aberto sob a licença MIT. Todos os mais de 125 componentes estão disponíveis para todos. **Q: Can I use Nitro UI with Vue without Nuxt?** Sim! Embora otimizado para Nuxt, o Nitro UI funciona perfeitamente com projetos Vue independentes via nosso plugin do Vite. Você pode seguir o [guia de instalação](https://ui.nitro.news/docs/getting-started/installation/vue) para começar. **Q: How does Nitro UI handle accessibility?** Por meio da integração com o [Reka UI](https://reka-ui.com/docs/overview/accessibility){rel=""nofollow""}, o Nitro UI fornece atributos ARIA automáticos, navegação por teclado, gerenciamento de foco e suporte a leitores de tela. Embora ofereça uma base sólida, testar no seu caso de uso específico continua sendo importante. **Q: Is Nitro UI production-ready?** Sim! O Nitro UI é usado em produção por milhares de aplicações, com mais de 1000 testes no Vitest, atualizações regulares e manutenção ativa. **Q: When should I consider alternatives?** Considere o **Vuetify** se você quer o estilo Material Design, o **ant-design-vue** para o estilo Ant Design, o **PrimeVue** ou o **Element Plus** se você não quer Tailwind CSS, o **shadcn-vue** se prefere copiar componentes para o seu repositório, o **Quasar** para apps multiplataforma (web, mobile, desktop), ou o **Reka UI** / **Headless UI** se você só precisa de primitivos sem estilo. **Q: Where can I get help?** Faça perguntas e obtenha ajuda no [GitHub Discussions](https://github.com/nuxt/ui/discussions/categories/q-a){rel=""nofollow""}, converse com a comunidade no [Discord](https://go.nuxt.com/discord){rel=""nofollow""} ou relate bugs no [GitHub](https://github.com/nuxt/ui/issues){rel=""nofollow""}. # Instalação > \[!NOTE] > See: /docs/getting-started/installation/vue > > Procurando pela versão **Vue**? ## Configuração ### Adicionar a um projeto Nuxt #### Instale o pacote do Nitro UI ```bash [pnpm] pnpm add @nitro/ui tailwindcss ``` ```bash [yarn] yarn add @nitro/ui tailwindcss ``` ```bash [npm] npm install @nitro/ui tailwindcss ``` ```bash [bun] bun add @nitro/ui tailwindcss ``` #### Adicione o módulo do Nitro UI no seu `nuxt.config.ts`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] export default defineNuxtConfig({ modules: ['@nitro/ui'] }) ``` > \[!NOTE] > > Não é necessário adicionar `@nuxt/icon`, `@nuxt/fonts` ou `@nuxtjs/color-mode` ao seu array `modules`, pois o Nitro UI os registra automaticamente. Você ainda pode configurar esses módulos no seu `nuxt.config.ts` usando as chaves `icon`, `fonts` e `colorMode`. #### Importe o Tailwind CSS e o Nitro UI no seu CSS ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; ``` ```ts [nuxt.config.ts] {3} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'] }) ``` > \[!TIP] > See: https\://nuxt.com/docs/getting-started/layers > > Ao usar [Nuxt Layers](https://nuxt.com/docs/getting-started/layers){rel=""nofollow""}, o módulo gera automaticamente diretivas [`@source`](https://tailwindcss.com/docs/functions-and-directives#source-directive){rel=""nofollow""} para cada diretório de layer, garantindo que o Tailwind CSS escaneie todos os arquivos-fonte dos seus layers em busca de classes utilitárias. > \[!NOTE] > > É recomendado instalar a extensão [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss){rel=""nofollow""} para o VSCode e adicionar as seguintes configurações: > > ```json [.vscode/settings.json] > { > "files.associations": { > "*.css": "tailwindcss" > }, > "editor.quickSuggestions": { > "strings": "on" > }, > "tailwindCSS.classAttributes": ["class", "ui"], > "tailwindCSS.classFunctions": ["defineAppConfig"] > } > ``` #### Envolva o seu app com o componente App ```vue [app.vue] ``` > \[!NOTE] > See: /docs/components/app > > O componente `App` fornece configurações globais e é necessário para que os componentes **Toast** e **Tooltip** funcionem, assim como os **overlays programáticos**. ### Usar um template Nuxt Comece com um dos nossos templates oficiais usando o botão `Use this template` no GitHub ou a CLI: ```bash [Starter] npm create nuxt@latest -- -t ui ``` ```bash [Landing] npm create nuxt@latest -- -t ui/landing ``` ```bash [Docs] npm create nuxt@latest -- -t ui/docs ``` ```bash [SaaS] npm create nuxt@latest -- -t ui/saas ``` ```bash [Dashboard] npm create nuxt@latest -- -t ui/dashboard ``` ```bash [Chat] npm create nuxt@latest -- -t ui/chat ``` ```bash [Portfolio] npm create nuxt@latest -- -t ui/portfolio ``` ```bash [Changelog] npm create nuxt@latest -- -t ui/changelog ``` ```bash [Editor] npm create nuxt@latest -- -t ui/editor ``` ## Opções Você pode personalizar o Nitro UI fornecendo opções no seu `nuxt.config.ts`. ### `prefix` Use a opção `prefix` para alterar o prefixo dos componentes. - Default: `N`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { prefix: 'Nuxt' } }) ``` ### `fonts` Use a opção `fonts` para habilitar ou desabilitar o módulo [`@nuxt/fonts`](https://github.com/nuxt/fonts){rel=""nofollow""}. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { fonts: false } }) ``` ### `colorMode` Use a opção `colorMode` para habilitar ou desabilitar o módulo [`@nuxt/color-mode`](https://github.com/nuxt-modules/color-mode){rel=""nofollow""}. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { colorMode: false } }) ``` ### `theme.colors` Use a opção `theme.colors` para definir os aliases de cor dinâmicos usados para gerar o tema dos componentes. - Default: `['primary', 'secondary', 'success', 'info', 'warning', 'error']`{.inline,language-ts-type,shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { colors: ['primary', 'error'] } } }) ``` > \[!TIP] > See: /docs/getting-started/theme/design-system#colors > > Saiba mais sobre personalização de cores e tematização na seção Tema. ### `theme.transitions` Use a opção `theme.transitions` para habilitar ou desabilitar as transições nos componentes. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { transitions: false } } }) ``` > \[!NOTE] > > Essa opção adiciona a classe `transition-colors` nos componentes com estados de hover ou ativo. ### `theme.unstyled` `4.9+` Use a opção `theme.unstyled` para remover todas as classes de tema padrão dos componentes, mantendo apenas sua estrutura e as classes que você fornece por meio de `class`, `ui` ou `app.config.ui`. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { unstyled: true } } }) ``` > \[!WARNING] > > Isso também remove classes **estruturais** (posicionamento, transições, flex/grid), não apenas as cosméticas. Componentes com muito layout, como `Modal`, `Drawer` ou `Calendar`, exigirão que você forneça novamente o layout deles, semelhante ao modo unstyled do PrimeVue. ### `theme.defaultVariants` Use a opção `theme.defaultVariants` para sobrescrever as variantes `color` e `size` padrão dos componentes. - Default: `{ color: 'primary', size: 'md' }`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-11} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { defaultVariants: { color: 'neutral', size: 'sm' } } } }) ``` ### `theme.prefix` `4.2+` Use a opção `theme.prefix` para configurar o mesmo prefixo que você definiu na importação do Tailwind CSS. Isso garante que os componentes do Nitro UI usem as classes utilitárias e variáveis CSS com o prefixo correto. ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { theme: { prefix: 'tw' } } }) ``` ```css [app/assets/css/main.css] {1} @import "tailwindcss" prefix(tw); @import "@nitro/ui"; ``` > \[!WARNING] > See: https\://fonts.nuxt.com/get-started/configuration#processcssvariables > > Você pode precisar habilitar `fonts.processCSSVariables` para usar a opção de prefixo com o módulo `@nuxt/fonts`: > > ```ts [nuxt.config.ts] {9-11} > export default defineNuxtConfig({ > modules: ['@nitro/ui'], > css: ['~/assets/css/main.css'], > ui: { > theme: { > prefix: 'tw' > } > }, > fonts: { > processCSSVariables: true > } > }) > ``` Isso adicionará automaticamente o prefixo a todas as classes utilitárias do Tailwind e variáveis CSS nos temas dos componentes do Nitro UI: ```html ``` > \[!NOTE] > See: https\://tailwindcss.com/docs/styling-with-utility-classes#using-the-prefix-option > > Saiba mais sobre o uso de um prefixo na documentação do Tailwind CSS. ### `prose` Use a opção `prose` para forçar a importação dos [componentes `Prose`](https://ui.nitro.news/docs/typography) do Nitro UI mesmo que o `@nuxtjs/mdc` ou o `@nuxt/content` não estejam instalados. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { prose: true } }) ``` ### `mdc` `Deprecated` Use a opção [`prose`](https://ui.nitro.news/#prose). ### `content` Use a opção `content` para forçar a importação dos componentes `` e `` do Nitro UI mesmo que o `@nuxt/content` não esteja instalado. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] {4-6} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { content: true } }) ``` ### `experimental.componentDetection` `4.1+` Use a opção `experimental.componentDetection` para habilitar a detecção automática de componentes para tree-shaking. Esse recurso escaneia seu código-fonte para detectar quais componentes são realmente usados e gera apenas o CSS necessário para esses componentes (incluindo suas dependências). - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - Type: `boolean | string[]`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} **Enable automatic detection:** ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { experimental: { componentDetection: true } } }) ``` **Include additional components for dynamic usage:** ```ts [nuxt.config.ts] {4-8} export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { experimental: { componentDetection: ['Modal', 'Dropdown', 'Popover'] } } }) ``` > \[!NOTE] > > Ao fornecer um array de nomes de componentes, a detecção automática é habilitada e esses componentes (junto com suas dependências) têm inclusão garantida. Isso é útil para componentes dinâmicos como `` que não podem ser analisados estaticamente. ## Lançamentos contínuos O Nitro UI usa o [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new){rel=""nofollow""} para lançamentos de preview contínuos, dando aos desenvolvedores acesso instantâneo aos recursos mais recentes e correções de bugs sem esperar pelos lançamentos oficiais. Lançamentos de preview automáticos são criados para todos os commits e PRs na branch `v4`. Use-os substituindo a versão do seu pacote pelo hash específico do commit ou pelo número do PR. ```diff [package.json] { "dependencies": { - "@nitro/ui": "^4.0.0", + "@nitro/ui": "https://pkg.pr.new/@nitro/ui@4c96909", } } ``` > \[!NOTE] > > **pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes. # Instalação > \[!NOTE] > See: /docs/getting-started/installation/nuxt > > Procurando pela versão **Nuxt**? ## Configuração ### Adicionar a um projeto Vue #### Instale o pacote do Nitro UI ```bash [pnpm] pnpm add @nitro/ui tailwindcss ``` ```bash [yarn] yarn add @nitro/ui tailwindcss ``` ```bash [npm] npm install @nitro/ui tailwindcss ``` ```bash [bun] bun add @nitro/ui tailwindcss ``` #### Adicione o plugin Vite do Nitro UI no seu `vite.config.ts`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts (Vite)] {3,8} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui() ] }) ``` ```ts [vite.config.ts (Laravel Inertia)] {3,20-22} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' import laravel from 'laravel-vite-plugin' export default defineConfig({ plugins: [ laravel({ input: ['resources/js/app.ts'], refresh: true }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false } } }), ui({ router: 'inertia' }) ] }) ``` ```ts [vite.config.ts (AdonisJS Inertia)] {3,15-17} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' import adonisjs from '@adonisjs/vite/client' import inertia from '@adonisjs/inertia/client' export default defineConfig({ plugins: [ adonisjs({ entrypoints: ['inertia/app/app.ts'], reload: ['resources/views/**/*.edge'] }), inertia(), vue(), ui({ router: 'inertia' }) ] }) ``` > \[!TIP] > > O Nitro UI registra o `unplugin-auto-import` e o `unplugin-vue-components`, que geram os arquivos de declaração de tipos `auto-imports.d.ts` e `components.d.ts`. Você provavelmente vai querer colocá-los no gitignore e adicioná-los ao seu `tsconfig`. > > ```json [tsconfig.app.json] > { > "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "auto-imports.d.ts", "components.d.ts"] > } > ``` > > ```bash [.gitignore] > # Auto-generated type declarations > auto-imports.d.ts > components.d.ts > ``` > \[!TIP] > > Internamente, o Nitro UI depende de um alias personalizado para resolver os tipos do tema. Se você usa TypeScript, deve adicionar um alias ao seu `tsconfig` para habilitar o autocompletar no seu `vite.config.ts`. > > ```json [tsconfig.node.json] > { > "compilerOptions": { > "paths": { > "#build/ui": [ > "./node_modules/.nuxt-ui/ui" > ] > } > } > } > ``` > > ```json [tsconfig.app.json] > { > "compilerOptions": { > "paths": { > "#build/ui/*": [ > "./node_modules/.nuxt-ui/ui/*" > ] > } > } > } > ``` #### Use o plugin Vue do Nitro UI ```ts [src/main.ts (Vite)] {3,14} import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import ui from '@nitro/ui/vue-plugin' import App from './App.vue' const app = createApp(App) const router = createRouter({ routes: [], history: createWebHistory() }) app.use(router) app.use(ui) app.mount('#app') ``` ```ts [resources/js/app.ts (Laravel Inertia)] {3,19} import type { DefineComponent } from 'vue' import { createInertiaApp } from '@inertiajs/vue3' import ui from '@nitro/ui/vue-plugin' import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' import { createApp, h } from 'vue' const appName = import.meta.env.VITE_APP_NAME || 'Laravel x Nitro UI' createInertiaApp({ title: title => (title ? `${title} - ${appName}` : appName), resolve: name => resolvePageComponent( `./pages/${name}.vue`, import.meta.glob('./pages/**/*.vue') ), setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(ui) .mount(el) } }) ``` ```ts [inertia/app/app.ts (AdonisJS Inertia)] {3,19} import type { DefineComponent } from 'vue' import { createInertiaApp } from '@inertiajs/vue3' import ui from '@nitro/ui/vue-plugin' import { resolvePageComponent } from '@adonisjs/inertia/helpers' import { createApp, h } from 'vue' const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS x Nitro UI' createInertiaApp({ title: title => (title ? `${title} - ${appName}` : appName), resolve: name => resolvePageComponent( `../pages/${name}.vue`, import.meta.glob('../pages/**/*.vue') ), setup({ el, App, props, plugin }) { createApp({ render: () => h(App, props) }) .use(plugin) .use(ui) .mount(el) } }) ``` #### Importe o Tailwind CSS e o Nitro UI no seu CSS ```css [src/assets/css/main.css (Vite)] @import "tailwindcss"; @import "@nitro/ui"; ``` ```css [resources/css/app.css (Laravel Inertia)] @import "tailwindcss"; @import "@nitro/ui"; ``` ```css [inertia/css/app.css (AdonisJS Inertia)] @import "tailwindcss"; @import "@nitro/ui"; ``` > \[!TIP] > > Importe o arquivo CSS no seu ponto de entrada. > > ```ts [src/main.ts] {1} > import './assets/css/main.css' > > import { createApp } from 'vue' > import { createRouter, createWebHistory } from 'vue-router' > import ui from '@nitro/ui/vue-plugin' > import App from './App.vue' > > const app = createApp(App) > > const router = createRouter({ > routes: [], > history: createWebHistory() > }) > > app.use(router) > app.use(ui) > > app.mount('#app') > ``` > > ```ts [resources/js/app.ts (Laravel Inertia)] {1} > import '../css/app.css' > import type { DefineComponent } from 'vue' > import { createInertiaApp } from '@inertiajs/vue3' > import ui from '@nitro/ui/vue-plugin' > import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' > import { createApp, h } from 'vue' > > const appName = import.meta.env.VITE_APP_NAME || 'Laravel x Nitro UI' > > createInertiaApp({ > title: title => (title ? `${title} - ${appName}` : appName), > resolve: name => > resolvePageComponent( > `./pages/${name}.vue`, > import.meta.glob('./pages/**/*.vue') > ), > setup({ el, App, props, plugin }) { > createApp({ render: () => h(App, props) }) > .use(plugin) > .use(ui) > .mount(el) > } > }) > ``` > > ```ts [inertia/app/app.ts (AdonisJS Inertia)] {1} > import '../css/app.css' > import type { DefineComponent } from 'vue' > import { createInertiaApp } from '@inertiajs/vue3' > import ui from '@nitro/ui/vue-plugin' > import { resolvePageComponent } from '@adonisjs/inertia/helpers' > import { createApp, h } from 'vue' > > const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS x Nitro UI' > > createInertiaApp({ > title: title => (title ? `${title} - ${appName}` : appName), > resolve: name => > resolvePageComponent( > `../pages/${name}.vue`, > import.meta.glob('../pages/**/*.vue') > ), > setup({ el, App, props, plugin }) { > createApp({ render: () => h(App, props) }) > .use(plugin) > .use(ui) > .mount(el) > } > }) > ``` > \[!NOTE] > > É recomendado instalar a extensão [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss){rel=""nofollow""} para o VSCode e adicionar as seguintes configurações: > > ```json [.vscode/settings.json] > { > "files.associations": { > "*.css": "tailwindcss" > }, > "editor.quickSuggestions": { > "strings": "on" > }, > "tailwindCSS.classAttributes": ["class", "ui"], > "tailwindCSS.classFunctions": ["defineAppConfig"] > } > ``` #### Envolva o seu app com o componente App ```vue [src/App.vue (Vite)] ``` ```vue [resources/js/pages/index.vue (Laravel Inertia)] ``` ```vue [inertia/pages/index.vue (AdonisJS Inertia)] ``` > \[!NOTE] > See: /docs/components/app > > O componente `App` configura o config global e é necessário para **Toast**, **Tooltip** e **overlays programáticos**. #### Adicione a classe `isolate` ao seu container raiz ```html [index.html (Vite)] {9} Nitro UI
``` ```blade [resources/views/app.blade.php (Laravel Inertia)] {10} @inertiaHead @vite('resources/js/app.ts')
@inertia
``` ```edge [resources/views/inertia_layout.edge (AdonisJS Inertia)] {10} @inertiaHead() @vite(['inertia/app/app.ts', `inertia/pages/${page.component}.vue`]) @inertia({ class: 'isolate' }) ``` > \[!NOTE] > > Isso garante que os estilos fiquem restritos ao seu app e evita problemas com overlays e contextos de empilhamento. ## Opções Você pode personalizar o Nitro UI fornecendo opções no seu `vite.config.ts`. ### `prefix` Use a opção `prefix` para alterar o prefixo dos componentes. - Default: `N`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ prefix: 'Nuxt' }) ] }) ``` ### `ui` Use a opção `ui` para fornecer a configuração do Nitro UI. ```ts [vite.config.ts] {9-14} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ ui: { colors: { primary: 'green', neutral: 'slate' } } }) ] }) ``` ### `colorMode` Use a opção `colorMode` para habilitar ou desabilitar a integração de modo de cor do `@vueuse/core`. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ colorMode: false }) ] }) ``` ### `theme.colors` Use a opção `theme.colors` para definir os aliases de cor dinâmicos usados para gerar o tema dos componentes. - Default: `['primary', 'secondary', 'success', 'info', 'warning', 'error']`{.inline,language-ts-type,shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { colors: ['primary', 'error'] } }) ] }) ``` > \[!TIP] > See: /docs/getting-started/theme/design-system#colors > > Saiba mais sobre personalização de cores e tematização na seção Tema. ### `theme.transitions` Use a opção `theme.transitions` para habilitar ou desabilitar as transições nos componentes. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { transitions: false } }) ] }) ``` > \[!NOTE] > > Essa opção adiciona a classe `transition-colors` nos componentes com estados de hover ou ativo. ### `theme.unstyled` `4.9+` Use a opção `theme.unstyled` para remover todas as classes de tema padrão dos componentes, mantendo apenas sua estrutura e as classes que você fornece por meio de `class`, `ui` ou `app.config.ui`. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { unstyled: true } }) ] }) ``` > \[!WARNING] > > Isso também remove classes **estruturais** (posicionamento, transições, flex/grid), não apenas as cosméticas. Componentes com muito layout, como `Modal`, `Drawer` ou `Calendar`, exigirão que você forneça novamente o layout deles, semelhante ao modo unstyled do PrimeVue. ### `theme.defaultVariants` Use a opção `theme.defaultVariants` para sobrescrever as variantes `color` e `size` padrão dos componentes. - Default: `{ color: 'primary', size: 'md' }`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9-14} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { defaultVariants: { color: 'neutral', size: 'sm' } } }) ] }) ``` ### `theme.prefix` `4.2+` Use a opção `theme.prefix` para configurar o mesmo prefixo que você definiu na importação do Tailwind CSS. Isso garante que os componentes do Nitro UI usem as classes utilitárias e variáveis CSS com o prefixo correto. ```ts [vite.config.ts] {9-11} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { prefix: 'tw' } }) ] }) ``` ```css [src/assets/css/main.css] {1} @import "tailwindcss" prefix(tw); @import "@nitro/ui"; ``` Isso adicionará automaticamente o prefixo a todas as classes utilitárias do Tailwind e variáveis CSS nos temas dos componentes do Nitro UI: ```html ``` > \[!NOTE] > See: https\://tailwindcss.com/docs/styling-with-utility-classes#using-the-prefix-option > > Saiba mais sobre o uso de um prefixo na documentação do Tailwind CSS. ### `prose` Use a opção `prose` para habilitar os [componentes `Prose`](https://ui.nitro.news/docs/typography) do Nitro UI e o tema deles. - Default: `false`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ prose: true }) ] }) ``` ### `autoImport` Use a opção `autoImport` para desabilitar a importação automática de composables ou para personalizar as opções do [`unplugin-auto-import`](https://github.com/unplugin/unplugin-auto-import){rel=""nofollow""}. - Default: `{}`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ autoImport: false }) ] }) ``` > \[!NOTE] > > Quando desabilitado, você ainda pode importar composables explicitamente de `@nitro/ui/composables`. ### `components` Use a opção `components` para desabilitar a importação automática de componentes ou para personalizar as opções do [`unplugin-vue-components`](https://github.com/unplugin/unplugin-vue-components){rel=""nofollow""}. - Default: `{}`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ components: false }) ] }) ``` > \[!NOTE] > > Quando desabilitado, você ainda pode importar componentes explicitamente, ex.: `import Button from '@nitro/ui/components/Button.vue'` ou `import ProseCode from '@nitro/ui/components/prose/Code.vue'`. ### `router` `4.3+` Use a opção `router` para configurar a integração de roteamento. Isso é útil para aplicações que não usam `vue-router`, como apps Electron, MPAs ou frameworks como [Inertia.js](https://inertiajs.com/){rel=""nofollow""} ou [Hybridly](https://hybridly.dev/){rel=""nofollow""}. - Default: `true`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} | Value | Description | | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | | `true`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | Uses `vue-router` for navigation with `RouterLink` component. | | `false`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | Disables routing integration, links render as plain `
` tags. | | `'inertia'`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | Uses Inertia.js for navigation with its `Link` component. | ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ router: false }) ] }) ``` > \[!TIP] > > Você pode fornecer uma lógica de navegação personalizada para frameworks como o **Hybridly** definindo `router: false` na configuração do Vite e passando uma função ao instalar o plugin do Vue: > > ```ts [src/main.ts] > import ui from '@nitro/ui/vue-plugin' > import { router } from 'hybridly' > > app.use(ui, { > router: (event, { href, external }) => { > if (external) { > return > } > > event.preventDefault() > > router.navigate({ url: href }) > } > }) > ``` > \[!NOTE] > > Quando definido como `false` ou `'inertia'`, o `vue-router` não é necessário como dependência. ### `scanPackages` `4.3+` Use a opção `scanPackages` para especificar pacotes npm adicionais que devem ser escaneados em busca de componentes que usam o Nitro UI. Isso é útil quando você tem uma biblioteca de componentes compartilhada que usa componentes do Nitro UI internamente. ```ts [vite.config.ts] {9} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ scanPackages: ['@my-org/ui-components'] }) ] }) ``` > \[!NOTE] > > Por padrão, apenas o `@nitro/ui` é escaneado. Use esta opção quando seus pacotes externos contiverem componentes Vue que usam o Nitro UI. ### `root` `4.9+` Use a opção `root` para sobrescrever o diretório onde o Nitro UI gera seu diretório `.nuxt-ui` (que contém os templates do tema). Por padrão, ele usa o `root` do Vite, mas em configurações como [`electron-vite`](https://electron-vite.org/){rel=""nofollow""} o `root` do renderer aponta para um subdiretório (ex.: `src/renderer`), então os templates acabam em `src/renderer/node_modules/.nuxt-ui`, onde o Tailwind não os escaneia, fazendo com que classes de tema como `bg-default`, `ring-default` e `divide-default` fiquem ausentes. ```ts [electron.vite.config.ts] {12} import { defineConfig } from 'electron-vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ renderer: { root: 'src/renderer', plugins: [ vue(), ui({ root: __dirname }) ] } }) ``` > \[!NOTE] > > Aponte o `root` para a raiz do seu projeto para que o diretório `.nuxt-ui` gerado fique em um `node_modules` que o Tailwind escaneia. ## Lançamentos contínuos O Nitro UI usa o [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new){rel=""nofollow""} para lançamentos de preview contínuos, dando aos desenvolvedores acesso instantâneo aos recursos mais recentes e correções de bugs sem esperar pelos lançamentos oficiais. Lançamentos de preview automáticos são criados para todos os commits e PRs na branch `v4`. Use-os substituindo a versão do seu pacote pelo hash específico do commit ou pelo número do PR. ```diff [package.json] { "dependencies": { - "@nitro/ui": "^4.0.0", + "@nitro/ui": "https://pkg.pr.new/@nitro/ui@4c96909", } } ``` > \[!NOTE] > > **pkg.pr.new** will automatically comment on PRs with the installation URL, making it easy to test changes. # Contribuição O Nitro UI prospera graças à sua incrível comunidade ❤️. Damos as boas-vindas a todas as contribuições por meio de relatos de bugs, pull requests e feedback para ajudar a tornar esta biblioteca ainda melhor. > \[!CAUTION] > > Antes de relatar um bug ou solicitar um recurso, certifique-se de ter lido nossa [documentação](https://ui.nitro.news/){rel=""nofollow""} e as [issues](https://github.com/nuxt/ui/issues?q=is%3Aissue%20is%3Aopen%20sort%3Aupdated-desc){rel=""nofollow""} existentes. Para perguntas e ajuda, use o [GitHub Discussions](https://github.com/nuxt/ui/discussions/categories/q-a){rel=""nofollow""}. ## Assistência de IA Fornecemos diretrizes de contribuição por meio do [`AGENTS.md`](https://github.com/nuxt/ui/blob/v4/AGENTS.md){rel=""nofollow""} para assistentes de IA ajudarem você a contribuir com o Nitro UI. Ele é detectado automaticamente por todos os agentes de IA de programação e orienta sobre a estrutura dos componentes, padrões de tematização, convenções de testes e diretrizes de documentação. ## Estrutura do projeto Aqui está uma visão geral dos principais diretórios e arquivos na estrutura do projeto Nitro UI: ### Documentação A documentação fica na pasta `docs` como um app Nuxt que usa o `@nuxt/content` para gerar páginas a partir de arquivos Markdown. Veja a [documentação do Nuxt Content](https://content.nuxt.com/docs/getting-started){rel=""nofollow""} para detalhes de como funciona. Aqui está um detalhamento da sua estrutura: ```bash ├── app/ │ ├── assets/ │ ├── components/ │ │ └── content/ │ │ └── examples # Components used in documentation as examples │ ├── composables/ │ └── ... ├── content/ │ ├── 1.getting-started │ ├── 2.composables │ └── 3.components # Components documentation ``` ### Módulo O código do módulo fica na pasta `src`. Aqui está um detalhamento da sua estrutura: ```bash ├── plugins/ ├── runtime/ │ ├── components/ # Where all the components are located │ │ ├── Accordion.vue │ │ ├── Alert.vue │ │ └── ... │ ├── composables/ │ ├── locale/ │ ├── plugins/ │ ├── types/ │ ├── utils/ │ └── vue/ │ ├── components/ │ └── plugins/ ├── theme/ # This where the theme for each component is located │ ├── accordion.ts # Theme for Accordion component │ ├── alert.ts │ └── ... └── module.ts ``` ## CLI Para facilitar o desenvolvimento, criamos uma CLI que você pode usar para gerar componentes e locales. Você a acessa usando o comando `nuxt-ui make`. Primeiro, você precisa vincular a CLI ao seu ambiente global: ```sh npm link ``` ### Componentes Você pode criar novos componentes usando o seguinte comando: ```sh nuxt-ui make component [options] ``` Available options: - `--primitive` Create a primitive component - `--prose` Create a prose component - `--content` Create a content component - `--template` Only generate specific template (available templates: `playground`, `docs`, `test`, `theme`, `component`) Example: ```sh # Create a basic component nuxt-ui make component my-component # Create a prose component nuxt-ui make component heading --prose # Create a content component nuxt-ui make component block --content # Generate only documentation template nuxt-ui make component my-component --template=docs ``` > \[!NOTE] > > Ao criar um novo componente, a CLI gera automaticamente todos os arquivos necessários, como o próprio componente, o tema, os testes e a documentação. ### Locales Você pode criar novos locales usando o seguinte comando: ```sh nuxt-ui make locale --code --name ``` > \[!NOTE] > See: /docs/getting-started/integrations/i18n/nuxt#supported-languages > > Saiba mais sobre **i18n** na documentação. ## Enviar um Pull Request (PR) Antes de começar, verifique se já existe uma issue descrevendo o problema ou a solicitação de recurso em que você está trabalhando. Se existir, deixe um comentário na issue para nos avisar que você está trabalhando nela. Se não existir, abra uma nova issue para discutir o problema ou o recurso. ### Desenvolvimento local To begin local development, follow these steps: #### Clone o repositório `nuxt/ui` para a sua máquina local ```sh git clone -b v4 https://github.com/nuxt/ui.git ``` #### Habilite o [Corepack](https://github.com/nodejs/corepack){rel=""nofollow""} ```sh corepack enable ``` #### Instale as dependências ```sh pnpm install ``` #### Gere os stubs de tipos ```sh pnpm run dev:prepare ``` #### Inicie o desenvolvimento - To work on the **documentation** located in the `docs` folder, run: ```sh pnpm run docs ``` - To test the Nuxt components using the **playground**, run: ```sh pnpm run dev ``` - To test the Vue components using the **playground**, run: ```sh pnpm run dev:vue ``` > \[!NOTE] > See: #cli > > Se você está trabalhando na implementação de um novo componente, confira a seção **CLI** para iniciar o processo. ### Configuração da IDE Recomendamos usar o VSCode junto com a [extensão do ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint){rel=""nofollow""}. Você pode habilitar a correção automática e a formatação ao salvar o código. Veja como: ```json [.vscode/settings.json] { "editor.codeActionsOnSave": { "source.fixAll": "never", "source.fixAll.eslint": "explicit" }, "prettier.enable": false } ``` > \[!WARNING] > > Como o ESLint já está configurado para formatar o código, não há necessidade de duplicar essa funcionalidade com o **Prettier**. Se você o tiver instalado no seu editor, recomendamos desabilitá-lo para evitar conflitos. ### Linting Você pode usar o comando `lint` para verificar erros de linting: ```sh pnpm run lint # check for linting errors pnpm run lint:fix # fix linting errors ``` ### Verificação de tipos Usamos TypeScript para a verificação de tipos. Você pode usar o comando `typecheck` para verificar erros de tipo: ```sh pnpm run typecheck ``` ### Testes Antes de enviar um PR, certifique-se de rodar os testes: ```sh pnpm run test ``` > \[!TIP] > > Se você precisar atualizar os snapshots, pressione `u` após a execução dos testes terminar. ### Convenções de commit Usamos [Conventional Commits](https://www.conventionalcommits.org/){rel=""nofollow""} para as mensagens de commit, o que permite gerar um changelog automaticamente com base nos commits. Por favor, leia o [guia](https://www.conventionalcommits.org/en/v1.0.0/#summary){rel=""nofollow""} caso ainda não esteja familiarizado com ele. - Use `fix` and `feat` for code changes that affect functionality or logic - Use `docs` for documentation changes and `chore` for maintenance tasks ### Abrindo um Pull Request - Follow along the [instructions](https://github.com/nuxt/ui/blob/v4/.github/PULL_REQUEST_TEMPLATE.md?plain=1){rel=""nofollow""} provided when creating a PR - Ensure your PR's title adheres to the [Conventional Commits](https://www.conventionalcommits.org/){rel=""nofollow""} 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 `lint`, `typecheck` and `tests` work before submitting the PR. Avoid making unrelated changes. Vamos revisá-lo prontamente. Se for atribuído a um mantenedor, ele o revisará com cuidado. Ignore o texto em vermelho; ele serve para fins de rastreamento. ## Agradecimentos Obrigado novamente por se interessar por este projeto! Você é incrível! ❤️ # Design System ## Tailwind CSS O Tailwind CSS usa uma configuração CSS-first, permitindo que você defina seus design tokens com a diretiva [`@theme`](https://tailwindcss.com/docs/functions-and-directives#theme-directive){rel=""nofollow""} diretamente no seu CSS. Isso torna seu tema portátil, de fácil manutenção e fácil de personalizar. ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; @theme { /* Your custom design tokens go here */ } ``` > \[!NOTE] > See: https\://tailwindcss.com/docs/theme > > Consulte a documentação do Tailwind CSS para todas as opções de personalização de variáveis de tema disponíveis. > \[!TIP] > > O Tailwind CSS v4 alterou seu [Preflight](https://tailwindcss.com/docs/upgrade-guide#buttons-use-the-default-cursor){rel=""nofollow""} para que os botões usem `cursor: default` em vez de `cursor: pointer`, para corresponder aos padrões do navegador. Se você quiser restaurar o cursor de ponteiro globalmente, adicione estes estilos base ao seu CSS: > > ```css [app/assets/css/main.css] > @layer base { > button:not(:disabled), > [role="button"]:not(:disabled) { > cursor: pointer; > } > } > ``` ### Fontes Use as variáveis de tema `--font-*` para [personalizar as utilidades de família de fontes](https://tailwindcss.com/docs/font-family#customizing-your-theme){rel=""nofollow""} no seu projeto. ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; @theme { --font-sans: 'Public Sans', system-ui, sans-serif; --font-mono: 'JetBrains Mono', monospace; } ``` **Nuxt:** > \[!NOTE] > See: /docs/getting-started/integrations/fonts > > As fontes definidas aqui são automaticamente carregadas e otimizadas pelo módulo `@nuxt/fonts`. ### Cores Use as variáveis de tema `--color-*` para [personalizar suas cores](https://tailwindcss.com/docs/colors#customizing-your-colors){rel=""nofollow""} ou [sobrescrever as cores padrão](https://tailwindcss.com/docs/colors#overriding-default-colors){rel=""nofollow""}. ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; @theme static { /* Override default green color */ --color-green-50: #EFFDF5; --color-green-100: #D9FBE8; --color-green-200: #B3F5D1; --color-green-300: #75EDAE; --color-green-400: #00DC82; --color-green-500: #00C16A; --color-green-600: #00A155; --color-green-700: #007F45; --color-green-800: #016538; --color-green-900: #0A5331; --color-green-950: #052E16; /* Define new custom color */ --color-brand-50: #fef2f2; --color-brand-100: #fee2e2; --color-brand-200: #fecaca; --color-brand-300: #fca5a5; --color-brand-400: #f87171; --color-brand-500: #ef4444; --color-brand-600: #dc2626; --color-brand-700: #b91c1c; --color-brand-800: #991b1b; --color-brand-900: #7f1d1d; --color-brand-950: #450a0a; } ``` > \[!WARNING] > > Ao adicionar cores personalizadas, certifique-se de definir todos os tons de `50` a `950` para cada cor. ### Breakpoints Use as variáveis de tema `--breakpoint-*` para [personalizar seus breakpoints](https://tailwindcss.com/docs/responsive-design#customizing-your-theme){rel=""nofollow""}. ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; @theme { --breakpoint-3xl: 1920px; --breakpoint-4xl: 2560px; --breakpoint-5xl: 3840px; } ``` ## Cores O sistema de cores do Nitro UI é baseado em **nomes semânticos** em vez de valores de cor específicos. Essa abordagem torna sua UI mais fácil de manter e permite trocar de tema facilmente. ### Cores semânticas O Nitro UI fornece aliases de cor semânticos que descrevem o **propósito** da cor. Cada alias é definido com base em uma cor da sua configuração `@theme`, que pode ser qualquer cor que você definir, além da [paleta padrão do Tailwind CSS](https://tailwindcss.com/docs/colors){rel=""nofollow""}. | Color | Default | Description | | ------------------------------ | -------- | ----------------------------------------------------------------- | | `primary`{color="primary"} | `green` | Main CTAs, active navigation, brand elements, important links | | `secondary`{color="secondary"} | `blue` | Secondary buttons, alternative actions, complementary UI elements | | `success`{color="success"} | `green` | Success messages, completed states, positive confirmations | | `info`{color="info"} | `blue` | Info alerts, tooltips, help text, neutral notifications | | `warning`{color="warning"} | `yellow` | Warning messages, pending states, attention-needed items | | `error`{color="error"} | `red` | Error messages, validation errors, destructive actions | | `neutral` | `slate` | Text, borders, backgrounds, disabled states | Essas cores semânticas estão disponíveis na prop `color` dos componentes do Nitro UI: ```vue ``` > \[!NOTE] > > Experimente o seletor de tema :prose-icon{.text-primary name="i-lucide-swatch-book"} no header para ver instantaneamente como diferentes esquemas de cores afetam toda a UI! ### Configuração em tempo de execução **Nuxt:** Você pode configurar essas cores em tempo de execução no seu arquivo [`app.config.ts`](https://nuxt.com/docs/4.x/directory-structure/app/app-config){rel=""nofollow""}, na chave `ui.colors`, permitindo a personalização dinâmica do tema sem reiniciar o servidor: ```ts [app/app.config.ts] export default defineAppConfig({ ui: { colors: { primary: 'blue', secondary: 'purple', neutral: 'zinc' } } }) ``` **Vue:** Você pode configurar essas cores em tempo de execução no seu arquivo `vite.config.ts`, na chave `ui.colors`, permitindo a personalização dinâmica do tema: ```ts [vite.config.ts] import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ ui: { colors: { primary: 'blue', secondary: 'purple', neutral: 'zinc' } } }) ] }) ``` > \[!CAUTION] > > Você só pode usar cores que existem no seu tema. Uma das opções: > > - Use [Tailwind's default colors](https://tailwindcss.com/docs/colors){rel=""nofollow""} (like `blue`, `green`, `zinc`) > - Define custom colors first using the `@theme` directive (like `brand` in our example above) ### Estender cores Você pode querer definir cores semânticas adicionais além das padrão, como adicionar uma cor `tertiary`: **Nuxt:** Primeiro, registre a nova cor no seu `nuxt.config.ts`, na chave `ui.theme.colors`: ```ts [nuxt.config.ts] {7} export default defineNuxtConfig({ ui: { theme: { colors: [ 'primary', 'secondary', 'tertiary', 'info', 'success', 'warning', 'error' ] } } }) ``` Depois, atribua-a no seu `app.config.ts`, na chave `ui.colors`: ```ts [app/app.config.ts] {6} export default defineAppConfig({ ui: { colors: { primary: 'blue', secondary: 'purple', tertiary: 'indigo' } } }) ``` **Vue:** Registre e atribua a nova cor no seu arquivo `vite.config.ts`: ```ts [vite.config.ts] {13,24} import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ theme: { colors: [ 'primary', 'secondary', 'tertiary', 'info', 'success', 'warning', 'error' ] }, ui: { colors: { primary: 'blue', secondary: 'purple', tertiary: 'indigo' } } }) ] }) ``` Por fim, use essa nova cor em componentes que suportam a prop `color` ou [como uma classe](https://ui.nitro.news/docs/getting-started/theme/css-variables): ```vue Special Action ``` # Variáveis CSS ## Cores O Nitro UI fornece classes utilitárias do Tailwind CSS para cada [cor semântica](https://ui.nitro.news/docs/getting-started/theme/design-system#semantic-colors) que você definir, permitindo usar nomes de classe como `text-error` ou `bg-success`: ```vue ``` Cada classe utilitária usa uma variável CSS para definir sua cor nos modos claro e escuro: ```css [Light] :root { --ui-primary: var(--ui-color-primary-500); --ui-secondary: var(--ui-color-secondary-500); --ui-success: var(--ui-color-success-500); --ui-info: var(--ui-color-info-500); --ui-warning: var(--ui-color-warning-500); --ui-error: var(--ui-color-error-500); } ``` ```css [Dark] .dark { --ui-primary: var(--ui-color-primary-400); --ui-secondary: var(--ui-color-secondary-400); --ui-success: var(--ui-color-success-400); --ui-info: var(--ui-color-info-400); --ui-warning: var(--ui-color-warning-400); --ui-error: var(--ui-color-error-400); } ``` > \[!TIP] > > Você pode ajustar qual tom cada classe utilitária usa nos modos claro e escuro no seu arquivo `main.css`: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > :root { > --ui-primary: var(--ui-color-primary-700); > } > > .dark { > --ui-primary: var(--ui-color-primary-200); > } > ``` > \[!WARNING] > > Você não pode usar `primary: 'black'` na sua [**configuração**](https://ui.nitro.news/docs/getting-started/theme/design-system#runtime-configuration) porque `black` não tem múltiplos tons. Para usar preto ou branco sólido como sua cor primária, defina-o diretamente no seu arquivo `main.css`: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > :root { > --ui-primary: black; > } > > .dark { > --ui-primary: white; > } > ``` ## Texto O Nitro UI fornece classes utilitárias do Tailwind CSS para cores de texto, permitindo usar nomes de classe como `text-dimmed` ou `text-muted`: ```vue ``` Cada classe utilitária usa uma variável CSS para definir sua cor nos modos claro e escuro: ```css [Light] :root { --ui-text-dimmed: var(--ui-color-neutral-400); --ui-text-muted: var(--ui-color-neutral-500); --ui-text-toned: var(--ui-color-neutral-600); --ui-text: var(--ui-color-neutral-700); --ui-text-highlighted: var(--ui-color-neutral-900); --ui-text-inverted: white; } ``` ```css [Dark] .dark { --ui-text-dimmed: var(--ui-color-neutral-500); --ui-text-muted: var(--ui-color-neutral-400); --ui-text-toned: var(--ui-color-neutral-300); --ui-text: var(--ui-color-neutral-200); --ui-text-highlighted: white; --ui-text-inverted: var(--ui-color-neutral-900); } ``` > \[!TIP] > > Você pode personalizar essas variáveis CSS no seu arquivo `main.css`: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > :root { > --ui-text: var(--ui-color-neutral-900); > } > > .dark { > --ui-text: white; > } > ``` ## Fundo O Nitro UI fornece classes utilitárias do Tailwind CSS para cores de fundo, permitindo usar nomes de classe como `bg-default` ou `bg-muted`: ```vue ``` Cada classe utilitária usa uma variável CSS para definir sua cor nos modos claro e escuro: ```css [Light] :root { --ui-bg: white; --ui-bg-muted: var(--ui-color-neutral-50); --ui-bg-elevated: var(--ui-color-neutral-100); --ui-bg-accented: var(--ui-color-neutral-200); --ui-bg-inverted: var(--ui-color-neutral-900); } ``` ```css [Dark] .dark { --ui-bg: var(--ui-color-neutral-900); --ui-bg-muted: var(--ui-color-neutral-800); --ui-bg-elevated: var(--ui-color-neutral-800); --ui-bg-accented: var(--ui-color-neutral-700); --ui-bg-inverted: white; } ``` > \[!TIP] > > Você pode personalizar essas variáveis CSS no seu arquivo `main.css`: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > :root { > --ui-bg: var(--ui-color-neutral-50); > } > > .dark { > --ui-bg: var(--ui-color-neutral-950); > } > ``` ## Borda O Nitro UI fornece classes utilitárias do Tailwind CSS para cores de borda, permitindo usar nomes de classe como `border-default` ou `border-muted`: ```vue ``` Cada classe utilitária usa uma variável CSS para definir sua cor nos modos claro e escuro: ```css [Light] :root { --ui-border: var(--ui-color-neutral-200); --ui-border-muted: var(--ui-color-neutral-200); --ui-border-accented: var(--ui-color-neutral-300); --ui-border-inverted: var(--ui-color-neutral-900); } ``` ```css [Dark] .dark { --ui-border: var(--ui-color-neutral-800); --ui-border-muted: var(--ui-color-neutral-700); --ui-border-accented: var(--ui-color-neutral-700); --ui-border-inverted: white; } ``` > \[!TIP] > > Você pode personalizar essas variáveis CSS no seu arquivo `main.css`: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > :root { > --ui-border: var(--ui-color-neutral-100); > } > > .dark { > --ui-border: var(--ui-color-neutral-900); > } > ``` ## Foco `4.9+` O Nitro UI aplica um contorno `focus-visible` em cada elemento interativo, tingido com a prop `color` do componente, ex.: `outline-primary/25` quando `color="primary"` ou `outline-inverted/25` quando `color="neutral"`. Se você prefere uma única cor de contorno em todo o seu app, independentemente da cor do componente, pode adicionar uma regra global no seu arquivo `main.css`: ```css [Primary] @import "tailwindcss"; @import "@nitro/ui"; *, ::before, ::after { @apply outline-primary/25; } *:focus-visible, *:has(> a:focus-visible) { --tw-ring-color: var(--ui-primary); } ``` ```css [Neutral] @import "tailwindcss"; @import "@nitro/ui"; *, ::before, ::after { @apply outline-inverted/25; } *:focus-visible, *:has(> a:focus-visible) { --tw-ring-color: var(--ui-border-inverted); } ``` A primeira regra tinge o contorno de foco de cada componente; a segunda alinha a recoloração do ring aplicada no foco pelas variantes com uma borda visível, como `outline` ou `subtle`, incluindo cards que se destacam quando o link deles está em foco. > \[!NOTE] > > Certifique-se de declarar essas regras fora de qualquer `@layer` para que tenham precedência sobre as cores definidas pelos temas dos componentes. Tenha em mente que a primeira regra também tinge o contorno de foco nativo dos seus próprios elementos, e as variantes que recolorem uma `border` no foco, como [FileUpload](https://ui.nitro.news/docs/components/file-upload) ou [ContentSurround](https://ui.nitro.news/docs/components/content-surround), continuam seguindo o `color` do componente. ## Raio O Nitro UI sobrescreve as utilidades `rounded-*` padrão do Tailwind CSS com um sistema unificado de raio de borda, permitindo usar as [utilidades de raio de borda](https://tailwindcss.com/docs/border-radius){rel=""nofollow""} comuns, como `rounded-xs` ou `rounded-2xl`: ```vue ``` Essas classes utilitárias são calculadas com base em uma variável CSS global `--ui-radius`, que define o valor de raio base aplicado a todos os componentes para uma aparência consistente. ```css :root { --ui-radius: 0.25rem; } ``` > \[!TIP] > > Você pode personalizar o valor do raio base no seu arquivo `main.css`: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > :root { > --ui-radius: 0.5rem; > } > ``` > \[!NOTE] > > Experimente o seletor de tema :prose-icon{.text-primary name="i-lucide-swatch-book"} no header acima para alterar o valor do raio base. ## Container O Nitro UI fornece uma variável CSS `--ui-container` que controla a largura máxima do componente [Container](https://ui.nitro.news/docs/components/container). ```css :root { --ui-container: 80rem; /* var(--container-7xl) */ } ``` > \[!TIP] > > Você pode personalizar esse valor no seu arquivo `main.css` para ajustar as larguras dos containers de forma consistente em toda a sua aplicação: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > @theme { > --container-8xl: 90rem; > } > > :root { > --ui-container: var(--container-8xl); > } > ``` ## Cabeçalho O Nitro UI fornece uma variável CSS `--ui-header-height` que controla a altura do componente [Header](https://ui.nitro.news/docs/components/header). ```css :root { --ui-header-height: 4rem; } ``` > \[!TIP] > > Você pode personalizar esse valor no seu `main.css` para ajustar a altura do header de forma consistente em toda a sua aplicação: > > ```css [app/assets/css/main.css] > @import "tailwindcss"; > @import "@nitro/ui"; > > :root { > --ui-header-height: --spacing(24); > } > ``` ## Corpo O Nitro UI aplica classes padrão no elemento ``{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="html"} do seu app para uma tematização consistente entre os modos claro e escuro: ```css body { @apply antialiased text-default bg-default scheme-light dark:scheme-dark; } ``` # Personalizar componentes ## Tailwind Variants Os componentes do Nitro UI são estilizados usando a API do [Tailwind Variants](https://www.tailwind-variants.org/){rel=""nofollow""}, que oferece uma maneira poderosa de criar variantes e gerenciar os estilos dos componentes. ### Slots Os componentes podem ter vários `slots`, cada um representando um elemento HTML ou seção distinta dentro do componente. Esses slots permitem inserção de conteúdo e estilização flexíveis. Vamos usar como exemplo o componente [Card](https://ui.nitro.news/docs/components/card), que tem vários slots: ```ts [src/theme/card.ts] export default { slots: { root: 'bg-default ring ring-default divide-y divide-default rounded-lg', header: 'p-4 sm:px-6', body: 'p-4 sm:p-6', footer: 'p-4 sm:px-6' } } ``` ```vue [src/runtime/components/Card.vue] ``` Alguns componentes não têm slots; eles são compostos apenas por um único elemento raiz. Nesse caso, o tema define apenas o slot `base`, como o componente [Container](https://ui.nitro.news/docs/components/container), por exemplo: ```ts [src/theme/container.ts] export default { base: 'max-w-(--ui-container) mx-auto px-4 sm:px-6 lg:px-8' } ``` ```vue [src/runtime/components/Container.vue] ``` > \[!WARNING] > > Componentes sem slots não têm a [prop `ui`](https://ui.nitro.news/#ui-prop); apenas a [prop `class`](https://ui.nitro.news/#class-prop) está disponível para sobrescrever os estilos. ### Variantes Os componentes suportam `variants`, que permitem ajustar dinamicamente os estilos dos diferentes `slots` com base nas props do componente. Por exemplo, o componente [Avatar](https://ui.nitro.news/docs/components/avatar) usa uma variante `size` para controlar sua aparência: ```ts [src/theme/avatar.ts] {6-18} export default { slots: { root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-elevated', image: 'h-full w-full rounded-[inherit] object-cover' }, variants: { size: { sm: { root: 'size-7 text-sm' }, md: { root: 'size-8 text-base' }, lg: { root: 'size-9 text-lg' } } }, defaultVariants: { size: 'md' } } ``` Dessa forma, a prop `size` aplicará os estilos correspondentes ao slot `root`: ```vue ``` ### Variantes padrão A propriedade `defaultVariants` define o valor padrão de cada variante quando nenhuma prop é passada. Por exemplo, o componente [Avatar](https://ui.nitro.news/docs/components/avatar) tem seu tamanho padrão definido como `md`: ```ts [src/theme/avatar.ts] {19-21} export default { slots: { root: 'inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle bg-elevated', image: 'h-full w-full rounded-[inherit] object-cover' }, variants: { size: { sm: { root: 'size-7 text-sm' }, md: { root: 'size-8 text-base' }, lg: { root: 'size-9 text-lg' } } }, defaultVariants: { size: 'md' } } ``` **Nuxt:** > \[!TIP] > See: /docs/getting-started/installation/nuxt#themedefaultvariants > > Você pode usar a opção `theme.defaultVariants` no seu `nuxt.config.ts` para sobrescrever os valores padrão de `size` e `color` de todos os componentes de uma vez. **Vue:** > \[!TIP] > See: /docs/getting-started/installation/vue#themedefaultvariants > > Você pode usar a opção `theme.defaultVariants` no seu `vite.config.ts` para sobrescrever os valores padrão de `size` e `color` de todos os componentes de uma vez. ### Variantes compostas Alguns componentes usam a propriedade `compoundVariants` para aplicar classes quando várias condições de variante são atendidas ao mesmo tempo. Por exemplo, o componente [Button](https://ui.nitro.news/docs/components/button) usa a propriedade `compoundVariants` para aplicar classes a uma combinação específica de `color` e `variant`: ```ts [src/theme/button.ts] {27-31} import type { ModuleOptions } from '../module' export default (options: Required) => ({ slots: { base: ['rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75', options.theme.transitions && 'transition-colors'] }, variants: { color: { ...Object.fromEntries((options.theme.colors || []).map((color: string) => [color, ''])), neutral: '' }, variant: { solid: '', outline: '', soft: '', subtle: '', ghost: '', link: '' } }, compoundVariants: [ ...(options.theme.colors || []).map((color: string) => ({ color, variant: 'outline', class: `ring ring-inset ring-${color}/50 text-${color} hover:bg-${color}/10 active:bg-${color}/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-${color}` })), { color: 'neutral', variant: 'outline', class: 'ring ring-inset ring-accented text-default bg-default hover:bg-elevated active:bg-elevated disabled:bg-default aria-disabled:bg-default focus:outline-none focus-visible:ring-2 focus-visible:ring-inverted' } ], defaultVariants: { color: 'primary', variant: 'solid' } }) ``` ## Personalizar o tema Você tem várias maneiras de personalizar a aparência dos componentes do Nitro UI: pode fazer isso para todos os componentes de uma vez ou individualmente por componente. > \[!NOTE] > > O Tailwind Variants usa o [`tailwind-merge`](https://github.com/dcastil/tailwind-merge){rel=""nofollow""} internamente para mesclar classes, então você não precisa se preocupar com classes conflitantes. > \[!TIP] > > Você pode explorar o tema de cada componente de duas maneiras: > > - Check the `Theme` section in the documentation of each individual component. > - Browse the source code directly in the GitHub repository at [`src/theme`](https://github.com/nuxt/ui/tree/v4/src/theme){rel=""nofollow""}. ### Configuração global **Nuxt:** Você pode sobrescrever o tema dos componentes globalmente dentro do seu `app.config.ts` usando exatamente a mesma estrutura do objeto de tema. **Vue:** Você pode sobrescrever o tema dos componentes globalmente dentro do seu `vite.config.ts` usando exatamente a mesma estrutura do objeto de tema. Você pode personalizar os [`slots`](https://ui.nitro.news/#slots), [`variants`](https://ui.nitro.news/#variants), [`compoundVariants`](https://ui.nitro.news/#compound-variants) e [`defaultVariants`](https://ui.nitro.news/#default-variants) de um componente para alterar o tema padrão dele: **Nuxt:** ```ts [app/app.config.ts] export default defineAppConfig({ ui: { button: { slots: { base: 'font-bold' }, variants: { size: { md: { leadingIcon: 'size-4' } } }, compoundVariants: [{ color: 'neutral', variant: 'outline', class: 'ring-default hover:bg-accented' }], defaultVariants: { color: 'neutral', variant: 'outline' } } } }) ``` **Vue:** ```ts [vite.config.ts] import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ ui: { button: { slots: { base: 'font-bold' }, variants: { size: { md: { leadingIcon: 'size-4' } } }, compoundVariants: [{ color: 'neutral', variant: 'outline', class: 'ring-default hover:bg-accented' }], defaultVariants: { color: 'neutral', variant: 'outline' } } } }) ] }) ``` > \[!NOTE] > > Neste exemplo, `font-bold` sobrescreve `font-medium` em todos os botões, `size-4` sobrescreve a classe `size-5` no ícone à esquerda quando `size="md"`, e `ring-default hover:bg-accented` sobrescreve `ring-accented hover:bg-elevated` quando `color="neutral"` e `variant="outline"`. Os botões agora usam por padrão `color="neutral"` e `variant="outline"`. Por padrão, essas classes são mescladas com os padrões do componente. Você também pode definir um slot como uma função para substituir suas classes por completo. Ela recebe as classes padrão resolvidas como argumento, então você pode reutilizar parte delas se necessário. **Nuxt:** ```ts [app/app.config.ts] export default defineAppConfig({ ui: { button: { slots: { label: () => 'text-base font-bold' } } } }) ``` **Vue:** ```ts [vite.config.ts] import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ ui: { button: { slots: { label: () => 'text-base font-bold' } } } }) ] }) ``` > \[!TIP] > See: /docs/getting-started/installation/nuxt#themeunstyled > > Para remover as classes padrão de todos os componentes de uma vez, use a opção `theme.unstyled`. ### Componente de tema O componente [Theme](https://ui.nitro.news/docs/components/theme) sobrescreve os slots e os valores padrão de props de todos os seus descendentes, sem afetar o resto do app. Isso tem prioridade sobre a configuração global, mas as props `ui` e `class` ainda prevalecem sobre ele. Os slots aceitam a mesma forma de função para substituir suas classes em vez de mesclá-las. :component-example{name="theme-ui-example"} ### `ui` prop Você também pode sobrescrever os **slots** de um componente usando a prop `ui`. Isso tem prioridade tanto sobre a configuração global quanto sobre as `variants` resolvidas. ```vue ``` > \[!NOTE] > > Neste exemplo, o slot `trailingIcon` é sobrescrito com `size-3`, mesmo que a variante de tamanho `md` fosse aplicar a ele uma classe `size-5`. O valor de um slot também pode ser uma função para substituir suas classes em vez de mesclá-las, da mesma forma que na configuração global: ```vue ``` ### `class` prop A prop `class` permite sobrescrever as classes do slot `root` ou `base`. Isso tem prioridade tanto sobre a configuração global quanto sobre as `variants` resolvidas. ```vue ``` > \[!NOTE] > > Neste exemplo, a classe `font-bold` sobrescreverá a classe padrão `font-medium` neste botão. # Ícones > \[!NOTE] > See: /docs/getting-started/integrations/icons/vue > > Procurando pela versão **Vue**? ## Uso O Nitro UI registra automaticamente o módulo [`@nuxt/icon`](https://github.com/nuxt/icon){rel=""nofollow""} para você, então nenhuma configuração adicional é necessária. ### Componente de ícone Você pode usar o componente [Icon](https://ui.nitro.news/docs/components/icon) com uma prop `name` para exibir um ícone: ```vue ``` > \[!NOTE] > > Você pode usar qualquer nome da coleção {rel=""nofollow""}. Navegue por eles facilmente em {rel=""nofollow""} ou busque diretamente pelo seu assistente de IA usando a ferramenta MCP [`search_icons`](https://ui.nitro.news/docs/getting-started/ai/mcp#available-tools). ### Props do componente Alguns componentes também têm uma prop `icon` para exibir um ícone, como o [Button](https://ui.nitro.news/docs/components/button), por exemplo: ```vue ``` ## Coleções ### Conjunto de dados do Iconify É altamente recomendado instalar os dados dos ícones localmente com: ```bash [pnpm] pnpm i @iconify-json/{collection_name} ``` ```bash [yarn] yarn add @iconify-json/{collection_name} ``` ```bash [npm] npm install @iconify-json/{collection_name} ``` Por exemplo, para usar o ícone `i-uil-github`, instale sua coleção com `@iconify-json/uil`. Assim os ícones podem ser servidos localmente ou a partir das suas funções serverless, o que é mais rápido e confiável tanto no SSR quanto no lado do cliente. Instalar a coleção também permite que o Nitro UI embuta os ícones que usa no bundle do cliente em tempo de build, para que fiquem disponíveis na primeira renderização em vez de serem carregados sob demanda em tempo de execução. Isso acontece automaticamente para os ícones próprios do Nitro UI, da coleção `lucide` por padrão. Para empacotar outros ícones, como os que você sobrescreve ou usa em outros lugares do seu app, adicione-os à opção [`clientBundle.icons`](https://github.com/nuxt/icon?tab=readme-ov-file#client-bundle){rel=""nofollow""} do `@nuxt/icon` no seu `nuxt.config.ts`: ```ts [nuxt.config.ts] export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], icon: { clientBundle: { icons: ['lucide:heart', 'simple-icons:github'] } } }) ``` Ou habilite `clientBundle.scan` para empacotar todos os ícones usados no seu app escaneando seu código-fonte, para que você não precise listá-los um a um: ```ts [nuxt.config.ts] export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], icon: { clientBundle: { scan: true } } }) ``` > \[!NOTE] > See: https\://github.com/nuxt/icon?tab=readme-ov-file#iconify-dataset > > Leia mais sobre isso na documentação do `@nuxt/icon`. ### Coleções locais personalizadas Você pode usar arquivos SVG locais para criar uma coleção Iconify personalizada. Por exemplo, coloque os arquivos SVG dos seus ícones em uma pasta de sua escolha, por exemplo, `./app/assets/icons`: ```bash assets/icons ├── add.svg └── remove.svg ``` No seu `nuxt.config.ts`, adicione um item em `icon.customCollections`: ```ts export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], icon: { customCollections: [{ prefix: 'custom', dir: './app/assets/icons' }] } }) ``` Depois, você pode usar os ícones assim: ```vue ``` > \[!NOTE] > See: https\://github.com/nuxt/icon?tab=readme-ov-file#custom-local-collections > > Leia mais sobre isso na documentação do `@nuxt/icon`. ## Tema Você pode alterar os ícones padrão usados pelos componentes no seu `app.config.ts`: *See the interactive theme picker on the documentation website.* > \[!NOTE] > > Os ícones que você sobrescreve em `app.config.ts` são carregados sob demanda em tempo de execução, em vez de serem embutidos no bundle do cliente. Para empacotá-los também, adicione-os no formato `{collection}:{name}` (por exemplo, `lucide:rocket`) à opção [`clientBundle.icons`](https://github.com/nuxt/icon?tab=readme-ov-file#client-bundle){rel=""nofollow""} do `@nuxt/icon` no seu `nuxt.config.ts`. # Ícones > \[!NOTE] > See: /docs/getting-started/integrations/icons/nuxt > > Procurando pela versão **Nuxt**? ## Uso ### Componente de ícone Você pode usar o componente [Icon](https://ui.nitro.news/docs/components/icon) com uma prop `name` para exibir um ícone: ```vue ``` > \[!NOTE] > > Você pode usar qualquer nome da coleção {rel=""nofollow""}. Navegue por eles facilmente em {rel=""nofollow""} ou busque diretamente pelo seu assistente de IA usando a ferramenta MCP [`search_icons`](https://ui.nitro.news/docs/getting-started/ai/mcp#available-tools). > \[!WARNING] > > Ao usar coleções com um hífen (`-`), você precisa separar o nome do ícone do nome da coleção com dois-pontos (`:`), pois o `@iconify/vue` não trata esse caso como o `@nuxt/icon`. Por exemplo, em vez de `i-simple-icons-github`, você precisa escrever `i-simple-icons:github` ou `simple-icons:github`. > > Learn more about the [Iconify naming convention](https://iconify.design/docs/icon-components/vue/#icon){rel=""nofollow""}. ### Props do componente Alguns componentes também têm uma prop `icon` para exibir um ícone, como o [Button](https://ui.nitro.news/docs/components/button), por exemplo: ```vue ``` ## Coleções ### Conjunto de dados do Iconify É altamente recomendado instalar os dados dos ícones localmente com: ```bash [pnpm] pnpm i @iconify-json/{collection_name} ``` ```bash [yarn] yarn add @iconify-json/{collection_name} ``` ```bash [npm] npm install @iconify-json/{collection_name} ``` Por exemplo, para usar o ícone `i-lucide-lightbulb`, instale sua coleção com `@iconify-json/lucide`. Instalar a coleção permite que o Nitro UI embuta os ícones que usa no seu build, para que sejam renderizados imediatamente durante o SSR e funcionem totalmente offline, em vez de serem buscados na API do Iconify em tempo de execução. Isso acontece automaticamente para os ícones próprios do Nitro UI, da coleção `lucide` por padrão. Para empacotar outros ícones, como os que você sobrescreve ou usa em outros lugares do seu app, adicione-os à opção `icon.clientBundle.icons` no seu `vite.config.ts`: ```ts [vite.config.ts] import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ ui({ icon: { clientBundle: { icons: ['lucide:heart', 'simple-icons:github'] } } }) ] }) ``` > \[!NOTE] > > Você pode usar tanto o formato `i-{collection}-{name}` quanto `{collection}:{name}`, por exemplo `i-lucide-heart` ou `lucide:heart`, e `i-material-symbols-menu` ou `material-symbols:menu`. Instale cada coleção que você referenciar com `@iconify-json/{collection_name}`. Para empacotar os ícones que você usa sem listá-los um a um, habilite `scan`. Ele escaneia seu código-fonte em busca de usos de ícones das suas coleções instaladas e os empacota, da mesma forma que o `clientBundle.scan` do `@nuxt/icon` funciona: ```ts [vite.config.ts] import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ ui({ icon: { clientBundle: { scan: true } } }) ] }) ``` Os ícones cuja coleção não está instalada ainda são carregados da API do Iconify em tempo de execução, então instale cada coleção que você usa com `@iconify-json/{collection_name}`. Para desativar o empacotamento por completo, defina `icon.clientBundle` como `false`. ## Tema Você pode alterar os ícones padrão usados pelos componentes do Nitro UI no seu `vite.config.ts`: *See the interactive theme picker on the documentation website.* # Fontes ## Uso O Nitro UI registra automaticamente o módulo [`@nuxt/fonts`](https://github.com/nuxt/fonts){rel=""nofollow""} para você, então nenhuma configuração adicional é necessária. ### Declaração Para usar uma fonte na sua aplicação Nitro UI, basta declará-la no seu CSS. Ela será carregada e otimizada automaticamente para você. ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; @theme { --font-sans: 'Public Sans', sans-serif; } ``` ### Configuração Você pode desabilitar o módulo `@nuxt/fonts` com a opção `ui.fonts` no seu `nuxt.config.ts`: ```ts [nuxt.config.ts] export default defineNuxtConfig({ ui: { fonts: false } }) ``` # Modo de cor > \[!NOTE] > See: /docs/getting-started/integrations/color-mode/vue > > Procurando pela versão **Vue**? ## Uso O Nitro UI registra automaticamente o módulo [`@nuxtjs/color-mode`](https://github.com/nuxt-modules/color-mode){rel=""nofollow""} para você, então nenhuma configuração adicional é necessária. ### Componentes Você pode usar os componentes integrados [ColorModeAvatar](https://ui.nitro.news/docs/components/color-mode-avatar) ou [ColorModeImage](https://ui.nitro.news/docs/components/color-mode-image) para exibir imagens diferentes nos modos claro e escuro, e os componentes [ColorModeButton](https://ui.nitro.news/docs/components/color-mode-button), [ColorModeSwitch](https://ui.nitro.news/docs/components/color-mode-switch) ou [ColorModeSelect](https://ui.nitro.news/docs/components/color-mode-select) para alternar entre os modos claro e escuro. Você também pode usar o composable [useColorMode](https://color-mode.nuxtjs.org/#usage){rel=""nofollow""} para construir seu próprio componente personalizado: ```vue [ColorModeButton.vue] ``` ### Configuração Você pode desabilitar o módulo `@nuxtjs/color-mode` com a opção `ui.colorMode` no seu `nuxt.config.ts`: ```ts [nuxt.config.ts] export default defineNuxtConfig({ modules: ['@nitro/ui'], css: ['~/assets/css/main.css'], ui: { colorMode: false } }) ``` # Modo de cor > \[!NOTE] > See: /docs/getting-started/integrations/color-mode/nuxt > > Procurando pela versão **Nuxt**? ## Uso O Nitro UI registra automaticamente o composable [useDark](https://vueuse.org/core/useDark){rel=""nofollow""} como um plugin do Vue, então nenhuma configuração adicional é necessária. ### Componentes Você pode usar os componentes integrados [ColorModeAvatar](https://ui.nitro.news/docs/components/color-mode-avatar) ou [ColorModeImage](https://ui.nitro.news/docs/components/color-mode-image) para exibir imagens diferentes nos modos claro e escuro, e os componentes [ColorModeButton](https://ui.nitro.news/docs/components/color-mode-button), [ColorModeSwitch](https://ui.nitro.news/docs/components/color-mode-switch) ou [ColorModeSelect](https://ui.nitro.news/docs/components/color-mode-select) para alternar entre os modos claro e escuro. Você também pode usar o composable [useColorMode](https://vueuse.org/core/useColorMode){rel=""nofollow""} para construir seu próprio componente personalizado: ```vue [ColorModeButton.vue] ``` ### Configuração Você pode desabilitar esse plugin com a opção `colorMode` no seu `vite.config.ts`: ```ts [vite.config.ts] import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import ui from '@nitro/ui/vite' export default defineConfig({ plugins: [ vue(), ui({ colorMode: false }) ] }) ``` # Internacionalização (i18n) > \[!NOTE] > See: /docs/getting-started/integrations/i18n/vue > > Procurando pela versão **Vue**? ## Uso > \[!NOTE] > See: /docs/components/app > > O Nitro UI fornece um componente **App** que envolve seu app para fornecer configurações globais, incluindo a prop `locale`. ### Locale Use a prop `locale` com o locale que você quer usar de `@nitro/ui/locale`: ```vue [app.vue] ``` > \[!TIP] > > Cada locale tem uma propriedade `code` (ex.: `en`, `en-GB`, `fr`) que determina o formato de data/hora em componentes como [Calendar](https://ui.nitro.news/docs/components/calendar), [InputDate](https://ui.nitro.news/docs/components/input-date) e [InputTime](https://ui.nitro.news/docs/components/input-time). ### Locale personalizado Você pode criar seu próprio locale usando o utilitário [defineLocale](https://ui.nitro.news/docs/composables/define-locale): ```vue [app.vue] ``` > \[!TIP] > > Observe o parâmetro `code`; nele você precisa passar o código ISO do idioma. Exemplo: > > - `hi` Hindi (language) > - `de-AT`: German (language) as used in Austria (region) ### Estender o locale Você pode personalizar um locale existente sobrescrevendo suas `messages` ou seu `code` usando o utilitário [extendLocale](https://ui.nitro.news/docs/composables/extend-locale): ```vue [app.vue] ``` ### Locale dinâmico Para alternar dinamicamente entre idiomas, você pode usar o módulo [Nuxt I18n](https://i18n.nuxtjs.org/){rel=""nofollow""}. #### Instale o pacote Nuxt I18n ```bash [pnpm] pnpm add @nuxtjs/i18n ``` ```bash [yarn] yarn add @nuxtjs/i18n ``` ```bash [npm] npm install @nuxtjs/i18n ``` ```bash [bun] bun add @nuxtjs/i18n ``` #### Adicione o módulo Nuxt I18n no seu `nuxt.config.ts`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```ts [nuxt.config.ts] export default defineNuxtConfig({ modules: [ '@nitro/ui', '@nuxtjs/i18n' ], css: ['~/assets/css/main.css'], i18n: { locales: [{ code: 'de', name: 'Deutsch' }, { code: 'en', name: 'English' }, { code: 'fr', name: 'Français' }] } }) ``` #### Defina a prop `locale` usando `useI18n` ```vue [app.vue] ``` #### Localização automática de links `4.7+` Quando o `@nuxtjs/i18n` está instalado, o componente [Link](https://ui.nitro.news/docs/components/link) localiza automaticamente os links internos usando o helper `$localePath`. Isso significa que você não precisa envolver manualmente seus links com `localePath()` ou `localeRoute()`. ```vue ``` > \[!TIP] > > Links externos e URLs absolutas são detectados automaticamente e ignoram a localização. Você ainda pode usar `localePath()` ou `localeRoute()` manualmente se necessário. ### Direção dinâmica Cada locale tem uma propriedade `dir` que será usada pelo componente `App` para definir a direcionalidade de todos os componentes. Em uma aplicação multilíngue, você pode querer definir os atributos `lang` e `dir` no elemento `` dinamicamente com base no locale do usuário, o que você pode fazer com o composable [useHead](https://nuxt.com/docs/api/composables/use-head){rel=""nofollow""}: ```vue [app.vue] ``` ## Idiomas suportados *See the full list of supported languages on the documentation website.* # Internacionalização (i18n) > \[!NOTE] > See: /docs/getting-started/integrations/i18n/nuxt > > Procurando pela versão **Nuxt**? ## Uso > \[!NOTE] > See: /docs/components/app > > O Nitro UI fornece um componente **App** que envolve seu app para fornecer configurações globais, incluindo a prop `locale`. ### Locale Use a prop `locale` com o locale que você quer usar de `@nitro/ui/locale`: ```vue [App.vue] ``` > \[!TIP] > > Cada locale tem uma propriedade `code` (ex.: `en`, `en-GB`, `fr`) que determina o formato de data/hora em componentes como [Calendar](https://ui.nitro.news/docs/components/calendar), [InputDate](https://ui.nitro.news/docs/components/input-date) e [InputTime](https://ui.nitro.news/docs/components/input-time). ### Locale personalizado Você pode criar seu próprio locale usando o utilitário [defineLocale](https://ui.nitro.news/docs/composables/define-locale): ```vue [App.vue] ``` > \[!TIP] > > Observe o parâmetro `code`; nele você precisa passar o código ISO do idioma. Exemplo: > > - `hi` Hindi (language) > - `de-AT`: German (language) as used in Austria (region) ### Estender o locale Você pode personalizar um locale existente sobrescrevendo suas `messages` ou seu `code` usando o utilitário [extendLocale](https://ui.nitro.news/docs/composables/extend-locale): ```vue [App.vue] ``` ### Locale dinâmico Para alternar dinamicamente entre idiomas, você pode usar o plugin [Vue I18n](https://vue-i18n.intlify.dev/){rel=""nofollow""}. #### Instale o pacote Vue I18n ```bash [pnpm] pnpm add vue-i18n@11 ``` ```bash [yarn] yarn add vue-i18n@11 ``` ```bash [npm] npm install vue-i18n@11 ``` ```bash [bun] bun add vue-i18n@11 ``` #### Use o plugin Vue I18n no seu `main.ts` ```ts [src/main.ts] {3,14-26,29} import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import { createI18n } from 'vue-i18n' import ui from '@nitro/ui/vue-plugin' import App from './App.vue' const app = createApp(App) const router = createRouter({ routes: [], history: createWebHistory() }) const i18n = createI18n({ legacy: false, locale: 'en', availableLocales: ['en', 'de'], messages: { en: { // ... }, de: { // ... } } }) app.use(router) app.use(i18n) app.use(ui) app.mount('#app') ``` #### Defina a prop `locale` usando `useI18n` ```vue [App.vue] ``` ### Direção dinâmica Cada locale tem uma propriedade `dir` que será usada pelo componente `App` para definir a direcionalidade de todos os componentes. Em uma aplicação multilíngue, você pode querer definir os atributos `lang` e `dir` no elemento `` dinamicamente com base no locale do usuário, o que você pode fazer com o composable [useHead](https://unhead.unjs.io/usage/composables/use-head){rel=""nofollow""}: ```vue [App.vue] ``` ## Idiomas suportados *See the full list of supported languages on the documentation website.* # Content ## Instalação Para começar, você pode seguir o [guia](https://content.nuxt.com/docs/getting-started/installation){rel=""nofollow""} oficial ou, em resumo: ```bash [pnpm] pnpm add @nuxt/content ``` ```bash [yarn] yarn add @nuxt/content ``` ```bash [npm] npm install @nuxt/content ``` ```bash [bun] bun add @nuxt/content ``` Depois, adicione o módulo `@nuxt/content` no seu `nuxt.config.ts`: ```ts [nuxt.config.ts] {4} export default defineNuxtConfig({ modules: [ '@nitro/ui', '@nuxt/content' ], css: ['~/assets/css/main.css'] }) ``` > \[!CAUTION] > > Você precisa registrar o `@nuxt/content` depois do `@nitro/ui` no array `modules`, caso contrário os componentes de prose não estarão disponíveis. ## Configuração Ao usar classes do Tailwind CSS nos seus arquivos de conteúdo markdown, você precisa garantir que o Tailwind consiga detectar e gerar as classes utilitárias necessárias. Por padrão, a detecção automática de conteúdo do Tailwind pode não captar as classes escritas em arquivos markdown. Para corrigir isso, use a [diretiva `@source`](https://tailwindcss.com/docs/functions-and-directives#source-directive){rel=""nofollow""} no seu arquivo CSS para incluir explicitamente o diretório de conteúdo: ```css [app/assets/css/main.css] @import "tailwindcss"; @import "@nitro/ui"; @source "../../../content/**/*"; ``` Isso garante que: - Tailwind scans all markdown files in your content directory - Any utility classes used in your markdown (like `text-primary`) are included in the final CSS - Dynamic classes in MDC components or custom Vue components within your content work properly > \[!TIP] > > Você também pode usar padrões glob para ser mais específico sobre quais arquivos escanear: > > - `@source "../../../content/docs/**/*.md"` - Only scan markdown in the docs folder > - `@source "../../../content/**/*.{md,yml}"` - Include both markdown and YAML files > \[!NOTE] > See: https\://tailwindcss.com/docs/detecting-classes-in-source-files > > Saiba mais sobre a detecção automática de conteúdo do Tailwind e as boas práticas para otimizar o desempenho do build. ## Componentes Você pode estar usando o `@nuxt/content` para construir uma documentação. Para ajudar você com isso, criamos alguns componentes que você pode usar nas suas páginas: - a built-in full-text search command palette with [ContentSearch](https://ui.nitro.news/docs/components/content-search), replacing the need for Algolia DocSearch - a navigation tree with the [ContentNavigation](https://ui.nitro.news/docs/components/content-navigation) component - a sticky Table of Contents with the [ContentToc](https://ui.nitro.news/docs/components/content-toc) component - a prev / next navigation with the [ContentSurround](https://ui.nitro.news/docs/components/content-surround) component ## Typography O Nitro UI fornece suas próprias implementações personalizadas de todos os componentes de prose para uma integração perfeita com o `@nuxt/content`. Essa abordagem garante estilização consistente, controle total sobre a tipografia e alinhamento perfeito com o design system do Nitro UI, para que seu conteúdo sempre pareça coeso desde o início. > \[!NOTE] > See: /docs/typography > > Conheça o sistema completo de **Tipografia** e explore todos os componentes de prose disponíveis para uma apresentação de conteúdo rica e consistente. ## Utilitários ### `mapContentNavigation` Este utilitário mapeará a navegação de `queryCollectionNavigation` e a transformará recursivamente em um array de objetos que pode ser usado por vários componentes. `mapContentNavigation(navigation, options?)` - `navigation`: The navigation tree (array of ContentNavigationItem). - `options`(optional): - `labelAttribute`: (string) Which field to use as label (`title` by default) - `deep`: (number or undefined) Controls how many levels of navigation are included (`undefined` by default : includes all levels) **Example:** As shown in the breadcrumb example below, it's commonly used to transform the navigation data into the correct format. ```vue [app.vue] ``` # SSR ## Uso Ao usar o Nitro UI com o framework Nuxt, o SSR do servidor funcionará totalmente por padrão. No entanto, ao usá-lo com Vue puro, você precisará prestar atenção a alguns detalhes para que funcione como esperado. ### Injeção de variáveis de cor Por padrão, o Nitro UI injeta no `` do documento as variáveis de cor usadas por todos os componentes. Como o documento não é gerenciado pela biblioteca de UI no SSR do Vue, você precisará injetá-las manualmente. Você pode fazer isso usando o `@unhead` da seguinte forma: ```ts [ssr.ts] import { createHead, renderSSRHead } from '@unhead/vue/server' // Create the header with unhead const head = createHead() // Render SSR header and append it to the SSR application instance const payload = await renderSSRHead(head) app.head.push(payload.headTags) ``` ```ts [resources/js/ssr.ts (Laravel Inertia)] {4,14,27,29-33} import { createInertiaApp } from '@inertiajs/vue3' import createServer from '@inertiajs/vue3/server' import ui from '@nitro/ui/vue-plugin' import { createHead, renderSSRHead } from '@unhead/vue/server' import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' import { createSSRApp, h } from 'vue' import { renderToString } from 'vue/server-renderer' import type { DefineComponent } from 'vue' const appName = import.meta.env.VITE_APP_NAME || 'Laravel x Nitro UI' createServer( (page) => { const head = createHead() return createInertiaApp({ page, render: renderToString, title: (title) => (title ? `${title} - ${appName}` : appName), resolve: (name) => resolvePageComponent( `./pages/${name}.vue`, import.meta.glob('./pages/**/*.vue') ), setup: ({ App, props, plugin }) => createSSRApp({ render: () => h(App, props) }) .use(plugin) .use(head) .use(ui) }).then(async (app) => { const payload = await renderSSRHead(head) app.head.push(payload.headTags) return app }) }, { cluster: true } ) ``` ```ts [inertia/app/ssr.ts (AdonisJS Inertia)] {4,14,27,29-33} import { createInertiaApp } from '@inertiajs/vue3' import createServer from '@inertiajs/vue3/server' import ui from '@nitro/ui/vue-plugin' import { createHead, renderSSRHead } from '@unhead/vue/server' import { resolvePageComponent } from '@adonisjs/inertia/helpers' import { createSSRApp, h } from 'vue' import { renderToString } from 'vue/server-renderer' import type { DefineComponent } from 'vue' const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS x Nitro UI' createServer( (page) => { const head = createHead() return createInertiaApp({ page, render: renderToString, title: (title) => (title ? `${title} - ${appName}` : appName), resolve: (name) => resolvePageComponent( `../pages/${name}.vue`, import.meta.glob('../pages/**/*.vue') ), setup: ({ App, props, plugin }) => createSSRApp({ render: () => h(App, props) }) .use(plugin) .use(head) .use(ui) }).then(async (app) => { const payload = await renderSSRHead(head) app.head.push(payload.headTags) return app }) }, { cluster: true } ) ``` ### Detecção de esquema de cores O mesmo vale para a detecção do esquema de cores. Para evitar piscadas no SSR por causa da diferença do esquema de cores selecionado, você precisará detectar o esquema de cores do usuário antes da inicialização da aplicação. Adicionar o script abaixo ao `` do seu documento detectará se o usuário está usando o tema escuro e, portanto, renderizará o SSR também no tema escuro. ```html [index.html] ``` ```html [resources/views/app.blade.php (Laravel Inertia)] {8-15} @inertiaHead @vite('resources/js/app.ts')
@inertia
``` ```html [resources/views/inertia_layout.edge (AdonisJS Inertia)] {8-15} @inertiaHead() @vite(['inertia/app/app.ts', `inertia/pages/${page.component}.vue`]) @inertia({ class: 'isolate' }) ``` ### Exibição de ícones O Nitro UI empacota os ícones que usa no seu build, então eles são renderizados durante o SSR e funcionam totalmente offline assim que você instala a coleção de ícones localmente, sem nenhuma requisição à API do Iconify. Veja a integração de [Ícones](https://ui.nitro.news/docs/getting-started/integrations/icons/vue#collections) para configurar isso e empacotar seus próprios ícones. # Servidor MCP ## O que é o MCP? O MCP (Model Context Protocol) é um protocolo padronizado que permite a assistentes de IA acessarem fontes de dados e ferramentas externas. O Nitro UI fornece um servidor MCP que permite a assistentes de IA como Claude Code, Cursor e Windsurf acessarem diretamente informações dos componentes, código-fonte e exemplos de uso. O servidor MCP fornece acesso estruturado à nossa biblioteca de componentes, facilitando que ferramentas de IA entendam e auxiliem no desenvolvimento com o Nitro UI. ## Recursos disponíveis O servidor MCP do Nitro UI fornece os seguintes recursos para descoberta: - **`resource://nuxt-ui/components`**: Browse all available components with categories - **`resource://nuxt-ui/composables`**: Browse all available composables with categories - **`resource://nuxt-ui/examples`**: Browse all available code examples - **`resource://nuxt-ui/templates`**: Browse all available project templates - **`resource://nuxt-ui/documentation-pages`**: Browse all available documentation pages Você pode acessar esses recursos com ferramentas como o Claude Code usando `@`. ## Ferramentas disponíveis O servidor MCP do Nitro UI fornece as seguintes ferramentas organizadas por categoria: ### Ferramentas de busca - **`search_components`**: Search components by name, description, or category. With no params, lists all components - **`search_composables`**: Search composables by name or description. With no params, lists all composables - **`search_icons`**: Search for icons across Iconify collections (defaults to `lucide`). Returns icon names in the `i-{prefix}-{name}` format used by Nitro UI ### Ferramentas de componente - **`get_component`**: Retrieves component documentation and details. Supports a `sections` parameter (`usage`, `examples`, `api`, `theme`, `changelog`) to fetch only specific parts and reduce response size - **`get_component_metadata`**: Retrieves detailed metadata for a component including props, slots, and events (lightweight, no documentation content) ### Ferramentas de documentação - **`search_documentation`**: Search documentation pages by title, description, or section. With no params, lists all pages. Use `section` to filter (e.g., `"getting-started"`, `"components"`) - **`get_documentation_page`**: Retrieves documentation page content by URL path. Supports a `headings` parameter to fetch only specific h2 sections (e.g., `["Usage", "API"]`) and reduce response size ### Ferramentas de exemplo - **`list_examples`**: Lists all available UI examples and code demonstrations - **`get_example`**: Retrieves specific UI example implementation code and details ## Prompts disponíveis O servidor MCP do Nitro UI fornece prompts guiados para fluxos de trabalho comuns: - **`find_component_for_usecase`**: Find the best component for your specific use case - **`implement_component_with_props`**: Generate complete component implementation with proper props - **`setup_project_with_template`**: Get guided setup instructions for project templates Você pode acessar esses recursos com ferramentas como o Claude Code usando `/`. ## Configuração O servidor MCP do Nitro UI usa transporte HTTP e pode ser configurado em diferentes assistentes de IA. ### ChatGPT > \[!NOTE] > > **Custom connectors using MCP are available on ChatGPT for Pro and Plus accounts.** Accessible on the web. Siga estas etapas para configurar o Nitro UI como um conector dentro do ChatGPT: 1. **Enable Developer mode:** - Go to "Settings" > "Connectors" > "Advanced settings" > "Developer mode" 2. **Open ChatGPT settings** 3. **Na aba Connectors, crie um novo conector:** - Give it a name: `Nitro UI` - MCP server URL: `https://ui.nitro.news/mcp` - Authentication: `None` 4. **Click Create** O conector do Nitro UI aparecerá na ferramenta "Developer mode" do compositor mais tarde, durante as conversas. ### Claude Code > \[!NOTE] > > **Ensure Claude Code is installed.** Visit [Anthropic's documentation](https://docs.anthropic.com/en/docs/claude-code/quickstart){rel=""nofollow""} for installation instructions. Adicione o servidor usando o comando da CLI: ```bash claude mcp add --transport http nuxt-ui-remote https://ui.nitro.news/mcp ``` ### Claude Desktop #### Instruções de configuração: 1. Abra o Claude Desktop e navegue até "Settings" > "Developer". 2. Clique em "Edit Config". Isso abrirá o diretório local do Claude. 3. Modifique o arquivo `claude_desktop_config.json` com a sua configuração personalizada do servidor MCP. ```json [claude_desktop_config.json] { "mcpServers": { "nuxt-ui": { "command": "npx", "args": [ "mcp-remote", "https://ui.nitro.news/mcp" ] } } } ``` 4. Reinicie o aplicativo Claude Desktop. O servidor MCP do Nitro UI deve estar registrado agora. ### Cursor #### Instalação rápida: Clique no botão abaixo para instalar o servidor MCP do Nitro UI diretamente no Cursor: [Install MCP Server](cursor://anysphere.cursor-deeplink/mcp/install?name=nuxt-ui&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vdWkubnV4dC5jb20vbWNwIn0%3D) #### Instruções de configuração manual: 1. Abra o Cursor e vá em "Settings" > "Tools & MCP" 2. Add the Nitro UI MCP server configuration Ou crie/atualize manualmente o `.cursor/mcp.json` na raiz do seu projeto: ```json [.cursor/mcp.json] { "mcpServers": { "nuxt-ui": { "type": "http", "url": "https://ui.nitro.news/mcp" } } } ``` ### Gemini CLI #### Instruções de configuração: 1. Localize o arquivo de configuração da sua Gemini CLI (geralmente \~/.gemini/settings.json ou conforme especificado no seu ambiente). 2. Adicione a seguinte configuração ao seu objeto mcpServers: ```json [~/.gemini/settings.json] { "mcpServers": { "nuxt-ui": { "url": "https://ui.nitro.news/mcp" } } } ``` 3. Reinicie a sessão do seu terminal ou recarregue a CLI. As ferramentas do servidor MCP do Nitro UI agora estarão disponíveis para uso. ### GitHub Copilot Agent > \[!NOTE] > > **Repository administrator access required.** This is needed to configure MCP servers for GitHub Copilot coding agent. Se você já configurou servidores MCP no [Visual Studio Code](https://ui.nitro.news/#visual-studio-code), substitua a chave `servers` por `mcpServers` e adicione uma chave `tools` especificando quais ferramentas estão disponíveis para o Copilot. #### Instruções de configuração: 1. Navegue até o seu repositório do GitHub 2. Go to **Settings** > **Code & automation** > **Copilot** > **Coding agent** 3. Na seção **MCP configuration**, adicione a seguinte configuração: ```json { "mcpServers": { "nuxt-ui": { "type": "http", "url": "https://ui.nitro.news/mcp", "tools": ["*"] } } } ``` 4. Click Save #### Validando a configuração: Para verificar se o servidor MCP está configurado corretamente: 1. Crie uma issue no seu repositório e atribua-a ao Copilot 2. Aguarde o Copilot criar um pull request 3. No pull request, clique em View session no evento da timeline "Copilot started work" 4. Clique no botão de reticências (...) no canto superior direito e depois clique em Copilot na barra lateral 5. Expanda a etapa Start MCP Servers para ver as ferramentas do Nuxt configuradas Para mais informações sobre o uso de MCP com o agente de programação do GitHub Copilot, veja [Extend coding agent with MCP](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/extend-coding-agent-with-mcp){rel=""nofollow""}. ### GitHub Copilot CLI #### Instruções de configuração: 1. Start GitHub Copilot CLI in interactive mode. 2. Run `/mcp add`. 3. Preencha o formulário de configuração com: - **Server Name**: `nuxt-ui` - **Server Type**: `HTTP` - **URL**: `https://ui.nitro.news/mcp` - **HTTP Headers**: leave empty - **Tools**: `*` 4. Pressione :kbd[Ctrl] + :kbd[S] para salvar. O servidor MCP fica disponível imediatamente, sem reiniciar a CLI. Ou adicione o servidor diretamente ao `~/.copilot/mcp-config.json`: ```json [~/.copilot/mcp-config.json] { "mcpServers": { "nuxt-ui": { "type": "http", "url": "https://ui.nitro.news/mcp", "tools": ["*"] } } } ``` Use `/mcp show` para confirmar que o servidor está configurado e disponível. Para mais detalhes, veja [Adding MCP servers for GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers){rel=""nofollow""}. ### Google Antigravity #### Instruções de configuração: 1. Abra a loja de MCP pelo menu "..." no topo do painel do agente do editor. 2. Click on "Manage MCP Servers" 3. Click on "View raw config" 4. Modifique o `mcp_config.json` com a sua configuração personalizada do servidor MCP: ```json [mcp_config.json] { "mcpServers": { "nuxt-ui": { "serverUrl": "https://ui.nitro.news/mcp" } } } ``` 5. Volte para a aba "Manage MCP Servers" e clique em "Refresh". O servidor MCP do Nitro UI deve aparecer agora. ### Le Chat Mistral #### Instruções de configuração: 1. Navigate to "Intelligence" > "Connectors" 2. Click on "Add Connector" button, then select "Custom MCP Connector" 3. Create your Custom MCP Connector: - Connector Name: `NuxtUI` - Connector Server: `https://ui.nitro.news/mcp` ### OpenCode #### Instruções de configuração: 1. Na raiz do seu projeto, crie `opencode.json` 2. Add the following configuration: ```json [opencode.json] { "$schema": "https://opencode.ai/config.json", "mcp": { "nuxt-ui": { "type": "remote", "url": "https://ui.nitro.news/mcp", "enabled": true } } } ``` ### Visual Studio Code > \[!NOTE] > > **Install required extensions.** Ensure you have [GitHub Copilot](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot){rel=""nofollow""} and [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat){rel=""nofollow""} extensions installed. #### Instruções de configuração: 1. Abra o VS Code e acesse a Paleta de Comandos (Ctrl/Cmd + Shift + P) 2. Digite "Preferences: Open Workspace Settings (JSON)" e selecione 3. Navegue até a pasta `.vscode` do seu projeto ou crie uma se ela não existir 4. Crie ou edite o arquivo `mcp.json` com a seguinte configuração: ```json [.vscode/mcp.json] { "servers": { "nuxt-ui": { "type": "http", "url": "https://ui.nitro.news/mcp" } } } ``` ### Windsurf #### Instruções de configuração: 1. Abra o Windsurf e navegue até "Settings" > "Windsurf Settings" > "Cascade" 2. Clique no botão "Manage MCPs" e selecione a opção "View raw config" 3. Adicione a seguinte configuração às suas configurações de MCP: ```json [.codeium/windsurf/mcp_config.json] { "mcpServers": { "nuxt-ui": { "type": "http", "url": "https://ui.nitro.news/mcp" } } } ``` ### Zed #### Instruções de configuração: 1. Abra o Zed e vá em "Settings" > "Open Settings" 2. Navegue até o arquivo de configurações JSON 3. Adicione a seguinte configuração de servidor de contexto às suas configurações: ```json [.config/zed/settings.json] { "context_servers": { "nuxt-ui": { "source": "custom", "command": "npx", "args": ["mcp-remote", "https://ui.nitro.news/mcp"], "env": {} } } } ``` ## Exemplos de uso Uma vez configurado, você pode fazer ao seu assistente de IA perguntas como: - "List all available Nitro UI components" - "Get Button component documentation" - "Show me just the Button usage examples" - "What props does Input accept?" - "Find form-related components" - "Search for arrow icons in lucide" - "List dashboard templates" - "Get template setup instructions" - "Show installation guide" - "List all examples" - "Get ContactForm example code" O assistente de IA usará o servidor MCP para buscar dados JSON estruturados e fornecer assistência guiada para o Nitro UI durante o desenvolvimento. > \[!TIP] > > Para a documentação de componentes, a IA pode usar o parâmetro `sections` (`usage`, `examples`, `api`, `theme`, `changelog`) para buscar apenas as partes relevantes. Para outras páginas, use o parâmetro `headings` com títulos h2 (ex.: `["Usage", "API"]`). # LLMs.txt ## O que é o LLMs.txt? LLMs.txt é um formato de documentação estruturado projetado especificamente para grandes modelos de linguagem (LLMs). O Nitro UI fornece arquivos LLMs.txt que contêm informações abrangentes sobre nossa biblioteca de componentes, facilitando que ferramentas de IA entendam e auxiliem no desenvolvimento com o Nitro UI. Esses arquivos são otimizados para consumo por IA e contêm informações estruturadas sobre componentes, APIs, padrões de uso e boas práticas. ## Rotas disponíveis We provide LLMs.txt routes to help AI tools access our documentation: - **`/llms.txt`** - Contains a structured overview of all components and their documentation links (\~5K tokens) - **`/llms-full.txt`** - Provides comprehensive documentation including implementation details, examples, theming and composables (\~1M+ tokens) ## Escolhendo o arquivo certo > \[!NOTE] > > **Most users should start with `/llms.txt`** - it contains all essential information and works with standard LLM context windows. Use `/llms-full.txt` only if you need comprehensive implementation examples and your AI tool supports large contexts (200K+ tokens). ## Notas importantes de uso > \[!WARNING] > > **@-symbol must be typed manually** - When using tools like Cursor or Windsurf, the `@` symbol must be typed by hand in the chat interface. Copy-pasting breaks the tool's ability to recognize it as a context reference. ## Uso com ferramentas de IA ### Cursor O Nitro UI fornece arquivos LLMs.txt especializados que você pode referenciar no Cursor para uma melhor assistência de IA no desenvolvimento de componentes. #### Como usar: 1. **Referência direta**: Mencione as URLs do LLMs.txt ao fazer perguntas 2. Adicione estas URLs específicas ao contexto do seu projeto usando `@docs` [Read more about Cursor Web and Docs Search](https://docs.cursor.com/en/context/@-symbols/@-docs){rel=""nofollow""} ### Windsurf O Windsurf pode acessar diretamente os arquivos LLMs.txt do Nitro UI para entender o uso dos componentes e as boas práticas. #### Usando o LLMs.txt com o Windsurf: - Use `@docs` to reference specific LLMs.txt URLs - Create persistent rules referencing these URLs in your workspace [Read more about Windsurf Web and Docs Search](https://docs.windsurf.com/windsurf/cascade/web-search){rel=""nofollow""} ### Outras ferramentas de IA Qualquer ferramenta de IA que suporte LLMs.txt pode usar essas rotas para entender melhor o Nitro UI. #### Exemplos para ChatGPT, Claude ou outros LLMs: - "Using Nitro UI documentation from {rel=""nofollow""}" - "Follow complete Nitro UI guidelines from {rel=""nofollow""}" # Skills ## O que são Skills? Skills são arquivos de conhecimento estruturados que dão aos agentes de IA de programação contexto sobre uma biblioteca, framework ou base de código. Diferentemente dos servidores MCP, que fornecem acesso a ferramentas em tempo real, as skills são carregadas diretamente no contexto do agente para que ele possa consultá-las ao longo da conversa. O Nitro UI fornece uma **skill de uso** que ensina os agentes de IA a construir UIs com o Nitro UI: instalação, tematização, componentes, composables, formulários, overlays e layouts. ## Uso A skill de uso dá aos agentes de IA um conhecimento abrangente sobre como construir com o Nitro UI v4. Ela abrange: - Installation for Nuxt, Vue, Laravel, and AdonisJS - Theming and branding with semantic colors and CSS variables - All 125+ components with props and usage patterns - Composables (`useToast`, `useOverlay`, `defineShortcuts`) - Form validation with Standard Schema - Layout composition (Dashboard, Docs, Chat, Editor) - Official starter templates A skill inclui referências adicionais que o agente de IA carrega sob demanda conforme a tarefa, mantendo as respostas focadas e eficientes em contexto. > \[!NOTE] > > Uma vez instalada, você pode invocar a skill digitando `/nuxt-ui` no chat do seu agente. ### Skills CLI A CLI [`skills`](https://skills.sh){rel=""nofollow""} é a maneira mais fácil de instalar a skill do Nitro UI. Ela suporta mais de 35 agentes, incluindo Cursor, Claude Code, Codex, Windsurf, Cline e outros. ```bash npx skills add nuxt/ui ``` Você pode direcionar agentes específicos com a flag `--agent`: ```bash npx skills add nuxt/ui --agent cursor npx skills add nuxt/ui --agent claude-code ``` Ou instale globalmente para que a skill fique disponível em todos os seus projetos: ```bash npx skills add nuxt/ui --global ``` Se clonar do GitHub estiver lento na sua rede, você pode instalar diretamente pelo site: ```bash npx skills add https://ui.nitro.news ``` > \[!TIP] > > Acesse [skills.sh](https://skills.sh){rel=""nofollow""} para saber mais sobre o ecossistema de skills e explorar as skills disponíveis. ### Cursor #### Instalação rápida Clique no botão abaixo para instalar a skill do Nitro UI diretamente no Cursor: [Install Skill](cursor://anysphere.cursor-deeplink/install-skill?url=https://github.com/nuxt/ui/tree/v4/skills/nuxt-ui) #### Configuração manual 1. Abra o Cursor e vá em "Settings" > "Skills" 2. Clique em "Add skill" e informe a seguinte URL: ```text https://github.com/nuxt/ui/tree/v4/skills/nuxt-ui ``` ### Claude Code > \[!NOTE] > > **Ensure Claude Code is installed.** Visit [Anthropic's documentation](https://docs.anthropic.com/en/docs/claude-code/quickstart){rel=""nofollow""} for installation instructions. Adicione a skill usando o comando da CLI: ```bash claude skill add https://github.com/nuxt/ui/tree/v4/skills/nuxt-ui ``` ### Outras ferramentas de IA Os arquivos da skill estão disponíveis publicamente no GitHub. Você pode referenciá-los diretamente em qualquer ferramenta de IA que suporte contexto ou instruções personalizadas: - **Skill entry point**: [`skills/nuxt-ui/SKILL.md`](https://github.com/nuxt/ui/tree/v4/skills/nuxt-ui/SKILL.md){rel=""nofollow""} - **Full skill directory**: [`skills/nuxt-ui/`](https://github.com/nuxt/ui/tree/v4/skills/nuxt-ui){rel=""nofollow""} # Accordion ## Uso Use o componente Accordion para exibir uma lista de itens recolhíveis. ```vue ``` ### Itens Use a prop `items` como um array de objetos com as seguintes propriedades: - `label?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `icon?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `trailingIcon?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `content?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `value?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `disabled?: boolean`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - [`slot?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"}](https://ui.nitro.news/#with-custom-slot) - `class?: any`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `ui?: { item?: ClassNameValue, header?: ClassNameValue, trigger?: ClassNameValue, leadingIcon?: ClassNameValue, label?: ClassNameValue, trailingIcon?: ClassNameValue, content?: ClassNameValue, body?: ClassNameValue }`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ```vue ``` ### Múltiplo Defina a prop `type` como `multiple` para permitir que vários itens fiquem ativos ao mesmo tempo. O padrão é `single`. ```vue ``` ### Recolhível Quando `type` é `single`, você pode definir a prop `collapsible` como `false` para evitar que o item ativo seja recolhido. ```vue ``` ### Desmontar Use a prop `unmount-on-hide` para evitar que o conteúdo seja desmontado quando o accordion é recolhido. O padrão é `true`. ```vue ``` > \[!NOTE] > > Você pode inspecionar o DOM para ver o conteúdo de cada item sendo renderizado. ### Desabilitado Use a propriedade `disabled` para desabilitar o Accordion. Você também pode desabilitar um item específico usando a propriedade `disabled` no objeto do item. ```vue ``` ### Ícone à direita Use a prop `trailing-icon` para personalizar o [Icon](https://ui.nitro.news/docs/components/icon) à direita de cada item. O padrão é `i-lucide-chevron-down`. > \[!TIP] > > Você também pode definir um ícone para um item específico usando a propriedade `trailingIcon` no objeto do item. ```vue ``` **Nuxt:** > \[!TIP] > See: /docs/getting-started/integrations/icons/nuxt#theme > > Você pode personalizar esse ícone globalmente no seu `app.config.ts` na chave `ui.icons.chevronDown`. **Vue:** > \[!TIP] > See: /docs/getting-started/integrations/icons/vue#theme > > Você pode personalizar esse ícone globalmente no seu `vite.config.ts` na chave `ui.icons.chevronDown`. ## Exemplos ### Controlar o(s) item(ns) ativo(s) Você pode controlar o item ativo usando a prop `default-value` ou a diretiva `v-model` com o `value` do item. Se nenhum `value` for fornecido, o padrão é o índice **como string**. ::component-example --- props: class: px-4 name: accordion-model-value-example --- :: > \[!TIP] > > Use a prop `value-key` para alterar a chave usada para corresponder os itens quando um `v-model` ou `default-value` é fornecido. > \[!CAUTION] > > Quando `type="multiple"`, certifique-se de passar um array para a prop `default-value` ou para a diretiva `v-model`. ### Com arrastar e soltar Use o composable [`useSortable`](https://vueuse.org/integrations/useSortable/){rel=""nofollow""} de [`@vueuse/integrations`](https://vueuse.org/integrations/README.html){rel=""nofollow""} para habilitar a funcionalidade de arrastar e soltar no Accordion. Essa integração envolve o [Sortable.js](https://sortablejs.github.io/Sortable/){rel=""nofollow""} para oferecer uma experiência de arrastar e soltar fluida. :component-example{name="accordion-drag-and-drop-example"} ### Com slot de corpo Use o slot `#body` para personalizar o corpo de cada item. ::component-example --- props: class: px-4 name: accordion-body-slot-example --- :: > \[!TIP] > > O slot `#body` inclui alguns estilos predefinidos; use o [slot `#content`](https://ui.nitro.news/#with-content-slot) se você quiser começar do zero. ### Com slot de conteúdo Use o slot `#content` para personalizar o conteúdo de cada item. ::component-example --- props: class: px-4 name: accordion-content-slot-example --- :: ### Com slot personalizado Use a propriedade `slot` para personalizar um item específico. Você terá acesso aos seguintes slots: - `#{{ item.slot }}`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `#{{ item.slot }}-body`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} ::component-example --- props: class: px-4 name: accordion-custom-slot-example --- :: ### Com conteúdo markdown Você pode usar o componente [MDC](https://github.com/nuxt-content/mdc?tab=readme-ov-file#mdc){rel=""nofollow""} do `@nuxtjs/mdc` para renderizar markdown nos itens do accordion. ::component-example{.px-8 collapse name="accordion-markdown-example"} :: ## API ### Props ```ts /** * Props for the Accordion component */ interface AccordionProps { /** * The element or component this component should render as. */ as?: any; items?: T[] | undefined; /** * The icon displayed on the right side of the trigger. */ trailingIcon?: any; /** * The key used to get the label from the item. * @default "\"label\"" */ labelKey?: GetItemKeys | undefined; ui?: { root?: SlotClass; item?: SlotClass; header?: SlotClass; trigger?: SlotClass; content?: SlotClass; body?: SlotClass; leadingIcon?: SlotClass; trailingIcon?: SlotClass; label?: SlotClass; } | undefined; /** * When type is "single", allows closing content when clicking trigger for an open item. * When type is "multiple", this prop has no effect. * @default "true" */ collapsible?: boolean | undefined; /** * The default active value of the item(s). * * Use when you do not need to control the state of the item(s). */ defaultValue?: string | string[] | undefined; /** * The controlled value of the active item(s). * * Use this when you need to control the state of the items. Can be binded with `v-model` */ modelValue?: string | string[] | undefined; /** * Determines whether a "single" or "multiple" items can be selected at a time. * * This prop will overwrite the inferred type from `modelValue` and `defaultValue`. * @default "\"single\"" */ type?: SingleOrMultipleType | undefined; /** * When `true`, prevents the user from interacting with the accordion and all its items */ disabled?: boolean | undefined; /** * When `true`, the element will be unmounted on closed state. * @default "true" */ unmountOnHide?: boolean | undefined; } ``` ### Slots ```ts /** * Slots for the Accordion component */ interface AccordionSlots { leading(): any; default(): any; trailing(): any; content(): any; body(): any; } ``` ### Emits ```ts /** * Emitted events for the Accordion component */ interface AccordionEmits { update:modelValue: (payload: [value: string | string[] | undefined]) => void; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { accordion: { slots: { root: 'w-full', item: 'border-b border-default last:border-b-0', header: 'flex', trigger: 'group flex-1 flex items-center gap-1.5 font-medium text-sm py-3.5 focus-visible:outline-primary min-w-0', content: 'data-[state=open]:animate-[accordion-down_200ms_ease-out] data-[state=closed]:animate-[accordion-up_200ms_ease-out] overflow-hidden focus:outline-none', body: 'text-sm pb-3.5', leadingIcon: 'shrink-0 size-5', trailingIcon: 'shrink-0 size-5 ms-auto group-data-[state=open]:rotate-180 transition-transform duration-200', label: 'text-start break-words' }, variants: { disabled: { true: { trigger: 'cursor-not-allowed opacity-75' } } } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/Accordion.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/accordion.ts). # Alert ## Uso ### Título Use a prop `title` para definir o título do Alert. ```vue ``` ### Descrição Use a prop `description` para definir a descrição do Alert. ```vue ``` ### Ícone Use a prop `icon` para exibir um [Icon](https://ui.nitro.news/docs/components/icon). ```vue ``` ### Avatar Use a prop `avatar` para exibir um [Avatar](https://ui.nitro.news/docs/components/avatar). ```vue ``` ### Cor Use a prop `color` para alterar a cor do Alert. ```vue ``` ### Variante Use a prop `variant` para alterar a variante do Alert. ```vue ``` ### Fechar Use a prop `close` para exibir um [Button](https://ui.nitro.news/docs/components/button) para dispensar o Alert. > \[!TIP] > > Um evento `update:open` será emitido quando o botão de fechar for clicado. ```vue ``` Você pode passar qualquer propriedade do componente [Button](https://ui.nitro.news/docs/components/button) para personalizá-lo. ```vue ``` ### Ícone de fechar Use a prop `close-icon` para personalizar o [Icon](https://ui.nitro.news/docs/components/icon) do botão de fechar. O padrão é `i-lucide-x`. ```vue ``` **Nuxt:** > \[!TIP] > See: /docs/getting-started/integrations/icons/nuxt#theme > > Você pode personalizar esse ícone globalmente no seu `app.config.ts` na chave `ui.icons.close`. **Vue:** > \[!TIP] > See: /docs/getting-started/integrations/icons/vue#theme > > Você pode personalizar esse ícone globalmente no seu `vite.config.ts` na chave `ui.icons.close`. ### Ações Use a prop `actions` para adicionar algumas ações de [Button](https://ui.nitro.news/docs/components/button) ao Alert. ```vue ``` ### Orientação Use a prop `orientation` para alterar a orientação do Alert. ```vue ``` ## Exemplos ### `class` prop Use a prop `class` para sobrescrever os estilos base do Alert. ```vue ``` ### `ui` prop Use a prop `ui` para sobrescrever os estilos dos slots do Alert. ```vue ``` ## API ### Props ```ts /** * Props for the Alert component */ interface AlertProps { /** * The element or component this component should render as. */ as?: any; title?: string | undefined; description?: string | undefined; icon?: any; avatar?: AvatarProps | undefined; color?: "error" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "neutral" | undefined; variant?: "solid" | "outline" | "soft" | "subtle" | undefined; /** * The orientation between the content and the actions. * @default "\"vertical\"" */ orientation?: "vertical" | "horizontal" | undefined; /** * Display a list of actions: * - under the title and description when orientation is `vertical` * - next to the close button when orientation is `horizontal` * `{ size: 'xs' }`{lang="ts-type"} */ actions?: ButtonProps[] | undefined; /** * Display a close button to dismiss the alert. * `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"} */ close?: boolean | Omit | undefined; /** * The icon displayed in the close button. */ closeIcon?: any; ui?: { root?: SlotClass; wrapper?: SlotClass; title?: SlotClass; description?: SlotClass; icon?: SlotClass; avatar?: SlotClass; avatarSize?: SlotClass; actions?: SlotClass; close?: SlotClass; } | undefined; } ``` ### Slots ```ts /** * Slots for the Alert component */ interface AlertSlots { leading(): any; title(): any; description(): any; actions(): any; close(): any; } ``` ### Emits ```ts /** * Emitted events for the Alert component */ interface AlertEmits { update:open: (payload: [value: boolean]) => void; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { alert: { slots: { root: 'relative overflow-hidden w-full rounded-lg p-4 flex gap-2.5', wrapper: 'min-w-0 flex-1 flex flex-col', title: 'text-sm font-medium', description: 'text-sm opacity-90', icon: 'shrink-0 size-5', avatar: 'shrink-0', avatarSize: '2xl', actions: 'flex flex-wrap gap-1.5 shrink-0', close: 'p-0' }, variants: { color: { primary: '', secondary: '', accent: '', success: '', info: '', warning: '', error: '', neutral: '' }, variant: { solid: '', outline: '', soft: '', subtle: '' }, orientation: { horizontal: { root: 'items-center', actions: 'items-center' }, vertical: { root: 'items-start', actions: 'items-start mt-2.5' } }, title: { true: { description: 'mt-1' } } }, compoundVariants: [ { color: 'primary', variant: 'solid', class: { root: 'bg-primary text-inverted' } }, { color: 'secondary', variant: 'solid', class: { root: 'bg-secondary text-inverted' } }, { color: 'accent', variant: 'solid', class: { root: 'bg-accent text-inverted' } }, { color: 'success', variant: 'solid', class: { root: 'bg-success text-inverted' } }, { color: 'info', variant: 'solid', class: { root: 'bg-info text-inverted' } }, { color: 'warning', variant: 'solid', class: { root: 'bg-warning text-inverted' } }, { color: 'error', variant: 'solid', class: { root: 'bg-error text-inverted' } }, { color: 'primary', variant: 'outline', class: { root: 'text-primary ring ring-inset ring-primary/25' } }, { color: 'secondary', variant: 'outline', class: { root: 'text-secondary ring ring-inset ring-secondary/25' } }, { color: 'accent', variant: 'outline', class: { root: 'text-accent ring ring-inset ring-accent/25' } }, { color: 'success', variant: 'outline', class: { root: 'text-success ring ring-inset ring-success/25' } }, { color: 'info', variant: 'outline', class: { root: 'text-info ring ring-inset ring-info/25' } }, { color: 'warning', variant: 'outline', class: { root: 'text-warning ring ring-inset ring-warning/25' } }, { color: 'error', variant: 'outline', class: { root: 'text-error ring ring-inset ring-error/25' } }, { color: 'primary', variant: 'soft', class: { root: 'bg-primary/10 text-primary' } }, { color: 'secondary', variant: 'soft', class: { root: 'bg-secondary/10 text-secondary' } }, { color: 'accent', variant: 'soft', class: { root: 'bg-accent/10 text-accent' } }, { color: 'success', variant: 'soft', class: { root: 'bg-success/10 text-success' } }, { color: 'info', variant: 'soft', class: { root: 'bg-info/10 text-info' } }, { color: 'warning', variant: 'soft', class: { root: 'bg-warning/10 text-warning' } }, { color: 'error', variant: 'soft', class: { root: 'bg-error/10 text-error' } }, { color: 'primary', variant: 'subtle', class: { root: 'bg-primary/10 text-primary ring ring-inset ring-primary/25' } }, { color: 'secondary', variant: 'subtle', class: { root: 'bg-secondary/10 text-secondary ring ring-inset ring-secondary/25' } }, { color: 'accent', variant: 'subtle', class: { root: 'bg-accent/10 text-accent ring ring-inset ring-accent/25' } }, { color: 'success', variant: 'subtle', class: { root: 'bg-success/10 text-success ring ring-inset ring-success/25' } }, { color: 'info', variant: 'subtle', class: { root: 'bg-info/10 text-info ring ring-inset ring-info/25' } }, { color: 'warning', variant: 'subtle', class: { root: 'bg-warning/10 text-warning ring ring-inset ring-warning/25' } }, { color: 'error', variant: 'subtle', class: { root: 'bg-error/10 text-error ring ring-inset ring-error/25' } }, { color: 'neutral', variant: 'solid', class: { root: 'text-inverted bg-inverted' } }, { color: 'neutral', variant: 'outline', class: { root: 'text-highlighted bg-default ring ring-inset ring-default' } }, { color: 'neutral', variant: 'soft', class: { root: 'text-highlighted bg-elevated/50' } }, { color: 'neutral', variant: 'subtle', class: { root: 'text-highlighted bg-elevated/50 ring ring-inset ring-accented' } } ], defaultVariants: { color: 'primary', variant: 'solid' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/Alert.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/alert.ts). # App ## Uso Este componente implementa o [ConfigProvider](https://reka-ui.com/docs/utilities/config-provider){rel=""nofollow""} do Reka UI para fornecer configuração global a todos os componentes: - Enables all primitives to inherit global reading direction. - Enables changing the behavior of scroll body when setting body lock. - Much more controls to prevent layout shifts. Ele também usa o [ToastProvider](https://reka-ui.com/docs/components/toast#provider){rel=""nofollow""} e o [TooltipProvider](https://reka-ui.com/docs/components/tooltip#provider){rel=""nofollow""} para fornecer toasts e tooltips globais, além de modais e slideovers programáticos. Envolva toda a sua aplicação com o componente App no seu arquivo `app.vue`: ```vue [app.vue] ``` **Nuxt:** > \[!TIP] > See: /docs/getting-started/integrations/i18n/nuxt#locale > > Aprenda a usar a prop `locale` para alterar o locale do seu app. Isso também controla o formato de data/hora em componentes como Calendar, InputDate e InputTime. **Vue:** > \[!TIP] > See: /docs/getting-started/integrations/i18n/vue#locale > > Aprenda a usar a prop `locale` para alterar o locale do seu app. Isso também controla o formato de data/hora em componentes como Calendar, InputDate e InputTime. ## API ### Props ```ts /** * Props for the App component */ interface AppProps { tooltip?: TooltipProviderProps | undefined; toaster?: ToasterProps | null | undefined; locale?: Locale | undefined; /** * @default "\"body\"" */ portal?: string | boolean | HTMLElement | undefined; /** * The global reading direction of your application. This will be inherited by all primitives. */ dir?: Direction | undefined; /** * The global scroll body behavior of your application. This will be inherited by the related primitives. */ scrollBody?: boolean | ScrollBodyOption | undefined; /** * The global `nonce` value of your application. This will be inherited by the related primitives. */ nonce?: string | undefined; /** * The global default teleport target for all portalled primitives (e.g. `Dialog`, `Popover`, `Tooltip`). * Individual `*Portal` components can still override this via their own `to` prop. * Useful when rendering inside a custom element / shadow DOM. */ teleportTo?: string | HTMLElement | undefined; } ``` ### Slots ```ts /** * Slots for the App component */ interface AppSlots { default(): any; } ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/App.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/app.ts). # AuthForm ## Uso Construído sobre o componente [Form](https://ui.nitro.news/docs/components/form), o componente `AuthForm` pode ser usado nas suas páginas ou envolvido em um [PageCard](https://ui.nitro.news/docs/components/page-card). ::component-example{collapse name="auth-form-example"} :: ### Campos O Form se constrói com base na prop `fields`, e o estado é tratado internamente. Use a prop `fields` como um array de objetos com as seguintes propriedades: - `name: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `type: 'checkbox' | 'select' | 'otp' | 'InputHTMLAttributes['type']'`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} Cada campo precisa incluir uma propriedade `type`, que determina o componente de input e quaisquer props adicionais aplicadas: campos `checkbox` usam props do [Checkbox](https://ui.nitro.news/docs/components/checkbox#props), campos `select` usam props do [SelectMenu](https://ui.nitro.news/docs/components/select-menu#props), campos `otp` usam props do [PinInput](https://ui.nitro.news/docs/components/pin-input#props), e todos os outros tipos usam props do [Input](https://ui.nitro.news/docs/components/input#props). Você também pode passar qualquer propriedade do componente [FormField](https://ui.nitro.news/docs/components/form-field#props) para cada campo. ```vue ``` ### Título Use a prop `title` para definir o título do Form. ```vue ``` ### Descrição Use a prop `description` para definir a descrição do Form. ```vue ``` ### Ícone Use a prop `icon` para definir o ícone do Form. ```vue ``` ### Provedores Use a prop `providers` para adicionar provedores ao formulário. Você pode passar qualquer propriedade do componente [Button](https://ui.nitro.news/docs/components/button), como `variant`, `color`, `to`, etc. ```vue ``` ### Separador Use a prop `separator` para personalizar o [Separator](https://ui.nitro.news/docs/components/separator) entre os provedores e os campos. O padrão é `or`. ```vue ``` Você pode passar qualquer propriedade do componente [Separator](https://ui.nitro.news/docs/components/separator#props) para personalizá-lo. ```vue ``` ### Enviar Use a prop `submit` para alterar o botão de envio do Form. Você pode passar qualquer propriedade do componente [Button](https://ui.nitro.news/docs/components/button), como `variant`, `color`, `to`, etc. ```vue ``` ## Exemplos ### Dentro de uma página Você pode envolver o componente `AuthForm` com o componente [PageCard](https://ui.nitro.news/docs/components/page-card) para exibi-lo dentro de uma página `login.vue`, por exemplo. ::component-example{collapse name="auth-form-page-example"} :: ## API ### Props ```ts /** * Props for the AuthForm component */ interface AuthFormProps { /** * The element or component this component should render as. */ as?: any; /** * The icon displayed above the title. */ icon?: any; title?: string | undefined; description?: string | undefined; fields?: F[] | undefined; /** * Display a list of Button under the description. * `{ color: 'neutral', variant: 'subtle', block: true }`{lang="ts-type"} */ providers?: ButtonProps[] | undefined; /** * The text displayed in the separator. * @default "\"or\"" */ separator?: string | SeparatorProps | undefined; /** * Display a submit button at the bottom of the form. * `{ label: 'Continue', block: true }`{lang="ts-type"} */ submit?: Omit | undefined; schema?: T | undefined; validate?: ((state: Partial>) => FormError[] | Promise[]>) | undefined; validateOn?: FormInputEvents[] | undefined; validateOnInputDelay?: number | undefined; disabled?: boolean | undefined; loading?: boolean | undefined; loadingAuto?: boolean | undefined; ui?: { root?: SlotClass; header?: SlotClass; leading?: SlotClass; leadingIcon?: SlotClass; title?: SlotClass; description?: SlotClass; body?: SlotClass; providers?: SlotClass; checkbox?: SlotClass; select?: SlotClass; password?: SlotClass; otp?: SlotClass; input?: SlotClass; separator?: SlotClass; form?: SlotClass; footer?: SlotClass; } | undefined; name?: string | undefined; autocomplete?: string | undefined; acceptcharset?: string | undefined; action?: string | undefined; enctype?: string | undefined; method?: string | undefined; novalidate?: Booleanish | undefined; target?: string | undefined; } ``` > \[!NOTE] > See: https\://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attributes > > Este componente também suporta todos os atributos HTML nativos de `
`. ### Slots ```ts /** * Slots for the AuthForm component */ interface AuthFormSlots { header(): any; leading(): any; title(): any; description(): any; providers(): any; separator(): any; validation(): any; submit(): any; footer(): any; } ``` ### Emits ```ts /** * Emitted events for the AuthForm component */ interface AuthFormEmits { submit: (payload: [payload: FormSubmitEvent>>]) => void; } ``` ### Expose Você pode acessar a instância tipada do componente (que expõe formRef e state) usando [`useTemplateRef`](https://vuejs.org/api/composition-api-helpers.html#usetemplateref){rel=""nofollow""}. Por exemplo, em um formulário separado (ex.: um formulário de "redefinição") você pode fazer: ```vue ``` Isso dá a você acesso às seguintes propriedades (expostas): | Name | Type | | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `formRef`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | `Ref`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | | `state`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | `Reactive`{.language-ts-type.shiki.shiki-themes.material-theme-lighter.material-theme.material-theme-palenight lang="ts-type"} | ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { authForm: { slots: { root: 'w-full space-y-6', header: 'flex flex-col text-center', leading: 'mb-2', leadingIcon: 'size-8 shrink-0 inline-block', title: 'text-xl text-pretty font-semibold text-highlighted', description: 'mt-1 text-base text-pretty text-muted', body: 'gap-y-6 flex flex-col', providers: 'space-y-3', checkbox: '', select: 'w-full', password: 'w-full', otp: 'w-full', input: 'w-full', separator: '', form: 'space-y-5', footer: 'text-sm text-center text-muted mt-2' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/AuthForm.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/auth-form.ts). # Avatar ## Uso O Avatar usa o componente `` quando o [`@nuxt/image`](https://github.com/nuxt/image){rel=""nofollow""} está instalado, recorrendo a `img` caso contrário. ```vue ``` > \[!NOTE] > > Você pode passar qualquer propriedade do elemento HTML ``, como `alt`, `loading`, etc. > \[!TIP] > > Para não usar o `@nuxt/image`, use a prop `as`: `:as="{ img: 'img' }"`. ### Src Use a prop `src` para definir a URL da imagem. ```vue ``` ### Tamanho Use a prop `size` para definir o tamanho do Avatar. ```vue ``` > \[!NOTE] > > O `width` e o `height` do elemento `` são definidos automaticamente com base na prop `size`. ### Ícone Use a prop `icon` para exibir um [Icon](https://ui.nitro.news/docs/components/icon) de fallback. ```vue ``` ### Texto Use a prop `text` para exibir um texto de fallback. ```vue ``` ### Alt Quando nenhum ícone ou texto é fornecido, as **iniciais** da prop `alt` são usadas como fallback. ```vue ``` > \[!NOTE] > > A prop `alt` é passada ao elemento `img` como o atributo `alt`. ### Cor `4.8+` Use a prop `color` para alterar a cor do Avatar. ```vue ``` ### Chip Use a prop `chip` para exibir um chip ao redor do Avatar. ```vue ``` ## Exemplos ### Com tooltip Você pode usar um componente [Tooltip](https://ui.nitro.news/docs/components/tooltip) para exibir um tooltip ao passar o mouse sobre o Avatar. :component-example{name="avatar-tooltip-example"} ### Com máscara Você pode usar uma máscara CSS para exibir um Avatar com um formato personalizado em vez de um simples círculo. :component-example{name="avatar-mask-example"} ## API ### Props ```ts /** * Props for the Avatar component */ interface AvatarProps { /** * The element or component this component should render as. */ as?: any; src?: string | undefined; alt?: string | undefined; icon?: any; text?: string | undefined; size?: "md" | "xs" | "sm" | "lg" | "xl" | "3xs" | "2xs" | "2xl" | "3xl" | undefined; color?: "error" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "neutral" | undefined; chip?: boolean | ChipProps | undefined; ui?: { root?: SlotClass; image?: SlotClass; fallback?: SlotClass; icon?: SlotClass; } | undefined; loading?: "lazy" | "eager" | undefined; referrerpolicy?: HTMLAttributeReferrerPolicy | undefined; crossorigin?: "" | "anonymous" | "use-credentials" | undefined; decoding?: "async" | "auto" | "sync" | undefined; height?: Numberish | undefined; sizes?: string | undefined; srcset?: string | undefined; usemap?: string | undefined; width?: Numberish | undefined; } ``` > \[!NOTE] > See: https\://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes > > Este componente também suporta todos os atributos HTML nativos de ``. ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { avatar: { slots: { root: 'inline-flex items-center justify-center shrink-0 select-none rounded-full align-middle', image: 'h-full w-full rounded-[inherit] object-cover', fallback: 'font-medium leading-none truncate uppercase', icon: 'shrink-0' }, variants: { color: { primary: { root: 'bg-primary-50', fallback: 'text-primary', icon: 'text-primary' }, secondary: { root: 'bg-secondary-50', fallback: 'text-secondary', icon: 'text-secondary' }, accent: { root: 'bg-accent-50', fallback: 'text-accent', icon: 'text-accent' }, success: { root: 'bg-success-50', fallback: 'text-success', icon: 'text-success' }, info: { root: 'bg-info-50', fallback: 'text-info', icon: 'text-info' }, warning: { root: 'bg-warning-50', fallback: 'text-warning', icon: 'text-warning' }, error: { root: 'bg-error-50', fallback: 'text-error', icon: 'text-error' }, neutral: { root: 'bg-elevated', fallback: 'text-muted', icon: 'text-default' } }, size: { '3xs': { root: 'size-4 text-[8px]' }, '2xs': { root: 'size-5 text-[10px]' }, xs: { root: 'size-6 text-xs' }, sm: { root: 'size-7 text-sm' }, md: { root: 'size-8 text-base' }, lg: { root: 'size-9 text-lg' }, xl: { root: 'size-10 text-xl' }, '2xl': { root: 'size-11 text-[22px]' }, '3xl': { root: 'size-12 text-2xl' } } }, defaultVariants: { color: 'neutral', size: 'md' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/Avatar.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/avatar.ts). # AvatarGroup ## Uso Envolva vários [Avatar](https://ui.nitro.news/docs/components/avatar) dentro de um AvatarGroup para empilhá-los. ```vue ``` ### Tamanho Use a prop `size` para alterar o tamanho de todos os avatares. ```vue ``` ### Máximo Use a prop `max` para limitar o número de avatares exibidos. O restante é exibido como um avatar `+X`. ```vue ``` ### Cor `4.8+` Use a prop `color` para alterar a cor de todos os avatares. ```vue ``` ## Exemplos ### Com tooltip Envolva cada avatar com um [Tooltip](https://ui.nitro.news/docs/components/tooltip) para exibir um tooltip no hover. :component-example{name="avatar-group-tooltip-example"} ### Com chip Envolva cada avatar com um [Chip](https://ui.nitro.news/docs/components/chip) para exibir um chip ao redor do avatar. :component-example{name="avatar-group-chip-example"} ### Com link Envolva cada avatar com um [Link](https://ui.nitro.news/docs/components/link) para torná-los clicáveis. :component-example{name="avatar-group-link-example"} ### Com máscara Envolva um avatar com uma máscara CSS para exibi-lo com um formato personalizado. :component-example{name="avatar-group-mask-example"} > \[!WARNING] > > A prop `chip` não funciona corretamente ao usar uma máscara. Os chips podem ser cortados dependendo do formato da máscara. ## API ### Props ```ts /** * Props for the AvatarGroup component */ interface AvatarGroupProps { /** * The element or component this component should render as. */ as?: any; size?: "md" | "xs" | "sm" | "lg" | "xl" | "3xs" | "2xs" | "2xl" | "3xl" | undefined; color?: "error" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "neutral" | undefined; /** * The maximum number of avatars to display. */ max?: string | number | undefined; ui?: { root?: SlotClass; base?: SlotClass; } | undefined; } ``` ### Slots ```ts /** * Slots for the AvatarGroup component */ interface AvatarGroupSlots { default(): any; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { avatarGroup: { slots: { root: 'inline-flex flex-row-reverse justify-end', base: 'relative rounded-full ring-bg first:me-0' }, variants: { size: { '3xs': { base: 'ring -me-0.5' }, '2xs': { base: 'ring -me-0.5' }, xs: { base: 'ring -me-0.5' }, sm: { base: 'ring-2 -me-1.5' }, md: { base: 'ring-2 -me-1.5' }, lg: { base: 'ring-2 -me-1.5' }, xl: { base: 'ring-3 -me-2' }, '2xl': { base: 'ring-3 -me-2' }, '3xl': { base: 'ring-3 -me-2' } }, color: { primary: '', secondary: '', accent: '', success: '', info: '', warning: '', error: '', neutral: '' } }, defaultVariants: { size: 'md', color: 'neutral' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/AvatarGroup.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/avatar-group.ts). # Badge ## Uso Use o slot padrão para definir o rótulo do Badge. ```vue ``` ### Label Use a prop `label` para definir o rótulo do Badge. ```vue ``` ### Cor Use a prop `color` para alterar a cor do Badge. ```vue ``` ### Variante Use a prop `variant` para alterar a variante do Badge. ```vue ``` ### Tamanho Use a prop `size` para alterar o tamanho do Badge. ```vue ``` ### Ícone Use a prop `icon` para exibir um [Icon](https://ui.nitro.news/docs/components/icon) dentro do Badge. ```vue ``` Use as props `leading` e `trailing` para definir a posição do ícone ou as props `leading-icon` e `trailing-icon` para definir um ícone diferente para cada posição. ```vue ``` ### Avatar Use a prop `avatar` para exibir um [Avatar](https://ui.nitro.news/docs/components/avatar) dentro do Badge. ```vue ``` ## Exemplos ### `class` prop Use a prop `class` para sobrescrever os estilos base do Badge. ```vue ``` ## API ### Props ```ts /** * Props for the Badge component */ interface BadgeProps { /** * The element or component this component should render as. * @default "\"span\"" */ as?: any; label?: string | number | undefined; color?: "error" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "neutral" | undefined; variant?: "solid" | "outline" | "soft" | "subtle" | undefined; size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined; /** * Render the badge with equal padding on all sides. */ square?: boolean | undefined; ui?: { base?: SlotClass; label?: SlotClass; leadingIcon?: SlotClass; leadingAvatar?: SlotClass; leadingAvatarSize?: SlotClass; trailingIcon?: SlotClass; } | undefined; /** * Display an icon based on the `leading` and `trailing` props. */ icon?: any; /** * Display an avatar on the left side. */ avatar?: AvatarProps | undefined; /** * When `true`, the icon will be displayed on the left side. */ leading?: boolean | undefined; /** * Display an icon on the left side. */ leadingIcon?: any; /** * When `true`, the icon will be displayed on the right side. */ trailing?: boolean | undefined; /** * Display an icon on the right side. */ trailingIcon?: any; } ``` ### Slots ```ts /** * Slots for the Badge component */ interface BadgeSlots { leading(): any; default(): any; trailing(): any; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { badge: { slots: { base: 'font-medium inline-flex items-center', label: 'truncate', leadingIcon: 'shrink-0', leadingAvatar: 'shrink-0', leadingAvatarSize: '', trailingIcon: 'shrink-0' }, variants: { fieldGroup: { horizontal: 'not-only:first:rounded-e-none not-only:last:rounded-s-none not-last:not-first:rounded-none focus-visible:z-[1]', vertical: 'not-only:first:rounded-b-none not-only:last:rounded-t-none not-last:not-first:rounded-none focus-visible:z-[1]' }, color: { primary: '', secondary: '', accent: '', success: '', info: '', warning: '', error: '', neutral: '' }, variant: { solid: '', outline: '', soft: '', subtle: '' }, size: { xs: { base: 'text-[8px]/3 px-1 py-0.5 gap-1 rounded-sm', leadingIcon: 'size-3', leadingAvatarSize: '3xs', trailingIcon: 'size-3' }, sm: { base: 'text-[10px]/3 px-1.5 py-1 gap-1 rounded-sm', leadingIcon: 'size-3', leadingAvatarSize: '3xs', trailingIcon: 'size-3' }, md: { base: 'text-xs px-2 py-1 gap-1 rounded-md', leadingIcon: 'size-4', leadingAvatarSize: '3xs', trailingIcon: 'size-4' }, lg: { base: 'text-sm px-2 py-1 gap-1.5 rounded-md', leadingIcon: 'size-5', leadingAvatarSize: '2xs', trailingIcon: 'size-5' }, xl: { base: 'text-base px-2.5 py-1 gap-1.5 rounded-md', leadingIcon: 'size-6', leadingAvatarSize: '2xs', trailingIcon: 'size-6' } }, square: { true: '' } }, compoundVariants: [ { color: 'primary', variant: 'solid', class: 'bg-primary text-inverted' }, { color: 'secondary', variant: 'solid', class: 'bg-secondary text-inverted' }, { color: 'accent', variant: 'solid', class: 'bg-accent text-inverted' }, { color: 'success', variant: 'solid', class: 'bg-success text-inverted' }, { color: 'info', variant: 'solid', class: 'bg-info text-inverted' }, { color: 'warning', variant: 'solid', class: 'bg-warning text-inverted' }, { color: 'error', variant: 'solid', class: 'bg-error text-inverted' }, { color: 'primary', variant: 'outline', class: 'text-primary ring ring-inset ring-primary/50' }, { color: 'secondary', variant: 'outline', class: 'text-secondary ring ring-inset ring-secondary/50' }, { color: 'accent', variant: 'outline', class: 'text-accent ring ring-inset ring-accent/50' }, { color: 'success', variant: 'outline', class: 'text-success ring ring-inset ring-success/50' }, { color: 'info', variant: 'outline', class: 'text-info ring ring-inset ring-info/50' }, { color: 'warning', variant: 'outline', class: 'text-warning ring ring-inset ring-warning/50' }, { color: 'error', variant: 'outline', class: 'text-error ring ring-inset ring-error/50' }, { color: 'primary', variant: 'soft', class: 'bg-primary/10 text-primary' }, { color: 'secondary', variant: 'soft', class: 'bg-secondary/10 text-secondary' }, { color: 'accent', variant: 'soft', class: 'bg-accent/10 text-accent' }, { color: 'success', variant: 'soft', class: 'bg-success/10 text-success' }, { color: 'info', variant: 'soft', class: 'bg-info/10 text-info' }, { color: 'warning', variant: 'soft', class: 'bg-warning/10 text-warning' }, { color: 'error', variant: 'soft', class: 'bg-error/10 text-error' }, { color: 'primary', variant: 'subtle', class: 'bg-primary/10 text-primary ring ring-inset ring-primary/25' }, { color: 'secondary', variant: 'subtle', class: 'bg-secondary/10 text-secondary ring ring-inset ring-secondary/25' }, { color: 'accent', variant: 'subtle', class: 'bg-accent/10 text-accent ring ring-inset ring-accent/25' }, { color: 'success', variant: 'subtle', class: 'bg-success/10 text-success ring ring-inset ring-success/25' }, { color: 'info', variant: 'subtle', class: 'bg-info/10 text-info ring ring-inset ring-info/25' }, { color: 'warning', variant: 'subtle', class: 'bg-warning/10 text-warning ring ring-inset ring-warning/25' }, { color: 'error', variant: 'subtle', class: 'bg-error/10 text-error ring ring-inset ring-error/25' }, { color: 'neutral', variant: 'solid', class: 'text-inverted bg-inverted' }, { color: 'neutral', variant: 'outline', class: 'ring ring-inset ring-accented text-default bg-default' }, { color: 'neutral', variant: 'soft', class: 'text-default bg-elevated' }, { color: 'neutral', variant: 'subtle', class: 'ring ring-inset ring-accented text-default bg-elevated' }, { size: 'xs', square: true, class: 'p-0.5' }, { size: 'sm', square: true, class: 'p-1' }, { size: 'md', square: true, class: 'p-1' }, { size: 'lg', square: true, class: 'p-1' }, { size: 'xl', square: true, class: 'p-1' } ], defaultVariants: { color: 'primary', variant: 'solid', size: 'md' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/Badge.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/badge.ts). # Banner ## Uso ### Título Use a prop `title` para exibir um título no Banner. ```vue ``` ### Ícone Use a prop `icon` para exibir um ícone no Banner. ```vue ``` ### Cor Use a prop `color` para alterar a cor do Banner. ```vue ``` ### Fechar Use a prop `close` para exibir um [Button](https://ui.nitro.news/docs/components/button) para dispensar o Banner. O padrão é `false`. > \[!TIP] > > Um evento `close` será emitido quando o botão de fechar for clicado. ::component-example --- iframe: style: "height: 48px;" overflowHidden: true name: banner-example --- #code ```vue ``` :: > \[!NOTE] > > Quando fechado, `banner-${id}` será armazenado no local storage para evitar que ele seja exibido novamente. :br Para o exemplo acima, `banner-example` será armazenado no local storage. > \[!CAUTION] > > Para persistir o estado de dispensado entre recarregamentos de página, você precisa especificar uma prop `id`. Sem um `id` explícito, o banner só ficará oculto na sessão atual e reaparecerá ao recarregar a página. ### Ícone de fechar Use a prop `close-icon` para personalizar o [Icon](https://ui.nitro.news/docs/components/icon) do botão de fechar. O padrão é `i-lucide-x`. ::component-example --- iframe: style: "height: 48px;" overflowHidden: true props: title: This is a closable banner with a custom close icon. closeIcon: i-lucide-x-circle name: banner-example --- #code ```vue ``` :: **Nuxt:** > \[!TIP] > See: /docs/getting-started/integrations/icons/nuxt#theme > > Você pode personalizar esse ícone globalmente no seu `app.config.ts` na chave `ui.icons.close`. **Vue:** > \[!TIP] > See: /docs/getting-started/integrations/icons/vue#theme > > Você pode personalizar esse ícone globalmente no seu `vite.config.ts` na chave `ui.icons.close`. ### Ações Use a prop `actions` para adicionar algumas ações de [Button](https://ui.nitro.news/docs/components/button) ao Banner. ```vue ``` > \[!NOTE] > > Os botões de ação usam por padrão `color="neutral"` e `size="xs"`. Você pode personalizar esses valores passando-os diretamente para cada botão de ação. ### Link Você pode passar qualquer propriedade do componente [``](https://nuxt.com/docs/api/components/nuxt-link){rel=""nofollow""}, como `to`, `target`, `rel`, etc. ```vue ``` > \[!NOTE] > > O componente `NuxtLink` herdará todos os outros atributos que você passar para o componente `User`. ## Exemplos ### Dentro de `app.vue` Use o componente Banner no seu `app.vue` ou em um layout: ```vue [app.vue] {3} ``` ## API ### Props ```ts /** * Props for the Banner component */ interface BannerProps { /** * The element or component this component should render as. */ as?: any; /** * A unique id saved to local storage to remember if the banner has been dismissed. * Without an explicit id, the banner will not be persisted and will reappear on page reload. */ id?: string | undefined; /** * The icon displayed next to the title. */ icon?: any; title?: string | undefined; /** * Display a list of actions next to the title. * `{ color: 'neutral', size: 'xs' }`{lang="ts-type"} */ actions?: ButtonProps[] | undefined; to?: string | it | et | undefined; target?: "_blank" | "_parent" | "_self" | "_top" | (string & {}) | null | undefined; color?: "error" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "neutral" | undefined; /** * Display a close button to dismiss the banner. * `{ size: 'md', color: 'neutral', variant: 'ghost' }`{lang="ts-type"} */ close?: boolean | Omit | undefined; /** * The icon displayed in the close button. */ closeIcon?: any; ui?: { root?: SlotClass; container?: SlotClass; left?: SlotClass; center?: SlotClass; right?: SlotClass; icon?: SlotClass; title?: SlotClass; actions?: SlotClass; close?: SlotClass; } | undefined; } ``` ### Slots ```ts /** * Slots for the Banner component */ interface BannerSlots { leading(): any; title(): any; actions(): any; close(): any; } ``` ### Emits ```ts /** * Emitted events for the Banner component */ interface BannerEmits { close: (payload: []) => void; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { banner: { slots: { root: [ 'relative z-50 w-full', 'transition-colors' ], container: 'flex items-center justify-between gap-3 h-12', left: 'hidden lg:flex-1 lg:flex lg:items-center', center: 'flex items-center gap-1.5 min-w-0', right: 'lg:flex-1 flex items-center justify-end', icon: 'size-5 shrink-0 text-inverted pointer-events-none', title: 'text-sm text-inverted font-medium truncate', actions: 'flex gap-1.5 shrink-0 isolate', close: 'text-inverted hover:bg-default/10 focus-visible:bg-default/10 -me-1.5 lg:me-0' }, variants: { color: { primary: { root: 'bg-primary' }, secondary: { root: 'bg-secondary' }, accent: { root: 'bg-accent' }, success: { root: 'bg-success' }, info: { root: 'bg-info' }, warning: { root: 'bg-warning' }, error: { root: 'bg-error' }, neutral: { root: 'bg-inverted' } }, to: { true: '' } }, compoundVariants: [ { color: 'primary', to: true, class: { root: 'hover:bg-primary/90' } }, { color: 'secondary', to: true, class: { root: 'hover:bg-secondary/90' } }, { color: 'accent', to: true, class: { root: 'hover:bg-accent/90' } }, { color: 'success', to: true, class: { root: 'hover:bg-success/90' } }, { color: 'info', to: true, class: { root: 'hover:bg-info/90' } }, { color: 'warning', to: true, class: { root: 'hover:bg-warning/90' } }, { color: 'error', to: true, class: { root: 'hover:bg-error/90' } }, { color: 'neutral', to: true, class: { root: 'hover:bg-inverted/90' } } ], defaultVariants: { color: 'primary' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/Banner.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/banner.ts). # BlogPost ## Uso O componente BlogPost oferece uma maneira flexível de exibir um elemento `
` com conteúdo personalizável, incluindo título, descrição, imagem, etc. ```vue ``` > \[!TIP] > See: /docs/components/blog-posts > > Use o componente `BlogPosts` para exibir vários posts de blog em um layout de grade responsivo. ### Título Use a prop `title` para exibir o título do BlogPost. ```vue ``` ### Descrição Use a prop `description` para exibir a descrição do BlogPost. ```vue ``` ### Dados Use a prop `date` para exibir a data do BlogPost. > \[!TIP] > > A data é formatada automaticamente para o [locale atual](https://ui.nitro.news/docs/getting-started/integrations/i18n/nuxt#locale). Você pode passar um objeto `Date` ou uma string. ```vue ``` ### Badge Use a prop `badge` para exibir um [Badge](https://ui.nitro.news/docs/components/badge) no BlogPost. ```vue ``` Você pode passar qualquer propriedade do componente [Badge](https://ui.nitro.news/docs/components/badge#props) para personalizá-lo. ```vue ``` ### Imagem Use a prop `image` para exibir uma imagem no BlogPost. > \[!NOTE] > > Se o [`@nuxt/image`](https://image.nuxt.com/get-started/installation){rel=""nofollow""} estiver instalado, o componente `` será usado no lugar da tag `img` nativa. ```vue ``` ### Autores Use a prop `authors` para exibir uma lista de [User](https://ui.nitro.news/docs/components/user) no BlogPost como um array de objetos com as seguintes propriedades: - `name?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `description?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `avatar?: Omit`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `chip?: boolean | Omit`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `size?: UserProps['size']`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `orientation?: UserProps['orientation']`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} Você pode passar qualquer propriedade do componente [Link](https://ui.nitro.news/docs/components/link#props), como `to`, `target`, etc. ```vue ``` Quando a prop `authors` tem mais de um item, o componente [AvatarGroup](https://ui.nitro.news/docs/components/avatar-group) é usado. ```vue ``` ### Link Você pode passar qualquer propriedade do componente [``](https://nuxt.com/docs/api/components/nuxt-link){rel=""nofollow""}, como `to`, `target`, `rel`, etc. ```vue ``` ### Variante Use a prop `variant` para alterar o estilo do BlogPost. ```vue ``` > \[!NOTE] > > A estilização será diferente conforme você forneça uma prop `to` ou uma `image`. ### Orientação Use a prop `orientation` para alterar a orientação do BlogPost. O padrão é `vertical`. ```vue ``` ## API ### Props ```ts /** * Props for the BlogPost component */ interface BlogPostProps { /** * The element or component this component should render as. * @default "\"article\"" */ as?: any; title?: string | undefined; description?: string | undefined; /** * The date of the blog post. Can be a string or a Date object. */ date?: string | Date | undefined; /** * Display a badge on the blog post. * Can be a string or an object. * `{ color: 'neutral', variant: 'subtle' }`{lang="ts-type"} */ badge?: string | BadgeProps | undefined; /** * The authors of the blog post. */ authors?: UserProps[] | undefined; /** * The image of the blog post. Can be a string or an object. */ image?: string | (Partial & { [key: string]: any; }) | undefined; /** * The orientation of the blog post. * @default "\"vertical\"" */ orientation?: "vertical" | "horizontal" | undefined; variant?: "outline" | "soft" | "subtle" | "ghost" | "naked" | undefined; to?: string | it | et | undefined; target?: "_blank" | "_parent" | "_self" | "_top" | (string & {}) | null | undefined; onClick?: ((event: MouseEvent) => void) | undefined; ui?: { root?: SlotClass; header?: SlotClass; body?: SlotClass; footer?: SlotClass; image?: SlotClass; title?: SlotClass; description?: SlotClass; authors?: SlotClass; avatar?: SlotClass; meta?: SlotClass; date?: SlotClass; badge?: SlotClass; } | undefined; } ``` ### Slots ```ts /** * Slots for the BlogPost component */ interface BlogPostSlots { date(): any; badge(): any; title(): any; description(): any; authors(): any; header(): any; body(): any; footer(): any; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { blogPost: { slots: { root: 'relative group/blog-post flex flex-col rounded-lg overflow-hidden', header: 'relative overflow-hidden aspect-[16/9] w-full pointer-events-none', body: 'min-w-0 flex-1 flex flex-col', footer: '', image: 'object-cover object-top w-full h-full', title: 'text-xl text-pretty font-semibold text-highlighted', description: 'mt-1 text-base text-pretty', authors: 'pt-4 mt-auto flex flex-wrap gap-x-3 gap-y-1.5', avatar: '', meta: 'flex items-center gap-2 mb-2', date: 'text-sm', badge: '' }, variants: { orientation: { horizontal: { root: 'lg:grid lg:grid-cols-2 lg:items-center gap-x-8', body: 'justify-center p-4 sm:p-6 lg:px-0' }, vertical: { root: 'flex flex-col', body: 'p-4 sm:p-6' } }, variant: { outline: { root: 'bg-default ring ring-default', date: 'text-toned', description: 'text-muted' }, soft: { root: 'bg-elevated/50', date: 'text-muted', description: 'text-toned' }, subtle: { root: 'bg-elevated/50 ring ring-default', date: 'text-muted', description: 'text-toned' }, ghost: { date: 'text-toned', description: 'text-muted', header: 'shadow-lg rounded-lg' }, naked: { root: 'p-0 sm:p-0', date: 'text-toned', description: 'text-muted', header: 'shadow-lg rounded-lg' } }, to: { true: { root: [ 'outline-primary/25 has-[>a:focus-visible]:outline-3', 'transition' ], image: 'transform transition-transform duration-200 group-hover/blog-post:scale-110', avatar: 'inline-flex transform transition-transform duration-200 hover:scale-115 rounded-full outline-primary/25 focus-visible:outline-3' } }, image: { true: '' } }, compoundVariants: [ { variant: 'outline', to: true, class: { root: 'hover:bg-elevated/50' } }, { variant: 'soft', to: true, class: { root: 'hover:bg-elevated' } }, { variant: 'subtle', to: true, class: { root: 'hover:bg-elevated hover:ring-accented' } }, { variant: [ 'outline', 'subtle' ], to: true, class: { root: 'has-[>a:focus-visible]:ring-primary' } }, { variant: 'ghost', to: true, class: { root: 'hover:bg-elevated/50', header: [ 'group-hover/blog-post:shadow-none', 'transition-all' ] } }, { variant: 'ghost', to: true, orientation: 'vertical', class: { header: 'group-hover/blog-post:rounded-b-none' } }, { variant: 'ghost', to: true, orientation: 'horizontal', class: { header: 'group-hover/blog-post:rounded-r-none' } }, { orientation: 'vertical', image: false, variant: 'naked', class: { body: 'p-0 sm:p-0' } } ], defaultVariants: { variant: 'outline' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/BlogPost.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/blog-post.ts). # BlogPosts ## Uso O componente BlogPosts oferece um layout flexível para exibir uma lista de componentes [BlogPost](https://ui.nitro.news/docs/components/blog-post) usando o slot padrão ou a prop `posts`. ```vue {2,8} ``` ### Posts Use a prop `posts` como um array de objetos com as propriedades do componente [BlogPost](https://ui.nitro.news/docs/components/blog-post#props). ```vue ``` ### Orientação Use a prop `orientation` para alterar a orientação do BlogPosts. O padrão é `horizontal`. ```vue ``` > \[!TIP] > > Ao usar a prop `posts` em vez do slot padrão, a `orientation` dos posts é invertida automaticamente, de `horizontal` para `vertical` e vice-versa. ## Exemplos > \[!NOTE] > > Embora estes exemplos usem o [Nuxt Content](https://content.nuxt.com){rel=""nofollow""}, os componentes podem ser integrados a qualquer sistema de gerenciamento de conteúdo. ### Dentro de uma página Use o componente BlogPosts em uma página para criar uma página de blog: ```vue [pages/blog/index.vue] {11-18} ``` > \[!NOTE] > > Neste exemplo, os `posts` são buscados usando `queryCollection` do módulo `@nuxt/content`. > \[!TIP] > > A prop `to` é sobrescrita aqui, já que o `@nuxt/content` usa a propriedade `path`. ## API ### Props ```ts /** * Props for the BlogPosts component */ interface BlogPostsProps { /** * The element or component this component should render as. */ as?: any; posts?: BlogPostProps[] | undefined; /** * The orientation of the blog posts. * @default "\"horizontal\"" */ orientation?: "horizontal" | "vertical" | undefined; ui?: { base?: any; } | undefined; } ``` ### Slots ```ts /** * Slots for the BlogPosts component */ interface BlogPostsSlots { date(): any; badge(): any; title(): any; description(): any; authors(): any; header(): any; body(): any; footer(): any; default(): any; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { blogPosts: { base: 'flex flex-col gap-8 lg:gap-y-16', variants: { orientation: { horizontal: 'sm:grid sm:grid-cols-2 lg:grid-cols-3', vertical: '' } } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/BlogPosts.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/blog-posts.ts). # Breadcrumb ## Uso Use o componente Breadcrumb para mostrar a localização da página atual na hierarquia do seu site. ```vue ``` ### Itens Use a prop `items` como um array de objetos com as seguintes propriedades: - `label?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `icon?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `avatar?: AvatarProps`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - [`slot?: string`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"}](https://ui.nitro.news/#with-custom-slot) - `class?: any`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `ui?: { item?: ClassNameValue, link?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLeadingAvatar?: ClassNameValue, linkLabel?: ClassNameValue, separator?: ClassNameValue, separatorIcon?: ClassNameValue }`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} Você pode passar qualquer propriedade do componente [Link](https://ui.nitro.news/docs/components/link#props), como `to`, `target`, etc. ```vue ``` > \[!NOTE] > > Um `span` é renderizado em vez de um link quando a propriedade `to` não é definida. ### Ícone de separador Use a prop `separator-icon` para personalizar o [Icon](https://ui.nitro.news/docs/components/icon) entre cada item. O padrão é `i-lucide-chevron-right`. ```vue ``` **Nuxt:** > \[!TIP] > See: /docs/getting-started/integrations/icons/nuxt#theme > > Você pode personalizar esse ícone globalmente no seu `app.config.ts` na chave `ui.icons.chevronRight`. **Vue:** > \[!TIP] > See: /docs/getting-started/integrations/icons/vue#theme > > Você pode personalizar esse ícone globalmente no seu `vite.config.ts` na chave `ui.icons.chevronRight`. ### Cor `4.8+` Use a prop `color` para alterar a cor do Breadcrumb ativo. ```vue ``` ## Exemplos ### Com slot de separador Use o slot `#separator` para personalizar o separador entre cada item. :component-example{name="breadcrumb-separator-slot-example"} ### Com slot personalizado Use a propriedade `slot` para personalizar um item específico. Você terá acesso aos seguintes slots: - `#{{ item.slot }}`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `#{{ item.slot }}-leading`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `#{{ item.slot }}-label`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} - `#{{ item.slot }}-trailing`{.shiki,shiki-themes,material-theme-lighter,material-theme,material-theme-palenight lang="ts-type"} :component-example{name="breadcrumb-custom-slot-example"} > \[!TIP] > See: #slots > > Você também pode usar os slots `#item`, `#item-leading`, `#item-label` e `#item-trailing` para personalizar todos os itens. ## API ### Props ```ts /** * Props for the Breadcrumb component */ interface BreadcrumbProps { /** * The element or component this component should render as. * @default "\"nav\"" */ as?: any; items?: T[] | undefined; /** * The icon to use as a separator. */ separatorIcon?: any; /** * The key used to get the label from the item. * @default "\"label\"" */ labelKey?: GetItemKeys | undefined; ui?: { root?: SlotClass; list?: SlotClass; item?: SlotClass; link?: SlotClass; linkLeadingIcon?: SlotClass; linkLeadingAvatar?: SlotClass; linkLeadingAvatarSize?: SlotClass; linkLabel?: SlotClass; separator?: SlotClass; separatorIcon?: SlotClass; } | undefined; } ``` ### Slots ```ts /** * Slots for the Breadcrumb component */ interface BreadcrumbSlots { item(): any; item-leading(): any; item-label(): any; item-trailing(): any; separator(): any; } ``` ## Tema ```ts [app.config.ts] export default defineAppConfig({ ui: { breadcrumb: { slots: { root: 'relative min-w-0', list: 'flex items-center gap-1.5', item: 'flex min-w-0', link: 'group relative flex items-center gap-1.5 text-sm min-w-0 rounded-md', linkLeadingIcon: 'shrink-0 size-5', linkLeadingAvatar: 'shrink-0', linkLeadingAvatarSize: '2xs', linkLabel: 'truncate', separator: 'flex', separatorIcon: 'shrink-0 size-5 text-muted' }, variants: { active: { true: { link: 'font-semibold' }, false: { link: 'text-muted font-medium' } }, disabled: { true: { link: 'cursor-not-allowed opacity-75' } }, to: { true: '' }, color: { primary: { link: 'outline-primary/25 focus-visible:outline-3' }, secondary: { link: 'outline-secondary/25 focus-visible:outline-3' }, accent: { link: 'outline-accent/25 focus-visible:outline-3' }, success: { link: 'outline-success/25 focus-visible:outline-3' }, info: { link: 'outline-info/25 focus-visible:outline-3' }, warning: { link: 'outline-warning/25 focus-visible:outline-3' }, error: { link: 'outline-error/25 focus-visible:outline-3' }, neutral: { link: 'outline-inverted/25 focus-visible:outline-3' } } }, compoundVariants: [ { disabled: false, active: false, to: true, class: { link: [ 'hover:text-default', 'transition-colors' ] } }, { color: 'primary', active: true, class: { link: 'text-primary' } }, { color: 'secondary', active: true, class: { link: 'text-secondary' } }, { color: 'accent', active: true, class: { link: 'text-accent' } }, { color: 'success', active: true, class: { link: 'text-success' } }, { color: 'info', active: true, class: { link: 'text-info' } }, { color: 'warning', active: true, class: { link: 'text-warning' } }, { color: 'error', active: true, class: { link: 'text-error' } }, { color: 'neutral', active: true, class: { link: 'text-highlighted' } } ], defaultVariants: { color: 'primary' } } } }) ``` ## Changelog See commit history for [component](https://github.com/nuxt/ui/commits/v4/src/runtime/components/Breadcrumb.vue) and [theme](https://github.com/nuxt/ui/commits/v4/src/theme/breadcrumb.ts). # Button ## Uso Use o slot padrão para definir o rótulo do Button. ```vue ``` ### Label Use a prop `label` para definir o rótulo do Button. ```vue ``` ### Cor Use a prop `color` para alterar a cor do Button. ```vue ``` ### Variante Use a prop `variant` para alterar a variante do Button. ```vue ``` ### Tamanho Use a prop `size` para alterar o tamanho do Button. ```vue ``` ### Ícone Use a prop `icon` para exibir um [Icon](https://ui.nitro.news/docs/components/icon) dentro do Button. ```vue ``` Use as props `leading` e `trailing` para definir a posição do ícone ou as props `leading-icon` e `trailing-icon` para definir um ícone diferente para cada posição. ```vue ``` O `label`, como prop ou slot, é opcional, então você pode usar o Button como um botão apenas com ícone. ```vue ``` ### Avatar Use a prop `avatar` para exibir um [Avatar](https://ui.nitro.news/docs/components/avatar) dentro do Button. ```vue ``` O `label`, como prop ou slot, é opcional, então você pode usar o Button como um botão apenas com avatar. ```vue ``` ### Link Você pode passar qualquer propriedade do componente [Link](https://ui.nitro.news/docs/components/link#props), como `to`, `target`, etc. ```vue ``` Quando o Button é um link ou ao usar a prop `active`, você pode usar as props `active-color` e `active-variant` para personalizar o estado ativo. ```vue ``` Você também pode usar as props `active-class` e `inactive-class` para personalizar o estado ativo. ```vue ``` > \[!TIP] > > Você pode configurar esses estilos globalmente no seu arquivo `app.config.ts`, na chave `ui.button.variants.active`. > > ```ts > export default defineAppConfig({ > ui: { > button: { > variants: { > active: { > true: { > base: 'font-bold' > } > } > } > } > } > }) > ``` ### Carregando Use a prop `loading` para exibir um ícone de carregamento e desabilitar o Button. ```vue ``` Use a prop `loading-auto` para exibir o ícone de carregamento automaticamente enquanto a promise do `@click` está pendente. :component-example{name="button-loading-auto-example"} Isso também funciona com o componente [Form](https://ui.nitro.news/docs/components/form). :component-example{name="button-loading-auto-form-example"} ### Ícone de carregamento Use a prop `loading-icon` para personalizar o ícone de carregamento. O padrão é `i-lucide-loader-circle`. ```vue ``` **Nuxt:** > \[!TIP] > See: /docs/getting-started/integrations/icons/nuxt#theme > > Você pode personalizar esse ícone globalmente no seu `app.config.ts` na chave `ui.icons.loading`. **Vue:** > \[!TIP] > See: /docs/getting-started/integrations/icons/vue#theme > > Você pode personalizar esse ícone globalmente no seu `vite.config.ts` na chave `ui.icons.loading`. ### Desabilitado Use a prop `disabled` para desabilitar o Button. ```vue ``` ## Exemplos ### `class` prop Use a prop `class` para sobrescrever os estilos base do Button. ```vue ``` ### `ui` prop Use a prop `ui` para sobrescrever os estilos dos slots do Button. ```vue ``` ## API ### Props ```ts /** * Props for the Button component */ interface ButtonProps { label?: string | undefined; color?: "error" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "neutral" | undefined; activeColor?: "error" | "primary" | "secondary" | "accent" | "success" | "info" | "warning" | "neutral" | undefined; variant?: "solid" | "outline" | "soft" | "subtle" | "ghost" | "link" | undefined; activeVariant?: "solid" | "outline" | "soft" | "subtle" | "ghost" | "link" | undefined; size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined; /** * Render the button with equal padding on all sides. */ square?: boolean | undefined; /** * Render the button full width. */ block?: boolean | undefined; /** * Set loading state automatically based on the `@click` promise state */ loadingAuto?: boolean | undefined; onClick?: ((event: MouseEvent) => void) | ((event: MouseEvent) => void)[] | undefined; ui?: { base?: SlotClass; label?: SlotClass; leadingIcon?: SlotClass; leadingAvatar?: SlotClass; leadingAvatarSize?: SlotClass; trailingIcon?: SlotClass; } | undefined; /** * Display an icon based on the `leading` and `trailing` props. */ icon?: any; /** * Display an avatar on the left side. */ avatar?: AvatarProps | undefined; /** * When `true`, the icon will be displayed on the left side. */ leading?: boolean | undefined; /** * Display an icon on the left side. */ leadingIcon?: any; /** * When `true`, the icon will be displayed on the right side. */ trailing?: boolean | undefined; /** * Display an icon on the right side. */ trailingIcon?: any; /** * When `true`, the loading icon will be displayed. */ loading?: boolean | undefined; /** * The icon when the `loading` prop is `true`. */ loadingIcon?: any; /** * Route Location the link should navigate to when clicked on. */ to?: string | it | et | undefined; /** * Class to apply when the link is active */ activeClass?: string | undefined; /** * Class to apply when the link is exact active */ exactActiveClass?: string | undefined; /** * Value passed to the attribute `aria-current` when the link is exact active. */ ariaCurrentValue?: "page" | "step" | "location" | "date" | "time" | "true" | "false" | undefined; /** * Pass the returned promise of `router.push()` to `document.startViewTransition()` if supported. */ viewTransition?: boolean | undefined; /** * Calls `router.replace` instead of `router.push`. */ replace?: boolean | undefined; autofocus?: Booleanish | undefined; disabled?: boolean | undefined; form?: string | undefined; formaction?: string | undefined; formenctype?: string | undefined; formmethod?: string | undefined; formnovalidate?: Booleanish | undefined; formtarget?: string | undefined; name?: string | undefined; /** * The type of the button when not a link. */ type?: "reset" | "submit" | "button" | undefined; download?: any; /** * An alias for `to`. If used with `to`, `href` will be ignored */ href?: string | it | et | undefined; hreflang?: string | undefined; media?: string | undefined; ping?: string | undefined; /** * A rel attribute value to apply on the link. Defaults to "noopener noreferrer" for external links. */ rel?: "noopener" | "noreferrer" | "nofollow" | "sponsored" | "ugc" | (string & {}) | null | undefined; /** * Where to display the linked URL, as the name for a browsing context. */ target?: (string & {}) | "_blank" | "_parent" | "_self" | "_top" | null | undefined; referrerpolicy?: HTMLAttributeReferrerPolicy | undefined; /** * The element or component this component should render as when not a link. */ as?: any; /** * Force the link to be active independent of the current route. */ active?: boolean | undefined; /** * Will only be active if the current route is an exact match. */ exact?: boolean | undefined; /** * Allows controlling how the current route query sets the link as active. */ exactQuery?: boolean | "partial" | undefined; /** * Will only be active if the current route hash is an exact match. */ exactHash?: boolean | undefined; /** * The class to apply when the link is inactive. */ inactiveClass?: string | undefined; /** * Control i18n auto-localization when `@nuxtjs/i18n` is installed. * - `undefined` / `true` (default): auto-localizes to the current locale using `$localePath`. * Paths already carrying a locale prefix (from e.g. `switchLocalePath()`) are detected * and left untouched to prevent double-prefixing. * - `false`: explicitly disables auto-localization. * - `string`: localizes to a specific locale (e.g. `'fr'`). */ locale?: string | boolean | undefined; /** * Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases */ external?: boolean | undefined; /** * If set to true, no rel attribute will be added to the link */ noRel?: boolean | undefined; /** * A class to apply to links that have been prefetched. */ prefetchedClass?: string | undefined; /** * When enabled will prefetch middleware, layouts and payloads of links in the viewport. */ prefetch?: boolean | undefined; /** * Allows controlling when to prefetch links. By default, prefetch is triggered only on visibility. */ prefetchOn?: "visibility" | "interaction" | Partial<{ visibility: boolean; interaction: boolean; }> | undefined; /** * Escape hatch to disable `prefetch` attribute. */ noPrefetch?: boolean | undefined; /** * An option to either add or remove trailing slashes in the `href` for this specific link. * Overrides the global `trailingSlash` option if provided. */ trailingSlash?: "remove" | "append" | undefined; } ``` > \[!NOTE] > See: https\://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes > > Este componente também suporta todos os atributos HTML nativos de `