Layout
Direction.
Sets the reading direction for Radix components below it, so menus, selects and sliders mirror correctly in right to left layouts.
Guestbookltr
Guestbookrtl
"use client";
import { ArrowRight, Search } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { DirectionProvider, useDirection } from "@/components/ui/direction";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
function Panel({ id }: { id: string }) {
const dir = useDirection();
return (
<div className="flex flex-col gap-4 rounded-lg border bg-card p-4">
<div className="flex items-center justify-between gap-2">
<span className="font-mono text-[10px] tracking-[0.2em] text-success uppercase">Guestbook</span>
<Badge variant="outline">{dir}</Badge>
</div>
<div className="relative">
<Search className="pointer-events-none absolute start-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
<Input aria-label="Search entries" placeholder="Search entries" className="ps-9" />
</div>
<div className="flex items-center gap-3">
<Checkbox id={`${id}-pin`} defaultChecked />
<Label htmlFor={`${id}-pin`}>Pin newest entry</Label>
</div>
<div className="grid gap-2.5">
<Label htmlFor={`${id}-sort`}>Sort entries</Label>
<Select defaultValue="newest">
<SelectTrigger id={`${id}-sort`} className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="newest">Newest first</SelectItem>
<SelectItem value="oldest">Oldest first</SelectItem>
</SelectContent>
</Select>
</div>
<Button className="w-full">
Sign guestbook <ArrowRight className="rtl:rotate-180" />
</Button>
</div>
);
}
export default function DirectionDemo() {
return (
<div className="grid w-full max-w-2xl gap-4 sm:grid-cols-2">
<DirectionProvider dir="ltr">
<div dir="ltr">
<Panel id="ltr" />
</div>
</DirectionProvider>
<DirectionProvider dir="rtl">
<div dir="rtl">
<Panel id="rtl" />
</div>
</DirectionProvider>
</div>
);
}Installation#
With the CLI
$npx lanterncn add directionThis also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/direction. See Installation if your project is not set up yet.
Manually
Install the dependencies
npm install radix-uiCopy the source into your project
components/ui/direction.tsx"use client"; import * as React from "react"; import { Direction } from "radix-ui"; function DirectionProvider({ dir, direction, children, }: React.ComponentProps<typeof Direction.DirectionProvider> & { direction?: React.ComponentProps<typeof Direction.DirectionProvider>["dir"]; }) { return <Direction.DirectionProvider dir={direction ?? dir}>{children}</Direction.DirectionProvider>; } const useDirection = Direction.useDirection; export { DirectionProvider, useDirection };Update the import paths to match your project
The source imports
cnfrom@/lib/utils.
Usage#
import { DirectionProvider, useDirection } from "@/components/ui/direction";<DirectionProvider dir="rtl">
<div dir="rtl">
<App />
</div>
</DirectionProvider>The provider only tells Radix components the direction. Also set the dir attribute on the html element or a wrapper so text, flex order and logical utilities like ps-* and start-* flip.
useDirection returns the current direction, handy for flipping icons such as arrows.