Direction Provider

Tells the component primitives which way the writing runs, so menus and sliders mirror with the rest of the page.

ltr

rtl

Installation

Terminal
pnpm dlx @dowel-ui/cli add direction

npm packages installed: radix-ui.

Accessibility

Needed only for right-to-left languages, and needed in addition to `dir` on the document rather than instead of it. The styling here is written with logical properties and follows `dir` by itself; the primitives underneath read direction from React context and assume left-to-right without a provider, which mirrors a page correctly except for its menus, selects and sliders — worse than not mirroring at all, because it looks deliberate.

Props

DirectionProvider

PropTypeDefault
dir (required)"ltr" | "rtl"
childrenReactNode

Quality

6/6 checks, measured from the source and its tests

  • Testedpasses
  • axe assertionpasses
  • Keyboard testeddoes not apply
  • Storybook examplespasses
  • Accessibility documentedpasses
  • Semantic tokens onlypasses
  • Motion from tokensdoes not apply
  • className mergeddoes not apply
  • Visible focusdoes not apply
  • No fixed widthspasses

Source

This is exactly what dowel add direction writes into your project, with imports rewritten to your own path alias.

ui/direction.tsx
"use client";

import { Direction as DirectionPrimitive } from "radix-ui";
import type { ReactNode } from "react";

/**
 * Tells the component set which way the writing runs.
 *
 * Every direction-dependent style in this library is written logically —
 * `ps-`, `me-`, `text-end` — so the CSS follows `dir` on its own. The
 * primitives underneath do not: several of them read direction from React
 * context rather than from the document, and with no provider they assume
 * left-to-right and set `dir="ltr"` on their own elements. The result is a page
 * that mirrors correctly except for its menus, selects and sliders, which is
 * worse than one that does not mirror at all, because it looks deliberate.
 *
 * So an RTL application needs both: `dir` on the document for the CSS, and this
 * for the primitives.
 *
 * ```tsx
 * <html dir="rtl" lang="ar">
 *   <body>
 *     <DirectionProvider dir="rtl">{children}</DirectionProvider>
 *   </body>
 * </html>
 * ```
 *
 * A left-to-right application needs neither. Nothing here is required to render
 * English correctly, which is why it is easy to ship without it and never know.
 */
export interface DirectionProviderProps {
  dir: "ltr" | "rtl";
  children?: ReactNode;
}

export function DirectionProvider({ dir, children }: DirectionProviderProps) {
  return <DirectionPrimitive.Provider dir={dir}>{children}</DirectionPrimitive.Provider>;
}