Reka UI - Vue Headless Components

2.9.6 · active · verified Sun Apr 19

Reka UI is a comprehensive Vue 3 port of the popular Radix UI Primitives, offering an unstyled, accessible, and highly customizable set of headless UI components. It empowers developers to build robust web applications with a strong focus on delivering excellent accessibility out-of-the-box and maximum flexibility for custom styling. The library is actively maintained, currently at version 2.9.6, and follows a frequent release cadence with regular bug fixes and feature additions, as seen in the recent v2.9.x patches and v2.9.0 feature release. It provides full TypeScript support, making it an ideal choice for TypeScript-first Vue projects. Its key differentiators include its headless architecture, strict adherence to WAI-ARIA standards, and a rich suite of Vue-specific components adapted from the battle-tested Radix UI primitives.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates the basic usage of a Reka Dialog component, including opening, content, and closing. It highlights the headless nature by showing required custom styling.

<!-- src/components/MyDialog.vue -->
<script setup lang="ts">
import { ref } from 'vue';
import { RekaButton, RekaDialogRoot, RekaDialogTrigger, RekaDialogContent, RekaDialogTitle, RekaDialogDescription } from 'reka-ui';

const isDialogOpen = ref(false);
</script>

<template>
  <RekaDialogRoot v-model:open="isDialogOpen">
    <RekaDialogTrigger as-child>
      <RekaButton class="my-custom-button">Open Dialog</RekaButton>
    </RekaDialogTrigger>
    <Teleport to="body">
      <RekaDialogContent class="my-dialog-content">
        <RekaDialogTitle class="my-dialog-title">My Dialog Title</RekaDialogTitle>
        <RekaDialogDescription class="my-dialog-description">
          This is an accessible dialog, built with Reka UI primitives.
          You need to provide your own styling for these headless components.
        </RekaDialogDescription>
        <RekaButton @click="isDialogOpen = false" class="my-close-button">Close</RekaButton>
      </RekaDialogContent>
    </Teleport>
  </RekaDialogRoot>
</template>

<style scoped>
.my-custom-button {
  padding: 10px 20px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.my-dialog-content {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  min-width: 300px;
}

.my-dialog-title {
  font-size: 1.5em;
  margin-bottom: 10px;
}

.my-dialog-description {
  margin-bottom: 15px;
}

.my-close-button {
  background-color: #f44336;
  color: white;
  padding: 8px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  float: right;
}
</style>

view raw JSON →