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

# `lr-document-library`

- **Import** `import '@aceshooting/lyra-ui/components/lr-document-library.js';` (stable tag alias; registers the tag)
- **Class** `LyraDocumentLibrary`, also available unregistered from `@aceshooting/lyra-ui/components/data/document-library/document-library.class.js`
- **Family** `components/data/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.1.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** 21 parts, 0 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-document-library`

Controlled searchable and filterable document inventory with versions, tags, owners, freshness,
sorting, and bulk selection. It composes the table's bounded 100-row default, so a large document
collection stays reachable through pagination without mounting an unbounded grid.

Own `tags: undefined` is treated like omitted tags; malformed tag arrays and entries remain invalid.
Removing `search-term` clears search filtering without rewriting its `null` property readback; an
explicitly empty query also clears filtering and a later query applies normally.

**9.0 migration:** `lr-filter-change.detail.text` is now `searchTerm`, backed by the public
`searchTerm`/`search-term` axis. Replace `sortDirection: 'ascending'|'descending'` with
`sortDir: 'asc'|'desc'`; document sorting now uses the same cancelable `lr-sort-request` followed
by accepted `lr-sort` transaction and `{ phase, sortKey, sortDir }` vocabulary as `lr-table`.

**Properties:** clone-owned frozen `documents: readonly LibraryDocument[] = []` (at most the first
10,000 source documents and 10,000 tags per document are retained; document records, nested tags,
and dates are snapshotted on assignment; malformed records (including missing/non-string names or
non-string tag entries), blank ids, and later duplicate ids are omitted first-wins before filters,
counts, selection, rows, and events; reads are detached so `Date`
mutators cannot reach retained state; reassign after changes), `filter`, `label`, `loading`,
clone-owned frozen `selectedDocumentIds: readonly string[] = []` (at most 10,000 unique ids; reassign after
changes), public controlled `searchTerm: string = ''`
(`search-term`), `sortKey: LibraryDocumentSortKey = 'name'` (`sort-key`), canonical
`sortDir: 'asc'|'desc' = 'asc'` (`sort-dir`), and clone-owned frozen
`tagFilter: readonly string[] = []` (at most 10,000 unique tags; reassign after changes).
`size?: LyraSize` (reflected) — opt-in density tier forwarded to BOTH composed toolbar controls, the
search `lr-input` and the tag-filter `lr-combobox`, on the library's one six-step ladder
(`2xs`/`xs`/`s`/`m`/`l`/`xl`, or `small`/`medium`/`large`). Forwarding is the only way to reach them:
each resolves its tier inside its own shadow root, so no custom property on this component would get
there. The two always stay on the same tier as each other, so the toolbar row never goes ragged.
With no `size` both keep their own `m` default; an unsupported value normalizes to the omitted state
and removes the attribute.
`error: boolean = false` (reflected) — reports a failed document-list load. Forwarded to the nested
`lr-table`, whose own built-in failed-load state (with retry button) replaces the document rows
while it's set; `error` beats the empty state, matching `lr-table`'s own precedence.
`errorHeading?: string` (`error-heading`) — failed-load heading override, forwarded to the nested
table. Omitted localizes the table's own `tableLoadFailed` default.
`errorDescription: string = ''` (`error-description`) — failed-load supporting copy, forwarded to
the nested table.

**Events:** `lr-filter-change` emits a fresh frozen readonly
`{ searchTerm, tags, matchCount }`; cancelable `lr-sort-request` proposes frozen readonly
`{ phase: 'request', sortKey, sortDir }`; accepted `lr-sort` commits the same canonical vocabulary
with `phase: 'commit'`; `lr-selection-change` emits a fresh frozen readonly `{ documentIds }`;
`lr-open` emits frozen readonly `{ documentId }`; and `lr-retry` (`detail: null`, cancelable) — the
nested table's built-in retry button was activated, only rendered while `error` is set; the default
action clears `error`, `preventDefault()` leaves it set. This component intercepts the nested
table's own `lr-retry` and re-proposes its own, so the outer `error` property never drifts out of
sync with the table's internal state.

**Slots:** `error` — replaces the nested table's built-in failed-load state, including its retry
button, while `error` is set.

**CSS parts:** `base`, `toolbar`, `search`, `tag-filter`, `selection-bar`, `selection-count`,
`clear-selection`, `table`, `row`, `cell`, `header-cell`, `document-name`, `error-row`, `error-cell`,
`error` (the nested table's built-in `lr-empty` host), `error-base`, `error-icon`, `error-heading`,
`error-description`, `error-actions`, `retry-button`.

`selection-bar` is visible ordinary content, not a shadow live region. Initial declarative
selection stays silent; every post-mount `selectedDocumentIds` change appends the localized selected count
to the document's shared light-DOM polite sink, including zero and repeated equal counts.
Internal search, tag-filter, and checkbox native `input`/`change` plus prefixed `lr-input`/
`lr-change` aliases, the tag combobox's lifecycle/filter/clear/invalid events, table pagination and
priority-column visibility events, and the table's click-anywhere selection event stop at the
component's translation boundary. The table is still in multiple-selection semantics so
`selectedDocumentIds` reaches row `aria-selected`; document selection itself remains checkbox-owned, while
row activation opens the document. Listen for the document-library events above; one interaction
emits one documented host contract without also leaking a composed child event.
