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

# `lr-format-number`

- **Import** `import '@aceshooting/lyra-ui/components/lr-format-number.js';` (stable tag alias; registers the tag)
- **Class** `LyraFormatNumber`, also available unregistered from `@aceshooting/lyra-ui/components/utility/format/format-number.class.js`
- **Family** `components/utility/` — 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** nothing component-specific — inherits only the shared surface
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-format-number`

`Intl.NumberFormat` output.

Removing `currency` preserves the removal readback while formatting with the declared USD fallback.
An explicitly blank currency also keeps its existing USD formatting fallback, and a later valid
currency takes effect normally.

Shared by all four formatters (`lr-format-number`, `lr-format-date`, `lr-format-bytes`,
`lr-relative-time`): each is text-only — a `display: inline` host with **no CSS parts, no events, and
no themeable custom properties of its own** — rendering one formatted string into its shadow root.
Locale comes from the shared `effectiveLocale` (this element's own `locale`, else the nearest
inherited `lang`; see `llms/shared.md`) and is passed to `Intl` as `undefined` when it resolves
empty, which means "the runtime's default locale". Every `Intl` instance is pulled from the shared
memoized `internal/intl-cache.ts` (one instance per locale + options pair, LRU-capped), so these are
cheap to use per row in a large table or feed.

Malformed runtime options fall back to a safe option set without discarding an otherwise-valid
effective locale. Only a malformed locale itself falls back to the runtime default.

**Properties:**

- `value: number = 0`
- `type: 'currency' | 'decimal' | 'percent' = 'decimal'`
- `currency: string = 'USD'` and `currencyDisplay: 'symbol' | 'narrowSymbol' | 'code' | 'name' =
'symbol'` (`currency-display`); used only by currency formatting
- `withoutGrouping: boolean = false` (`without-grouping`) and `noGrouping: boolean = false`
  (`no-grouping`) — Web Awesome/Shoelace aliases; either disables grouping separators. With both
  false, the `Intl.NumberFormat` option is omitted so each locale and notation keeps its own default
  grouping policy
- `notation: 'standard' | 'compact' | 'scientific' | 'engineering' = 'standard'`
- `minimumIntegerDigits?: number` (attribute `minimum-integer-digits`)
- `minimumFractionDigits?: number` (attribute `minimum-fraction-digits`)
- `maximumFractionDigits?: number` (attribute `maximum-fraction-digits`)
- `minimumSignificantDigits?: number` / `maximumSignificantDigits?: number` (matching kebab-case
  attributes)

**Slots:** default — fallback content, rendered only when `value` is not finite (`NaN`/`Infinity`,
e.g. a malformed attribute) or the formatted string is empty.

All digit properties are finite-integer guarded before `Intl` construction: integer/significant
digits clamp to `[1, 21]`, fractions to `[0, 100]`, and crossed minimum/maximum pairs are ordered.
Leaving one `undefined` preserves `Intl`'s own defaults. Closed-set values assigned through untyped
JavaScript fall back to their documented defaults.
