# Buttons

> [llms.txt](https://zriz.dev/llms.txt)

`Rotate` turns the photo a quarter turn, `Flip` mirrors it and `Reset` undoes every change.

The page at https\://zriz.dev/docs/buttons runs this cropper: a 3:2 photo, rotate left, rotate right, flip and flip vertical buttons, and open, reset and download in the corners.

## Anatomy

Each one is a button that goes anywhere inside `Root`. Put an icon or a word inside, and give an icon-only button an `aria-label`:

```tsx
<Cropper.Rotate aria-label="Rotate left">
  <svg
    aria-hidden="true"
    width={20}
    height={20}
    viewBox="0 0 20 20"
  >
    <path
      d="M4 4v4h4M4.5 8a6 6 0 1 1 1.5 6.5"
      fill="none"
      stroke="currentColor"
      strokeWidth={1.5}
    />
  </svg>
</Cropper.Rotate>
<Cropper.Flip aria-label="Flip">
  <svg
    aria-hidden="true"
    width={20}
    height={20}
    viewBox="0 0 20 20"
  >
    <path
      d="M10 3v14M7 5l-4 10h4zM13 5l4 10h-4z"
      fill="none"
      stroke="currentColor"
      strokeWidth={1.5}
    />
  </svg>
</Cropper.Flip>
<Cropper.Reset>Reset</Cropper.Reset>
```

zriz ships them bare, with no paint and no icons. The demo above adds a right turn and a vertical flip, and uses the icons and styles from the zriz site.

## See what each button moves

| Part | What it does |
| - | - |
| `Rotate` | Turns the photo 90° with a spring. A 3:2 crop becomes 2:3 |
| `Flip` | Mirrors the photo, left to right by default, with a spring |
| `Reset` | Springs back to where the crop started: `defaultValue` and the starting `aspect`, `rotation` and `zoom`, or the full photo |

Every button part sets `touch-action: manipulation` and `user-select: none` inline, so a double tap on a phone never zooms the page and a long press never selects the label and loses the click.

While `Root` is disabled, a press does nothing, and before the photo loads only `Reset` acts. The buttons stay natively enabled and report `aria-disabled`, so style them from `data-disabled` on `Root`, as [root](https://zriz.dev/docs/root.md) shows.

While a move runs, `Root` carries `data-transition`: `"rotate"`, `"flip"` or `"morph"` for `Reset`. A `Reset` across a quarter turn runs as `"rotate"`, and so does a `Flip` or `Reset` pressed while a rotate still runs. During `"rotate"` the photo turns under the crop, the crop frame changes shape to the new side ratio, and the frame, its handles and the photo outside the crop stay visible, as during a flip. [Accessibility](https://zriz.dev/docs/accessibility.md) lists how long each move takes, with and without reduced motion.

## Rotate both ways

`Rotate` turns left, like iOS Photos. `direction="cw"` turns right:

```tsx
<Cropper.Rotate>Rotate left</Cropper.Rotate>
<Cropper.Rotate direction="cw">Rotate right</Cropper.Rotate>
```

## Keep reset hidden

`Reset` hides with the `hidden` attribute while nothing has changed. If a class sets `display` on it, add this rule:

```css
[data-zriz-item="reset"][hidden] {
  display: none;
}
```

## API

### `Rotate`

Renders a `<button type="button">` anywhere inside `Root`. Every part also takes `className`, `render` and the props of its element, see [composition](https://zriz.dev/docs/composition.md).

- `direction` `"ccw" | "cw"` = `"ccw"`

  `"ccw"` turns left, `"cw"` turns right

### `Flip`

Renders a `<button type="button">` with `aria-pressed` anywhere inside `Root`. `className` and `render` get `{ mirrored }`.

- `axis` `"x" | "y"` = `"x"`

  `"x"` swaps left and right, `"y"` swaps top and bottom

| Attribute | When |
| - | - |
| `data-mirrored` | While the photo is mirrored, with `aria-pressed="true"` |

### `Reset`

Renders a `<button type="button">` anywhere inside `Root`. It has no props of its own. `className` and `render` get `{ pristine }`.

| Attribute | When |
| - | - |
| `data-pristine` | While nothing has changed. The button is `hidden` then |
