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 default- itemsPerPagevalue, 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 of- SelectValuewill render the selected- SelectItemvia 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:
- Accordion
- Collapsible
- Tabs
- NavigationMenu
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 ++] -->
 ],
})