Migration - Radix Vue to Reka UI
Installation
First and foremost, you need to install the latest reka-ui.
$ npm add reka-uiCongratulation! 🎉 Now that you've installed the above package, let's perform the migration! The first 2 steps are relatively simple. Just do a global search and replace for the following changes.
Import Statement Changes
The primary change in imports is replacing radix-vue with reka-ui.
<script setup lang="ts">
import { TooltipPortal, TooltipRoot, TooltipTrigger } from 'radix-vue'
import { TooltipPortal, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>Naming Convention Changes
CSS variable and data attributes names have been updated to use the reka prefix instead of radix.
--radix-accordion-content-width: 300px;
--reka-accordion-content-width: 300px;
[data-radix-collection-item] {}
[data-reka-collection-item] {} Component Breaking Changes
Combobox
Remove
filter-functionprops -Comboboxhas been refactored and improved to support better custom filtering. Read more.vue<template> <ComboboxRoot :filter-function="customFilter" /> </template>Move
displayValueprops from Root to Inputvue<template> <ComboboxRoot v-model:search-term="search" :display-value="(v) => v.name" /> <ComboboxRoot> <ComboboxInput v-model="search" :display-value="(v) => v.name" /> </ComboboxRoot> </template>
Arrow
- Improve arrow polygon - Change the svg polygon to allow better styling.
Form component
- Rename controlled state to
v-model- Replacev-model:checked,v-model:pressedwith more familiar API for form component.
<template>
<CheckboxRoot v-model:checked="value" />
<CheckboxRoot v-model="value" />
</template>- Reposition
VisuallyHidden- Previously,VisuallyHiddenwere positioned at the root node, causing style scoped to not be applied.
Menu CheckboxItem
- Similar to the changes in form component, the API for binding
CheckboxItemhas been changed fromv-model:checkedtov-model.
<template>
<DropdownMenuCheckboxItem v-model:checked="value" />
<DropdownMenuCheckboxItem v-model="value" />
<DropdownMenuCheckboxItem checked />
<DropdownMenuCheckboxItem :model-value="true" />
</template>Pagination
Required
itemsPerPageprop - Instead of defaultitemsPerPagevalue, now it is required as to provide a more explicit hint about the page size.vue<template> <PaginationRoot :items-per-page="10" /> </template>
Calendar
Remove deprecated step prop - Use
prevPage/nextPageprops for greater control.vue<script setup lang="ts"> function pagingFunc(date: DateValue, sign: -1 | 1) { if (sign === -1) return date.subtract({ years: 1 }) return date.add({ years: 1 }) } </script> <template> <CalendarPrev step="year" /> <CalendarPrev :prev-page="(date: DateValue) => pagingFunc(date, -1)" /> <CalendarNext step="year" /> <CalendarNext :next-page="(date: DateValue) => pagingFunc(date, 1)" /> </template>
Select
SelectValueno longer render teleported element - Previous implementation ofSelectValuewill render the selectedSelectItemvia teleporting fragment. This causes SSR flickering, and it is unnecessarily computation.vue<template> <SelectValue> <!-- render the content similar to `SelectItem` --> </SelectValue> </template>
Presence
To have better supports for SSR content, we also modify the logic around the usage of forceMount for component that utilize Presence:
AccordionCollapsibleTabsNavigationMenu
forceMount will now render the component eventhough the state is inactive. You are now required to handle the visibility logic of the component manually.
<template>
<TabsRoot
v-slot="{ modelValue }"
default-value="tab1"
>
<TabsContent
value="tab1"
force-mount
:hidden="modelValue !== 'tab1'"
>
…
</TabsContent>
<TabsContent
value="tab2"
force-mount
:hidden="modelValue !== 'tab2'"
>
…
</TabsContent>
</TabsRoot>
</template>For Nuxt module users
If you are using Nuxt, you need to update your module import.
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'radix-vue/nuxt' <!-- [!code --] -->
'reka-ui/nuxt' <!-- [!code ++] -->
],
})