# Separator

> A hairline divider, horizontal or vertical, decorative by default.

Component · display. Registry item `separator`, shown in the vega Style. JSON: https://nativecn.dev/r/styles/vega/separator.json

## Installation

```sh
npx nativecn-cli@latest add separator
```

Also installs: [theme](https://nativecn.dev/docs/theme/theme).

## Usage

### Separator demo

Horizontal and vertical Separators.

```tsx
import { View } from "react-native";

import { Separator } from "@/components/separator";
import { Text } from "@/components/text";
import { createStyles } from "@/theme";

export default function SeparatorDemo() {
  const styles = useStyles();
  return (
    <View style={styles.stack}>
      <Text variant="h4">nativecn</Text>
      <Text variant="small" color="mutedForeground">
        Components for Expo apps.
      </Text>
      <Separator />
      <View style={styles.row}>
        <Text variant="small">Docs</Text>
        <Separator orientation="vertical" />
        <Text variant="small">Blocks</Text>
        <Separator orientation="vertical" />
        <Text variant="small">Themes</Text>
      </View>
    </View>
  );
}

const useStyles = createStyles((t) => ({
  stack: { gap: t.spacing[3] },
  row: { flexDirection: "row", alignItems: "center", gap: t.spacing[3] },
}));
```

## Props

| Prop | Type and description |
|---|---|
| `orientation` | "horizontal" (default) \| "vertical" |
| `decorative` | boolean (default true): hidden from screen readers; false exposes it with role separator |
| `style` | merged last |

## Accessibility

- Decorative by default: hidden from screen readers.
- decorative={false} exposes it with role separator.

## Notes

A vertical Separator stretches to its row's height, so put it in a row with alignItems center. Between virtualized ListItems, pass it as FlashList's ItemSeparatorComponent.

## Source

### {components}/separator.tsx

```tsx
import type { Ref } from "react";
import { StyleSheet, View, type ViewProps } from "react-native";

import { createStyles } from "@/theme";

export type SeparatorOrientation = "horizontal" | "vertical";

export type SeparatorProps = Omit<ViewProps, "children"> & {
  /** Default `horizontal`. A vertical Separator stretches to its row's height. */
  orientation?: SeparatorOrientation;
  /**
   * Purely visual (default `true`): hidden from screen readers. Set `false` when the line
   * separates content in a way that matters, so it is exposed with role `separator`.
   */
  decorative?: boolean;
  ref?: Ref<View>;
};

// The `borderWidth.hairline` Token: the thinnest line the screen can draw.
const hairline = StyleSheet.hairlineWidth;

const useStyles = createStyles((t) => ({
  root: { backgroundColor: t.colors.border, flexShrink: 0 },
  horizontal: { height: hairline, alignSelf: "stretch" },
  vertical: { width: hairline, alignSelf: "stretch" },
}));

/**
 * A hairline that divides content, horizontally or vertically, in the `border` Colour Role.
 * Decorative by default. `style` is merged last.
 */
export function Separator({
  orientation = "horizontal",
  decorative = true,
  style,
  ...props
}: SeparatorProps) {
  const styles = useStyles();
  return (
    <View
      role={decorative ? undefined : "separator"}
      aria-hidden={decorative}
      accessible={!decorative}
      importantForAccessibility={decorative ? "no-hide-descendants" : undefined}
      style={[styles.root, styles[orientation], style]}
      {...props}
    />
  );
}
```
