---
title: Direction Provider
subtitle: Enables RTL behavior for Base UI components.
description: A direction provider component that enables RTL behavior for Base UI components.
---

> FineSoft Components documentation. Independent Stencil port; not the official Base UI website.
>
> React API text and `@base-ui/react` examples are upstream references. FineSoft Stencil examples use `finesoft-components`. Do not treat the two packages as interchangeable.

# Direction Provider

A direction provider component that enables RTL behavior for Base UI components.

## Demo

### Tailwind

This example shows how to implement the component using Tailwind CSS.

```tsx
/* docs-comparison.tsx */
import { StencilComparison } from 'docs/src/components/StencilComparison';
import ReactExample from './react-direction-provider';
import StencilExample from './stencil-direction-provider';
export default function Comparison() {
  return <StencilComparison component="direction-provider" react={<ReactExample />} stencil={<StencilExample />} />;
}
```

```tsx
/* react-direction-provider.tsx */
import { Slider } from '@base-ui/react/slider';
import { DirectionProvider } from '@base-ui/react/direction-provider';

export default function ExampleDirectionProvider() {
  return (
    <div dir="rtl">
      <DirectionProvider direction="rtl">
        <Slider.Root defaultValue={25}>
          <Slider.Control className="flex w-56 touch-none items-center py-3 select-none">
            <Slider.Track className="h-1 w-full bg-neutral-200 select-none dark:bg-neutral-800">
              <Slider.Indicator className="bg-neutral-950 select-none dark:bg-white" />
              <Slider.Thumb
                aria-label="Volume"
                className="size-4 border border-neutral-950 bg-white select-none has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-neutral-950 dark:has-[:focus-visible]:outline-white dark:border-white dark:bg-neutral-950"
              />
            </Slider.Track>
          </Slider.Control>
        </Slider.Root>
      </DirectionProvider>
    </div>
  );
}
```

```tsx
/* stencil-direction-provider.tsx */
export default function StencilDirectionProvider() {
  return (
    <div dir="rtl">
      <fs-direction-provider-root direction="rtl">
        <fs-slider-root default-value={25}>
          <fs-slider-control className="flex w-56 touch-none items-center py-3 select-none">
            <fs-slider-track className="h-1 w-full bg-neutral-200 select-none dark:bg-neutral-800">
              <fs-slider-indicator className="bg-neutral-950 select-none dark:bg-white" />
              <fs-slider-thumb
                aria-label="Volume"
                className="size-4 border border-neutral-950 bg-white select-none has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-neutral-950 dark:has-[:focus-visible]:outline-white dark:border-white dark:bg-neutral-950"
              />
            </fs-slider-track>
          </fs-slider-control>
        </fs-slider-root>
      </fs-direction-provider-root>
    </div>
  );
}
```

### CSS Modules

This example shows how to implement the component using CSS Modules.

```css
/* index.module.css */
.Control {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  width: 14rem;
  padding-block: 0.75rem;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

.Track {
  width: 100%;
  height: 0.25rem;
  background-color: oklch(92.2% 0 0deg);
  -webkit-user-select: none;
  user-select: none;

  @media (prefers-color-scheme: dark) {
    background-color: oklch(26.9% 0 0deg);
  }
}

.Indicator {
  background-color: oklch(14.5% 0 0deg);
  -webkit-user-select: none;
  user-select: none;

  @media (prefers-color-scheme: dark) {
    background-color: white;
  }
}

.Thumb {
  box-sizing: border-box;
  width: 1rem;
  height: 1rem;
  border: 1px solid oklch(14.5% 0 0deg);
  background-color: white;
  -webkit-user-select: none;
  user-select: none;

  @media (prefers-color-scheme: dark) {
    border: 1px solid white;
    background-color: oklch(14.5% 0 0deg);
  }

  &:has(:focus-visible) {
    outline: 2px solid oklch(14.5% 0 0deg);
    outline-offset: 2px;

    @media (prefers-color-scheme: dark) {
      outline-color: white;
    }
  }
}
```

