# Cluster

A layout component that manages a groups of elements with varying lengths
responsively. When there is no more room for an item in the cluster, it will
wrap to the next line.

## Design & usage guidelines

The Cluster component is ideal for:

* Button groups
* Collections of tags or keywords
* Metadata displays
* Any horizontally arranged elements that need consistent spacing

You can control the alignment of clustered elements (left, right, or center) to
match your layout requirements with the `align` prop, along with the
justification of the cluster itself with the `justify` prop.

## Examples

### Basic Usage

The most common use case is grouping related elements with consistent spacing.

```tsx
import React from "react";
import { Cluster } from "@jobber/components/Cluster";
import { Button } from "@jobber/components/Button";

export function ClusterBasicUsageExample() {
  return (
    <Cluster>
      <Button label="Save" />
      <Button label="Cancel" type="secondary" />
      <Button label="Delete" variation="destructive" type="secondary" />
    </Cluster>
  );
}
```

### Tag Collections

Perfect for displaying multiple tags or status indicators.

```tsx
import React from "react";
import { Cluster } from "@jobber/components/Cluster";
import { Chip } from "@jobber/components/Chip";

export function ClusterTagCollectionsExample() {
  return (
    <Cluster>
      <Chip label="Active" />
      <Chip label="High Priority" />
      <Chip label="In Progress" />
      <Chip label="Needs Review" />
    </Cluster>
  );
}
```

### Justification Options

Control how items are justified within the cluster.

```tsx
import React from "react";
import { Cluster } from "@jobber/components/Cluster";
import { Button } from "@jobber/components/Button";
import { Stack } from "@jobber/components/Stack";
import { ContentBlock } from "@jobber/components/ContentBlock";

export function ClusterJustificationOptionsExample() {
  return (
    <ContentBlock maxWidth="100%">
      <Stack>
        <Cluster justify="start">
          <Button label="Left" />
          <Button label="Justify" type="secondary" />
        </Cluster>
      </Stack>
      <Stack>
        <Cluster justify="center">
          <Button label="Center" />
          <Button label="Justify" type="secondary" />
        </Cluster>
      </Stack>
      <Stack>
        <Cluster justify="end">
          <Button label="Right" />
          <Button label="Justify" type="secondary" />
        </Cluster>
      </Stack>
    </ContentBlock>
  );
}
```

### Alignment Options

Control how items are aligned within the cluster.

```tsx
import React from "react";
import { Cluster } from "@jobber/components/Cluster";
import { Button } from "@jobber/components/Button";
import { Stack } from "@jobber/components/Stack";
import { Text } from "@jobber/components/Text";
import { ContentBlock } from "@jobber/components/ContentBlock";

export function ClusterAlignmentOptionsExample() {
  return (
    <Stack gap="larger">
      <Cluster align="start">
        <Button label="Start" />
        <Button label="Align" type="secondary" />
        <ContentBlock maxWidth="50%">
          <Stack>
            <Text>
              Plus some text to make the cluster longer and wider and taller to
              show off how the alignment works
            </Text>
            <Text>
              Plus some text to make the cluster longer and wider and taller to
              show off how the alignment works
            </Text>
          </Stack>
        </ContentBlock>
      </Cluster>
      <Cluster align="center">
        <Button label="Center" />
        <Button label="Align" type="secondary" />
        <ContentBlock maxWidth="50%">
          <Stack>
            <Text>
              Plus some text to make the cluster longer and wider and taller to
              show off how the alignment works
            </Text>
            <Text>
              Plus some text to make the cluster longer and wider and taller to
              show off how the alignment works
            </Text>
          </Stack>
        </ContentBlock>
      </Cluster>
      <Cluster align="end">
        <Button label="End" />
        <Button label="Align" type="secondary" />
        <ContentBlock maxWidth="50%">
          <Stack>
            <Text>
              Plus some text to make the cluster longer and wider and taller to
              show off how the alignment works
            </Text>
            <Text>
              Plus some text to make the cluster longer and wider and taller to
              show off how the alignment works
            </Text>
          </Stack>
        </ContentBlock>
      </Cluster>
    </Stack>
  );
}
```

### Gap Variations

Adjust the gap between items using the `gap` prop.

```tsx
import React from "react";
import { Cluster } from "@jobber/components/Cluster";
import { Chip } from "@jobber/components/Chip";
import { Stack } from "@jobber/components/Stack";

export function ClusterGapVariationsExample() {
  return (
    <Stack>
      <Stack>
        <Cluster gap="small">
          <Chip label="Small" />
          <Chip label="Spacing" />
          <Chip label="Between" />
        </Cluster>
      </Stack>
      <Stack>
        <Cluster gap="base">
          <Chip label="Base" />
          <Chip label="Spacing" />
          <Chip label="Between" />
        </Cluster>
      </Stack>
      <Stack>
        <Cluster gap="large">
          <Chip label="Large" />
          <Chip label="Spacing" />
          <Chip label="Between" />
        </Cluster>
      </Stack>
    </Stack>
  );
}
```

## Related components

Use [Stack](../Stack/Stack.md) when you need to arrange elements vertically
instead of in a horizontal cluster.

Use [Tiles](../Tiles/Tiles.md) when you need elements arranged in a grid with
equal spacing and consistent sizing.


## Props

### Web

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `align` | `"start" | "end" | "center" | "stretch"` | No | — | The vertical alignment of the cluster elements. |
| `ariaAttributes` | `AriaAttributes` | No | — | Standard HTML aria attributes. Accepts all standard HTML aria attributes. |
| `as` | `CommonAllowedElements` | No | `div` | The HTML tag to render the cluster as. |
| `autoWidth` | `boolean` | No | `false` | Enabling this prevents the cluster from taking 100% of the width of the parent and instead flows with the content. |
| `collapseBelow` | `"xs" | "sm" | "md" | "lg" | "xl"` | No | — | The breakpoint below which the cluster will collapse. |
| `collapsed` | `boolean` | No | — | Force the cluster to collapse. Use this when our breakpoints are not enough control. |
| `dataAttributes` | `{ [key: `data-${string}`]: string; }` | No | — | Standard HTML data attributes. Accepts anything in a {{"data-key":"value"}} format. |
| `gap` | `GapSpacing` | No | — | The amount of space between the cluster elements. Semantic tokens are available. |
| `id` | `string` | No | — | Standard HTML id attribute. |
| `justify` | `"start" | "end" | "center" | "space-between" | "space-around"` | No | — | The horizontal justification of the cluster elements. |
| `role` | `AriaRole` | No | — | Standard HTML role attribute. |
| `UNSAFE_className` | `{ container?: string; }` | No | — | **Use at your own risk:** Custom class names for specific elements. This should only be used as a **last resort**. Us... |
| `UNSAFE_style` | `{ container?: CSSProperties; }` | No | — | **Use at your own risk:** Custom style for specific elements. This should only be used as a **last resort**. Using th... |
