{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "direction",
  "title": "Direction Utilities",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "Right-to-left support helpers: useDirection reads the reading direction, DirectionProvider tells Radix-based components, and Dir scopes a region to ltr or rtl.",
  "dependencies": [
    "radix-ui@^1"
  ],
  "files": [
    {
      "path": "registry/ballmac/lib/direction.tsx",
      "content": "// Ballmac UI: Direction utilities. https://ui.ballmac.com/docs/rtl\n\"use client\"\n\nimport * as React from \"react\"\nimport { Direction } from \"radix-ui\"\n\nexport type TextDirection = \"ltr\" | \"rtl\"\n\nfunction subscribe(onChange: () => void) {\n  if (typeof MutationObserver === \"undefined\") return () => {}\n  const observer = new MutationObserver(onChange)\n  observer.observe(document.documentElement, { attributes: true, attributeFilter: [\"dir\"] })\n  return () => observer.disconnect()\n}\nconst readDocument = (): TextDirection => (document.documentElement.dir === \"rtl\" ? \"rtl\" : \"ltr\")\n\n/**\n * The reading direction for code that has to know it (arrow-key order, pointer maths, which way a chevron faces).\n * An explicit `dir` wins, then a surrounding `<Direction>` or Radix `DirectionProvider`, then `<html dir>`.\n * Server render and the first client render say \"ltr\", so markup matches, and it updates right after hydration.\n */\nexport function useDirection(dir?: TextDirection): TextDirection {\n  const provided = Direction.useDirection(dir)\n  const document_ = React.useSyncExternalStore(subscribe, readDocument, () => \"ltr\" as TextDirection)\n  return dir ?? (provided === \"rtl\" ? \"rtl\" : document_)\n}\n\n/**\n * Sets the direction for a part of the page and tells every Radix-based component inside it, so keyboard arrows,\n * sliders, menus and tabs follow it. For the whole app, put it in the root layout next to `<html dir>`.\n */\nexport function DirectionProvider({ dir, children }: { dir: TextDirection; children: React.ReactNode }) {\n  return <Direction.Provider dir={dir}>{children}</Direction.Provider>\n}\n\n/** A box with its own direction (`display: contents`, so it adds no layout), for previews and mixed-language regions. */\nexport function Dir({ dir, children, ...props }: Omit<React.ComponentProps<\"div\">, \"dir\"> & { dir: TextDirection }) {\n  return (\n    <Direction.Provider dir={dir}>\n      <div dir={dir} className=\"contents\" {...props}>\n        {children}\n      </div>\n    </Direction.Provider>\n  )\n}\n",
      "type": "registry:lib",
      "target": "@lib/ballmac/direction.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "rtl",
      "ltr",
      "direction",
      "i18n",
      "arabic",
      "hebrew",
      "persian"
    ],
    "version": "1.0.0",
    "updated": "2026-10-02",
    "ai": {
      "summary": "Import useDirection, DirectionProvider and Dir from @/lib/ballmac/direction. Set <html dir> and wrap the app in DirectionProvider so keyboard arrows, sliders, menus and tabs follow the reading direction.",
      "whenToUse": [
        "Shipping the app in Arabic, Hebrew, Persian or Urdu",
        "A region of mixed-direction content",
        "Code that must know which way is forward"
      ],
      "whenNotToUse": [
        "Layout alone: logical properties (ms-, me-, start-, end-) already follow dir with no JavaScript"
      ],
      "composesWith": [],
      "a11y": [],
      "customization": [
        "dir: pass it to useDirection to force a direction",
        "Dir renders a div with display: contents"
      ]
    },
    "examples": [],
    "url": "https://ui.ballmac.com/components/direction"
  },
  "categories": [
    "foundation"
  ],
  "type": "registry:lib"
}