reka-ui

repository·v2·Indexed 27 days ago

https://github.com/unovue/reka-ui

A library for crafting accessible web applications using Vue, providing headless components inspired by patterns from Radix UI and Headless UI. Version 2.10.1.

Tokens
278.8K
Snippets
354
Records
1.5K
Agent score
90%

What's inside reka-ui

  1. Introduction to Reka UI

    v2

    Reka UI (formerly Radix Vue) is an open-source, low-level UI component library for Vue.js designed to serve as the foundation for accessible design systems and web applications. It provides unstyled, accessible components that follow WAI-ARIA design patterns, handling complex details like keyboard navigation, focus management, and ARIA attributes automatically.

    Key features include:

    • Unstyled Components: Complete freedom to style components using any CSS solution (vanilla CSS, Tailwind, CSS-in-JS, etc.).
    • Flexible State Management: Components support both uncontrolled and controlled patterns.
    • asChild Prop: Provides full control over the rendered element, allowing you to merge component logic onto your own elements.
    • Modular & Tree-shakable: Designed for performance, ensuring unused components do not increase your bundle size.
  2. Ensure accessibility with WAI-ARIA compliance

    v2
    Reka UI components are designed to follow the WAI-ARIA authoring practices guidelines. They handle complex implementation details such as aria and role attributes, focus management, and keyboard navigation automatically. In most contexts, components can be used as-is to provide expected accessibility design patterns for screen readers and other assistive technologies.
  3. Understand DateValue types in Reka UI

    v2

    Reka UI uses immutable DateValue objects from @internationalized/date. Choose the type that matches your requirements:

    • CalendarDate: Date only (e.g., 2023-10-11). Use for birthdays or deadlines.
    • CalendarDateTime: Date and time, but no timezone (e.g., 2023-10-11T12:30:00). Use for local appointments.
    • ZonedDateTime: Date, time, and timezone (e.g., 2023-10-11T21:00:00:00-04:00[America/New_York]). Use for global events like conferences or meetings.
  4. Quickstart: Implement a Popover component

    v2

    To implement a Popover using Reka UI, follow these three steps:

    1. Install the library: Install reka-ui via your package manager.
    2. Import the parts: Import the necessary sub-components from reka-ui and structure them within your Vue template.
    3. Add your styles: Apply custom CSS classes to the component parts to control their appearance.

    The Popover component adheres to WAI-ARIA design patterns, supports both controlled and uncontrolled modes, and allows for customization of side, alignment, offsets, collision handling, and focus management.

    <!-- Popover.vue -->
    <script setup lang="ts">
    import { PopoverArrow, PopoverClose, PopoverContent, PopoverPortal, PopoverRoot, PopoverTrigger } from 'reka-ui'
    </script>
    
    <template>
      <PopoverRoot>
        <PopoverTrigger>More info</PopoverTrigger>
        <PopoverPortal>
          <PopoverContent>
            Some more info...
            <PopoverClose />
            <PopoverArrow />
          </PopoverContent>
        </PopoverPortal>
      </PopoverRoot>
    </template>
  5. Animate Reka UI with Vue Transition

    v2

    You can use the native Vue <Transition> component to animate Reka UI Primitives. Wrap the component (such as DialogOverlay or DialogContent) with <Transition>. Note that for some components, you may need to ensure the component is properly managed within the transition lifecycle.

    <template>
      <DialogRoot v-model:open="open">
        <DialogTrigger>
          Edit profile
        </DialogTrigger>
        <DialogPortal>
          <Transition name="fade">
            <DialogOverlay />
          </Transition>
          <Transition name="fade">
            <DialogContent>
              <h1 class="Hello from inside the Dialog!">Hello from inside the Dialog!</h1>
              <DialogClose>Close</DialogClose>
            </DialogContent>
          </Transition>
        </DialogPortal>
      </DialogRoot>
    </template>
    
    <style>
    .fade-enter-active,
    .fade-leave-active {
      transition: opacity 0.3s ease;
    }
    
    .fade-enter-from,
    .fade-leave-to {
      opacity: 0;
    }
    </style>
  6. Assemble the Tags Input component

    v2

    The Tags Input component is composed of several parts that must be imported and assembled manually. The core parts are TagsInputRoot, TagsInputItem, TagsInputItemText, TagsInputItemDelete, TagsInputInput, and TagsInputClear.

    <script setup>
    import { TagsInputClear, TagsInputInput, TagsInputItem, TagsInputItemDelete, TagsInputItemText, TagsInputRoot } from 'reka-ui'
    </script>
    
    <template>
      <TagsInputRoot>
        <TagsInputItem>
          <TagsInputItemText />
          <TagsInputItemDelete />
        </TagsInputItem>
    
        <TagsInputInput />
        <TagsInputClear />
      </TagsInputRoot>
    </template>
  7. Animate Reka UI with CSS animations

    v2

    The simplest way to animate Reka UI Primitives is using CSS keyframes. You can animate both the mount and unmount phases because Reka UI will suspend unmounting while your animation plays out. Use the [data-state] attribute (e.g., [data-state="open"] or [data-state="closed"]) on the component to target specific animation states.

    @keyframes fadeIn {
      from { opacity: 0; }
      to { opacity: 1; }
    }
    
    @keyframes fadeOut {
      from { opacity: 1; }
      to { opacity: 0; }
    }
    
    .DialogOverlay[data-state="open"],
    .DialogContent[data-state="open"] {
      animation: fadeIn 300ms ease-out;
    }
    
    .DialogOverlay[data-state="closed"],
    .DialogContent[data-state="closed"] {
      animation: fadeOut 300ms ease-in;
    }
  8. Assemble the Avatar component

    v2

    The Avatar component is composed of several parts. You must import and piece them together using AvatarRoot, AvatarImage, and AvatarFallback.

    <script setup>
    import { AvatarImage, AvatarFallback, AvatarRoot } from 'reka-ui'
    </script>
    
    <template>
      <AvatarRoot>
        <AvatarImage />
        <AvatarFallback />
      </AvatarRoot>
    </template>
  9. Implement dynamic text direction

    v2

    You can dynamically switch between ltr and rtl by combining Reka UI's ConfigProvider with the useTextDirection composable from @vueuse/core.

    Note: The dir prop does not support auto as a value, so you must use an intermediate Ref to explicitly define the direction as either ltr or rtl.

    For SSR support, provide an initialValue to useTextDirection so the server can determine the direction when the html tag is not yet accessible.

    <script setup lang="ts">
    import { ConfigProvider } from 'reka-ui'
    import { useTextDirection } from '@vueuse/core'
    import { computed } from 'vue'
    
    // For SSR support, set initialValue
    const textDirection = useTextDirection({ initialValue: 'rtl' })
    const dir = computed(() => textDirection.value === 'rtl' ? 'rtl' : 'ltr')
    </script>
    
    <template>
      <ConfigProvider :dir="dir">
        <slot />
      </ConfigProvider>
    </template>
  10. Implement a Dialog component

    v2

    The Dialog component is a window overlaid on the primary window or another dialog, rendering the content underneath inert. It supports both modal and non-modal modes, automatically traps focus when modal, and handles screen reader announcements via DialogTitle and DialogDescription.

    To implement a basic dialog, import the necessary parts from reka-ui and assemble them within a DialogRoot component.

    <script setup>
    import {
      DialogClose,
      DialogContent,
      DialogDescription,
      DialogOverlay,
      DialogPortal,
      DialogRoot,
      DialogTitle,
      DialogTrigger,
    } from 'reka-ui'
    </script>
    
    <template>
      <DialogRoot>
        <DialogTrigger />
        <DialogPortal>
          <DialogOverlay />
          <DialogContent>
            <DialogTitle />
            <DialogDescription />
            <DialogClose />
          </DialogContent>
        </DialogPortal>
      </DialogRoot>
    </template>