Skip to content
edmi-ui

Direction

DirectionProvider and useDirection for LTR / RTL layouts.

StackBlitz ↗StackBlitz ↗StackBlitz ↗
Magnificent Four
4 tokens · rebalanced weekly
مؤشر الأربعة العظماء
٤ رموز · إعادة توازن أسبوعية
Magnificent Four
4 tokens · rebalanced weekly
مؤشر الأربعة العظماء
٤ رموز · إعادة توازن أسبوعية
Magnificent Four
4 tokens · rebalanced weekly
مؤشر الأربعة العظماء
٤ رموز · إعادة توازن أسبوعية
Terminal window
npx shadcn@latest add @edmi-ui/direction
Terminal window
pnpm dlx shadcn@latest add @edmi-ui/direction
Terminal window
yarn dlx shadcn@latest add @edmi-ui/direction
Terminal window
bunx shadcn@latest add @edmi-ui/direction

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

Terminal window
npx shadcn-vue@latest add @edmi-ui/direction
Terminal window
pnpm dlx shadcn-vue@latest add @edmi-ui/direction
Terminal window
yarn dlx shadcn-vue@latest add @edmi-ui/direction
Terminal window
bunx shadcn-vue@latest add @edmi-ui/direction

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

Terminal window
npx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/direction.json
Terminal window
pnpm dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/direction.json
Terminal window
yarn dlx shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/direction.json
Terminal window
bunx --bun shadcn-svelte@latest add https://viandwi24.github.io/edmi-ui/r/svelte/direction.json

Pick your package manager above; the choice is remembered. Add the @edmi-ui registry first, see Getting started.

import { Button } from "@/components/ui/button";
<div className="w-64 rounded-xl border border-border bg-card p-4">
<div className="text-sm font-medium">{title}</div>
<div className="text-xs text-muted-foreground">{sub}</div>
<div className="mt-3 flex gap-2">
<Button size="sm">{join}</Button>
<Button size="sm" variant="secondary">
{share}
</Button>
</div>
</div>
<script setup lang="ts">
import { Button } from "@/components/ui/button";
import { DirectionProvider } from "@/components/ui/direction";
</script>
<template>
<div class="flex flex-wrap gap-6">
<DirectionProvider direction="ltr">
<div dir="ltr">
<div class="w-64 rounded-xl border border-border bg-card p-4">
<div class="text-sm font-medium">Magnificent Four</div>
<div class="text-xs text-muted-foreground">4 tokens · rebalanced weekly</div>
<div class="mt-3 flex gap-2">
<Button size="sm">Join</Button>
<Button size="sm" variant="secondary">Share</Button>
</div>
</div>
</div>
</DirectionProvider>
<DirectionProvider direction="rtl">
<div dir="rtl">
<div class="w-64 rounded-xl border border-border bg-card p-4">
<div class="text-sm font-medium">مؤشر الأربعة العظماء</div>
<div class="text-xs text-muted-foreground">٤ رموز · إعادة توازن أسبوعية</div>
<div class="mt-3 flex gap-2">
<Button size="sm">انضم</Button>
<Button size="sm" variant="secondary">مشاركة</Button>
</div>
</div>
</div>
</DirectionProvider>
</div>
</template>
<script lang="ts">
import { DirectionProvider } from "$lib/components/ui/direction";
</script>
<div class="flex flex-wrap gap-6">
<DirectionProvider direction="ltr">
<div dir="ltr">
</div>
</DirectionProvider>
<DirectionProvider direction="rtl">
<div dir="rtl">
</div>
</DirectionProvider>
</div>
registry/ui/direction.tsx
export {
DirectionProvider,
useDirection,
} from "@base-ui/react/direction-provider";
registry/ui/direction/DirectionProvider.vue
<script setup lang="ts">
import type { Direction } from 'reka-ui'
import { ConfigProvider } from 'reka-ui'
// Same API as the React item (`direction`); Reka's ConfigProvider calls it `dir`.
// It only provides context (no DOM node): set `dir` on a wrapper element too.
defineProps<{ direction?: Direction }>()
</script>
<template>
<ConfigProvider :dir="direction ?? 'ltr'">
<slot />
</ConfigProvider>
</template>
registry/ui/direction/index.ts
// Reka's composable: `useDirection()` -> ComputedRef<"ltr" | "rtl"> from the nearest provider.
export { useDirection } from "reka-ui";
export { default as DirectionProvider } from "./DirectionProvider.vue";
src/lib/registry/ui/direction/direction-provider.svelte
<script lang="ts">
import type { Snippet } from "svelte";
import { type Direction, setDirectionContext } from "./context.js";
// Same API as the React item (`direction`). Provides context only (no DOM node):
// set `dir` on a wrapper element too, and pass `useDirection().current` to Bits UI's `dir` props.
let { direction = "ltr", children }: { direction?: Direction; children?: Snippet } = $props();
setDirectionContext(() => direction);
</script>
{@render children?.()}
src/lib/registry/ui/direction/context.ts
import { getContext, setContext } from "svelte";
export type Direction = "ltr" | "rtl";
const DIRECTION_CONTEXT = Symbol("EDMI_DIRECTION_CONTEXT");
export function setDirectionContext(getDirection: () => Direction) {
setContext(DIRECTION_CONTEXT, getDirection);
}
// `useDirection()` -> `{ current }`: the direction of the nearest <DirectionProvider>, "ltr" without one.
// `current` is a getter, so reading it inside `$derived` / the template stays reactive.
// Pass a local override to mirror Base UI's `useDirection(localDir)`.
export function useDirection(localDirection?: Direction): {
readonly current: Direction;
} {
const getDirection = getContext<(() => Direction) | undefined>(
DIRECTION_CONTEXT,
);
return {
get current() {
return localDirection ?? getDirection?.() ?? "ltr";
},
};
}
src/lib/registry/ui/direction/index.ts
import DirectionProvider from "./direction-provider.svelte";
export { type Direction, useDirection } from "./context.js";
export { DirectionProvider };
Export Notes
DirectionProvider direction "ltr" | "rtl" — also set dir on <html>
useDirection() returns the current direction

None — re-export of Base UI’s direction provider.

  • Vue: DirectionProvider direction="rtl"; useDirection() returns a ComputedRef.
  • Svelte: DirectionProvider direction="rtl"; useDirection() returns { current }.