diff --git a/CHANGELOG.md b/CHANGELOG.md index ddd0d316..79cb05cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,46 @@ # Changelog +## [3.1.2](https://github.com/nuxt/ui/compare/v3.1.1...v3.1.2) (2025-05-15) + +### Features + +* **Badge:** add `square` prop ([#4008](https://github.com/nuxt/ui/issues/4008)) ([894e8a6](https://github.com/nuxt/ui/commit/894e8a61b6fea3618fc863bd77678385e9d021c2)) +* **CheckboxGroup:** add `table` variant ([#3997](https://github.com/nuxt/ui/issues/3997)) ([1b6ab27](https://github.com/nuxt/ui/commit/1b6ab271ea3875a7c77ffe9367c7c341083dd53c)) +* **components:** add `ui` field in items ([#4060](https://github.com/nuxt/ui/issues/4060)) ([b9adc83](https://github.com/nuxt/ui/commit/b9adc83e787db02507e6e7bb1aabc684eccc197b)) +* **InputNumber:** add `increment-disabled` / `decrement-disabled` props ([#4141](https://github.com/nuxt/ui/issues/4141)) ([c7fba2e](https://github.com/nuxt/ui/commit/c7fba2e0ebfb7153f3bfb727165d653bbd3dbe54)) +* **locale:** add Slovenian language ([#4140](https://github.com/nuxt/ui/issues/4140)) ([e86dc79](https://github.com/nuxt/ui/commit/e86dc79e51b2773a77ada5f12d4f0964fbc83354)) +* **NavigationMenu:** add `collapsible` field in items ([2be60cd](https://github.com/nuxt/ui/commit/2be60cddfe10fd1e2466900fd53e21ee0c877227)), closes [#3353](https://github.com/nuxt/ui/issues/3353) [#3911](https://github.com/nuxt/ui/issues/3911) +* **NavigationMenu:** handle `tooltip` in items ([46c2987](https://github.com/nuxt/ui/commit/46c2987ebfd30b2b071a96a745b7270e852e96de)), closes [#4050](https://github.com/nuxt/ui/issues/4050) +* **Slider:** handle `tooltip` around thumbs ([d140acc](https://github.com/nuxt/ui/commit/d140acc608c6ae11c0a0531fe443588776ea7807)), closes [#1469](https://github.com/nuxt/ui/issues/1469) +* **Toast:** add `progress` prop to hide progress bar ([#4125](https://github.com/nuxt/ui/issues/4125)) ([92632e9](https://github.com/nuxt/ui/commit/92632e969eaa11521a166e50e346753929b7f523)) + +### Bug Fixes + +* **Badge/Button:** handle zero value in label correctly ([#4108](https://github.com/nuxt/ui/issues/4108)) ([f244d15](https://github.com/nuxt/ui/commit/f244d15b96d97cd8ba34ba9c18f23965e17e3cef)) +* **ButtonGroup:** add `z-index` on focused element ([204953b](https://github.com/nuxt/ui/commit/204953b780bde08dbfde230fc8887674449227b7)) +* **Calendar:** wrong color for today date with `neutral` color ([7d51a9e](https://github.com/nuxt/ui/commit/7d51a9e479cb6105ea37759c5cd67ff9f7702c49)), closes [#4084](https://github.com/nuxt/ui/issues/4084) [#3629](https://github.com/nuxt/ui/issues/3629) +* **Checkbox/RadioGroup:** render correct element without `variant` ([f2fd778](https://github.com/nuxt/ui/commit/f2fd778c0a604f2d65aec9f3fe2d54b6d4e8c3a2)), closes [#3998](https://github.com/nuxt/ui/issues/3998) +* **CheckboxGroup:** relative `UCheckbox` import ([7551a85](https://github.com/nuxt/ui/commit/7551a85ad2d92b59e2909396affb862403d5b27a)), closes [#4090](https://github.com/nuxt/ui/issues/4090) +* **ColorPicker:** make thumb touch draggable ([#4101](https://github.com/nuxt/ui/issues/4101)) ([cc20a26](https://github.com/nuxt/ui/commit/cc20a26f07268d19119ab4c7c254033143bb63f4)) +* **components:** `class` should have priority over `ui` prop ([e6e510b](https://github.com/nuxt/ui/commit/e6e510b848d995a286a51d50a120d67483e11232)) +* **FormField:** block form field injection after use ([#4150](https://github.com/nuxt/ui/issues/4150)) ([d79da9d](https://github.com/nuxt/ui/commit/d79da9d7b60c9972af64acd8e6eef4ae7d6bc3eb)) +* **FormField:** use `div` for `error` and `help` slots ([459a041](https://github.com/nuxt/ui/commit/459a0410ab729fde60865e84632b36903465f57e)) +* **inertia:** link always render as anchor tag ([#3989](https://github.com/nuxt/ui/issues/3989)) ([e81464a](https://github.com/nuxt/ui/commit/e81464a43ede4e63ce3dc92429bbfef48614f731)) +* **inertia:** make `useAppConfig` reactive ([12303a8](https://github.com/nuxt/ui/commit/12303a87be62dae84ef774e3a9795deb0ac90cc7)) +* **Input/Textarea:** handle generic types ([3c8d6cd](https://github.com/nuxt/ui/commit/3c8d6cd01dfafed5844c376f52adbdda0c814420)), closes [nuxt/ui-pro#887](https://github.com/nuxt/ui-pro/issues/887) +* **InputNumber:** handle inside button group ([2e4c308](https://github.com/nuxt/ui/commit/2e4c3082a1e66fa597086dc3431fec37fa29ef62)), closes [#4155](https://github.com/nuxt/ui/issues/4155) +* **Link:** consistent behavior between nuxt, vue and inertia ([#4134](https://github.com/nuxt/ui/issues/4134)) ([67da90a](https://github.com/nuxt/ui/commit/67da90a2f638124f640c4271d3376c5ff3fab6a1)) +* **module:** configure `@nuxt/fonts` with default weights ([276268d](https://github.com/nuxt/ui/commit/276268d311f57715cec47bc600a0ccc3d3885682)) +* **NavigationMenu:** arrow position conflict ([#4137](https://github.com/nuxt/ui/issues/4137)) ([0dc4678](https://github.com/nuxt/ui/commit/0dc4678c68e4b500be49c38336dc75b73843e38d)) +* **Select:** support more primitive types in `value` field ([#4105](https://github.com/nuxt/ui/issues/4105)) ([09b4699](https://github.com/nuxt/ui/commit/09b4699aeadaa195ea081509f8e237bb2c346238)) +* **Slider:** handle generic types ([d7a4d02](https://github.com/nuxt/ui/commit/d7a4d029b77d2dfa0b8efcd2755d482fa5e31fd3)) +* **Stepper:** use `div` tag for `title` & `description` ([a57844e](https://github.com/nuxt/ui/commit/a57844e41676c13ed1af861424961b88cee7b4da)), closes [#4096](https://github.com/nuxt/ui/issues/4096) +* **Tabs:** prevent trigger truncate without parent width ([06e5689](https://github.com/nuxt/ui/commit/06e5689da80b36205d0548d5d6b58510938e4a6e)), closes [#4056](https://github.com/nuxt/ui/issues/4056) +* **Tabs:** set `focus:outline-none` with `link` variant ([999a0f8](https://github.com/nuxt/ui/commit/999a0f84671fad20fa3dc50c6774af2e0200b32e)) +* **templates:** dont write unused variants in theme files ([d3df3bb](https://github.com/nuxt/ui/commit/d3df3bb929fe6732f27b182d1664213884a662ec)) +* **Toaster:** allow `base` slot override ([c63d2f3](https://github.com/nuxt/ui/commit/c63d2f380aac16f1d1e812516df3dca7fa7c8034)) +* **vue:** make `useAppConfig` reactive ([869c070](https://github.com/nuxt/ui/commit/869c0708bd351c7be44e5e430c348b19dd316db9)), closes [#3952](https://github.com/nuxt/ui/issues/3952) + ## [3.1.1](https://github.com/nuxt/ui/compare/v3.1.0...v3.1.1) (2025-05-02) ### Features diff --git a/docs/app/app.vue b/docs/app/app.vue index ea4542b4..b4785918 100644 --- a/docs/app/app.vue +++ b/docs/app/app.vue @@ -51,7 +51,7 @@ provide('navigation', mappedNavigation) diff --git a/docs/app/components/content/ComponentPropsSchema.vue b/docs/app/components/content/ComponentPropsSchema.vue index 5867f8b4..91d1728c 100644 --- a/docs/app/components/content/ComponentPropsSchema.vue +++ b/docs/app/components/content/ComponentPropsSchema.vue @@ -38,7 +38,7 @@ const schemaProps = computed(() => { diff --git a/docs/content/1.getting-started/3.theme.md b/docs/content/1.getting-started/3.theme.md index ac6d2db3..391bad02 100644 --- a/docs/content/1.getting-started/3.theme.md +++ b/docs/content/1.getting-started/3.theme.md @@ -229,6 +229,10 @@ export default defineConfig({ :: +::caution +When configuring your theme colors, you must use either color names from the [default Tailwind palette](https://tailwindcss.com/docs/colors) (like 'blue', 'green', etc.) or reference custom colors that you've previously defined in your [CSS file](#theme). +:: + ### Extend colors ::framework-only diff --git a/docs/content/3.components/accordion.md b/docs/content/3.components/accordion.md index cc83f157..e825bd3e 100644 --- a/docs/content/3.components/accordion.md +++ b/docs/content/3.components/accordion.md @@ -23,6 +23,8 @@ Use the `items` prop as an array of objects with the following properties: - `value?: string`{lang="ts-type"} - `disabled?: boolean`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, header?: ClassNameValue, trigger?: ClassNameValue, leadingIcon?: ClassNameValue, label?: ClassNameValue, trailingIcon?: ClassNameValue, content?: ClassNameValue, body?: ClassNameValue }`{lang="ts-type"} ::component-code --- diff --git a/docs/content/3.components/breadcrumb.md b/docs/content/3.components/breadcrumb.md index 6e5540e5..d7aa63aa 100644 --- a/docs/content/3.components/breadcrumb.md +++ b/docs/content/3.components/breadcrumb.md @@ -16,8 +16,9 @@ Use the `items` prop as an array of objects with the following properties: - `label?: string`{lang="ts-type"} - `icon?: string`{lang="ts-type"} - `avatar?: AvatarProps`{lang="ts-type"} -- `class?: any`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, link?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLeadingAvatar?: ClassNameValue, linkLabel?: ClassNameValue, separator?: ClassNameValue, separatorIcon?: ClassNameValue }`{lang="ts-type"} You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc. diff --git a/docs/content/3.components/carousel.md b/docs/content/3.components/carousel.md index afb0f78e..862c2a04 100644 --- a/docs/content/3.components/carousel.md +++ b/docs/content/3.components/carousel.md @@ -27,6 +27,11 @@ class: 'p-8' --- :: +You can also pass an array of objects with the following properties: + +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue }`{lang="ts-type"} + You can control how many items are visible by using the [`basis`](https://tailwindcss.com/docs/flex-basis) / [`width`](https://tailwindcss.com/docs/width) utility classes on the `item`: ::component-example diff --git a/docs/content/3.components/checkbox-group.md b/docs/content/3.components/checkbox-group.md index 665f0ea2..e9daadba 100644 --- a/docs/content/3.components/checkbox-group.md +++ b/docs/content/3.components/checkbox-group.md @@ -49,6 +49,8 @@ You can also pass an array of objects with the following properties: - `description?: string`{lang="ts-type"} - [`value?: string`{lang="ts-type"}](#value-key) - `disabled?: boolean`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, icon?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} ::component-code --- @@ -199,6 +201,7 @@ items: variant: - list - card + - table props: color: 'primary' variant: 'card' @@ -229,6 +232,7 @@ items: variant: - list - card + - table props: size: 'xl' variant: 'list' @@ -259,6 +263,7 @@ items: variant: - list - card + - table props: orientation: 'horizontal' variant: 'list' @@ -293,6 +298,7 @@ items: variant: - list - card + - table props: indicator: 'end' variant: 'card' diff --git a/docs/content/3.components/command-palette.md b/docs/content/3.components/command-palette.md index c25c4274..30b3e72e 100644 --- a/docs/content/3.components/command-palette.md +++ b/docs/content/3.components/command-palette.md @@ -53,6 +53,8 @@ Each group contains an `items` array of objects that define the commands. Each i - `disabled?: boolean`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) - `onSelect?(e?: Event): void`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelPrefix?: ClassNameValue, itemLabelBase?: ClassNameValue, itemLabelSuffix?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue, itemTrailingHighlightedIcon?: ClassNameValue, itemTrailingIcon?: ClassNameValue,}`{lang="ts-type"} You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc. diff --git a/docs/content/3.components/context-menu.md b/docs/content/3.components/context-menu.md index 9b14fce5..3d007e83 100644 --- a/docs/content/3.components/context-menu.md +++ b/docs/content/3.components/context-menu.md @@ -28,11 +28,12 @@ Use the `items` prop as an array of objects with the following properties: - [`color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"`{lang="ts-type"}](#with-color-items) - [`checked?: boolean`{lang="ts-type"}](#with-checkbox-items) - `disabled?: boolean`{lang="ts-type"} -- `class?: any`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) - `onSelect?(e: Event): void`{lang="ts-type"} - [`onUpdateChecked?(checked: boolean): void`{lang="ts-type"}](#with-checkbox-items) - `children?: ContextMenuItem[] | ContextMenuItem[][]`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelExternalIcon?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue }`{lang="ts-type"} You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc. diff --git a/docs/content/3.components/dropdown-menu.md b/docs/content/3.components/dropdown-menu.md index 7d7c3f54..34ed4a78 100644 --- a/docs/content/3.components/dropdown-menu.md +++ b/docs/content/3.components/dropdown-menu.md @@ -28,11 +28,12 @@ Use the `items` prop as an array of objects with the following properties: - [`color?: "error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"`{lang="ts-type"}](#with-color-items) - [`checked?: boolean`{lang="ts-type"}](#with-checkbox-items) - `disabled?: boolean`{lang="ts-type"} -- `class?: any`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) - `onSelect?(e: Event): void`{lang="ts-type"} - [`onUpdateChecked?(checked: boolean): void`{lang="ts-type"}](#with-checkbox-items) - `children?: DropdownMenuItem[] | DropdownMenuItem[][]`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLabel?: ClassNameValue, itemLabelExternalIcon?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue, itemTrailingKbds?: ClassNameValue, itemTrailingKbdsSize?: ClassNameValue }`{lang="ts-type"} You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc. diff --git a/docs/content/3.components/input-menu.md b/docs/content/3.components/input-menu.md index fbd8d411..c8e69624 100644 --- a/docs/content/3.components/input-menu.md +++ b/docs/content/3.components/input-menu.md @@ -55,6 +55,8 @@ You can also pass an array of objects with the following properties: - [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items) - `disabled?: boolean`{lang="ts-type"} - `onSelect?(e: Event): void`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { tagsItem?: ClassNameValue, tagsItemText?: ClassNameValue, tagsItemDelete?: ClassNameValue, tagsItemDeleteIcon?: ClassNameValue, label?: ClassNameValue, separator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLabel?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue }`{lang="ts-type"} ::component-code --- diff --git a/docs/content/3.components/navigation-menu.md b/docs/content/3.components/navigation-menu.md index 87a09a0a..d5179692 100644 --- a/docs/content/3.components/navigation-menu.md +++ b/docs/content/3.components/navigation-menu.md @@ -21,14 +21,19 @@ Use the `items` prop as an array of objects with the following properties: - `icon?: string`{lang="ts-type"} - `avatar?: AvatarProps`{lang="ts-type"} - `badge?: string | number | BadgeProps`{lang="ts-type"} +- `tooltip?: TooltipProps`{lang="ts-type"} - `trailingIcon?: string`{lang="ts-type"} - `type?: 'label' | 'link'`{lang="ts-type"} +- `collapsible?: boolean`{lang="ts-type"} +- `defaultOpen?: boolean`{lang="ts-type"} +- `open?: boolean`{lang="ts-type"} - `value?: string`{lang="ts-type"} - `disabled?: boolean`{lang="ts-type"} -- `class?: any`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) - `onSelect?(e: Event): void`{lang="ts-type"} - `children?: NavigationMenuChildItem[]`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { linkLeadingAvatarSize?: ClassNameValue, linkLeadingAvatar?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLabel?: ClassNameValue, linkLabelExternalIcon?: ClassNameValue, linkTrailing?: ClassNameValue, linkTrailingBadgeSize?: ClassNameValue, linkTrailingBadge?: ClassNameValue, linkTrailingIcon?: ClassNameValue, label?: ClassNameValue, link?: ClassNameValue, content?: ClassNameValue, childList?: ClassNameValue, childItem?: ClassNameValue, childLink?: ClassNameValue, childLinkIcon?: ClassNameValue, childLinkWrapper?: ClassNameValue, childLinkLabel?: ClassNameValue, childLinkLabelExternalIcon?: ClassNameValue, childLinkDescription?: ClassNameValue }`{lang="ts-type"} You can pass any property from the [Link](/components/link#props) component such as `to`, `target`, etc. @@ -130,8 +135,8 @@ Each item can take a `children` array of objects with the following properties t - `label: string` - `description?: string` - `icon?: string` -- `class?: any` - `onSelect?(e: Event): void` +- `class?: any` :: @@ -237,6 +242,108 @@ props: Groups will be spaced when orientation is `horizontal` and separated when orientation is `vertical`. :: +### Collapsed + +Use the `collapsed` prop to collapse the NavigationMenu, this can be useful in a sidebar for example. + +::component-code +--- +collapse: true +ignore: + - items + - orientation + - class +external: + - items +externalTypes: + - NavigationMenuItem[][] +props: + collapsed: true + orientation: 'vertical' + items: + - - label: Links + type: 'label' + - label: Guide + icon: i-lucide-book-open + children: + - label: Introduction + description: Fully styled and customizable components for Nuxt. + icon: i-lucide-house + - label: Installation + description: Learn how to install and configure Nuxt UI in your application. + icon: i-lucide-cloud-download + - label: 'Icons' + icon: 'i-lucide-smile' + description: 'You have nothing to do, @nuxt/icon will handle it automatically.' + - label: 'Colors' + icon: 'i-lucide-swatch-book' + description: 'Choose a primary and a neutral color from your Tailwind CSS theme.' + - label: 'Theme' + icon: 'i-lucide-cog' + description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.' + - label: Composables + icon: i-lucide-database + collapsible: false + open: false + children: + - label: defineShortcuts + icon: i-lucide-file-text + description: Define shortcuts for your application. + to: /composables/define-shortcuts + - label: useOverlay + icon: i-lucide-file-text + description: Display a modal/slideover within your application. + to: /composables/use-overlay + - label: useToast + icon: i-lucide-file-text + description: Display a toast within your application. + to: /composables/use-toast + - label: Components + icon: i-lucide-box + collapsible: false + open: false + to: /components + active: true + children: + - label: Link + icon: i-lucide-file-text + description: Use NuxtLink with superpowers. + to: /components/link + - label: Modal + icon: i-lucide-file-text + description: Display a modal within your application. + to: /components/modal + - label: NavigationMenu + icon: i-lucide-file-text + description: Display a list of links. + to: /components/navigation-menu + - label: Pagination + icon: i-lucide-file-text + description: Display a list of pages. + to: /components/pagination + - label: Popover + icon: i-lucide-file-text + description: Display a non-modal dialog that floats around a trigger element. + to: /components/popover + - label: Progress + icon: i-lucide-file-text + description: Show a horizontal bar to indicate task progression. + to: /components/progress + - - label: GitHub + icon: i-simple-icons-github + badge: 3.8k + to: https://github.com/nuxt/ui + target: _blank + - label: Help + icon: i-lucide-circle-help + disabled: true +--- +:: + +::tip +You can set the `collapsible: false` property on items with children to prevent them from being collapsible. This allows the item to act as a regular link while still displaying its children in a submenu. +:: + ### Highlight Use the `highlight` prop to display a highlighted border for the active item. @@ -778,6 +885,126 @@ You can inspect the DOM to see each item's content being rendered. ## Examples +### With tooltips in items :badge{label="New" class="align-text-top"} + +You can use the `tooltip` property to display a [Tooltip](/components/tooltip) around an item. This can be useful when the menu is collapsed. + +::component-code +--- +collapse: true +ignore: + - items + - orientation + - class +external: + - items +externalTypes: + - NavigationMenuItem[][] +props: + collapsed: true + orientation: 'vertical' + items: + - - label: Links + type: 'label' + - label: Guide + icon: i-lucide-book-open + tooltip: + text: 'Guide' + children: + - label: Introduction + description: Fully styled and customizable components for Nuxt. + icon: i-lucide-house + tooltip: + text: 'Introduction' + - label: Installation + description: Learn how to install and configure Nuxt UI in your application. + icon: i-lucide-cloud-download + tooltip: + text: 'Installation' + - label: 'Icons' + icon: 'i-lucide-smile' + description: 'You have nothing to do, @nuxt/icon will handle it automatically.' + tooltip: + text: 'Icons' + - label: 'Colors' + icon: 'i-lucide-swatch-book' + description: 'Choose a primary and a neutral color from your Tailwind CSS theme.' + tooltip: + text: 'Colors' + - label: 'Theme' + icon: 'i-lucide-cog' + description: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.' + tooltip: + text: 'Theme' + - label: Composables + icon: i-lucide-database + tooltip: + text: 'Composables' + collapsible: false + open: false + children: + - label: defineShortcuts + icon: i-lucide-file-text + description: Define shortcuts for your application. + to: /composables/define-shortcuts + - label: useOverlay + icon: i-lucide-file-text + description: Display a modal/slideover within your application. + to: /composables/use-overlay + - label: useToast + icon: i-lucide-file-text + description: Display a toast within your application. + to: /composables/use-toast + - label: Components + icon: i-lucide-box + tooltip: + text: 'Components' + to: /components + active: true + collapsible: false + open: false + children: + - label: Link + icon: i-lucide-file-text + description: Use NuxtLink with superpowers. + to: /components/link + - label: Modal + icon: i-lucide-file-text + description: Display a modal within your application. + to: /components/modal + - label: NavigationMenu + icon: i-lucide-file-text + description: Display a list of links. + to: /components/navigation-menu + - label: Pagination + icon: i-lucide-file-text + description: Display a list of pages. + to: /components/pagination + - label: Popover + icon: i-lucide-file-text + description: Display a non-modal dialog that floats around a trigger element. + to: /components/popover + - label: Progress + icon: i-lucide-file-text + description: Show a horizontal bar to indicate task progression. + to: /components/progress + - - label: GitHub + icon: i-simple-icons-github + badge: 3.8k + to: https://github.com/nuxt/ui + target: _blank + tooltip: + text: 'GitHub' + kbds: + - 3.8k + - label: Help + icon: i-lucide-circle-help + disabled: true + tooltip: + text: 'Help' +--- +:: + ### Control active item You can control the active item by using the `default-value` prop or the `v-model` directive with the index of the item. diff --git a/docs/content/3.components/radio-group.md b/docs/content/3.components/radio-group.md index f4b50ec5..c7d5f13d 100644 --- a/docs/content/3.components/radio-group.md +++ b/docs/content/3.components/radio-group.md @@ -46,6 +46,8 @@ You can also pass an array of objects with the following properties: - `description?: string`{lang="ts-type"} - [`value?: string`{lang="ts-type"}](#value-key) - `disabled?: boolean`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, container?: ClassNameValue, base?: ClassNameValue, 'indicator'?: ClassNameValue, wrapper?: ClassNameValue, label?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} ::component-code --- diff --git a/docs/content/3.components/select-menu.md b/docs/content/3.components/select-menu.md index 82f711f5..fbdbcc5a 100644 --- a/docs/content/3.components/select-menu.md +++ b/docs/content/3.components/select-menu.md @@ -57,6 +57,8 @@ You can also pass an array of objects with the following properties: - [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items) - `disabled?: boolean`{lang="ts-type"} - `onSelect?(e: Event): void`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { label?: ClassNameValue, separator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLabel?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue }`{lang="ts-type"} ::component-code --- diff --git a/docs/content/3.components/select.md b/docs/content/3.components/select.md index 2f32b0df..5a642c15 100644 --- a/docs/content/3.components/select.md +++ b/docs/content/3.components/select.md @@ -48,6 +48,8 @@ You can also pass an array of objects with the following properties: - [`avatar?: AvatarProps`{lang="ts-type"}](#with-avatar-in-items) - [`chip?: ChipProps`{lang="ts-type"}](#with-chip-in-items) - `disabled?: boolean`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { label?: ClassNameValue, separator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, itemLeadingAvatarSize?: ClassNameValue, itemLeadingAvatar?: ClassNameValue, itemLeadingChipSize?: ClassNameValue, itemLeadingChip?: ClassNameValue, itemLabel?: ClassNameValue, itemTrailing?: ClassNameValue, itemTrailingIcon?: ClassNameValue }`{lang="ts-type"} ::component-code --- diff --git a/docs/content/3.components/slider.md b/docs/content/3.components/slider.md index b905db80..28784be3 100644 --- a/docs/content/3.components/slider.md +++ b/docs/content/3.components/slider.md @@ -136,6 +136,21 @@ props: --- :: +### Tooltip :badge{label="New" class="align-text-top"} + +Use the `tooltip` prop to display a [Tooltip](/components/tooltip) around the Slider thumbs with the current value. You can set it to `true` for default behavior or pass an object to customize it with any property from the [Tooltip](/components/tooltip#props) component. + +::component-code +--- +ignore: + - defaultValue + - tooltip +props: + defaultValue: 50 + tooltip: true +--- +:: + ### Disabled Use the `disabled` prop to disable the Slider. diff --git a/docs/content/3.components/stepper.md b/docs/content/3.components/stepper.md index ca5d2145..5622d123 100644 --- a/docs/content/3.components/stepper.md +++ b/docs/content/3.components/stepper.md @@ -23,6 +23,8 @@ Use the `items` prop as an array of objects with the following properties: - `value?: string | number`{lang="ts-type"} - `disabled?: boolean`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, container?: ClassNameValue, trigger?: ClassNameValue, indicator?: ClassNameValue, icon?: ClassNameValue, separator?: ClassNameValue, wrapper?: ClassNameValue, title?: ClassNameValue, description?: ClassNameValue }`{lang="ts-type"} ::component-code --- diff --git a/docs/content/3.components/tabs.md b/docs/content/3.components/tabs.md index 99e521f6..3dc8a564 100644 --- a/docs/content/3.components/tabs.md +++ b/docs/content/3.components/tabs.md @@ -23,6 +23,8 @@ Use the `items` prop as an array of objects with the following properties: - `value?: string | number`{lang="ts-type"} - `disabled?: boolean`{lang="ts-type"} - [`slot?: string`{lang="ts-type"}](#with-custom-slot) +- `class?: any`{lang="ts-type"} +- `ui?: { trigger?: ClassNameValue, leadingIcon?: ClassNameValue, leadingAvatar?: ClassNameValue, label?: ClassNameValue, content?: ClassNameValue }`{lang="ts-type"} ::component-code --- @@ -210,10 +212,6 @@ You can control the active item by using the `default-value` prop or the `v-mode :component-example{name="tabs-model-value-example"} -::tip -You can also pass the `value` of one of the items if provided. -:: - ### With content slot Use the `#content` slot to customize the content of each item. diff --git a/docs/content/3.components/tree.md b/docs/content/3.components/tree.md index 95f96001..35fe5aca 100644 --- a/docs/content/3.components/tree.md +++ b/docs/content/3.components/tree.md @@ -26,6 +26,8 @@ Use the `items` prop as an array of objects with the following properties: - `children?: TreeItem[]`{lang="ts-type"} - `onToggle?(e: Event): void`{lang="ts-type"} - `onSelect?(e?: Event): void`{lang="ts-type"} +- `class?: any`{lang="ts-type"} +- `ui?: { item?: ClassNameValue, itemWithChildren?: ClassNameValue, link?: ClassNameValue, linkLeadingIcon?: ClassNameValue, linkLabel?: ClassNameValue, linkTrailing?: ClassNameValue, linkTrailingIcon?: ClassNameValue, listWithChildren?: ClassNameValue }`{lang="ts-type"} ::note A unique identifier is required for each item. The component will use the `value` prop as identifier, falling back to `label` if `value` is not provided. One of these must be provided for the component to work properly. diff --git a/docs/package.json b/docs/package.json index 562159a6..ec60c57c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -3,26 +3,26 @@ "name": "@nuxt/ui-docs", "type": "module", "dependencies": { - "@ai-sdk/vue": "^1.2.11", + "@ai-sdk/vue": "^1.2.12", "@iconify-json/logos": "^1.2.4", - "@iconify-json/lucide": "^1.2.41", - "@iconify-json/simple-icons": "^1.2.33", - "@iconify-json/vscode-icons": "^1.2.20", + "@iconify-json/lucide": "^1.2.43", + "@iconify-json/simple-icons": "^1.2.34", + "@iconify-json/vscode-icons": "^1.2.21", "@nuxt/content": "^3.5.1", "@nuxt/image": "^1.10.0", "@nuxt/ui": "latest", - "@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@a30de4d", + "@nuxt/ui-pro": "^3.1.2", "@nuxthub/core": "^0.8.27", "@nuxtjs/plausible": "^1.2.0", "@octokit/rest": "^21.1.1", "@rollup/plugin-yaml": "^4.1.2", - "@vueuse/integrations": "^13.1.0", - "@vueuse/nuxt": "^13.1.0", + "@vueuse/integrations": "^13.2.0", + "@vueuse/nuxt": "^13.2.0", "ai": "^4.3.15", "capture-website": "^4.2.0", "joi": "^17.13.3", "motion-v": "^1.0.2", - "nuxt": "^3.17.2", + "nuxt": "^3.17.3", "nuxt-component-meta": "^0.11.0", "nuxt-llms": "^0.1.2", "nuxt-og-image": "^5.1.3", @@ -33,11 +33,11 @@ "superstruct": "^2.0.2", "ufo": "^1.6.1", "valibot": "^1.1.0", - "workers-ai-provider": "^0.3.1", + "workers-ai-provider": "^0.4.1", "yup": "^1.6.1", "zod": "^3.24.4" }, "devDependencies": { - "wrangler": "^4.14.4" + "wrangler": "^4.15.1" } } diff --git a/docs/server/plugins/llms.ts b/docs/server/plugins/llms.ts index 6a3d20ae..c5fbdec7 100644 --- a/docs/server/plugins/llms.ts +++ b/docs/server/plugins/llms.ts @@ -351,6 +351,7 @@ export default defineNitroPlugin((nitroApp) => { visitAndReplace(doc, 'component-props', (node) => { const attributes = node[1] as Record const mdcSpecificName = attributes?.name + const isProse = parseBoolean(attributes[':prose']) const finalComponentName = mdcSpecificName ? camelCase(mdcSpecificName) : componentName @@ -358,11 +359,13 @@ export default defineNitroPlugin((nitroApp) => { if (!componentMeta?.props) return + const interfaceName = isProse ? `Prose${pascalCaseName}Props` : `${pascalCaseName}Props` + const interfaceCode = generateTSInterface( - `${pascalCaseName}Props`, + interfaceName, Object.values(componentMeta.props), propItemHandler, - `Props for the ${pascalCaseName} component` + `Props for the ${isProse ? 'Prose' : ''}${pascalCaseName} component` ) replaceNodeWithPre(node, 'ts', interfaceCode) }) diff --git a/package.json b/package.json index d06d12f2..76d9d4fc 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "@nuxt/ui", "description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.", - "version": "3.1.1", - "packageManager": "pnpm@10.10.0", + "version": "3.1.2", + "packageManager": "pnpm@10.11.0", "repository": { "type": "git", "url": "git+https://github.com/nuxt/ui.git" @@ -115,18 +115,18 @@ "@iconify/vue": "^4.3.0", "@internationalized/date": "^3.8.0", "@internationalized/number": "^3.6.1", - "@nuxt/fonts": "^0.11.2", + "@nuxt/fonts": "^0.11.4", "@nuxt/icon": "^1.12.0", - "@nuxt/kit": "^3.17.2", - "@nuxt/schema": "^3.17.2", + "@nuxt/kit": "^3.17.3", + "@nuxt/schema": "^3.17.3", "@nuxtjs/color-mode": "^3.5.2", "@standard-schema/spec": "^1.0.0", - "@tailwindcss/postcss": "^4.1.5", - "@tailwindcss/vite": "^4.1.5", + "@tailwindcss/postcss": "^4.1.6", + "@tailwindcss/vite": "^4.1.6", "@tanstack/vue-table": "^8.21.3", "@unhead/vue": "^2.0.8", - "@vueuse/core": "^13.1.0", - "@vueuse/integrations": "^13.1.0", + "@vueuse/core": "^13.2.0", + "@vueuse/integrations": "^13.2.0", "colortranslator": "^4.1.0", "consola": "^3.4.2", "defu": "^6.1.4", @@ -147,24 +147,24 @@ "reka-ui": "^2.2.1", "scule": "^1.3.0", "tailwind-variants": "^1.0.0", - "tailwindcss": "^4.1.5", + "tailwindcss": "^4.1.6", "tinyglobby": "^0.2.13", - "unplugin": "^2.3.2", + "unplugin": "^2.3.4", "unplugin-auto-import": "^19.2.0", "unplugin-vue-components": "^28.5.0", "vaul-vue": "^0.4.1", "vue-component-type-helpers": "^2.2.10" }, "devDependencies": { - "@nuxt/eslint-config": "^1.3.0", + "@nuxt/eslint-config": "^1.3.1", "@nuxt/module-builder": "^1.0.1", "@nuxt/test-utils": "^3.18.0", "@release-it/conventional-changelog": "^10.0.1", "@vue/test-utils": "^2.4.6", "embla-carousel": "^8.6.0", "eslint": "^9.26.0", - "happy-dom": "^17.4.6", - "nuxt": "^3.17.2", + "happy-dom": "^17.4.7", + "nuxt": "^3.17.3", "release-it": "^19.0.2", "vitest": "^3.1.3", "vitest-environment-nuxt": "^1.0.1", @@ -209,7 +209,7 @@ "debug": "4.3.7", "rollup": "4.34.9", "unimport": "4.1.1", - "unplugin": "^2.3.2" + "unplugin": "^2.3.4" }, "pnpm": { "onlyBuiltDependencies": [ diff --git a/playground-vue/package.json b/playground-vue/package.json index 7f4b7d1b..e264ce60 100644 --- a/playground-vue/package.json +++ b/playground-vue/package.json @@ -11,12 +11,12 @@ }, "dependencies": { "@nuxt/ui": "latest", - "vue": "^3.5.13", + "vue": "^3.5.14", "vue-router": "^4.5.1", "zod": "^3.24.4" }, "devDependencies": { - "@vitejs/plugin-vue": "^5.2.3", + "@vitejs/plugin-vue": "^5.2.4", "typescript": "^5.8.3", "vite": "^6.3.5", "vue-tsc": "^2.2.10" diff --git a/playground/app/pages/components/badge.vue b/playground/app/pages/components/badge.vue index 8694c259..b85227ee 100644 --- a/playground/app/pages/components/badge.vue +++ b/playground/app/pages/components/badge.vue @@ -36,14 +36,27 @@ const variants = Object.keys(theme.variants.variant) as Array -
+
-
+
-
+
+
+ +
+
+ +
diff --git a/playground/app/pages/components/checkbox-group.vue b/playground/app/pages/components/checkbox-group.vue index edac0bb2..ddf0fef6 100644 --- a/playground/app/pages/components/checkbox-group.vue +++ b/playground/app/pages/components/checkbox-group.vue @@ -1,9 +1,8 @@ @@ -72,7 +75,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.badge || {}) - + {{ label }} diff --git a/src/runtime/components/Breadcrumb.vue b/src/runtime/components/Breadcrumb.vue index f2a309ba..3ba83c99 100644 --- a/src/runtime/components/Breadcrumb.vue +++ b/src/runtime/components/Breadcrumb.vue @@ -15,6 +15,8 @@ export interface BreadcrumbItem extends Omit { icon?: string avatar?: AvatarProps slot?: string + class?: any + ui?: Pick [key: string]: any } @@ -84,16 +86,16 @@ const ui = computed(() => tv({ extend: tv(theme), ...(appConfig.ui?.breadcrumb |
    diff --git a/src/runtime/components/Button.vue b/src/runtime/components/Button.vue index 3e14bb68..343438e2 100644 --- a/src/runtime/components/Button.vue +++ b/src/runtime/components/Button.vue @@ -1,9 +1,8 @@ -