<!-- GENERATED by scripts/build-llms.mjs from llms/data.md — do not edit this file. -->

# `lr-flow-controls`

- **Import** `import '@aceshooting/lyra-ui/components/lr-flow-controls.js';` (stable tag alias; registers the tag)
- **Class** `LyraFlowControls`, also available unregistered from `@aceshooting/lyra-ui/components/data/flow-controls/flow-controls.class.js`
- **Family** `components/data/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
- **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
- **Deprecations** none
- **Optional peers** none
- **Themeable via** 5 parts, 1 custom property — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-flow-controls`

The canvas's button cluster: zoom in/out, fit, and interaction lock, so every flow surface ships the
same affordances without hosts rebuilding them. Manipulates only view state, never `nodes`/`edges` —
no editing commands live here. Zoom-in/out disabled state reads the canvas snapshot's effective
finite, sorted bounds, so invalid or reversed raw `minZoom`/`maxZoom` values cannot disable an
otherwise available direction.

**Properties:**

- `for: string = ''` — id of the target `lr-flow-canvas`; empty resolves to the nearest ancestor
- `orientation: 'vertical' | 'horizontal' = 'vertical'` (reflected) — button-cluster layout axis
- `hideLock: boolean = false` (attribute `hide-lock`) — omits the lock/unlock toggle button
- `frame: 'card' | 'plain' = 'card'` (reflected) — container treatment, on the library-wide `frame`
  vocabulary. `'plain'` drops `[part="base"]`'s border, background, padding, corner radius and its
  floating-surface `box-shadow`, for a cluster placed in a host toolbar or panel that already draws
  its own surface. There is deliberately no `compact`: the padding is already the smallest spacing
  step and the only remaining room is the buttons' `--lr-icon-button-size` hit-area floor. The
  canonical type is `LyraFrame`; the former component-local appearance alias is removed.

**Events:** none dispatched directly — each button calls the resolved canvas's own `zoomIn()`/
`zoomOut()`/`fit()`, or toggles its `locked` property.

**Slots:** default — extra host buttons appended to the cluster, styled by the same group. A slotted
`<button>` is matched by a `::slotted(button)` rule that gives it the built-in controls' treatment:
the shared `--lr-icon-button-size` hit-area floor, the chrome-less transparent box, and the same
hover/press/disabled/focus-visible affordances. Only the slotted element itself is styled — markup
the consumer nests inside it is left alone — so an icon or label child keeps whatever the host
page gives it.

**CSS parts:** `base` (the `role="group"` wrapper; drops its floating-surface chrome under
`frame="plain"`), `zoom-in`, `zoom-out`, `fit`, `lock` (omitted when `hideLock`).

**Themeable custom properties:** `--lr-flow-controls-lock-active-color` (default
`var(--lr-color-brand)`, pressed lock-button foreground), plus shared tokens —
`--lr-icon-button-size` (each button's minimum hit area, unchanged by `frame`), `--lr-shadow-m`,
`--lr-color-surface`, `--lr-color-border`, `--lr-radius`, `--lr-space-2xs`,
`--lr-focus-ring-width`/`-color`/`-offset`.

**Optional peer deps:** none.

```html
<lr-flow-canvas id="canvas" style="height:480px">
  <lr-flow-controls slot="bottom-start" for="canvas"></lr-flow-controls>
</lr-flow-canvas>
```

**Known gotchas:**

- `for` resolution is identical across all three companions: a non-empty `for` is strict and never
  falls back; only an empty `for` chooses the nearest ancestor. Id changes, target replacement, and
  a canvas that upgrades after the companion are observed in the companion's own document/root.
  Wrong-tag or wrong-capability targets fail closed.
- `frame="plain"` drops the `box-shadow` along with the border and background — unlike most
  `plain` escapes in this library, which only reset the border/background/padding/radius. A lift
  shadow with no surface under it reads as a stray smudge, so the whole floating-surface treatment
  goes together (same as `lr-flow-run-status`'s `plain`).
- Under a narrow allocation the group wraps without overflowing, while each button retains the
  shared hit-area floor.

---
