✨ Highlights
🌟 InputRating component
A new InputRating component lets you display and collect ratings, with support for half-steps, custom length, clearing, hover preview and any icon:
<script setup lang="ts">
const value = shallowRef(3.5)
</script>
<template>
<UInputRating v-model="value" :step="0.5" hoverable />
</template>📦 Bundled, offline-ready icons
Nuxt UI now embeds the icons it uses into your build, so they render straight away during SSR and work fully offline instead of being fetched from the Iconify API at runtime. As long as the collection is installed locally, this happens automatically for Nuxt UI's own icons (the lucide collection by default), on both Nuxt and pure Vue/Vite.
On Nuxt this rides on @nuxt/icon's existing client bundle. On Vue the @nuxt/ui/vite plugin gains an icon.clientBundle option to bring the same bundling to Vite, either by listing icons or by scanning your source. This is powered by the standalone Vite plugin and utils added in @nuxt/icon v2.3.0:
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
ui({
icon: {
clientBundle: {
// list them explicitly...
icons: ['lucide:heart', 'simple-icons:github'],
// ...or scan your whole app
scan: true
}
}
})
]
})Tip
Install each collection you use with @iconify-json/{collection_name} so its icons can be bundled. See the Icons integration for the details.
♻️ Keep overlay state with unmountOnHide
The Modal and Slideover components now accept the unmountOnHide prop. Set it to false to keep their content mounted while closed so form state, scroll position and expensive children survive open/close cycles:
<template>
<UModal :unmount-on-hide="false">
<UButton label="Open" />
<template #content>
<!-- kept alive when the modal is closed -->
</template>
</UModal>
</template>🚀 Features
- ChatPrompt: add body slot and focus highlight (#6709) (123184b)
- ChatTool: add
actionsprop for tool approval (#6694) (1a3a9dc) - ContentSearch/DashboardSearch: support
unmountOnHideprop (#6523) (f03f98b) - ContentToc: scroll list independently and center active link (#6697) (64b9f7d)
- Drawer: add
closeandcloseIconprops (#6669) (53e88a4) - Editor: allow disabling starter kit for plain text (#6713) (76d613c)
- Empty: add
loadingandloadingIconprops (#6707) (86cd25c) - InputRating: new component (#5757) (cba2c2c)
- Modal/Slideover: support
unmountOnHideprop (#6626) (4deb61b), closes #5839 #3605 - module: pre-bundle used icons into
@nuxt/iconclient bundle (#6633) (8d46034) - Popover: support
enableTouchprop (#6626) (54125f3), closes #2346 - Prompt: add
claudeaction (#6693) (7bdcb13) - prose: configurable heading anchors and copy button (#6735) (f419731)
- ScrollArea: add
getScrollElementvirtualize option (#6650) (a84de85) - Table: add
getScrollElementvirtualize option (#6657) (7e6d0f7) - unplugin: pre-bundle used icons into the Vue/Vite build (#6635) (dcf7cbc)
🐛 Bug Fixes
- AuthForm: track password visibility per field (#6638) (0faeb92)
- BlogPost/ChangelogVersion: format date in UTC to prevent hydration mismatch (#6722) (fe5bb23)
- Button: allow inline event handlers with non-void return types (#6668) (269080a)
- Carousel: prevent reset when plugin props use inline objects (f41d11e), closes #6221
- ChatMessages: re-evaluate streaming indicator on each render (#6673) (5c986dd)
- components: forward
$attrsto root element whentoprop is absent (#6628) (d3b5f1d) - components: forward
data-slotto component root (#6643) (c9c5232) - components: respect
prefers-reduced-motionin animations (#6723) (f951529) - ContentNavigation: key items by identity to prevent leading icon flash (#6640) (09fb52b)
- defineShortcuts: add missing
arrowdownto shiftable keys (#6702) (2128414) - defineShortcuts: defer standalone shortcuts that prefix a chain (#6703) (76ee176)
- Editor: prevent suggestion menu blinking on keystroke (#6712) (7e6d8b0)
- FileUpload: add
aria-disabledattribute when disabled (#6653) (c3b2996) - inertia: make
useRoute().fullPathreactive across navigations (#6696) (c256997) - Link: apply
relprop to internal links (#6677) (276302e) - Link: fall back to original path when
localePathfails (#6637) (906e8fd) - LocaleSelect: add missing keys in emoji mapping (#6629) (fab73ab)
- module: avoid unhead v2-only
hookOncein colors plugin (#6658) (e4ca579) - SelectMenu/InputMenu: only re-highlight first item with
create-item(#6689) (a71dece) - Separator: forward fall-through attributes to root (#6641) (88baabc)
- theme: use logical properties for RTL (#6724) (3179012)
- types: type prose components in app config (#6711) (d56e39a)
- useComponentProps: let app config
defaultVariantsoverridewithDefaults(#6686) (f5e58fb) - useFileUpload: keep dropzone type filter reactive to accept (#6699) (000aba4)
- useResizable: recover from corrupted persisted storage (#6704) (4c60745)
- useResizable: share resize logic between mouse and touch (#6705) (730a54c)
- useScrollspy: unobserve previous headings on update (#6700) (5944067)
- useToast: dedupe duplicate ids and handle max of 0 (#6698) (71c623b)
🔥 Performances
- components: drop the redundant inner in component extend (#6647) (3bf1a92)
- module: declare
sideEffectsfor barrel tree-shaking (#6729) (2cc2849) - types: decouple
useComponentPropsfrom the component-types barrel (#6648) (6576fb8) - types: import cross-component types from source, not the barrel (#6646) (7eab4bc)
- vue: skip rewriting unchanged templates (#6730) (14b6001)
❤️ Contributors
- @benjamincanac
- @solidusite
- @sandros94
- @Dtem4ik
- @mikenewbon
- @innocenzi
- @faizkhairi
- @reslear
- @syazany
- @yamachi4416
- @martipops
- @typed-sigterm
Full Changelog: v4.9.0...v4.10.0