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

# `lr-scroller`

- **Import** `import '@aceshooting/lyra-ui/components/lr-scroller.js';` (stable tag alias; registers the tag)
- **Class** `LyraScroller`, also available unregistered from `@aceshooting/lyra-ui/components/layout/scroller/scroller.class.js`
- **Family** `components/layout/` — 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** 10 parts, 10 custom properties — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-scroller`

Responsive overflow surface with optional previous/next controls. The default slot remains the
consumer's content, and the viewport is a native scroll container that works in narrow panels as
well as full-width layouts.

**Properties:**

- `orientation: 'horizontal' | 'vertical' = 'horizontal'` (reflected)
- `controls: boolean = false` (reflected) — show previous/next controls
- `withoutScrollbar: boolean = false` (attribute `without-scrollbar`, reflected) — hides the
  native scrollbar while preserving scrolling
- `withoutShadow: boolean = false` (attribute `without-shadow`, reflected) — suppresses both
  logical edge cues without changing native scrolling or the optional controls
- `scrollStep: number = 0` (attribute `scroll-step`) — custom step; zero uses 80% of the viewport
- `label: string = ''` — accessible region name; a host `aria-label` is used when set

**Events:** `lr-scroll` has detail `{ scrollStart, scrollEnd, scrollLeft, scrollTop }`.
Scroll-driven emissions are coalesced through one `requestAnimationFrame` tick, so a fling that
fires dozens of native `scroll` events produces at most one `lr-scroll` per frame. This is the
scroller's own event shape, not `lr-virtual-list`'s `lr-virtual-scroll` event
(`{ scrollTop, viewportHeight }`).

**Slots:** default scrollable content.

**CSS parts:** `base`, `viewport`, `content`, `start-shadow`, `end-shadow`, `previous`, `next`,
`control` (shared by `previous` and `next`), and `previous-glyph`/`next-glyph` (the chevron inside
each, mirrored under RTL). Each shadow is hidden at its corresponding measured edge and uses
logical positioning, so both cues and gradients mirror under RTL and rotate to the block axis in a
vertical scroller. Before the first client measurement, both cues are hidden and both optional
controls are disabled, so server-rendered markup never advertises a false scroll direction.

**Themeable custom properties:** `--lr-scroller-control-size` (default `var(--lr-size-2rem)`) — the
previous/next control's box size; the interactive target never shrinks below `--lr-icon-button-size`
regardless. `--lr-scroller-min-block-size` (default `var(--lr-size-10rem)`) — the vertical
orientation's minimum block size, ignored while horizontal. `--shadow-color` (default
`var(--lr-color-surface)`) and `--shadow-size` (default `var(--lr-size-2rem)`) theme each edge cue's
base color and logical extent; `--lr-scroller-shadow-color` and `--lr-scroller-shadow-size` are
Lyra-prefixed aliases for the same two (mirroring `lr-split-panel`'s alias pattern for its own
upstream-named props), and win when both spellings are set. The viewport's mouse-hover preview has
its own four-longhand outline shape, matching `lr-virtual-list`'s: `--lr-scroller-hover-outline-width`
(default `var(--lr-border-width-thin)`), `--lr-scroller-hover-outline-style` (default `solid`),
`--lr-scroller-hover-outline-color` (default `var(--lr-color-border)`, set to `transparent` to opt
out entirely), and `--lr-scroller-hover-outline-offset` (default `var(--lr-focus-ring-offset)`).
Unset, all four resolve to the rule's previous literal paint. The `viewport` part also honors the
opt-in theme-level `--lr-theme-scrollbar-width`/`--lr-theme-scrollbar-gutter` hooks (defaults
`auto`/`auto`, matching its previous unconditional `scrollbar-width: auto`) — set either on `:root`
or any ancestor for one declaration to retheme every internal scroll container in the library,
including `lr-table`, `lr-virtual-list`, `lr-code-block`, and `lr-code-editor`.

```html
<lr-scroller controls label="Project cards">
  <lr-card>Solar</lr-card>
  <lr-card>Wind</lr-card>
  <lr-card>Battery</lr-card>
</lr-scroller>
```

---
