import{type PropertyValues,type TemplateResult}from'lit';import{LyraElement}from'../../../internal/lyra-element.js';import{type FormOwnerValue}from'../../../internal/form-associated.js';import{type LyraSize}from'../../../internal/variants.js';import{type LyraFormValidator}from'../../forms/form-validator.js'; /** Visual density of the rendered symbols, on the library's one size ladder. */ export type LyraRatingSize=LyraSize; /** Which point of a hover gesture an `lr-hover` event describes. */ export type LyraRatingHoverPhase='start'|'move'|'end'; /** * Renders one symbol. Called twice per position — once for the empty backdrop (`selected` false) * and once for the overlay clipped to that position's filled fraction (`selected` true) — so a * fractional `precision` still renders a partial fill. Output is decorative presentation: it is * inert and pointer-transparent, so pointer and keyboard selection stay on the rating control. * Return any Lit-renderable value; a plain string renders as text, never as markup. */ export type LyraRatingSymbolRenderer=(value:number,selected:boolean)=>unknown;export interface LyraRatingEventMap{change:Event;'lr-change':CustomEvent<{value:number;}>;'lr-activate':CustomEvent<{value:number;}>;'lr-hover':CustomEvent<{phase:LyraRatingHoverPhase;value:number;}>;focus:FocusEvent;blur:FocusEvent;'lr-invalid':CustomEvent;} /** * `` — a keyboard-accessible star rating control. Pointer position within a symbol is * mirrored under RTL and snapped to `precision`, matching keyboard/value fractional selection. * * Form-associated through `ElementInternals` directly rather than through the shared * `FormAssociated` mixin: this control's `value` is a number, not the plain string that mixin's * contract assumes, so the mixin would force every consumer through string round-tripping for what * is natively a numeric score. The submitted entry is the clamped value stringified (`"0"` while * unrated), and `required` reports `valueMissing` until a rating above zero is set. As with a * native range-like controls and both mirrored rating elements, the `value` content attribute and * IDL property control the live score. `defaultValue` / `default-value` independently own the form * reset target, so changing `value` never silently rewrites what `form.reset()` restores. * * The host is the single focusable `role="slider"` owner and carries its value/name/state ARIA, * including explicit `aria-invalid="true"|"false"` from effective intrinsic/custom validity. * The shadow symbol row is presentational chrome, so host ARIA customization cannot create a * second competing slider. * * Deliberately no label/hint/error chrome: `label` here is an accessible-name override, not visible * label text. A rating is a row of symbols with no field frame of its own, so a consumer wanting a * labeled field wraps this element in their own layout, exactly as `` does. * * Readonly transitions synchronize validity and aria-invalid in the same completed update. Form reset restores the independent default-value rather than the live value attribute. * * @customElement lr-rating * @event change - Bubbling, composed native `Event` emitted when a user commits a new value, * immediately before `lr-change`. Programmatic writes and no-op gestures are silent. * @event lr-change - The rating changed. `detail: { value }`. * @event lr-activate - Fired on every interactive commit of a rating -- a click on a symbol, or an * Arrow/Home/End key -- whether or not the value actually moved. `detail: { value }` carries the * committed rating. Bubbling and composed, so a host outside the shadow tree receives it. * Not cancelable: it is a notification that the user committed a rating, not a veto point, and * nothing in this component branches on it. Re-committing the current rating is the case * `lr-change` deliberately stays silent for, and from the keyboard it is otherwise unobservable: * End on an already-maximum rating, Home on an already-zero one, or an arrow key at either bound * commits a rating and produces no click at all. When the commit does move the value, `change` * and `lr-change` are emitted first, so a listener reading `value` from any of them sees the * settled rating. A non-interactive (`readonly`/`disabled`) rating fires none of them. * @event lr-hover - The pointer entered, moved across, or left the symbols while the rating is * settable. `detail: { phase, value }`, where `value` is the rating that committing the current * pointer position would produce — enough to render a live description of what is being hovered. * @event focus - The native focus event from the host-owned slider. * @event blur - The native blur event from the host-owned slider. * @event lr-invalid - The rating failed a validity check. Cancelable: calling * `preventDefault()` also cancels the native `invalid` event behind it, suppressing the * browser's own validation bubble so an app can present the failure its own way. * @method focus - Focuses the host-owned slider. * @method blur - Blurs the host-owned slider. * @method click - Activates the host unless disabled. * @method checkValidity - Returns whether the control currently satisfies its constraints. * @method reportValidity - Same as `checkValidity`, additionally showing the browser's validation UI. * @method setCustomValidity - Sets (or, with `''`, clears) a consumer-supplied validation error. * Survives intrinsic revalidation and a form reset; clearing it restores the computed validity * rather than forcing the control valid. * @csspart base - Compatibility name for the presentational symbol row; use `rating`. * @csspart rating - The presentational symbol row. It is the same node as `base`. * @csspart star - Each visual symbol. * @csspart star-fill - The filled overlay inside each symbol, clipped to that * symbol's filled fraction (0%, a partial percentage under a fractional * `precision`, or 100%). * @cssprop [--lr-rating-fill=var(--lr-color-warning)] - Filled-symbol color. * @cssprop [--lr-rating-empty-color=var(--lr-color-border)] - Unfilled-symbol color, retained during * hover preview. * @cssprop [--lr-rating-size=var(--lr-font-size-xl)] - Symbol size. Its private default follows each * `size` step; an inherited or direct public value wins. The `m` default reproduces the treatment * this component had before `size` existed. * @cssprop [--lr-rating-gap=var(--symbol-spacing,var(--lr-space-xs))] - Gap between symbols. It * takes precedence over the `--symbol-spacing` compatibility hook while preserving that hook and * the shared spacing token as fallbacks. * @cssprop [--lr-rating-active-color=color-mix(in oklab, var(--lr-rating-empty-color, var(--symbol-color, var(--lr-color-border-strong))), var(--lr-color-mix-partner) var(--lr-color-mix-active))] - Pressed-symbol color. Set it independently of * `--lr-rating-empty-color` to recolor the pressed state without changing resting or hover * symbols. * @cssprop [--symbol-color=var(--lr-rating-empty-color,var(--lr-color-border))] - Compatibility * alias for the inactive symbol color. `--lr-rating-empty-color` wins when both are set. * @cssprop [--symbol-color-active=var(--lr-rating-fill,var(--lr-color-warning))] - Compatibility * alias for the active symbol color. `--lr-rating-fill` wins when both are set. * @cssprop --symbol-size - Shoelace-compatible symbol size. It feeds the current `size` step when * `--lr-rating-size` is unset; the Lyra-prefixed property wins when both are set. * @cssprop [--symbol-spacing=var(--lr-space-xs)] - Compatibility spacing around symbols. * @cssstate required - A rating above zero is required. Style with `lr-rating:state(required)`. * @cssstate optional - No rating is required. * @cssstate valid - The control currently satisfies its constraints. * @cssstate invalid - The control currently fails its constraints — true for a pristine * `required` rating that has never been set, which is why validation styling should key off * `user-invalid` instead. * @cssstate user-valid - Valid, and the user has interacted: rated it, blurred it, * `reportValidity()`, or a submission attempt. Not after a silent `checkValidity()` alone. * @cssstate user-invalid - Invalid, and the user has interacted. This is the state to paint red; * a form reset returns the control to pristine and drops it again. * @status stable * @since 4.0.0 */ export declare class LyraRating extends LyraElement{ /** Public WA-compatible intrinsic validator catalog. */ static get validators():LyraFormValidator[];static formAssociated:boolean;static styles:import("lit").CSSResultGroup[];static get observedAttributes():string[];static properties:{customError:{attribute:string;reflect:boolean;noAccessor:boolean;};value:{attribute:string;type:NumberConstructor;noAccessor:boolean;};defaultValue:{attribute:boolean;noAccessor:boolean;};max:{type:NumberConstructor;noAccessor:boolean;};name:{reflect:boolean;noAccessor:boolean;converter:import("lit").ComplexAttributeConverter;};required:{type:BooleanConstructor;reflect:boolean;noAccessor:boolean;};disabled:{type:BooleanConstructor;reflect:boolean;noAccessor:boolean;};};precision:number;readonly:boolean; /** Accessible-name property override. A host `aria-label` attribute has higher priority, and an * explicitly empty host attribute is preserved instead of restoring a fallback name. */ accessibleLabel:string; /** Accessible name for the whole control, used when the host carries no `aria-label`. Not * rendered as visible text — a rating has no field frame of its own. */ label:string; /** Visual density; changes the private fallback behind `--lr-rating-size`. An inherited or * direct public value wins. Valid upstream long-form sizes remain observable verbatim rather * than being reflected back as a different token. */ size:LyraRatingSize;private get effectiveSize(); /** Renders a consumer-supplied decorative symbol per position instead of the built-in star. * Its output cannot become a second focus or pointer target; interact with the rating control * itself to select a value. */ getSymbol?:LyraRatingSymbolRenderer;set defaultValueAlias(next:number|null); /** The rating the current pointer position would commit; only meaningful while `hovering`. */ private hoverValue;private hovering;private internals;private validityController; /** Consumer-supplied validation message reflected through `custom-error`. */ customError:string|null;private _value;private _max;private _name;private _required;private _disabled;private _fieldsetDisabled;private _defaultValue;private _valueDirty;private settingDefaultValue;private reflectingDefaultValue; /** Whether the user has driven this control yet — rated it, blurred it, or triggered interactive * validation (`reportValidity()` or a submission attempt, via `installInteractionOnInvalid()`). * A silent `checkValidity()` alone never counts. Gates the `user-valid`/`user-invalid` custom * states: a pristine `required` rating IS invalid, but painting it red before anyone has touched * it is hostile. Mirrors the `FormAssociated` mixin's own flag; this control drives * `ElementInternals` directly (its value is a number, not the string that mixin assumes) so it * has to track the flag itself. */ private _hasInteracted;private authorAriaLabel;private syncingHostSemantics;private externalLabelNameActive; /** Live presentational symbol row, or `null` before the render root is populated. */ get rating():HTMLElement|null;constructor();attributeChangedCallback(name:string,oldValue:string|null,value:string|null):void; /** The current rating. Clamped to `[0, max]` wherever it is read; the raw assignment is kept so * a value set before `max` arrives from markup isn't silently truncated. */ get value():number;set value(next:number); /** Current reset default; changing it never overwrites a dirty live rating. The independently * reflected `default-value` compatibility attribute reaches this same property. * @default 0 */ get defaultValue():number;set defaultValue(next:number|null); /** The highest rating to show, i.e. the number of symbols rendered. */ get max():number;set max(next:number); /** Submitted as the name half of the form-data name/value pair. */ get name():string;set name(next:string|null); /** Blocks form submission until a rating above zero is set. */ get required():boolean;set required(next:boolean);get disabled():boolean;set disabled(next:boolean); /** Whether the control is disabled explicitly or by an ancestor `
`. */ get effectiveDisabled():boolean;get form():HTMLFormElement|null;set form(owner:FormOwnerValue);getForm():HTMLFormElement|null;get labels():NodeList;get validity():ValidityState;get validationMessage():string;get willValidate():boolean;checkValidity():boolean;reportValidity():boolean; /** * Sets or clears a consumer-supplied validation error — the standard channel for a rejection no * client-side constraint can express ("you have already rated this item"). A non-empty `message` * raises `customError` and becomes `validationMessage`, so the control fails `checkValidity()`, * blocks submission, and matches `:state(invalid)`; `''` clears it. * * Clearing restores the control's own computed validity rather than forcing it valid: a * `required` control that is still unrated stays `valueMissing`. The custom error also survives * every intrinsic recomputation in between (each rating/`max`/`required` change re-runs * `updateValidity()`) and a `form.reset()` — matching a native control, where only another * `setCustomValidity('')` clears it. * * The message is caller-supplied content, so it is used verbatim and never localized here. */ setCustomValidity(message:string):void; /** Clears consumer-supplied validity and restores the current required/value constraint. */ resetValidity():void;formResetCallback():void;formStateRestoreCallback(state:string|File|FormData|null,reason:'autocomplete'|'restore'):void;private restoreLiveValueFromDefault;formDisabledCallback(fieldsetDisabled:boolean):void;connectedCallback():void;disconnectedCallback():void; /** `max`, normalized to a finite non-negative integer count and capped at `MAX_STARS` so an * untrusted attribute can't blow up the star count rendered below. */ private get safeMax(); /** `value`, normalized to a finite number clamped to `[0, safeMax]`. */ private get safeValue(); /** `precision`, normalized to a finite number and kept within `[MIN_PRECISION, safeMax]` — a * `<= 0` precision would otherwise divide-by-zero in `setValue`'s `next / precision` step. */ private get safePrecision(); /** Whether pointer/keyboard input can currently change the value. */ private get interactive();private syncFormValue; /** * Shared with every other form control: own `disabled`, a `
` ancestor, and * `readonly` all bar constraint validation. `readonly` used to be missing here -- every other * read-only-capable control barred on it, so `` reported * `valueMissing` while `` did not. */ private get barredFromValidation();private updateValidity; /** * Publishes the six validity custom states. The implementation lives in * `internal/custom-states.ts` and is shared with the `FormAssociated` mixin, so a consumer's * `lr-rating:state(user-invalid)` rule behaves identically to the same rule on `lr-input`. */ private syncValidityStates; /** Idempotent, and an arrow so it can be handed straight to `addEventListener`. */ private markInteracted;private setValue; /** * The rating the pointer is currently over, snapped up to `precision`, or `null` when the * pointer is between symbols (the gap) rather than on one. Resolved from the symbol's own box * rather than the control's, since the symbols are centred inside a hit-area floor that is * usually wider than they are. */ private pointerValue;private onClick;private onPointerEnter;private onPointerMove; /** Ends the gesture on pointerleave and on pointercancel alike — a touch drag taken over by * scrolling, or palm rejection, ends with `pointercancel` and no `pointerleave` at all. */ private onPointerEnd; /** Drops the preview without announcing an end phase, for teardown paths the user didn't drive. */ private resetHover;private onKeyDown; /** Real keyboard input targets the host semantic owner. Keeping the same handler on the * presentational base supports synthetic integration events without handling a composed native * event twice as it crosses the shadow boundary. */ private onHostKeyDown;focus(options?:FocusOptions):void;blur():void;click():void;private onBlur; /** * Captures a serialized author name before the managed fallback can replace it. Lit's browser * upgrade invokes `attributeChangedCallback()` for an authored `aria-label`, but its server * element renderer seeds template attributes on its host facade without that callback. The * private marker is therefore the durable provenance signal shared by both paths: matching * marker/text is our managed fallback, while unmarked (or mismatched) text belongs to the * author, including an explicitly empty string. */ private captureHostNameProvenance;private syncHostSemantics;protected willUpdate(changed:PropertyValues):void;protected updated(changed:PropertyValues):void; /** One symbol: the consumer's `getSymbol` when set, otherwise the built-in star. */ private symbol; /** Wraps renderer output so a consumer-supplied control cannot compete with the one slider * interaction surface. The star remains the event target carrying `data-value`. */ private renderSymbol;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-rating':LyraRating;}}