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

# `lr-html-viewer`

- **Import** `import '@aceshooting/lyra-ui/components/lr-html-viewer.js';` (stable tag alias; registers the tag)
- **Class** `LyraHtmlViewer`, also available unregistered from `@aceshooting/lyra-ui/components/viewers/html-viewer/html-viewer.class.js`
- **Family** `components/viewers/` — 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)
- **Deprecations** none
- **Optional peers** `dompurify` — see `llms/peers.md`
- **Themeable via** 6 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-html-viewer`

Fetches an HTML document, sanitizes it with the optional `dompurify` peer, and renders the safe markup
inside a bounded, scrollable body.
Its passive-document profile is network-silent and non-interactive: links, form controls, and custom
elements are unwrapped to their ordinary text/children where safe; remote navigation and resource
attributes are removed. Images load only inline base64 GIF, JPEG, PNG, or WebP data, while
same-document SVG fragment references may remain; an `<a>` itself never remains in the rendered
preview.

**Properties:** `src: string = ''`, `name: string = ''`, and `maxHeight: string = ''` (attribute
`max-height`); invalid CSS
`max-height` values, declaration breaks, and `url()` are ignored. A nonempty host `aria-label`
makes the host the sole named semantic owner; an explicitly empty host label keeps the shadow
`document` role with an empty name, and an absent host label falls back to `name` or the localized
label. `highlights`, `activeHighlightId`, `anchor`, and
`anchorKinds` (`['text-quote', 'fragment']`) provide the shared text-viewer contract.

**Methods:** `search(query)`, `searchNext()`, `searchPrevious()`, `clearSearch()`, and
`scrollToAnchor()` operate on sanitized HTML text and emit the shared search/anchor events.

**Events:**

- `lr-render-error` with `detail.error` when fetching or sanitizing fails.
- `lr-search-change` — `detail: { query: string; matchCount: number; matchCountExact: boolean; activeIndex: number }` — fired
  whenever rendered-document search state changes.
- `lr-anchor-result` — `detail: { found: boolean }` — fired after an `anchor` assignment or
  `scrollToAnchor()` call is applied.
- `lr-text-select` — `detail: TextSelectDetail` (`{ text: string; anchor: LyraAnchor | null; rects:
DOMRect[] }`) — fired after a selection ends inside the rendered document.

`lr-highlight-activate` is not part of this viewer's event contract: painted sanitized-text
highlights are passive and cannot be activated.

The three shared text-viewer events bubble and compose and are non-cancelable.

**CSS parts:** `base`, `body`, `html`, `spinner`, `error`, and `anchor-live-region` (an aria-hidden,
non-live shadow mirror of the latest anchor-jump message; the spoken copy is appended to the shared
document-level polite sink only while the viewer and its composed ancestors are exposed to the
accessibility tree).

**Themeable custom properties:** `--lr-html-viewer-max-height` (default `none`) — maximum block size
of `[part="body"]`; also settable via the `max-height` property, which writes this token inline.

**Optional peer dependency:** `dompurify`. The registry matches `text/html` and `.htm`/`.html`
filenames, declaring `{ anchors: ['text-quote', 'fragment'], search: true, textSelect: true }`
capabilities and forwarding `anchor`/`highlights` onto the created element, so a deep link opened
through `<lr-document-viewer>` survives the registry hop.

Remote resources are capped at 25 MB; exceeding it surfaces the localized
`documentPreviewResourceTooLarge` message instead of the document.