```tsx
/* docs-comparison.tsx */
import { StencilComparison } from 'docs/src/components/StencilComparison';
import ReactExample from './react-direction-provider';
import StencilExample from './stencil-direction-provider';
export default function Comparison() {
  return <StencilComparison component="direction-provider" react={<ReactExample />} stencil={<StencilExample />} />;
}
```

```tsx
/* react-direction-provider.tsx */
import { DirectionProvider } from '@base-ui/react/direction-provider';
import { Slider } from '@base-ui/react/slider';
import styles from './index.module.css';

export default function ExampleDirectionProvider() {
  return (
    <div dir="rtl">
      <DirectionProvider direction="rtl">
        <Slider.Root defaultValue={25}>
          <Slider.Control className={styles.Control}>
            <Slider.Track className={styles.Track}>
              <Slider.Indicator className={styles.Indicator} />
              <Slider.Thumb aria-label="Volume" className={styles.Thumb} />
            </Slider.Track>
          </Slider.Control>
        </Slider.Root>
      </DirectionProvider>
    </div>
  );
}
```

```tsx
/* stencil-direction-provider.tsx */
export default function StencilDirectionProvider() {
  return (
    <div dir="rtl">
      <fs-direction-provider-root direction="rtl">
        <fs-slider-root default-value={25}>
          <fs-slider-control>
            <fs-slider-track>
              <fs-slider-indicator />
              <fs-slider-thumb aria-label="Volume" />
            </fs-slider-track>
          </fs-slider-control>
        </fs-slider-root>
      </fs-direction-provider-root>
    </div>
  );
}
```

## Anatomy

Import the component and wrap it around your app:

```jsx title="Anatomy"
import { DirectionProvider } from '@base-ui/react/direction-provider';

// prettier-ignore
<DirectionProvider>
  {/* Your app or a group of components */}
</DirectionProvider>
```

`<DirectionProvider>` enables child Base UI components to adjust behavior based on RTL text direction, but does not affect HTML and CSS. The `dir="rtl"` HTML attribute or `direction: rtl` CSS style must be set additionally by your own application code.

## Stencil API

```html
<div dir="rtl">
  <fs-direction-provider-root direction="rtl">
    <fs-slider-root default-value="25"><!-- Slider parts --></fs-slider-root>
  </fs-direction-provider-root>
</div>
```

Import `finesoft-components/direction-provider` for automatic registration, or register with `defineCustomElements()` from `finesoft-components/define-custom-elements`.

`direction` accepts `"ltr"` or `"rtl"` and defaults to `"ltr"`. It changes component behavior without setting the HTML `dir` attribute. Set `dir` separately when the layout should also change. Nested providers replace the outer direction, including when the inner provider uses the default. Portals inherit the provider at their declaration site.

```ts
import { useDirection } from 'finesoft-components/direction-provider';
const direction = useDirection(element);
```

In Stencil, `useDirection(element)` is a DOM utility and requires an element in the relevant subtree. It returns `"ltr"` when no provider exists. Already migrated components also retain their existing HTML/CSS `dir` shorthand when no provider is present; an explicit provider takes precedence. Dynamic provider updates refresh component behavior and popup positioning.

## API reference

### DirectionProvider

Enables RTL behavior for Base UI components.

**DirectionProvider Props:**

| Prop      | Type              | Default | Description                       |
| :-------- | :---------------- | :------ | :-------------------------------- |
| direction | `TextDirection`   | `'ltr'` | The reading direction of the text |
| children  | `React.ReactNode` | -       | -                                 |

### DirectionProvider.Props

Re-export of [DirectionProvider](/react/utils/direction-provider.md) props.

### DirectionProvider.State

```typescript
type DirectionProviderState = {};
```

### useDirection

**useDirection Return Value:**

```tsx
type ReturnValue = TextDirection;
```

## Additional Types

### TextDirection

```typescript
type TextDirection = 'ltr' | 'rtl';
```

## Canonical Types

Maps `Canonical`: `Alias` — Use Canonical when its namespace is already imported; otherwise use Alias.

- `DirectionProvider.Props`: `DirectionProviderProps`

Use this hook to read the current text direction. This is useful for wrapping portaled components that may be rendered outside your application root and are unaffected by the `dir` attribute set within.
