Skip to content

Releases: nuxt/ui

v4.5.1

02 Mar 16:31
v4.5.1
6f3a255

Choose a tag to compare

🐛 Bug Fixes

  • components: improve arrow styling with stroke-default and fill-bg (#6095) (0e9198e)
  • components: improve slots return types and tests (#6109) (7d1e863)
  • components: prevent transformUI from mutating cached useComponentUI value (286738a), closes #6104 #4387
  • ContentToc: add relative positioning to content slot (fcdb231), closes #6117
  • ContentToc: use rem units for indicator size calculation (d631853)
  • NavigationMenu: prevent navigation when clicking trailing area in horizontal orientation (8f84c90), closes #6083
  • Page: make slot presence reactive for variant computation (082ea41)
  • types: resolve isArrayOfArray type return (#6097) (04292d9)
  • useResizable: use function declaration to prevent false auto-import (c22ecf4)

👋 New Contributors

Full Changelog: v4.5.0...v4.5.1

v4.5.0

24 Feb 13:22
v4.5.0
3fa54f5

Choose a tag to compare

✨ Highlights

🎨 New Theme component

The Theme component lets you override the theme of all child components without modifying each one individually. Pass an object to the ui prop where keys are component names and values are their slot class overrides:

<UTheme
  :ui="{
    button: {
      base: 'rounded-full'
    },
    input: {
      base: 'rounded-full'
    }
  }"
>
  <UButton label="Button" color="neutral" variant="outline" />
  <UInput placeholder="Search..." />
</UTheme>

The Theme component doesn't render any HTML element. It uses Vue's provide / inject under the hood, so overrides propagate through the entire component tree regardless of nesting depth. Theme components can be nested (innermost wins) and the ui prop on individual components always takes priority.

🌈 New neutral colors

Thanks to Tailwind CSS v4.2, four new neutral color options are now available: taupe, mauve, mist and olive. Configure them through the ui.neutral option in your app.config.ts.

🚫 Duplicate toast prevention

The Toaster now automatically prevents duplicate toasts and displays a pulse animation when a duplicate is triggered, providing a cleaner notification experience: https://ui.nuxt.com/docs/components/toast#deduplicated-toasts

1oUPxZsXIbjXRiJt.mp4

🚀 Features

  • DashboardSidebar/Header: add autoClose prop (#6089) (2663deb)
  • EditorDragHandle: proxy nested / nestedOptions props and emit hover event (#5960) (ed60193)
  • Form: add HTML5 validation to programmatic submit (#6002) (ed552fc)
  • module: add support for taupe / mauve / mist / olive neutral colors (#6081) (bc49d3f)
  • NavigationMenu: allow tooltip usage in horizontal orientation (#5682) (f46b504)
  • NavigationMenu: handle chip in items (#6064) (401a2c0)
  • ScrollArea: add skipMeasurement virtualize option (#5721) (548b711)
  • Select/SelectMenu: add hover effects on outline and subtle variants (94b0c31)
  • Theme: new component (#4387) (c97047d)
  • Toaster: prevent duplicate toasts and add pulse animation (3f6581a)

🐛 Bug Fixes

  • BlogPost/ChangelogVersion: use ImgHTMLAttributes type for image prop (#6007) (0185856)
  • ChatMessages: allow message props to override role defaults (#6000) (f64ec17)
  • ChatMessages: prevent flash at top before scrolling to bottom on mount (4bdcb83)
  • Checkbox/Switch: prevent data-state conflict when used inside Tooltip (2bb1a8b), closes #3599
  • CheckboxGroup: update update:modelValue emit type (#5927) (64d2e88)
  • ColorModeImage: add baseURL support for public paths (#6006) (db510f3)
  • components: add fixed prop to prevent responsive text size reduction (#6074) (8f5f44c)
  • components: nullable and optional type support (#6060) (cd3432b)
  • components: prevent iOS auto-zoom on input fields with font-size below 16px (#6040) (1262016)
  • ContentNavigation: pass nested child data to slots (#6043) (e67f77e)
  • defineShortcuts: add alt key guard (#6020) (8451f45)
  • defineShortcuts: allow shifted special character shortcuts (08facc0)
  • Drawer/Modal/Popover/Slideover: prevent unexpected close on touch when interacting with other overlays (#5695) (e2c038c)
  • Editor: handle placeholder in RTL mode (#5977) (3cc16e3)
  • EditorMentionMenu: use char prop as mention prefix instead of always @ (0b9b097), closes #6035
  • EditorToolbar: proxy size prop to dropdown menu (8f8d989)
  • InputMenu/InputNumber/SelectMenu: proxy size to buttons (1ec1698), closes #5958
  • InputMenu/Select/SelectMenu: exclude cosmetic items from model value type (#6044) (22cf1ea)
  • InputMenu/SelectMenu: sort filtered items by match relevance (058c66b), closes #4672
  • InputMenu: prevent focus on trailing button (88073b6)
  • module: update icon cssLayer option from components to base (#6076) (e8bc322)
  • NavigationMenu: allow clicking trailing slot in horizontal orientation (7f9996f), closes #5192 #6083
  • NavigationMenu: unique auto-generated item values for grouped items (7b317d9)
  • PricingPlan: truncate title (#6041) (8e86c51)
  • Select: remove useless by prop (14dceaf)
  • Table: improve perfs with shallowRef when watch deep is disabled (#6023) (bc06ce2)
  • Toast: allow update to keep toast open and reset duration (82afa0a)
  • Toast: improve animation smoothness (#6065) (ee2c0a5)
  • types: improve DotPathKeys accuracy and GetItemKeys performance (#6077) (6f7af3e)
  • useEditorMenu: rank filtered results by relevance (f53484a)

🌐 Locales

👋 New Contributors

Read more

v4.4.0

21 Jan 14:21
v4.4.0
59707ff

Choose a tag to compare

🚀 Features

  • Calendar: add weekNumbers prop (#4555) (7a1a71b)
  • ChangelogVersions: handle scroll options in indicator prop (#5257) (6a925cd)
  • CommandPalette/InputMenu/SelectMenu/Tree: handle virtualizer estimateSize as function (#5748) (d51b424)
  • CommandPalette: add input prop (#5736) (12052e8)
  • CommandPalette: add size prop (#5878) (3ae04c6)
  • components: add by prop (#5906) (36cd5e5)
  • components: add valueKey prop (#5905) (55646ea)
  • Editor: add placeholder.mode prop (d90acb3), closes #5785
  • Editor: add size prop in menus (#5889) (571d50d)
  • Editor: add taskList handler (#5837) (db04197)
  • Editor: add support for code inside links (2ed2d5d)
  • Editor: handle boolean in image and mention props (b6fa83a), closes #5820
  • EditorMentionMenu: handle async search with ignoreFilter prop (#5880) (f8d1883)
  • InputMenu/Select/SelectMenu: expose viewportRef for infinite scroll (#5836) (f4a945c)
  • InputMenu/SelectMenu: add clear prop (#5643) (ec6b8ec)
  • Link: support custom navigate function in vue (#5860) (f51e58a)
  • ProseTd/ProseTh: handle align prop (859390e), closes #5795
  • Timeline/Stepper: add wrapper slot and fix dynamic slot conditions (#5868) (8610d4d)
  • Timeline: add select event (#5826) (8e431be)

🐛 Bug Fixes

  • Banner: isolate banner visibility using per-instance CSS variables (#5751) (c7332eb)
  • Banner: prevent XSS via id prop injection (4e334a0)
  • CommandPalette/ContextMenu/DropdownMenu: keyboard selection on link items (3f5bdb3)
  • CommandPalette: prevent XSS in search highlight (e12ceb6)
  • ContentSurround: align next link to right on tablet without prev (#5833) (b3adccc)
  • defineShortcuts: check shift modifier for special character shortcuts (bd344d7), closes #5911
  • Editor: set contentType when updating value (c37d6f7), closes #5709
  • Editor: support all heading levels by default (3046c3e)
  • EditorToolbar: prevent onClick from being called twice on items (cbed0cc), closes #5784
  • EditorToolbar: prevent disabled dropdown when items have no kind (d473f63)
  • Error/Main: render as main instead of div (6ccb1f5)
  • FileUpload: emit null when clearing file (#5892) (1d9a2fd)
  • FileUpload: keep input visible when preview is disabled with multiple files (597ac29), closes #5875
  • locale: improve cs and sk terminology for correct inflection (#5789) (af6f288)
  • module: only override primary color and md size default variants (f422de8)
  • ProseCodeTree: prevent infinite update loop with expandAll prop (c79cb77), closes #5828
  • useOverlay: refine close event argument extraction (#5775) (182af20)

👋 New Contributors

Full Changelog: v4.3.0...v4.4.0

v4.3.0

17 Dec 16:07
v4.3.0
686a08c

Choose a tag to compare

✨ Highlights

📝 New Editor components

We're introducing a suite of 6 new components to build rich text editors, powered by TipTap:

  • Editor: The root component supporting JSON, HTML, and Markdown content types.
  • EditorToolbar: A customizable toolbar with formatting actions, link editing, and extensible item groups.
  • EditorSuggestionMenu: A command menu (/) to insert headings, lists, code blocks, images, and more.
  • EditorMentionMenu: A mention menu (@) to reference users or other entities.
  • EditorEmojiMenu: An emoji picker (:) to insert emojis inline.
  • EditorDragHandle: A drag handle to reorder blocks with a dropdown menu for block actions.

The Editor is fully extensible through TipTap's extension system and exposes the editor instance for advanced use cases.

We've also released a new Editor template that showcases all the Editor components in a production-ready setup with real-time collaboration via PartyKit and AI autocompletion using AI SDK and Vercel AI Gateway.

nuxt-ui-editor.mp4

📜 New ScrollArea component

The ScrollArea component provides a flexible scroll container with built-in virtualization support through TanStack Virtual.

CleanShot.2025-12-17.at.16.38.52.mp4

🚀 Features

🐛 Bug Fixes

  • BlogPost/ChangelogVersion/PageFeature/User: allow tab focus (47d93d3), closes #5635
  • Carousel: consistent stopOnInteraction behavior (#5489) (36a7861)
  • Carousel: improve dots focus styles (cc90fb8)
  • ColorModeButton: improve icon class merging (2ce9af2)
  • ContentSearch/DasboardSearch: set full height on mobile to prevent jump (70317e5)
  • DashboardResizeHandle: allow hover over panel with z-index (07147f1)
  • FormField: hide error if error prop is false (#5599) (6b7fe25)
  • InputDate/InputTime: add missing field group variant (#5596) (cb3cec2)
  • PageCard/PageCTA/PageSection: handle reverse prop under lg screens (#5545) (60b430c)
  • ProseA/ProseCallout/ProseCard: improve focus styles (df5f8c2)
  • Slider: add aria-label to thumb (#5313) (f99ec46)
  • Table: only forward necessary props (#5527) (b0b209e)
  • Table: properly position pinned columns based on size (e885b0e), closes #4721 #3927

🌐 Locales

👋 New Contributors

Full Changelog: v4.2.1...v4.3.0

v4.2.1

21 Nov 14:17
v4.2.1
bb7df30

Choose a tag to compare

🐛 Bug Fixes

  • ChatPromptSubmit: proxy event to stop and reload emits (#5400) 736a547
  • ColorModeButton: missing icon import 5f30ccf, closes #5486
  • Icon: improve name type (#5498) b654a77
  • Link: define NuxtLinkProps instead of importing from #app (#5491) da8daaa
  • Link: ensure consistency across Nuxt, Vue and Inertia a9ed10d, closes #5012
  • module: put back #build/ui.css alias (#5499) d9aadc7

👋 New Contributors

Full Changelog: v4.2.0...v4.2.1

v4.2.0

18 Nov 17:12
v4.2.0
8cb7871

Choose a tag to compare

✨ Highlights

📅 New InputDate & InputTime components

Two new components are now available to handle date and time inputs: InputDate (#5387) and InputTime (#5302).

<script setup lang="ts">
const date = ref(new CalendarDate(2022, 2, 3))
const time = ref(new Time(12, 30, 0))
</script>

<template>
  <UInputDate v-model="date" />

  <UInputTime v-model="time" />
</template>

🎨 Tailwind CSS prefix

You can now use Tailwind CSS's prefix option (#5341) to prefix all utilities generated by Nuxt UI and avoid conflicts with your own styles or other libraries.

export default defineNuxtConfig({
  modules: ['@nuxt/ui'],
  css: ['~/assets/css/main.css'],
  ui: {
    theme: {
      prefix: 'tw'
    }
  }
})
@import "tailwindcss" prefix(tw);
@import "@nuxt/ui";

🚨 Breaking Changes

Exposed refs now consistently return the HTML element directly instead of the component instance. This affects InputMenu, InputNumber, InputTags, Select, and SelectMenu.

<script setup lang="ts">
const inputMenu = useTemplateRef('inputMenu')

- inputMenu.value.inputRef.$el // Component instance
+ inputMenu.value.inputRef // HTML element directly
</script>
  • module: properly export composables from module (cb25902)

There was an issue with how composables were exported, you no longer need the .js extension:

<script setup lang="ts">
- import { useToast } from '@nuxt/ui/composables/useToast.js'
+ import { useToast } from '@nuxt/ui/composables/useToast'
// or
+ import { useToast } from '@nuxt/ui/composables'
</script>

The Vite plugin now properly generates theme files as real files instead of incorrectly shipping them inside .nuxt/ on NPM. This ensures the #build/ui.css import and custom theme configuration work correctly.

When using the Vite plugin, update your tsconfig.node.json alias:

{
  "compilerOptions": {
    "paths": {
      "#build/ui": [
-       "./node_modules/@nuxt/ui/.nuxt/ui"
+       "./node_modules/.nuxt-ui/ui"
      ]
    }
  }
}

🚀 Features

🐛 Bug Fixes

  • AuthForm: ensure header is shown with leading slot (#5405) (b61127a)
  • AuthForm: use password input id for aria-controls (#5312) (55ea9be)
  • ChatPrompt: proxy disabled prop (a8f2156), closes #5300
  • CheckboxGroup/RadioGroup/Switch: consistent disabled styles (ddd8faf), closes #5391
  • ColorModeButton: use css to display color mode icon (#5394) (1d1c638)
  • CommandPalette/ContentSearch: improve performances and filtering logic (#5433) (e751b37)
  • components: calc virtualizer estimateSize based on item description (56ae8e7)
  • components: consistent exposed refs (#5385) (fce2df4)
  • components: remove locale / dir props proxy (#5432) (a6efa7a)
  • ContentNavigation/NavigationMenu/Tabs: ensure proper badge display (e5c11e6)
  • ContentSearchButton/DashboardSearchButton: hide label and trailing with css when collapsed (3e72bf8)
  • FileUpload: ensure native validation works with required (#5358) (eb491e1)
  • Form: refine nested prop type handling and simplify logic (#5360) (8d5c26f)
  • inertia: set serverRendered dynamically to prevent SSR crash (#5396) (c0da1b2)
  • Input/InputNumber/Textarea: make modelModifiers generic (#5361) (5c347af)
  • InputMenu: prevent change event when selecting create item (418c87b), closes #4664
  • Link: partial extend for vue-router and inertia (637ef58)
  • Marquee: move keyframes into global css (1e6242e)
  • module: detect lazy components when using experimental.componentDetection (5a5ac45)
  • module: properly export composables from module (cb25902), closes #5370
  • module: scan layers when using experimental.componentDetection (9872740), closes #5389
  • NavigationMenu: hide label and trailing with css when collapsed (f004031), closes #4254
  • NavigationMenu: proxy modelValue / defaultValue in vertical orientation (cffaaaa), closes #5392
  • ProseCallout: add inline-block class to icon (#5317) (fc36f69)
  • RadioGroup: update update:modelValue emit type (#5349) (4cb0638)
  • Table: apply styles to th based on column meta (#5418) (620defa)
  • types: export missing utils types (#5448) (5f0a107)
  • vite: write theme templates (#5355) (411ebcc)
  • vue: check import.meta.env.SSR to support vite-ssg (#5347) (8f38c04)

🌐 Locales

👋 New Contributors

Full Changelog: v4.1.0...v4.2.0

v4.1.0

23 Oct 14:22
v4.1.0
65d065c

Choose a tag to compare

✨ Highlights

📦 New Empty Component

A new Empty component is now available to display empty states when there's no content to show (#5200).

CleanShot 2025-10-23 at 16 17 10@2x

⚡️ Component Virtualization

Use the virtualize prop to enable virtualization for large datasets on CommandPalette, InputMenu, SelectMenu, Table and Tree components (#5162).

<template>
  <UTable :data="data" :columns="columns" virtualize />
</template>

🎯 Experimental Component Detection

Enable the new experimental.componentDetection option in your nuxt.config.ts to automatically detect which components are actually used and only generate the necessary CSS for those components including their dependencies (#5222).

export default defineNuxtConfig({
  modules: ['@nuxt/ui'],
  css: ['~/assets/css/main.css'],
  ui: {
    experimental: {
      componentDetection: true
    }
  }
})

🚨 Breaking Changes

We apologize for these small breaking changes. With 110+ components in the library, we occasionally need to make corrections to maintain consistency and quality. We aim to minimize breaking changes, but sometimes they're necessary to improve the developer experience in the long run.

  • CommandPalette: add children-icon prop to use trailing-icon in input (#4397) (edda8a6)

The trailing-icon prop is now used for the Input, and a new children-icon prop has been added to customize the icon for child items:

<template>
- <UCommandPalette :trailing-icon="i-lucide-arrow-right" />
+ <UCommandPalette :children-icon="i-lucide-arrow-right" />
</template>
  • Table: consistent args order in select event (9526a1b)

The @select event now passes arguments in a consistent order: (event, row) instead of (row, event):

<template>
- <UTable @select="(row, e) => {}" />
+ <UTable @select="(e, row) => {}" />
</template>

🚀 Features

  • Calendar: add variant prop (#5138) (bb4f42c)
  • CommandPalette: add children-icon prop to use trailing-icon in input (#4397) (edda8a6)
  • CommandPalette: preserve group order in search results (#5197) (38647a2)
  • components: expose ui in slot props where used (#5207) (63c0a5f)
  • components: handle description in items (#5193) (70cf05f)
  • components: implement virtualization (#5162) (c744d6f)
  • Empty: new component (#5200) (6a6de8d)
  • InputNumber: handle increment / decrement as booleans (#4805) (1858908)
  • module: add experimental.componentDetection option (#5222) (f80474c)
  • Popover: add close method in slots (#5176) (53c6508)
  • ProseImg: improve zoom transition (#4998) (d502c30)
  • Tree: add global event handlers and checkbox example (#5195) (84f87a5)
  • Tree: expose $el for drag and drop example (#5239) (fcf6117)
  • Tree: provide additional slot props (#5194) (c8b01c9)
  • useToast: handle max global configuration (#5068) (e4c6113)

🐛 Bug Fixes

  • BlogPost/ChangelogVersion: allow any attrs inimage prop (9632f99), closes #5276
  • Breadcrumb: handle active in items (cc8cbf3), closes #4771
  • ChatMessage: ensure left side takes full width (af8c023)
  • ChatMessage: only apply max-width on right side (a85b0e1)
  • ChatMessage: reset top and bottom margin (8f9176c)
  • ChatMessages: allow user scroll with should-auto-scroll (#5252) (db73765)
  • ChatMessages: define user & assistant ui prop type (#5234) (240bc1a)
  • CodeTree/Tree: restore item wrapper with presentation role (70aaf4a), closes #4945
  • components: add missing ui prop in prose proxy components (#5205) (d1afe90)
  • ContextMenu/DropdownMenu: allow item content class override (ab5032d), closes #5277
  • Drawer/Modal/Slideover: remove close autofocus prevent (#5191) (8099440)
  • Error/Main: render as div instead of main (2a09ac0), closes #4955
  • FileUpload: handle disabling file delete button (08c30cf), closes #5249
  • FileUpload: stuck focus while tabbing (#5128) (2477d44)
  • FileUpload: use native img element for blob URLs preview (69906bc), closes #5121 #4824
  • InputMenu/SelectMenu: enrich reusable template item prop (63074d6)
  • InputMenu: ensure tag can be removed when number (028538a)
  • Kbd: return original value and use uppercase class (#5238) (4095c9a)
  • NavigationMenu: display trailing slot when badge not undefined (f24204f), closes #4670
  • Table: consistent args order in select event (9526a1b)
  • Table: expose $el instead of rootRef (c019f8f), closes #5230 #5162

🌐 Locales

Read more

v3.3.7

23 Oct 15:22
v3.3.7
33280e9

Choose a tag to compare

🐛 Bug Fixes

  • FileUpload: handle disabling file delete button (8e506c4), closes #5249
  • FileUpload: stuck focus while tabbing (#5128) (1752f21)
  • NavigationMenu: display trailing slot when badge not undefined (ee9e02a), closes #4670

Full Changelog: v3.3.6...v3.3.7

v3.3.6

03 Oct 14:45
v3.3.6
2cceffc

Choose a tag to compare

🐛 Bug Fixes

  • App: allow global portal disabling (#5111) (43c119f)
  • Carousel: ensure plugins init after client-side navigation (#5117) (0f7a1b7)
  • Carousel: invert arrow keys in RTL direction (#5072) (27cb2b6)
  • Drawer: prevent unwanted close when dismissible is false (#5085) (027c06a)
  • Drawer: use full height/width for snapPoints (#5041) (8f21339)
  • Pagination: make ellipsis non-interactive (#5081) (ab168af)
  • Table: empty cell value causing hydration errors (#5069) (cd2662a)
  • useKbd: update escape key from to Esc (#5076) (27aa80c)

Full Changelog: v3.3.5...v3.3.6

v4.0.1

02 Oct 15:50
v4.0.1
ddc3b10

Choose a tag to compare

🐛 Bug Fixes

  • App: allow global portal disabling (#5111) (7659fa1)
  • AuthForm: export type with proper inference for field-specific props (#5106) (344f269)
  • Avatar: remove redundant img role (066b8a1), closes #5044
  • Carousel: ensure plugins init after client-side navigation (#5117) (21fbe63)
  • Carousel: invert arrow keys in RTL direction (#5072) (fde53ee)
  • ChatMessages: ensure content is render before scrolling (0db622a)
  • ChatMessages: watch deep to handle streaming with parts (ff67fa3)
  • components: add missing data-orientation for consistency (a9fe7c6)
  • ContentNavigation: improve path matching and recursion with default-open (22ee075), closes #5112
  • ContentSearch/DashboardSearch: proxy modal props to support fullscreen (095a0c1)
  • DashboardPanel/DashboardSidebar: handle RTL mode (#5109) (fface35)
  • Drawer: prevent unwanted close when dismissible is false (#5085) (2abdc21)
  • Drawer: use full height/width for snapPoints (#5041) (b145768)
  • locale: improve ckb translations (#5079) (3ee3a5e)
  • locale: improve typography with ellipsis (#5052) (391f9f5)
  • Pagination: make ellipsis non-interactive (#5081) (62f64cc)
  • Table: empty cell value causing hydration errors (#5069) (44a38ea)
  • unplugin: handle components resolution with subpath (31db8d9)
  • useKbd: update escape key from to Esc (#5076) (64d1589)
  • vue: align useCookie stub with nuxt's default value handling (#5089) (f531807)

👋 New Contributors

Full Changelog: v4.0.0...v4.0.1