/** Locales with a built-in translation for every component's copy. */ export declare const MUD_LOCALES: readonly ["ro-MD", "ru-MD", "en-US"]; export type MudLocale = (typeof MUD_LOCALES)[number]; /** The library's language: used when neither `locale` nor an ancestor `lang` names a supported one. */ export declare const DEFAULT_LOCALE: MudLocale; /** A component's built-in strings, one entry per key, for every supported locale. */ export type LocaleMessages = Record; /** * The `locale` prop's type: autocompletes the three built-in locales, but accepts any BCP-47 * tag, matching `resolveLocale`'s runtime subtag resolution (`en-GB` → `en-US`). */ export type LocaleProp = MudLocale | (string & {}); /** * The supported locale a BCP-47 tag resolves to: the exact tag first, then its language * subtag (`en-GB` → `en-US`, `ro` → `ro-MD`, a Romanian tag of another region → `ro-MD`). Case-insensitive; `undefined` when none matches. */ export declare const matchLocale: (tag: string | null | undefined) => MudLocale | undefined; /** * The `lang` of the closest ANCESTOR that sets one, crossing shadow roots, so a component * rendered inside another component's shadow DOM still reads the page's language. `el`'s own * `lang` is never read — the walk starts at `el`'s parent — so a value the component itself * wrote to its own host (see `hostLang`) is never read back, and call order inside `render()` * no longer matters. An empty `lang=""` means "unknown" in HTML and stops the search. */ export declare const inheritedLang: (el: Element) => string | undefined; /** * The locale a component renders its copy in: its own `locale` prop, else the closest * ancestor `lang`, else `ro-MD`. An explicit `locale` with no translation warns once per * component and tag; an unsupported page `lang` does not, since the page did not address * the library. */ export declare const resolveLocale: (component: string, host: Element, locale: string | null | undefined) => MudLocale; /** Resets the once-per-`component|locale` warning dedup. Test-only: call between specs asserting a warning. */ export declare const resetLocaleWarnings: () => void; /** Every built-in string is a plain string, or a plural form set keyed by `Intl.PluralRules` category. */ export interface Plural { one?: string; few?: string; many?: string; other: string; } /** * A component's built-in strings in its resolved locale (see `resolveLocale`), with each * override applied on top. Three classes of override prop exist (`scripts/eslint/override-classes.json`): * - an accessible name (`*Label`, `*AriaLabel`, announcements) and a validation message * (`*Message`, `*ErrorText`, `requiredText`): wins only when it is a non-empty string — an * empty `aria-label` names nothing, and `setValidity` throws on an empty message; * - a visible optional caption, listed in `captions`: any string wins, `""` included, so * `""` renders nothing, exactly as HTML's own `placeholder=""` does. Only `undefined` / `null` * falls back to the dictionary. * A plural message's override stays a plain string, applied for every count — the same rule, * since `messages[key]` only ever holds a string once an override wins. * * @param captions The keys whose override may be an empty string. Caption keys only: the list * is checked against `override-classes.json` by `scripts/check-locale-specs.mjs`. */ export declare const localeMessages: (component: string, host: Element, locale: string | null | undefined, table: LocaleMessages, overrides?: { [K in keyof M]?: string | null; }, captions?: ReadonlyArray) => M; /** * Canonical BCP-47 tag for `Intl` number/date/region formatting — never for picking a * dictionary (see `resolveLocale`). `_` separators are normalised to `-` first (`en_US` → * `en-US`), then `Intl.getCanonicalLocales` canonicalises the syntax; a tag that fails to * parse (`xx-!!`) falls back to the `MudLocale` it matches, else `ro-MD` — never throws. */ export declare const intlTag: (raw: string | null | undefined) => string; /** * The BCP-47 tag every `Intl` call in a component uses (numbers, dates, region names), and * the `lang` a component's HOST carries once `locale` is explicit (see `hostLang`). The * `locale` prop, else the closest ancestor `lang`, else `DEFAULT_LOCALE`, canonicalised by * `intlTag`: * - a tag with no region whose language has a `MudLocale` takes that locale's region * (`ro` → `ro-MD`, `ru` → `ru-MD`); * - a tag with a region whose language has a `MudLocale` is used as given (`en-GB`, a Romanian tag of another region); * - a tag whose language has no `MudLocale` (`de-DE`) resolves to the shown dictionary's * locale, so a component never mixes Romanian labels with German dates. * An explicit `locale` with no dictionary warns once, exactly as `resolveLocale` does. */ export declare const formatLocale: (host: Element, locale: string | null | undefined) => string; /** * The `locale` a component hands to a `mud-*` it renders in its OWN shadow DOM (date-input → * date-picker, time-input → time-picker, file-input → file-item, breadcrumb → spinner / * breadcrumb-item, …): the parent's own RESOLVED format tag (`formatLocale(host, locale)`), * never the raw `locale` prop. The raw prop is wrong here for the same reason `inheritedLang` * skips `el`'s own `lang`: the nested child's `inheritedLang` walk crosses the shadow boundary * and lands on the PARENT's host, where it reads whatever `lang` that host itself carries — a * `lang` the parent's own resolution never reads back (see `inheritedLang`). Passing the * resolved tag instead makes the child's `locale` prop explicit, so its own resolution * short-circuits straight to that tag regardless of what `lang` its ancestor chain carries, * matching the parent's own dictionary and format locale exactly. */ export declare const childLocale: (host: Element, locale: string | null | undefined) => string; /** * An `Intl.NumberFormat` for `tag` + `options`, cached per `tag` and per `options` VALUE (the * fields `numberFormatOptionsKey` reads) — two calls with equal but DISTINCT `options` objects * hit the same cache entry, not only calls sharing one module-level constant object. */ export declare const numberFormatFor: (tag: string, options: Intl.NumberFormatOptions) => Intl.NumberFormat; /** * `value` formatted in the component's resolved `formatLocale`, through the same cached * `Intl.NumberFormat` pool every other locale-aware number in this module draws from. * `options` defaults to grouping off, matching `fillPlaceholders`'s own placeholder numbers * (which additionally set `maximumFractionDigits: 20`, so a placeholder number never rounds). */ export declare const formatNumber: (host: Element, locale: string | null | undefined, value: number, options?: Intl.NumberFormatOptions) => string; /** * A built-in string or `Plural`, in its final rendered form: `{name}` placeholders filled * from `vars`, and — for a `Plural` — the form `Intl.PluralRules` selects for `vars.count` * under the RESOLVED `MudLocale` (the dictionary actually shown), never the raw `locale` tag. * A `Plural` with no usable `vars.count` (missing, non-finite) renders its `other` form. */ export declare const formatMessage: (value: string | Plural, host: Element, locale: string | null | undefined, vars?: Record) => string; /** * Calls `onChange` whenever a `lang` attribute changes anywhere under `document.documentElement` * — `` itself, or any light-DOM descendant, including another `mud-*` component's own * host once its `locale` changes — so a mounted component re-renders its copy when an ancestor's * language changes (a slotted `mud-breadcrumb-item` follows a `mud-breadcrumb`'s `locale` set * after mount, for instance). Shadow-internal `lang` (inside another component's shadow root) * stays unobserved — `subtree` only reaches light-DOM descendants of `document.documentElement`. * One observer serves every component. Without `MutationObserver` (the hydrate build, mock-doc) * nothing is observed. * * @returns A function that stops listening; call it from `disconnectedCallback`. */ export declare const observeDocumentLang: (onChange: () => void) => (() => void); /** * Drops every registered `observeDocumentLang` listener and disconnects the shared observer. * Test-only: mock-doc does not reliably run `disconnectedCallback` on every descendant a `remove()` * cascades through (a nested locale-aware child, e.g. `mud-spinner` inside `mud-breadcrumb`, can * outlive its host's removal) — a leaked listener then keeps `langObserver` bound to a PRIOR * test's now-discarded `MutationObserver` stub, so the next test's own stub never gets the * `document.documentElement` observation and its `fire()` reaches nothing. Call before installing * a fresh stub (`withLangObserver` does this itself). */ export declare const resetDocumentLangObserver: () => void; /** * The `lang` a component with an explicit `locale` puts on its own HOST (WCAG 3.1.2, * `_agents/localization.md` §7): the copy is spread over sibling shadow elements and * host-level `aria-label`s, so only the host names the language of all of it, and only the * host is visible to a slotted light-DOM child or a nested `mud-*` component reading an * ancestor `lang`. * * Stateless: `formatLocale(host, locale)` while `locale` is a non-empty string, else * `undefined` — nothing else, no side effects. A `lang` a consumer set directly on the host is * overwritten for as long as `locale` is set, and is NOT restored once `locale` clears again * (accepted consequence — the documented API for a component's own language is `locale`, never * a consumer `lang` on its own host); `` then carries no attribute * at all, same as a Stencil `Host` prop that has always been `undefined`. */ export declare const hostLang: (host: Element, locale: string | null | undefined) => string | undefined; /** * `observeDocumentLang`, gated to the component's own RESOLVED locale: `locale` is the * component's `locale`-prop getter (e.g. `() => this.locale`), re-read on every document-wide * `lang` mutation. `onChange` fires only when the pair (dictionary `MudLocale`, `Intl` format * tag) that mutation resolves to for `host` actually changed since the last firing — so a `lang` * mutation anywhere under `document.documentElement`, including another mounted component's own * host-lang write (`hostLang`), no longer re-renders every OTHER mounted component, only the * ones whose own resolution it actually moved. Labeled with the host's own tag so a throwing * listener is traceable to its component: `console.error('[] lang-change listener threw', * err)`. `onChange` typically calls `forceUpdate(this)`. * * @returns A function that stops listening; call it from `disconnectedCallback`. */ export declare const watchDocumentLang: (host: Element, locale: () => string | null | undefined, onChange: () => void) => (() => void);