# Switcher
> A layout component that switches directly from laying out elements along one row to stacking them based on the container size.

## Import

```js
import { Switcher } from '@gemini-suite/vera-react';
```

## Background

For smaller numbers of items, there may be cases where you wish to switch directly from a horizontal (one row) to a vertical (one column) layout and bypass any intermediary layout states.
This is exactly what **Switcher** layout does: it switches between a horizontal and a vertical layout at a given, container-based threshold.
**Switcher** is especially useful when each of the items should be considered equivalent, or part of a continuum.
Say, you have three cards and don’t want an “awkward situation” in which one of the cards is placed all alone on a new row.

**Switcher**, similar to [Auto Grid](/components/layout/auto-grid) fits into any container and adapts automatically thanks to CSS grid’s `auto-fit()` and `minmax()` functions, eliminating the need for viewport `@media` queries altogether.

## Examples

### Default configuration

```jsx resizable=true
<Switcher>
  <ExampleBox />
  <ExampleBox />
  <ExampleBox />
</Switcher>
```

### Configuring threshold

In the example below `threshold` is set to `25rem`, meaning when the parent element (the container) is less than `25rem` wide, the layout will switch to a vertical configuration.

```jsx resizable=true
<Switcher threshold="25rem" alignItems="start">
  <Box css={{ backgroundColor: '$colorBlue10', padding: '$spacingM' }}>
    <Flex flow="column">
      <Box
        css={{
          color: '$foregroundNeutralMinimal',
          display: 'flex',
          borderRadius: '50%',
          alignItems: 'center',
          justifyContent: 'center',
          border: '2px solid',
          width: '3rem',
          height: '3rem'
        }}
      >
        1
      </Box>
      <FakeText words="10,15" />
    </Flex>
  </Box>
  <Box css={{ backgroundColor: '$colorBlue10', padding: '$spacingM' }}>
    <Flex flow="column">
      <Box
        css={{
          color: '$foregroundNeutralMinimal',
          display: 'flex',
          borderRadius: '50%',
          alignItems: 'center',
          justifyContent: 'center',
          border: '2px solid',
          width: '3rem',
          height: '3rem'
        }}
      >
        2
      </Box>
      <FakeText words="10,15" />
    </Flex>
  </Box>
  <Box css={{ backgroundColor: '$colorBlue10', padding: '$spacingM' }}>
    <Flex flow="column">
      <Box
        css={{
          color: '$foregroundNeutralMinimal',
          display: 'flex',
          borderRadius: '50%',
          alignItems: 'center',
          justifyContent: 'center',
          border: '2px solid',
          width: '3rem',
          height: '3rem'
        }}
      >
        3
      </Box>
      <FakeText words="10,15" />
    </Flex>
  </Box>
</Switcher>
```

### Configuring limit

The more elements you add, the less space each gets alloted, and things can easily start to get squashed up in horizontal layout.
Set `limit` to control maximum number of items allowed to appear in one row. When the limit gets exceeded, wrapping will occur.

```jsx resizable=true
<Switcher limit="6">
  {Array(8)
    .fill()
    .map((_, i) => (
      <ExampleBox key={i} />
    ))}
</Switcher>
```

### Alignment

Items can be aligned on the block (column) axis via `alignItems` property.

```jsx resizable=true
<Switcher
  alignItems="center"
  css={{
    backgroundColor: '$colorBlue10'
  }}
>
  <ExampleBox css={{ height: '6rem' }} />
  <ExampleBox />
  <ExampleBox />
  <ExampleBox css={{ height: '6rem' }} />
</Switcher>
```

---

## API Reference

| Name         | Type                                                      | Default      | Description                                                                                                                                                                                                                                                                                  | Required |
| ------------ | --------------------------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`         | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`        | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](/get-started/composition#polymorphism) guide. |          |
| `css`        | `StitchesCss`                                             |              | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                 |          |
| `threshold`  | `StitchesCss['maxWidth']`                                 | `30rem`      | The container width at which the component switches between a horizontal and vertical layout. A CSS `max-width` value.                                                                                                                                                                       |          |
| `limit`      | `number`                                                  | `5`          | The maximum number of items allowed to appear in one row.                                                                                                                                                                                                                                    |          |
| `alignItems` | `"start" \| "center" \| "end" \| "baseline" \| "stretch"` |              | Defines the alignment of the items inside the grid container on the block (column) axis.                                                                                                                                                                                                     |          |
| `gap`        | `SpacingToken`                                            | `"spacingM"` | Spacing between grid items.                                                                                                                                                                                                                                                                  |          |
