@aceshooting/lyra-ui 8.1.0 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -221,6 +221,11 @@ export declare class LyraToolParamForm extends LyraElement<LyraToolParamFormEven
221
221
  private firstInvalidField;
222
222
  private get missingRequiredKeys();
223
223
  private firstMissingPropertyError;
224
+ private focusFirstControl;
225
+ /** Forwards host clicks to the first rendered form field so the component behaves like a regular
226
+ * control from caller code and event re-dispatch paths.
227
+ */
228
+ click(): void;
224
229
  connectedCallback(): void;
225
230
  disconnectedCallback(): void;
226
231
  /** `value`, with any property missing from it filled in from `schema`'s own `default` — see the class doc. */
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{AnchoredValidityController,resolveValidityAnchor,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{styles}from"./tool-param-form.styles.js";import"../../forms/select/select.class.js";import"../../forms/combobox/option.class.js";import"../../forms/checkbox/checkbox.class.js";import{getListFormat}from"../../../internal/intl-cache.js";import{getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldMustBeBoolean,LYRA_DEFAULT_fieldMustBeInteger,LYRA_DEFAULT_fieldMustBeNumber,LYRA_DEFAULT_fieldMustBeOneOf,LYRA_DEFAULT_fieldMustBeString,LYRA_DEFAULT_fieldMustEqual,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_schemaMustBeObject,LYRA_DEFAULT_schemaPropertiesMustBeFlat,LYRA_DEFAULT_toolParamMissingProperty,LYRA_DEFAULT_unsupportedFieldType,LYRA_DEFAULT_valueMustBeSerializable}from"../../../internal/default-strings.generated.js";const EMPTY_SCHEMA={type:"object",properties:{}};function createInternalsSafely(host){if(typeof host.attachInternals!=="function")return createNoopInternals();try{return host.attachInternals()}catch{return createNoopInternals()}}function createNoopInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue(){},setValidity(){},checkValidity(){return true},reportValidity(){return true}}}class LyraToolParamForm extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldMustBeBoolean:LYRA_DEFAULT_fieldMustBeBoolean,fieldMustBeInteger:LYRA_DEFAULT_fieldMustBeInteger,fieldMustBeNumber:LYRA_DEFAULT_fieldMustBeNumber,fieldMustBeOneOf:LYRA_DEFAULT_fieldMustBeOneOf,fieldMustBeString:LYRA_DEFAULT_fieldMustBeString,fieldMustEqual:LYRA_DEFAULT_fieldMustEqual,fieldRequired:LYRA_DEFAULT_fieldRequired,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,schemaMustBeObject:LYRA_DEFAULT_schemaMustBeObject,schemaPropertiesMustBeFlat:LYRA_DEFAULT_schemaPropertiesMustBeFlat,toolParamMissingProperty:LYRA_DEFAULT_toolParamMissingProperty,unsupportedFieldType:LYRA_DEFAULT_unsupportedFieldType,valueMustBeSerializable:LYRA_DEFAULT_valueMustBeSerializable}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},schema:{attribute:false,noAccessor:true},value:{attribute:false,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true}}}constructor(){super();this._errors={};this._formError="";this.showFormError=false;this.touchedFields=new Set;this.baseId=nextId("tool-param-form");this._fieldsetDisabled=false;this._name="";this._schema=EMPTY_SCHEMA;this._value={};this._effectiveValue={};this._validityFlags={};this._disabled=false;this.hasInteracted=false;this.visibleErrorSnapshot=new Map;this.suppressNextErrorAnnouncement=true;this.stopNestedControlEvent=e=>{e.stopPropagation()};this.onFieldFocus=()=>{this.emit("focus")};this.onFieldBlur=()=>{this.emit("blur")};this.internals=createInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,()=>this.emit("lr-invalid"));this.syncFormState()}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}[VALIDITY_ANCHOR](){const field=this.firstInvalidField();if(field){const input=field.querySelector("input.control");if(input)return input;for(const child of field.children){const anchor=resolveValidityAnchor(child);if(anchor)return anchor}}return this.firstMissingPropertyError()}firstInvalidField(){if(!this.renderRoot)return void 0;const fields=Array.from(this.renderRoot.querySelectorAll('[part="field"]'));for(const key of Object.keys(this._errors)){const field=fields.find(candidate=>candidate.dataset["key"]===key);if(field)return field}return void 0}get missingRequiredKeys(){const properties=this.schemaProperties;return this.requiredKeys.filter(key=>!Object.prototype.hasOwnProperty.call(properties,key)&&Boolean(this._errors[key]))}firstMissingPropertyError(){if(!this.renderRoot)return void 0;const errors=Array.from(this.renderRoot.querySelectorAll('[part="error"][data-missing-property]'));for(const key of Object.keys(this._errors)){const error=errors.find(candidate=>candidate.dataset["key"]===key);if(error)return error}return void 0}connectedCallback(){super.connectedCallback();if(this.errorAnnouncementSink?.element.ownerDocument!==this.ownerDocument){this.errorAnnouncementSink?.release();this.errorAnnouncementSink=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this})}if(this.hasUpdated){this.suppressNextErrorAnnouncement=true;this.requestUpdate()}this.syncFormState()}disconnectedCallback(){super.disconnectedCallback();this.errorAnnouncementSink?.release();this.errorAnnouncementSink=void 0;this.suppressNextErrorAnnouncement=true}get effectiveValue(){return{...this._effectiveValue}}get schemaProperties(){const properties=this.schema?.properties;return properties!==null&&typeof properties==="object"&&!Array.isArray(properties)?properties:{}}get requiredKeys(){const required=this.schema?.required;return Array.isArray(required)?required.filter(key=>typeof key==="string"):[]}resolveEffectiveValue(){const props=this.schemaProperties;const out={...this.value};for(const[key,prop]of Object.entries(props)){if(!Object.prototype.hasOwnProperty.call(this.value,key)&&prop.default!==void 0){Object.defineProperty(out,key,{configurable:true,enumerable:true,writable:true,value:prop.default})}}return out}get schema(){return this._schema}set schema(next){const old=this._schema;this._schema=next??EMPTY_SCHEMA;this.syncFormState();this.requestUpdate("schema",old)}get value(){return this._value}set value(next){const old=this._value;this._value=next??{};this.syncFormState();this.requestUpdate("value",old)}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name){this.setAttribute("name",this._name)}else{this.removeAttribute("name")}this.requestUpdate("name",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.applyValidity();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get errors(){return{...this._errors}}get formError(){return this._formError}computeValidation(effective){const props=this.schemaProperties;const required=new Set(this.requiredKeys);const out={};const flags={};const addError=(key,message)=>{Object.defineProperty(out,key,{configurable:true,enumerable:true,writable:true,value:message})};for(const[key,prop]of Object.entries(props)){const type=prop?.type;if(type!=="string"&&type!=="number"&&type!=="integer"&&type!=="boolean"){addError(key,this.localize("unsupportedFieldType",void 0,{type:String(type)}));flags.customError=true;continue}const present=Object.prototype.hasOwnProperty.call(effective,key)&&effective[key]!==void 0;if(!present){if(required.has(key)){addError(key,this.localize("fieldRequired"));flags.valueMissing=true}continue}const v=effective[key];if(type==="string"&&typeof v!=="string"){addError(key,this.localize("fieldMustBeString"));flags.typeMismatch=true;continue}if(type==="number"&&(typeof v!=="number"||!Number.isFinite(v))){addError(key,this.localize("fieldMustBeNumber"));flags.typeMismatch=true;continue}if(type==="integer"&&(typeof v!=="number"||!Number.isFinite(v))){addError(key,this.localize("fieldMustBeInteger"));flags.typeMismatch=true;continue}if(type==="integer"&&!Number.isInteger(v)){addError(key,this.localize("fieldMustBeInteger"));flags.stepMismatch=true;continue}if(type==="boolean"&&typeof v!=="boolean"){addError(key,this.localize("fieldMustBeBoolean"));flags.typeMismatch=true;continue}if(type==="string"&&Array.isArray(prop.enum)&&!prop.enum.includes(v)){addError(key,this.localize("fieldMustBeOneOf",void 0,{values:getListFormat(this.effectiveLocale,{style:"long",type:"disjunction"}).format(prop.enum)}));flags.customError=true;continue}if(prop.const!==void 0&&v!==prop.const){addError(key,this.localize("fieldMustEqual",void 0,{value:JSON.stringify(prop.const)}));flags.customError=true}}for(const key of required){if(Object.prototype.hasOwnProperty.call(props,key))continue;if(!Object.prototype.hasOwnProperty.call(effective,key)||effective[key]===void 0){addError(key,this.localize("fieldRequired"));flags.valueMissing=true}}return{errors:out,flags}}checkValidity(){this.syncFormState();return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.syncFormState();if(Object.keys(this._errors).length>0){this.touchedFields=new Set([...this.touchedFields,...Object.keys(this._errors)])}if(this._formError)this.showFormError=true;const valid=this.internals.reportValidity();if(!valid&&!this.firstInvalidField()&&this.missingRequiredKeys.length>0){void this.updateComplete.then(()=>{const error=this.firstMissingPropertyError();this.validityController.refreshAnchor();error?.focus()})}return valid}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncValidityCustomStates()}formResetCallback(){this.hasInteracted=false;this.value={};this.touchedFields=new Set;this.showFormError=false}formStateRestoreCallback(state2,_mode){let restored={};if(typeof state2==="string"){try{const parsed=JSON.parse(state2);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed)){restored=parsed}}catch{}}this.value=restored}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.applyValidity();this.requestUpdate()}schemaShapeError(){const schema=this.schema;if(schema===null||typeof schema!=="object"||schema.type!=="object"){return this.localize("schemaMustBeObject")}const properties=schema.properties;if(properties===null||typeof properties!=="object"||Array.isArray(properties)){return this.localize("schemaPropertiesMustBeFlat")}return""}serializeEffectiveValue(effective){const serialized=JSON.stringify(effective,(_key,value)=>{if(typeof value==="number"&&!Number.isFinite(value)){throw new TypeError("Non-finite numbers are not JSON values.")}return value});if(typeof serialized!=="string")throw new TypeError("Value did not serialize to JSON.");return serialized}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}syncInternals(formValue){this.internals.setFormValue(formValue,formValue);this.applyValidity()}applyValidity(){if(!this.validityController)return;if(this.barredFromValidation||Object.keys(this._validityFlags).length===0){this.validityController.setValidity({})}else{const firstMessage=Object.values(this._errors)[0]??this._formError;this.validityController.setValidity(this._validityFlags,firstMessage)}this.syncValidityCustomStates()}syncValidityCustomStates(){syncValidityStates(this.internals,{required:this.requiredKeys.length>0,hasInteracted:this.hasInteracted,barred:this.barredFromValidation})}syncFormState(){let effective={};let errors={};let flags={};let formError="";let formValue=null;try{formError=this.schemaShapeError();effective=this.resolveEffectiveValue();const validation=this.computeValidation(effective);errors=validation.errors;flags=validation.flags;formValue=this.serializeEffectiveValue(effective)}catch{formError=this.localize("valueMustBeSerializable");formValue=null}if(formError){flags.customError=true;formValue=null}this._effectiveValue=effective;if(JSON.stringify(this._errors)!==JSON.stringify(errors))this._errors=errors;this._formError=formError;this._validityFlags=flags;this.syncInternals(formValue)}updated(changed){if(changed.has("value")||changed.has("schema")||changed.has("_errors")||changed.has("_formError")){const valid=Object.keys(this._errors).length===0&&this._formError==="";const key=JSON.stringify({valid,errors:this._errors,formError:this._formError});if(key!==this.lastValidityKey){this.lastValidityKey=key;this.emit("lr-validity-change",{valid,errors:{...this._errors}})}const nestedUpdates=Array.from(this.firstInvalidField()?.children??[]).filter(element=>typeof element[VALIDITY_ANCHOR]==="function").map(element=>element.updateComplete).filter(update=>update!==void 0);if(nestedUpdates.length>0){void Promise.all(nestedUpdates).then(()=>this.validityController.refreshAnchor())}}const currentErrors=new Map;for(const node of this.renderRoot.querySelectorAll('[part="error"]')){const fieldKey=node.closest('[part~="field"]')?.dataset["key"];const key=node.dataset["key"]??fieldKey??"form";const text=node.textContent?.trim()??"";if(text)currentErrors.set(key,text)}if(!this.suppressNextErrorAnnouncement){const freshMessages=[];for(const[key,text]of currentErrors){if(this.visibleErrorSnapshot.get(key)!==text&&!freshMessages.includes(text)){freshMessages.push(text)}}if(freshMessages.length>0)this.errorAnnouncementSink?.announce(freshMessages.join(" "))}this.visibleErrorSnapshot=currentErrors;this.suppressNextErrorAnnouncement=false}setFieldValue(key,val){if(this.effectiveDisabled)return;this.hasInteracted=true;this.value={...this.value,[key]:val};this.emit("lr-input",{value:this.effectiveValue})}markTouched(key){this.hasInteracted=true;this.syncValidityCustomStates();if(this.touchedFields.has(key))return;this.touchedFields=new Set(this.touchedFields).add(key)}onTextInput(key,e){this.setFieldValue(key,e.target.value)}onNumberInput(key,e){const raw=e.target;const n=raw.valueAsNumber;this.setFieldValue(key,Number.isNaN(n)?void 0:n)}onSelectChange(key,e){e.stopPropagation();this.setFieldValue(key,e.target.value)}onCheckboxChange(key,e){e.stopPropagation();this.setFieldValue(key,e.detail.checked)}renderControl(key,prop,fieldId,label,required,describedBy,errorMessage,effective){if(prop.type==="string"&&prop.enum&&prop.enum.length>0){return html`<lr-select
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{AnchoredValidityController,resolveValidityAnchor,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{styles}from"./tool-param-form.styles.js";import"../../forms/select/select.class.js";import"../../forms/combobox/option.class.js";import"../../forms/checkbox/checkbox.class.js";import{getListFormat}from"../../../internal/intl-cache.js";import{getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldMustBeBoolean,LYRA_DEFAULT_fieldMustBeInteger,LYRA_DEFAULT_fieldMustBeNumber,LYRA_DEFAULT_fieldMustBeOneOf,LYRA_DEFAULT_fieldMustBeString,LYRA_DEFAULT_fieldMustEqual,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_schemaMustBeObject,LYRA_DEFAULT_schemaPropertiesMustBeFlat,LYRA_DEFAULT_toolParamMissingProperty,LYRA_DEFAULT_unsupportedFieldType,LYRA_DEFAULT_valueMustBeSerializable}from"../../../internal/default-strings.generated.js";const EMPTY_SCHEMA={type:"object",properties:{}};function createInternalsSafely(host){if(typeof host.attachInternals!=="function")return createNoopInternals();try{return host.attachInternals()}catch{return createNoopInternals()}}function createNoopInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue(){},setValidity(){},checkValidity(){return true},reportValidity(){return true}}}class LyraToolParamForm extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldMustBeBoolean:LYRA_DEFAULT_fieldMustBeBoolean,fieldMustBeInteger:LYRA_DEFAULT_fieldMustBeInteger,fieldMustBeNumber:LYRA_DEFAULT_fieldMustBeNumber,fieldMustBeOneOf:LYRA_DEFAULT_fieldMustBeOneOf,fieldMustBeString:LYRA_DEFAULT_fieldMustBeString,fieldMustEqual:LYRA_DEFAULT_fieldMustEqual,fieldRequired:LYRA_DEFAULT_fieldRequired,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,schemaMustBeObject:LYRA_DEFAULT_schemaMustBeObject,schemaPropertiesMustBeFlat:LYRA_DEFAULT_schemaPropertiesMustBeFlat,toolParamMissingProperty:LYRA_DEFAULT_toolParamMissingProperty,unsupportedFieldType:LYRA_DEFAULT_unsupportedFieldType,valueMustBeSerializable:LYRA_DEFAULT_valueMustBeSerializable}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},schema:{attribute:false,noAccessor:true},value:{attribute:false,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true}}}constructor(){super();this._errors={};this._formError="";this.showFormError=false;this.touchedFields=new Set;this.baseId=nextId("tool-param-form");this._fieldsetDisabled=false;this._name="";this._schema=EMPTY_SCHEMA;this._value={};this._effectiveValue={};this._validityFlags={};this._disabled=false;this.hasInteracted=false;this.visibleErrorSnapshot=new Map;this.suppressNextErrorAnnouncement=true;this.stopNestedControlEvent=e=>{e.stopPropagation()};this.onFieldFocus=()=>{this.emit("focus")};this.onFieldBlur=()=>{this.emit("blur")};this.internals=createInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,()=>this.emit("lr-invalid"));this.syncFormState()}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}[VALIDITY_ANCHOR](){const field=this.firstInvalidField();if(field){const input=field.querySelector("input.control");if(input)return input;for(const child of field.children){const anchor=resolveValidityAnchor(child);if(anchor)return anchor}}return this.firstMissingPropertyError()}firstInvalidField(){if(!this.renderRoot)return void 0;const fields=Array.from(this.renderRoot.querySelectorAll('[part="field"]'));for(const key of Object.keys(this._errors)){const field=fields.find(candidate=>candidate.dataset["key"]===key);if(field)return field}return void 0}get missingRequiredKeys(){const properties=this.schemaProperties;return this.requiredKeys.filter(key=>!Object.prototype.hasOwnProperty.call(properties,key)&&Boolean(this._errors[key]))}firstMissingPropertyError(){if(!this.renderRoot)return void 0;const errors=Array.from(this.renderRoot.querySelectorAll('[part="error"][data-missing-property]'));for(const key of Object.keys(this._errors)){const error=errors.find(candidate=>candidate.dataset["key"]===key);if(error)return error}return void 0}focusFirstControl(){if(!this.renderRoot)return;const firstField=this.renderRoot.querySelector('[part="field"]');if(!firstField)return;const control=firstField.querySelector("input.control")||firstField.querySelector("lr-select")||firstField.querySelector("lr-checkbox");control?.focus()}click(){if(this.effectiveDisabled)return;this.focusFirstControl()}connectedCallback(){super.connectedCallback();if(this.errorAnnouncementSink?.element.ownerDocument!==this.ownerDocument){this.errorAnnouncementSink?.release();this.errorAnnouncementSink=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this})}if(this.hasUpdated){this.suppressNextErrorAnnouncement=true;this.requestUpdate()}this.syncFormState()}disconnectedCallback(){super.disconnectedCallback();this.errorAnnouncementSink?.release();this.errorAnnouncementSink=void 0;this.suppressNextErrorAnnouncement=true}get effectiveValue(){return{...this._effectiveValue}}get schemaProperties(){const properties=this.schema?.properties;return properties!==null&&typeof properties==="object"&&!Array.isArray(properties)?properties:{}}get requiredKeys(){const required=this.schema?.required;return Array.isArray(required)?required.filter(key=>typeof key==="string"):[]}resolveEffectiveValue(){const props=this.schemaProperties;const out={...this.value};for(const[key,prop]of Object.entries(props)){if(!Object.prototype.hasOwnProperty.call(this.value,key)&&prop.default!==void 0){Object.defineProperty(out,key,{configurable:true,enumerable:true,writable:true,value:prop.default})}}return out}get schema(){return this._schema}set schema(next){const old=this._schema;this._schema=next??EMPTY_SCHEMA;this.syncFormState();this.requestUpdate("schema",old)}get value(){return this._value}set value(next){const old=this._value;this._value=next??{};this.syncFormState();this.requestUpdate("value",old)}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name){this.setAttribute("name",this._name)}else{this.removeAttribute("name")}this.requestUpdate("name",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.applyValidity();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get errors(){return{...this._errors}}get formError(){return this._formError}computeValidation(effective){const props=this.schemaProperties;const required=new Set(this.requiredKeys);const out={};const flags={};const addError=(key,message)=>{Object.defineProperty(out,key,{configurable:true,enumerable:true,writable:true,value:message})};for(const[key,prop]of Object.entries(props)){const type=prop?.type;if(type!=="string"&&type!=="number"&&type!=="integer"&&type!=="boolean"){addError(key,this.localize("unsupportedFieldType",void 0,{type:String(type)}));flags.customError=true;continue}const present=Object.prototype.hasOwnProperty.call(effective,key)&&effective[key]!==void 0;if(!present){if(required.has(key)){addError(key,this.localize("fieldRequired"));flags.valueMissing=true}continue}const v=effective[key];if(type==="string"&&typeof v!=="string"){addError(key,this.localize("fieldMustBeString"));flags.typeMismatch=true;continue}if(type==="number"&&(typeof v!=="number"||!Number.isFinite(v))){addError(key,this.localize("fieldMustBeNumber"));flags.typeMismatch=true;continue}if(type==="integer"&&(typeof v!=="number"||!Number.isFinite(v))){addError(key,this.localize("fieldMustBeInteger"));flags.typeMismatch=true;continue}if(type==="integer"&&!Number.isInteger(v)){addError(key,this.localize("fieldMustBeInteger"));flags.stepMismatch=true;continue}if(type==="boolean"&&typeof v!=="boolean"){addError(key,this.localize("fieldMustBeBoolean"));flags.typeMismatch=true;continue}if(type==="string"&&Array.isArray(prop.enum)&&!prop.enum.includes(v)){addError(key,this.localize("fieldMustBeOneOf",void 0,{values:getListFormat(this.effectiveLocale,{style:"long",type:"disjunction"}).format(prop.enum)}));flags.customError=true;continue}if(prop.const!==void 0&&v!==prop.const){addError(key,this.localize("fieldMustEqual",void 0,{value:JSON.stringify(prop.const)}));flags.customError=true}}for(const key of required){if(Object.prototype.hasOwnProperty.call(props,key))continue;if(!Object.prototype.hasOwnProperty.call(effective,key)||effective[key]===void 0){addError(key,this.localize("fieldRequired"));flags.valueMissing=true}}return{errors:out,flags}}checkValidity(){this.syncFormState();return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.syncFormState();if(Object.keys(this._errors).length>0){this.touchedFields=new Set([...this.touchedFields,...Object.keys(this._errors)])}if(this._formError)this.showFormError=true;const valid=this.internals.reportValidity();if(!valid&&!this.firstInvalidField()&&this.missingRequiredKeys.length>0){void this.updateComplete.then(()=>{const error=this.firstMissingPropertyError();this.validityController.refreshAnchor();error?.focus()})}return valid}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncValidityCustomStates()}formResetCallback(){this.hasInteracted=false;this.value={};this.touchedFields=new Set;this.showFormError=false}formStateRestoreCallback(state2,_mode){let restored={};if(typeof state2==="string"){try{const parsed=JSON.parse(state2);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed)){restored=parsed}}catch{}}this.value=restored}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.applyValidity();this.requestUpdate()}schemaShapeError(){const schema=this.schema;if(schema===null||typeof schema!=="object"||schema.type!=="object"){return this.localize("schemaMustBeObject")}const properties=schema.properties;if(properties===null||typeof properties!=="object"||Array.isArray(properties)){return this.localize("schemaPropertiesMustBeFlat")}return""}serializeEffectiveValue(effective){const serialized=JSON.stringify(effective,(_key,value)=>{if(typeof value==="number"&&!Number.isFinite(value)){throw new TypeError("Non-finite numbers are not JSON values.")}return value});if(typeof serialized!=="string")throw new TypeError("Value did not serialize to JSON.");return serialized}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}syncInternals(formValue){this.internals.setFormValue(formValue,formValue);this.applyValidity()}applyValidity(){if(!this.validityController)return;if(this.barredFromValidation||Object.keys(this._validityFlags).length===0){this.validityController.setValidity({})}else{const firstMessage=Object.values(this._errors)[0]??this._formError;this.validityController.setValidity(this._validityFlags,firstMessage)}this.syncValidityCustomStates()}syncValidityCustomStates(){syncValidityStates(this.internals,{required:this.requiredKeys.length>0,hasInteracted:this.hasInteracted,barred:this.barredFromValidation})}syncFormState(){let effective={};let errors={};let flags={};let formError="";let formValue=null;try{formError=this.schemaShapeError();effective=this.resolveEffectiveValue();const validation=this.computeValidation(effective);errors=validation.errors;flags=validation.flags;formValue=this.serializeEffectiveValue(effective)}catch{formError=this.localize("valueMustBeSerializable");formValue=null}if(formError){flags.customError=true;formValue=null}this._effectiveValue=effective;if(JSON.stringify(this._errors)!==JSON.stringify(errors))this._errors=errors;this._formError=formError;this._validityFlags=flags;this.syncInternals(formValue)}updated(changed){if(changed.has("value")||changed.has("schema")||changed.has("_errors")||changed.has("_formError")){const valid=Object.keys(this._errors).length===0&&this._formError==="";const key=JSON.stringify({valid,errors:this._errors,formError:this._formError});if(key!==this.lastValidityKey){this.lastValidityKey=key;this.emit("lr-validity-change",{valid,errors:{...this._errors}})}const nestedUpdates=Array.from(this.firstInvalidField()?.children??[]).filter(element=>typeof element[VALIDITY_ANCHOR]==="function").map(element=>element.updateComplete).filter(update=>update!==void 0);if(nestedUpdates.length>0){void Promise.all(nestedUpdates).then(()=>this.validityController.refreshAnchor())}}const currentErrors=new Map;for(const node of this.renderRoot.querySelectorAll('[part="error"]')){const fieldKey=node.closest('[part~="field"]')?.dataset["key"];const key=node.dataset["key"]??fieldKey??"form";const text=node.textContent?.trim()??"";if(text)currentErrors.set(key,text)}if(!this.suppressNextErrorAnnouncement){const freshMessages=[];for(const[key,text]of currentErrors){if(this.visibleErrorSnapshot.get(key)!==text&&!freshMessages.includes(text)){freshMessages.push(text)}}if(freshMessages.length>0)this.errorAnnouncementSink?.announce(freshMessages.join(" "))}this.visibleErrorSnapshot=currentErrors;this.suppressNextErrorAnnouncement=false}setFieldValue(key,val){if(this.effectiveDisabled)return;this.hasInteracted=true;this.value={...this.value,[key]:val};this.emit("lr-input",{value:this.effectiveValue})}markTouched(key){this.hasInteracted=true;this.syncValidityCustomStates();if(this.touchedFields.has(key))return;this.touchedFields=new Set(this.touchedFields).add(key)}onTextInput(key,e){this.setFieldValue(key,e.target.value)}onNumberInput(key,e){const raw=e.target;const n=raw.valueAsNumber;this.setFieldValue(key,Number.isNaN(n)?void 0:n)}onSelectChange(key,e){e.stopPropagation();this.setFieldValue(key,e.target.value)}onCheckboxChange(key,e){e.stopPropagation();this.setFieldValue(key,e.detail.checked)}renderControl(key,prop,fieldId,label,required,describedBy,errorMessage,effective){if(prop.type==="string"&&prop.enum&&prop.enum.length>0){return html`<lr-select
2
2
  id=${fieldId}
3
3
  .label=${label}
4
4
  .hint=${prop.description??""}
@@ -92,4 +92,4 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
92
92
  ${this.hasCustomDataTable()?nothing:this.renderDataTable()}
93
93
  </div>
94
94
  </div>
95
- `}get showsLegend(){return this.legend&&!this.withoutLegend}}__decorate([property({converter:{fromAttribute:value=>normalizeChartType(value)}})],LyraChart.prototype,"type",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"labels",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"datasets",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"legend",void 0);__decorate([property()],LyraChart.prototype,"description",void 0);__decorate([property()],LyraChart.prototype,"grid",void 0);__decorate([property({attribute:"index-axis"})],LyraChart.prototype,"indexAxis",void 0);__decorate([property()],LyraChart.prototype,"label",void 0);__decorate([property({attribute:"legend-position"})],LyraChart.prototype,"legendPosition",void 0);__decorate([property({type:Number})],LyraChart.prototype,"max",void 0);__decorate([property({type:Number})],LyraChart.prototype,"min",void 0);__decorate([property({type:Array})],LyraChart.prototype,"plugins",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"valueFormatter",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"area",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"zoom",void 0);__decorate([property()],LyraChart.prototype,"height",void 0);__decorate([property({attribute:"x-label"})],LyraChart.prototype,"xLabel",void 0);__decorate([property({attribute:"y-label"})],LyraChart.prototype,"yLabel",void 0);__decorate([property({attribute:"y2-label"})],LyraChart.prototype,"y2Label",void 0);__decorate([property({type:Boolean,attribute:"begin-at-zero",converter:trueDefaultBooleanConverter})],LyraChart.prototype,"beginAtZero",void 0);__decorate([property({attribute:"accessible-label"})],LyraChart.prototype,"accessibleLabel",void 0);__decorate([property({attribute:"accessible-description"})],LyraChart.prototype,"accessibleDescription",void 0);__decorate([property({type:Boolean,attribute:"show-data-table"})],LyraChart.prototype,"showDataTable",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"horizontal",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"stacked",void 0);__decorate([property({type:Boolean,attribute:"without-animation",reflect:true})],LyraChart.prototype,"withoutAnimation",void 0);__decorate([property({type:Boolean,attribute:"without-legend",reflect:true})],LyraChart.prototype,"withoutLegend",void 0);__decorate([property({type:Boolean,attribute:"without-tooltip",reflect:true})],LyraChart.prototype,"withoutTooltip",void 0);__decorate([property({type:Boolean,attribute:"data-labels"})],LyraChart.prototype,"dataLabels",void 0);__decorate([property({type:Boolean,attribute:"stack-totals"})],LyraChart.prototype,"stackTotals",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"config",void 0);__decorate([state()],LyraChart.prototype,"slottedConfig",void 0);__decorate([state()],LyraChart.prototype,"loading",void 0);__decorate([state()],LyraChart.prototype,"loadFailed",void 0);__decorate([state()],LyraChart.prototype,"zoomed",void 0);__decorate([state()],LyraChart.prototype,"visible",void 0);__decorate([query("canvas")],LyraChart.prototype,"canvasEl",void 0);__decorate([state()],LyraChart.prototype,"autoLegendPosition",void 0);__decorate([state()],LyraChart.prototype,"keyboardDatumAnnouncement",void 0);function lockChartType(ctor,value){Object.defineProperty(ctor.prototype,"type",{configurable:true,enumerable:true,get(){return value},set(_v){}})}export{LyraChart,lockChartType,seriesPalette2 as seriesPalette};
95
+ `}get showsLegend(){return this.legend&&!this.withoutLegend}}__decorate([property({converter:{fromAttribute:value=>normalizeChartType(value)}})],LyraChart.prototype,"type",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"labels",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"datasets",void 0);__decorate([property({type:Boolean,converter:trueDefaultBooleanConverter})],LyraChart.prototype,"legend",void 0);__decorate([property()],LyraChart.prototype,"description",void 0);__decorate([property()],LyraChart.prototype,"grid",void 0);__decorate([property({attribute:"index-axis"})],LyraChart.prototype,"indexAxis",void 0);__decorate([property()],LyraChart.prototype,"label",void 0);__decorate([property({attribute:"legend-position"})],LyraChart.prototype,"legendPosition",void 0);__decorate([property({type:Number})],LyraChart.prototype,"max",void 0);__decorate([property({type:Number})],LyraChart.prototype,"min",void 0);__decorate([property({type:Array})],LyraChart.prototype,"plugins",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"valueFormatter",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"area",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"zoom",void 0);__decorate([property()],LyraChart.prototype,"height",void 0);__decorate([property({attribute:"x-label"})],LyraChart.prototype,"xLabel",void 0);__decorate([property({attribute:"y-label"})],LyraChart.prototype,"yLabel",void 0);__decorate([property({attribute:"y2-label"})],LyraChart.prototype,"y2Label",void 0);__decorate([property({type:Boolean,attribute:"begin-at-zero",converter:trueDefaultBooleanConverter})],LyraChart.prototype,"beginAtZero",void 0);__decorate([property({attribute:"accessible-label"})],LyraChart.prototype,"accessibleLabel",void 0);__decorate([property({attribute:"accessible-description"})],LyraChart.prototype,"accessibleDescription",void 0);__decorate([property({type:Boolean,attribute:"show-data-table"})],LyraChart.prototype,"showDataTable",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"horizontal",void 0);__decorate([property({type:Boolean})],LyraChart.prototype,"stacked",void 0);__decorate([property({type:Boolean,attribute:"without-animation",reflect:true})],LyraChart.prototype,"withoutAnimation",void 0);__decorate([property({type:Boolean,attribute:"without-legend",reflect:true})],LyraChart.prototype,"withoutLegend",void 0);__decorate([property({type:Boolean,attribute:"without-tooltip",reflect:true})],LyraChart.prototype,"withoutTooltip",void 0);__decorate([property({type:Boolean,attribute:"data-labels"})],LyraChart.prototype,"dataLabels",void 0);__decorate([property({type:Boolean,attribute:"stack-totals"})],LyraChart.prototype,"stackTotals",void 0);__decorate([property({attribute:false})],LyraChart.prototype,"config",void 0);__decorate([state()],LyraChart.prototype,"slottedConfig",void 0);__decorate([state()],LyraChart.prototype,"loading",void 0);__decorate([state()],LyraChart.prototype,"loadFailed",void 0);__decorate([state()],LyraChart.prototype,"zoomed",void 0);__decorate([state()],LyraChart.prototype,"visible",void 0);__decorate([query("canvas")],LyraChart.prototype,"canvasEl",void 0);__decorate([state()],LyraChart.prototype,"autoLegendPosition",void 0);__decorate([state()],LyraChart.prototype,"keyboardDatumAnnouncement",void 0);function lockChartType(ctor,value){Object.defineProperty(ctor.prototype,"type",{configurable:true,enumerable:true,get(){return value},set(_v){}})}export{LyraChart,lockChartType,seriesPalette2 as seriesPalette};
@@ -308,6 +308,10 @@ export declare class LyraGraphQueryBuilder extends LyraElement<LyraGraphQueryBui
308
308
  formResetCallback(): void;
309
309
  formStateRestoreCallback(state: string | File | FormData | null, _mode?: 'restore' | 'autocomplete'): void;
310
310
  formDisabledCallback(disabled: boolean): void;
311
+ private focusFirstControl;
312
+ /** Forwards host clicks to the first rendered control so callers can interact with this wrapper
313
+ * as if it exposed a single root control. */
314
+ click(): void;
311
315
  private setValue;
312
316
  private addRelationshipType;
313
317
  private removeRelationshipType;
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{closeIcon}from"../../../internal/icons.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{finiteInteger}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{nextId}from"../../../internal/a11y.js";import{styles}from"./graph-query-builder.styles.js";import"../../forms/select/select.class.js";import"../../forms/combobox/option.class.js";import"../../forms/input/input.class.js";import"../../overlays/chip/chip.class.js";import"../../overlays/chip/chip-group.class.js";import{getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_date,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_graphQueryBuilderLabel,LYRA_DEFAULT_graphQueryDeleteWithContext,LYRA_DEFAULT_graphQueryDirectionLabel,LYRA_DEFAULT_graphQueryEndLabel,LYRA_DEFAULT_graphQueryHopRangeInvalid,LYRA_DEFAULT_graphQueryLoadWithContext,LYRA_DEFAULT_graphQueryMaxHopsLabel,LYRA_DEFAULT_graphQueryMinHopsLabel,LYRA_DEFAULT_graphQueryNodeTypeLabel,LYRA_DEFAULT_graphQueryRelationshipTypeLabel,LYRA_DEFAULT_graphQueryRun,LYRA_DEFAULT_graphQuerySaveButton,LYRA_DEFAULT_graphQuerySaveNameLabel,LYRA_DEFAULT_graphQuerySavedQueriesLabel,LYRA_DEFAULT_graphQueryStartLabel,LYRA_DEFAULT_neighborDirectionBoth,LYRA_DEFAULT_neighborDirectionIn,LYRA_DEFAULT_neighborDirectionOut,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_search,LYRA_DEFAULT_select}from"../../../internal/default-strings.generated.js";const EMPTY_VALUE={startId:"",endId:"",relationshipTypes:[],nodeTypes:[],direction:"both",minHops:1,maxHops:1};const EMPTY_OPTIONS=[];const EMPTY_SAVED=[];function stringArray(value){if(!Array.isArray(value))return[];return[...new Set(value.filter(entry=>typeof entry==="string"))]}function normalizeGraphQuery(value){const record=value!==null&&typeof value==="object"&&!Array.isArray(value)?value:{};const direction=record["direction"];return{startId:typeof record["startId"]==="string"?record["startId"]:"",endId:typeof record["endId"]==="string"?record["endId"]:"",relationshipTypes:stringArray(record["relationshipTypes"]),nodeTypes:stringArray(record["nodeTypes"]),direction:direction==="out"||direction==="in"||direction==="both"?direction:"both",minHops:finiteInteger(typeof record["minHops"]==="number"?record["minHops"]:EMPTY_VALUE.minHops,EMPTY_VALUE.minHops,1,20),maxHops:finiteInteger(typeof record["maxHops"]==="number"?record["maxHops"]:EMPTY_VALUE.maxHops,EMPTY_VALUE.maxHops,1,20)}}class LyraGraphQueryBuilder extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,graphQueryBuilderLabel:LYRA_DEFAULT_graphQueryBuilderLabel,graphQueryDeleteWithContext:LYRA_DEFAULT_graphQueryDeleteWithContext,graphQueryDirectionLabel:LYRA_DEFAULT_graphQueryDirectionLabel,graphQueryEndLabel:LYRA_DEFAULT_graphQueryEndLabel,graphQueryHopRangeInvalid:LYRA_DEFAULT_graphQueryHopRangeInvalid,graphQueryLoadWithContext:LYRA_DEFAULT_graphQueryLoadWithContext,graphQueryMaxHopsLabel:LYRA_DEFAULT_graphQueryMaxHopsLabel,graphQueryMinHopsLabel:LYRA_DEFAULT_graphQueryMinHopsLabel,graphQueryNodeTypeLabel:LYRA_DEFAULT_graphQueryNodeTypeLabel,graphQueryRelationshipTypeLabel:LYRA_DEFAULT_graphQueryRelationshipTypeLabel,graphQueryRun:LYRA_DEFAULT_graphQueryRun,graphQuerySaveButton:LYRA_DEFAULT_graphQuerySaveButton,graphQuerySaveNameLabel:LYRA_DEFAULT_graphQuerySaveNameLabel,graphQuerySavedQueriesLabel:LYRA_DEFAULT_graphQuerySavedQueriesLabel,graphQueryStartLabel:LYRA_DEFAULT_graphQueryStartLabel,neighborDirectionBoth:LYRA_DEFAULT_neighborDirectionBoth,neighborDirectionIn:LYRA_DEFAULT_neighborDirectionIn,neighborDirectionOut:LYRA_DEFAULT_neighborDirectionOut,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},value:{attribute:false,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true}}}constructor(){super();this.relationshipTypeOptions=EMPTY_OPTIONS;this.nodeTypeOptions=EMPTY_OPTIONS;this.savedQueries=EMPTY_SAVED;this.hopLimit=6;this.label="";this.hint="";this.errorText="";this._errors={};this.touchedFields=new Set;this.saveName="";this.hasHintSlot=false;this.hasErrorSlot=false;this.labelId=nextId("graph-query-builder-label");this.hintId=nextId("graph-query-builder-hint");this.errorId=nextId("graph-query-builder-error");this._fieldsetDisabled=false;this._name="";this._value=EMPTY_VALUE;this._disabled=false;this.hasInteracted=false;this.onChromeSlotChange=event=>{const slot=event.currentTarget;const hasContent=slot.assignedNodes({flatten:true}).some(node=>node.nodeType===Node.TEXT_NODE?Boolean(node.textContent?.trim()):true);if(slot.name==="hint")this.hasHintSlot=hasContent;else if(slot.name==="error")this.hasErrorSlot=hasContent};this.internals=this.safeAttachInternals();this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,()=>this.emit("lr-invalid"));this.syncFormState()}safeAttachInternals(){if(typeof globalThis.ElementInternals==="undefined"){return this.inertInternals()}try{return this.attachInternals()}catch{return this.inertInternals()}}inertInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue:()=>{},setValidity:()=>{},checkValidity:()=>true,reportValidity:()=>true,states:new Set}}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}get value(){return this._value}set value(next){const old=this._value;this._value=normalizeGraphQuery(next);this.syncFormState();this.requestUpdate("value",old)}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.requestUpdate("name",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);if(this.validityController)this.syncFormState();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get errors(){return{...this._errors}}[VALIDITY_ANCHOR](){const firstInvalidPart=Object.keys(this._errors)[0];if(!firstInvalidPart||!this.renderRoot)return void 0;return this.renderRoot.querySelector(`[part="${firstInvalidPart}"]`)??void 0}computeValidation(){const errors={};const flags={};if(!this._value.startId.trim()){errors["start-input"]=this.localize("fieldRequired");flags.valueMissing=true}if(this._value.minHops>this._value.maxHops){errors["max-hops"]=this.localize("graphQueryHopRangeInvalid");flags.rangeUnderflow=true}return{errors,flags}}syncFormState(){const{errors,flags}=this.computeValidation();this._errors=errors;let formValue=null;try{formValue=JSON.stringify(this._value)}catch{formValue=null}this.internals.setFormValue(formValue,formValue);if(this.barredFromValidation||Object.keys(flags).length===0){this.validityController.setValidity({})}else{const message=Object.values(errors)[0]??"";this.validityController.setValidity(flags,message)}this.syncValidityCustomStates()}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}syncValidityCustomStates(){syncValidityStates(this.internals,{required:true,hasInteracted:this.hasInteracted,barred:this.barredFromValidation})}checkValidity(){this.syncFormState();return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.syncFormState();if(Object.keys(this._errors).length>0){this.touchedFields=new Set([...this.touchedFields,...Object.keys(this._errors)])}return this.internals.reportValidity()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncValidityCustomStates()}formResetCallback(){this.hasInteracted=false;this.value=EMPTY_VALUE;this.touchedFields=new Set;this.saveName=""}formStateRestoreCallback(state2,_mode){let restored=EMPTY_VALUE;if(typeof state2==="string"){try{const parsed=JSON.parse(state2);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed)){restored=normalizeGraphQuery(parsed)}}catch{}}this.value=restored}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.syncFormState();this.requestUpdate()}setValue(next){if(this.effectiveDisabled)return;this.hasInteracted=true;this.value=next;this.emit("lr-input",{value:{...this._value}})}addRelationshipType(type){if(!type||this._value.relationshipTypes.includes(type))return;this.setValue({...this._value,relationshipTypes:[...this._value.relationshipTypes,type]})}removeRelationshipType(type){this.setValue({...this._value,relationshipTypes:this._value.relationshipTypes.filter(t=>t!==type)})}addNodeType(type){if(!type||this._value.nodeTypes.includes(type))return;this.setValue({...this._value,nodeTypes:[...this._value.nodeTypes,type]})}removeNodeType(type){this.setValue({...this._value,nodeTypes:this._value.nodeTypes.filter(t=>t!==type)})}markTouched(part){this.hasInteracted=true;this.syncValidityCustomStates();if(this.touchedFields.has(part))return;this.touchedFields=new Set(this.touchedFields).add(part)}runQuery(){if(this.effectiveDisabled)return;if(!this.reportValidity())return;this.emit("lr-query-run",{query:{...this._value}})}saveQuery(){if(this.effectiveDisabled)return;const name=this.saveName.trim();if(!name)return;this.emit("lr-query-save",{name,query:{...this._value}});this.saveName=""}loadQuery(item){if(this.effectiveDisabled)return;this.setValue({...EMPTY_VALUE,...item.query});this.emit("lr-query-load",{id:item.id,query:{...this._value}})}deleteQuery(item){if(this.effectiveDisabled)return;this.emit("lr-query-delete",{id:item.id})}updated(changed){if(changed.has("value")||changed.has("_errors")){const valid=Object.keys(this._errors).length===0;const key=JSON.stringify({valid,errors:this._errors});if(key!==this.lastValidityKey){this.lastValidityKey=key;this.emit("lr-validity-change",{valid,errors:{...this._errors}})}}}hopOptions(){const limit=finiteInteger(this.hopLimit,6,1,20);const options=new Set(Array.from({length:limit},(_,i)=>i+1));options.add(this._value.minHops);options.add(this._value.maxHops);return[...options].sort((a,b)=>a-b)}labelForType(options,value){return options.find(o=>o.value===value)?.label??value}renderTypeFilter(kind,options,selected,add,remove,disabled){const pickerPart=kind==="relationship"?"relationship-picker":"node-type-picker";const chipsPart=kind==="relationship"?"relationship-chips":"node-type-chips";const pickerLabel=kind==="relationship"?this.localize("graphQueryRelationshipTypeLabel"):this.localize("graphQueryNodeTypeLabel");const available=options.filter(o=>!selected.includes(o.value));return html`
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{closeIcon}from"../../../internal/icons.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{finiteInteger}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{nextId}from"../../../internal/a11y.js";import{styles}from"./graph-query-builder.styles.js";import"../../forms/select/select.class.js";import"../../forms/combobox/option.class.js";import"../../forms/input/input.class.js";import"../../overlays/chip/chip.class.js";import"../../overlays/chip/chip-group.class.js";import{getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_date,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_graphQueryBuilderLabel,LYRA_DEFAULT_graphQueryDeleteWithContext,LYRA_DEFAULT_graphQueryDirectionLabel,LYRA_DEFAULT_graphQueryEndLabel,LYRA_DEFAULT_graphQueryHopRangeInvalid,LYRA_DEFAULT_graphQueryLoadWithContext,LYRA_DEFAULT_graphQueryMaxHopsLabel,LYRA_DEFAULT_graphQueryMinHopsLabel,LYRA_DEFAULT_graphQueryNodeTypeLabel,LYRA_DEFAULT_graphQueryRelationshipTypeLabel,LYRA_DEFAULT_graphQueryRun,LYRA_DEFAULT_graphQuerySaveButton,LYRA_DEFAULT_graphQuerySaveNameLabel,LYRA_DEFAULT_graphQuerySavedQueriesLabel,LYRA_DEFAULT_graphQueryStartLabel,LYRA_DEFAULT_neighborDirectionBoth,LYRA_DEFAULT_neighborDirectionIn,LYRA_DEFAULT_neighborDirectionOut,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_search,LYRA_DEFAULT_select}from"../../../internal/default-strings.generated.js";const EMPTY_VALUE={startId:"",endId:"",relationshipTypes:[],nodeTypes:[],direction:"both",minHops:1,maxHops:1};const EMPTY_OPTIONS=[];const EMPTY_SAVED=[];function stringArray(value){if(!Array.isArray(value))return[];return[...new Set(value.filter(entry=>typeof entry==="string"))]}function normalizeGraphQuery(value){const record=value!==null&&typeof value==="object"&&!Array.isArray(value)?value:{};const direction=record["direction"];return{startId:typeof record["startId"]==="string"?record["startId"]:"",endId:typeof record["endId"]==="string"?record["endId"]:"",relationshipTypes:stringArray(record["relationshipTypes"]),nodeTypes:stringArray(record["nodeTypes"]),direction:direction==="out"||direction==="in"||direction==="both"?direction:"both",minHops:finiteInteger(typeof record["minHops"]==="number"?record["minHops"]:EMPTY_VALUE.minHops,EMPTY_VALUE.minHops,1,20),maxHops:finiteInteger(typeof record["maxHops"]==="number"?record["maxHops"]:EMPTY_VALUE.maxHops,EMPTY_VALUE.maxHops,1,20)}}class LyraGraphQueryBuilder extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,date:LYRA_DEFAULT_date,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,graphQueryBuilderLabel:LYRA_DEFAULT_graphQueryBuilderLabel,graphQueryDeleteWithContext:LYRA_DEFAULT_graphQueryDeleteWithContext,graphQueryDirectionLabel:LYRA_DEFAULT_graphQueryDirectionLabel,graphQueryEndLabel:LYRA_DEFAULT_graphQueryEndLabel,graphQueryHopRangeInvalid:LYRA_DEFAULT_graphQueryHopRangeInvalid,graphQueryLoadWithContext:LYRA_DEFAULT_graphQueryLoadWithContext,graphQueryMaxHopsLabel:LYRA_DEFAULT_graphQueryMaxHopsLabel,graphQueryMinHopsLabel:LYRA_DEFAULT_graphQueryMinHopsLabel,graphQueryNodeTypeLabel:LYRA_DEFAULT_graphQueryNodeTypeLabel,graphQueryRelationshipTypeLabel:LYRA_DEFAULT_graphQueryRelationshipTypeLabel,graphQueryRun:LYRA_DEFAULT_graphQueryRun,graphQuerySaveButton:LYRA_DEFAULT_graphQuerySaveButton,graphQuerySaveNameLabel:LYRA_DEFAULT_graphQuerySaveNameLabel,graphQuerySavedQueriesLabel:LYRA_DEFAULT_graphQuerySavedQueriesLabel,graphQueryStartLabel:LYRA_DEFAULT_graphQueryStartLabel,neighborDirectionBoth:LYRA_DEFAULT_neighborDirectionBoth,neighborDirectionIn:LYRA_DEFAULT_neighborDirectionIn,neighborDirectionOut:LYRA_DEFAULT_neighborDirectionOut,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,search:LYRA_DEFAULT_search,select:LYRA_DEFAULT_select}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},value:{attribute:false,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true}}}constructor(){super();this.relationshipTypeOptions=EMPTY_OPTIONS;this.nodeTypeOptions=EMPTY_OPTIONS;this.savedQueries=EMPTY_SAVED;this.hopLimit=6;this.label="";this.hint="";this.errorText="";this._errors={};this.touchedFields=new Set;this.saveName="";this.hasHintSlot=false;this.hasErrorSlot=false;this.labelId=nextId("graph-query-builder-label");this.hintId=nextId("graph-query-builder-hint");this.errorId=nextId("graph-query-builder-error");this._fieldsetDisabled=false;this._name="";this._value=EMPTY_VALUE;this._disabled=false;this.hasInteracted=false;this.onChromeSlotChange=event=>{const slot=event.currentTarget;const hasContent=slot.assignedNodes({flatten:true}).some(node=>node.nodeType===Node.TEXT_NODE?Boolean(node.textContent?.trim()):true);if(slot.name==="hint")this.hasHintSlot=hasContent;else if(slot.name==="error")this.hasErrorSlot=hasContent};this.internals=this.safeAttachInternals();this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,()=>this.emit("lr-invalid"));this.syncFormState()}safeAttachInternals(){if(typeof globalThis.ElementInternals==="undefined"){return this.inertInternals()}try{return this.attachInternals()}catch{return this.inertInternals()}}inertInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue:()=>{},setValidity:()=>{},checkValidity:()=>true,reportValidity:()=>true,states:new Set}}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}get value(){return this._value}set value(next){const old=this._value;this._value=normalizeGraphQuery(next);this.syncFormState();this.requestUpdate("value",old)}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.requestUpdate("name",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);if(this.validityController)this.syncFormState();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get errors(){return{...this._errors}}[VALIDITY_ANCHOR](){const firstInvalidPart=Object.keys(this._errors)[0];if(!firstInvalidPart||!this.renderRoot)return void 0;return this.renderRoot.querySelector(`[part="${firstInvalidPart}"]`)??void 0}computeValidation(){const errors={};const flags={};if(!this._value.startId.trim()){errors["start-input"]=this.localize("fieldRequired");flags.valueMissing=true}if(this._value.minHops>this._value.maxHops){errors["max-hops"]=this.localize("graphQueryHopRangeInvalid");flags.rangeUnderflow=true}return{errors,flags}}syncFormState(){const{errors,flags}=this.computeValidation();this._errors=errors;let formValue=null;try{formValue=JSON.stringify(this._value)}catch{formValue=null}this.internals.setFormValue(formValue,formValue);if(this.barredFromValidation||Object.keys(flags).length===0){this.validityController.setValidity({})}else{const message=Object.values(errors)[0]??"";this.validityController.setValidity(flags,message)}this.syncValidityCustomStates()}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}syncValidityCustomStates(){syncValidityStates(this.internals,{required:true,hasInteracted:this.hasInteracted,barred:this.barredFromValidation})}checkValidity(){this.syncFormState();return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.syncFormState();if(Object.keys(this._errors).length>0){this.touchedFields=new Set([...this.touchedFields,...Object.keys(this._errors)])}return this.internals.reportValidity()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncValidityCustomStates()}formResetCallback(){this.hasInteracted=false;this.value=EMPTY_VALUE;this.touchedFields=new Set;this.saveName=""}formStateRestoreCallback(state2,_mode){let restored=EMPTY_VALUE;if(typeof state2==="string"){try{const parsed=JSON.parse(state2);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed)){restored=normalizeGraphQuery(parsed)}}catch{}}this.value=restored}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.syncFormState();this.requestUpdate()}focusFirstControl(){if(!this.renderRoot||this.effectiveDisabled)return;const control=this.renderRoot.querySelector('[part="start-input"]')||this.renderRoot.querySelector('[part="end-input"]')||this.renderRoot.querySelector('[part="min-hops"]')||this.renderRoot.querySelector('[part="max-hops"]')||this.renderRoot.querySelector('[part="direction"]')||this.renderRoot.querySelector('[part="save-name-input"]');control?.focus()}click(){this.focusFirstControl()}setValue(next){if(this.effectiveDisabled)return;this.hasInteracted=true;this.value=next;this.emit("lr-input",{value:{...this._value}})}addRelationshipType(type){if(!type||this._value.relationshipTypes.includes(type))return;this.setValue({...this._value,relationshipTypes:[...this._value.relationshipTypes,type]})}removeRelationshipType(type){this.setValue({...this._value,relationshipTypes:this._value.relationshipTypes.filter(t=>t!==type)})}addNodeType(type){if(!type||this._value.nodeTypes.includes(type))return;this.setValue({...this._value,nodeTypes:[...this._value.nodeTypes,type]})}removeNodeType(type){this.setValue({...this._value,nodeTypes:this._value.nodeTypes.filter(t=>t!==type)})}markTouched(part){this.hasInteracted=true;this.syncValidityCustomStates();if(this.touchedFields.has(part))return;this.touchedFields=new Set(this.touchedFields).add(part)}runQuery(){if(this.effectiveDisabled)return;if(!this.reportValidity())return;this.emit("lr-query-run",{query:{...this._value}})}saveQuery(){if(this.effectiveDisabled)return;const name=this.saveName.trim();if(!name)return;this.emit("lr-query-save",{name,query:{...this._value}});this.saveName=""}loadQuery(item){if(this.effectiveDisabled)return;this.setValue({...EMPTY_VALUE,...item.query});this.emit("lr-query-load",{id:item.id,query:{...this._value}})}deleteQuery(item){if(this.effectiveDisabled)return;this.emit("lr-query-delete",{id:item.id})}updated(changed){if(changed.has("value")||changed.has("_errors")){const valid=Object.keys(this._errors).length===0;const key=JSON.stringify({valid,errors:this._errors});if(key!==this.lastValidityKey){this.lastValidityKey=key;this.emit("lr-validity-change",{valid,errors:{...this._errors}})}}}hopOptions(){const limit=finiteInteger(this.hopLimit,6,1,20);const options=new Set(Array.from({length:limit},(_,i)=>i+1));options.add(this._value.minHops);options.add(this._value.maxHops);return[...options].sort((a,b)=>a-b)}labelForType(options,value){return options.find(o=>o.value===value)?.label??value}renderTypeFilter(kind,options,selected,add,remove,disabled){const pickerPart=kind==="relationship"?"relationship-picker":"node-type-picker";const chipsPart=kind==="relationship"?"relationship-chips":"node-type-chips";const pickerLabel=kind==="relationship"?this.localize("graphQueryRelationshipTypeLabel"):this.localize("graphQueryNodeTypeLabel");const available=options.filter(o=>!selected.includes(o.value));return html`
2
2
  <div part="filter-group" data-kind=${kind}>
3
3
  <lr-select
4
4
  part=${pickerPart}
@@ -229,6 +229,9 @@ export declare class LyraCheckboxGroup extends LyraElement<LyraCheckboxGroupEven
229
229
  * The message is caller-supplied content, so it is used verbatim and never localized here.
230
230
  */
231
231
  setCustomValidity(message: string): void;
232
+ private focusFirstControl;
233
+ /** Forwards host clicks to the first enabled checkbox in the group. */
234
+ click(): void;
232
235
  formResetCallback(): void;
233
236
  formStateRestoreCallback(state: string | File | FormData | null, _mode?: 'restore' | 'autocomplete'): void;
234
237
  formDisabledCallback(disabled: boolean): void;
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{nextId}from"../../../internal/a11y.js";import{sizes}from"../../../internal/sizes.styles.js";import{styles}from"./checkbox-group.styles.js";import{createStringArrayFormDataState,getFormOwner,installCustomErrorProperty,isBarredFromValidation,readStringArrayFormDataState,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{LYRA_DEFAULT_checkboxGroupRequired,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_open,LYRA_DEFAULT_restore}from"../../../internal/default-strings.generated.js";function createInternalsSafely(host){if(typeof host.attachInternals!=="function")return createNoopInternals();try{return host.attachInternals()}catch{return createNoopInternals()}}function createNoopInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue(){},setValidity(){},checkValidity(){return true},reportValidity(){return true}}}function warnValueAssigned(group){console.warn(`<lr-checkbox-group> \`value\` is derived from its <lr-checkbox> children and is overwritten by the next sync (any child toggle, a slot change, a \`name\`/\`required\` change, blur, or form reset), so assigning it has no lasting effect${group.name?` (name="${group.name}")`:""}. Set \`checked\` on the children instead.`)}function warnDuplicateValue(group,value){console.warn(`<lr-checkbox-group> has more than one <lr-checkbox> child with value="${value}"${group.name?` (name="${group.name}")`:""}; every checked one contributes an identical FormData entry, so the submitted data cannot say which was checked. Give each child a distinct \`value\`.`)}class LyraCheckboxGroup extends LyraElement{static{this.defaultStrings={...super.defaultStrings,checkboxGroupRequired:LYRA_DEFAULT_checkboxGroupRequired,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,sizes,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},required:{type:Boolean,reflect:true,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true},size:{reflect:true},orientation:{reflect:true},value:{attribute:false,noAccessor:true}}}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.sync();this.requestUpdate("name",old)}get value(){return this._value}set value(next){if(!this._writingValue&&!this._warnedValueAssigned){this._warnedValueAssigned=true;warnValueAssigned(this)}const old=this._value;this._value=Array.isArray(next)?next:[];this.requestUpdate("value",old)}get required(){return this._required}set required(next){const old=this._required;this._required=Boolean(next);this.toggleAttribute("required",this._required);this.sync();this.requestUpdate("required",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.propagateDisabled();this.sync();this.requestUpdate("disabled",old)}constructor(){super();this.size="m";this.orientation="vertical";this.label="";this.hint="";this.withLabel=false;this.withHint=false;this.errorText="";this.accessibleLabel="";this.touched=false;this.hasInteracted=false;this.hasLabelSlot=false;this.hasHintSlot=false;this.hasErrorSlot=false;this.labelId=nextId("checkbox-group-label");this.hintId=nextId("checkbox-group-hint");this.errorId=nextId("checkbox-group-error");this._fieldsetDisabled=false;this._name="";this._required=false;this._disabled=false;this._value=[];this._writingValue=false;this._warnedValueAssigned=false;this._warnedDuplicateValues=new Set;this.childObserverGeneration=0;this.childControllers=new Map;this.onChildEvent=event=>{if(!this.isOwnedCheckbox(event.target))return;event.stopImmediatePropagation();if(event.type!=="change"||this.effectiveDisabled)return;this.hasInteracted=true;this.sync();this.emit("input",{value:this.value});this.emit("change",{value:this.value});this.emit("lr-change",{value:this.value})};this.onChildMutations=records=>{if(records.some(record=>record.type==="childList"||record.attributeName==="slot")){this.onSlotChange();return}if(records.some(record=>record.attributeName==="size"&&this.isOwnedCheckbox(record.target))){this.propagateSize()}if(records.some(record=>this.isOwnedCheckbox(record.target)))this.sync()};this.onSlotChange=()=>{this.hasLabelSlot=this.hasDirectSupportSlot("label");this.hasHintSlot=this.hasDirectSupportSlot("hint");this.hasErrorSlot=this.hasDirectSupportSlot("error");this.reconcileChildControllers();if(!this.applyPendingRestore())this.sync();this.propagateDisabled();this.propagateSize()};this.internals=createInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,init=>this.emit("lr-invalid",void 0,init))}checkboxGroupOwner(element){const group=element.closest("lr-checkbox-group");if(!group)return null;let topLevelChild=element;while(topLevelChild.parentElement&&topLevelChild.parentElement!==group){topLevelChild=topLevelChild.parentElement}if(topLevelChild.parentElement!==group)return null;const slot=topLevelChild.getAttribute("slot");return slot==="label"||slot==="hint"||slot==="error"?null:group}ownsCheckbox(element){return element.localName==="lr-checkbox"&&this.checkboxGroupOwner(element)===this}get boxes(){const querySelectorAll=this.querySelectorAll;if(typeof querySelectorAll!=="function")return[];return Array.from(querySelectorAll.call(this,"lr-checkbox")).filter(box=>this.ownsCheckbox(box))}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}propagateDisabled(){const effective=this.effectiveDisabled;this.boxes.forEach(box=>box.setGroupDisabled?.(effective))}propagateSize(){this.boxes.forEach(box=>{box.size=this.size})}readValue(){return this.boxes.filter(box=>box.checked).map(box=>box.value??"on")}warnOnDuplicateValues(){const seen=new Set;for(const box of this.boxes){const value=box.value??box.getAttribute("value")??"on";if(!seen.has(value)){seen.add(value);continue}if(this._warnedDuplicateValues.has(value))continue;this._warnedDuplicateValues.add(value);warnDuplicateValue(this,value)}}sync(){const next=this.readValue();this.warnOnDuplicateValues();this._writingValue=true;try{this.value=next}finally{this._writingValue=false}const data=new FormData;if(this.name)next.forEach(value=>data.append(this.name,value));this.internals.setFormValue(this.name?data:null,createStringArrayFormDataState(this.name,next));if(!this.barredFromValidation&&this.required&&next.length===0)this.validityController.setValidity({valueMissing:true},this.localize("checkboxGroupRequired"));else this.validityController.setValidity({});this.reflectValidityStates()}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}reflectValidityStates(){const barred=this.barredFromValidation;this.toggleAttribute("data-invalid",!barred&&this.touched&&!this.internals.validity.valid);syncValidityStates(this.internals,{required:this.required,hasInteracted:this.hasInteracted,barred})}isOwnedCheckbox(target){return target?.nodeType===1&&this.ownsCheckbox(target)}reconcileChildControllers(){const current=new Set(this.boxes);for(const[box,controller]of this.childControllers){if(current.has(box))continue;box.removeController(controller);this.childControllers.delete(box);const nextOwner=this.checkboxGroupOwner(box);if(!nextOwner||nextOwner===this)box.setGroupDisabled?.(false)}for(const box of current){if(this.childControllers.has(box)||typeof box.addController!=="function")continue;const controller={hostUpdated:()=>{if(this.isConnected&&this.ownsCheckbox(box))this.sync()}};box.addController(controller);this.childControllers.set(box,controller)}}hasDirectSupportSlot(name){return Array.from(this.children).some(child=>child.getAttribute("slot")===name)}applyPendingRestore(){if(this.pendingRestoreValues===void 0||this.boxes.length===0)return false;const remaining=[...this.pendingRestoreValues];this.pendingRestoreValues=void 0;for(const box of this.boxes){const value=box.value??"on";const index=remaining.indexOf(value);box.checked=index>=0;if(index>=0)remaining.splice(index,1)}this.touched=false;this.hasInteracted=false;this.sync();return true}connectedCallback(){super.connectedCallback();this.addEventListener("input",this.onChildEvent);this.addEventListener("change",this.onChildEvent);this.addEventListener("lr-change",this.onChildEvent);this.onSlotChange();this.armChildObserver()}armChildObserver(){const ownerDocument=this.ownerDocument;if(!this.isConnected)return;if(this.childObserver&&this.childObserverDocument===ownerDocument)return;this.resetChildObserver();const MutationObserverCtor=ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor)return;const generation=this.childObserverGeneration;const observer=new MutationObserverCtor(records=>{if(this.childObserver!==observer||this.childObserverDocument!==ownerDocument||this.childObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument){return}this.onChildMutations(records)});this.childObserver=observer;this.childObserverDocument=ownerDocument;observer.observe(this,{attributes:true,childList:true,subtree:true,attributeFilter:["checked","value","disabled","size","slot"]})}disconnectedCallback(){this.removeEventListener("input",this.onChildEvent);this.removeEventListener("change",this.onChildEvent);this.removeEventListener("lr-change",this.onChildEvent);this.resetChildObserver();for(const[box,controller]of this.childControllers){box.removeController(controller);box.setGroupDisabled?.(false)}this.childControllers.clear();super.disconnectedCallback()}adoptedCallback(){this.resetChildObserver()}resetChildObserver(){this.childObserverGeneration+=1;this.childObserver?.disconnect();this.childObserver=void 0;this.childObserverDocument=void 0}firstUpdated(){this.addEventListener("blur",()=>{this.touched=true;this.hasInteracted=true;this.sync()},true)}updated(changed){super.updated(changed);if(changed.has("size"))this.propagateSize()}[VALIDITY_ANCHOR](){return this.renderRoot?.querySelector('[part~="options"]')??null}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}checkValidity(){return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.reflectValidityStates();return this.internals.reportValidity()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.reflectValidityStates();this.requestUpdate()}formResetCallback(){this.boxes.forEach(box=>box.resetFromGroup());this.touched=false;this.hasInteracted=false;this.sync()}formStateRestoreCallback(state2,_mode){this.pendingRestoreValues=readStringArrayFormDataState(state2);this.applyPendingRestore()}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.propagateDisabled();this.sync();this.requestUpdate()}render(){const hasLabel=this.hasLabelSlot||Boolean(this.label)||this.withLabel;const hasHint=this.hasHintSlot||Boolean(this.hint)||this.withHint;const described=[hasHint?this.hintId:"",this.hasErrorSlot||this.errorText?this.errorId:""].filter(Boolean).join(" ")||nothing;return html`<fieldset
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{nextId}from"../../../internal/a11y.js";import{sizes}from"../../../internal/sizes.styles.js";import{styles}from"./checkbox-group.styles.js";import{createStringArrayFormDataState,getFormOwner,installCustomErrorProperty,isBarredFromValidation,readStringArrayFormDataState,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{LYRA_DEFAULT_checkboxGroupRequired,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_open,LYRA_DEFAULT_restore}from"../../../internal/default-strings.generated.js";function createInternalsSafely(host){if(typeof host.attachInternals!=="function")return createNoopInternals();try{return host.attachInternals()}catch{return createNoopInternals()}}function createNoopInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue(){},setValidity(){},checkValidity(){return true},reportValidity(){return true}}}function warnValueAssigned(group){console.warn(`<lr-checkbox-group> \`value\` is derived from its <lr-checkbox> children and is overwritten by the next sync (any child toggle, a slot change, a \`name\`/\`required\` change, blur, or form reset), so assigning it has no lasting effect${group.name?` (name="${group.name}")`:""}. Set \`checked\` on the children instead.`)}function warnDuplicateValue(group,value){console.warn(`<lr-checkbox-group> has more than one <lr-checkbox> child with value="${value}"${group.name?` (name="${group.name}")`:""}; every checked one contributes an identical FormData entry, so the submitted data cannot say which was checked. Give each child a distinct \`value\`.`)}class LyraCheckboxGroup extends LyraElement{static{this.defaultStrings={...super.defaultStrings,checkboxGroupRequired:LYRA_DEFAULT_checkboxGroupRequired,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,sizes,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},required:{type:Boolean,reflect:true,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true},size:{reflect:true},orientation:{reflect:true},value:{attribute:false,noAccessor:true}}}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.sync();this.requestUpdate("name",old)}get value(){return this._value}set value(next){if(!this._writingValue&&!this._warnedValueAssigned){this._warnedValueAssigned=true;warnValueAssigned(this)}const old=this._value;this._value=Array.isArray(next)?next:[];this.requestUpdate("value",old)}get required(){return this._required}set required(next){const old=this._required;this._required=Boolean(next);this.toggleAttribute("required",this._required);this.sync();this.requestUpdate("required",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.propagateDisabled();this.sync();this.requestUpdate("disabled",old)}constructor(){super();this.size="m";this.orientation="vertical";this.label="";this.hint="";this.withLabel=false;this.withHint=false;this.errorText="";this.accessibleLabel="";this.touched=false;this.hasInteracted=false;this.hasLabelSlot=false;this.hasHintSlot=false;this.hasErrorSlot=false;this.labelId=nextId("checkbox-group-label");this.hintId=nextId("checkbox-group-hint");this.errorId=nextId("checkbox-group-error");this._fieldsetDisabled=false;this._name="";this._required=false;this._disabled=false;this._value=[];this._writingValue=false;this._warnedValueAssigned=false;this._warnedDuplicateValues=new Set;this.childObserverGeneration=0;this.childControllers=new Map;this.onChildEvent=event=>{if(!this.isOwnedCheckbox(event.target))return;event.stopImmediatePropagation();if(event.type!=="change"||this.effectiveDisabled)return;this.hasInteracted=true;this.sync();this.emit("input",{value:this.value});this.emit("change",{value:this.value});this.emit("lr-change",{value:this.value})};this.onChildMutations=records=>{if(records.some(record=>record.type==="childList"||record.attributeName==="slot")){this.onSlotChange();return}if(records.some(record=>record.attributeName==="size"&&this.isOwnedCheckbox(record.target))){this.propagateSize()}if(records.some(record=>this.isOwnedCheckbox(record.target)))this.sync()};this.onSlotChange=()=>{this.hasLabelSlot=this.hasDirectSupportSlot("label");this.hasHintSlot=this.hasDirectSupportSlot("hint");this.hasErrorSlot=this.hasDirectSupportSlot("error");this.reconcileChildControllers();if(!this.applyPendingRestore())this.sync();this.propagateDisabled();this.propagateSize()};this.internals=createInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,init=>this.emit("lr-invalid",void 0,init))}checkboxGroupOwner(element){const group=element.closest("lr-checkbox-group");if(!group)return null;let topLevelChild=element;while(topLevelChild.parentElement&&topLevelChild.parentElement!==group){topLevelChild=topLevelChild.parentElement}if(topLevelChild.parentElement!==group)return null;const slot=topLevelChild.getAttribute("slot");return slot==="label"||slot==="hint"||slot==="error"?null:group}ownsCheckbox(element){return element.localName==="lr-checkbox"&&this.checkboxGroupOwner(element)===this}get boxes(){const querySelectorAll=this.querySelectorAll;if(typeof querySelectorAll!=="function")return[];return Array.from(querySelectorAll.call(this,"lr-checkbox")).filter(box=>this.ownsCheckbox(box))}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}propagateDisabled(){const effective=this.effectiveDisabled;this.boxes.forEach(box=>box.setGroupDisabled?.(effective))}propagateSize(){this.boxes.forEach(box=>{box.size=this.size})}readValue(){return this.boxes.filter(box=>box.checked).map(box=>box.value??"on")}warnOnDuplicateValues(){const seen=new Set;for(const box of this.boxes){const value=box.value??box.getAttribute("value")??"on";if(!seen.has(value)){seen.add(value);continue}if(this._warnedDuplicateValues.has(value))continue;this._warnedDuplicateValues.add(value);warnDuplicateValue(this,value)}}sync(){const next=this.readValue();this.warnOnDuplicateValues();this._writingValue=true;try{this.value=next}finally{this._writingValue=false}const data=new FormData;if(this.name)next.forEach(value=>data.append(this.name,value));this.internals.setFormValue(this.name?data:null,createStringArrayFormDataState(this.name,next));if(!this.barredFromValidation&&this.required&&next.length===0)this.validityController.setValidity({valueMissing:true},this.localize("checkboxGroupRequired"));else this.validityController.setValidity({});this.reflectValidityStates()}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}reflectValidityStates(){const barred=this.barredFromValidation;this.toggleAttribute("data-invalid",!barred&&this.touched&&!this.internals.validity.valid);syncValidityStates(this.internals,{required:this.required,hasInteracted:this.hasInteracted,barred})}isOwnedCheckbox(target){return target?.nodeType===1&&this.ownsCheckbox(target)}reconcileChildControllers(){const current=new Set(this.boxes);for(const[box,controller]of this.childControllers){if(current.has(box))continue;box.removeController(controller);this.childControllers.delete(box);const nextOwner=this.checkboxGroupOwner(box);if(!nextOwner||nextOwner===this)box.setGroupDisabled?.(false)}for(const box of current){if(this.childControllers.has(box)||typeof box.addController!=="function")continue;const controller={hostUpdated:()=>{if(this.isConnected&&this.ownsCheckbox(box))this.sync()}};box.addController(controller);this.childControllers.set(box,controller)}}hasDirectSupportSlot(name){return Array.from(this.children).some(child=>child.getAttribute("slot")===name)}applyPendingRestore(){if(this.pendingRestoreValues===void 0||this.boxes.length===0)return false;const remaining=[...this.pendingRestoreValues];this.pendingRestoreValues=void 0;for(const box of this.boxes){const value=box.value??"on";const index=remaining.indexOf(value);box.checked=index>=0;if(index>=0)remaining.splice(index,1)}this.touched=false;this.hasInteracted=false;this.sync();return true}connectedCallback(){super.connectedCallback();this.addEventListener("input",this.onChildEvent);this.addEventListener("change",this.onChildEvent);this.addEventListener("lr-change",this.onChildEvent);this.onSlotChange();this.armChildObserver()}armChildObserver(){const ownerDocument=this.ownerDocument;if(!this.isConnected)return;if(this.childObserver&&this.childObserverDocument===ownerDocument)return;this.resetChildObserver();const MutationObserverCtor=ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor)return;const generation=this.childObserverGeneration;const observer=new MutationObserverCtor(records=>{if(this.childObserver!==observer||this.childObserverDocument!==ownerDocument||this.childObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument){return}this.onChildMutations(records)});this.childObserver=observer;this.childObserverDocument=ownerDocument;observer.observe(this,{attributes:true,childList:true,subtree:true,attributeFilter:["checked","value","disabled","size","slot"]})}disconnectedCallback(){this.removeEventListener("input",this.onChildEvent);this.removeEventListener("change",this.onChildEvent);this.removeEventListener("lr-change",this.onChildEvent);this.resetChildObserver();for(const[box,controller]of this.childControllers){box.removeController(controller);box.setGroupDisabled?.(false)}this.childControllers.clear();super.disconnectedCallback()}adoptedCallback(){this.resetChildObserver()}resetChildObserver(){this.childObserverGeneration+=1;this.childObserver?.disconnect();this.childObserver=void 0;this.childObserverDocument=void 0}firstUpdated(){this.addEventListener("blur",()=>{this.touched=true;this.hasInteracted=true;this.sync()},true)}updated(changed){super.updated(changed);if(changed.has("size"))this.propagateSize()}[VALIDITY_ANCHOR](){return this.renderRoot?.querySelector('[part~="options"]')??null}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}checkValidity(){return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.reflectValidityStates();return this.internals.reportValidity()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.reflectValidityStates();this.requestUpdate()}focusFirstControl(){const first=this.boxes.find(box=>!box.effectiveDisabled);first?.focus()}click(){this.focusFirstControl()}formResetCallback(){this.boxes.forEach(box=>box.resetFromGroup());this.touched=false;this.hasInteracted=false;this.sync()}formStateRestoreCallback(state2,_mode){this.pendingRestoreValues=readStringArrayFormDataState(state2);this.applyPendingRestore()}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.propagateDisabled();this.sync();this.requestUpdate()}render(){const hasLabel=this.hasLabelSlot||Boolean(this.label)||this.withLabel;const hasHint=this.hasHintSlot||Boolean(this.hint)||this.withHint;const described=[hasHint?this.hintId:"",this.hasErrorSlot||this.errorText?this.errorId:""].filter(Boolean).join(" ")||nothing;return html`<fieldset
2
2
  part="form-control"
3
3
  ?disabled=${this.effectiveDisabled}
4
4
  aria-label=${this.accessibleLabel||nothing}
@@ -193,6 +193,9 @@ export declare class LyraRadioGroup extends LyraElement<LyraRadioGroupEventMap>
193
193
  private onRadioSlotChange;
194
194
  /** Moves focus to the selected enabled option, or the first enabled option when empty. */
195
195
  focus(options?: FocusOptions): void;
196
+ /** Activates the selected/first enabled option, matching host click semantics on the internal
197
+ * radio collection rather than leaving `<lr-radio-group>` a no-op. */
198
+ click(): void;
196
199
  private syncFormState;
197
200
  /** Shared with every other form control: disabled (own or fieldset-cascaded) bars validation. */
198
201
  private get barredFromValidation();
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{tag}from"../../../internal/prefix.js";import{sizes}from"../../../internal/sizes.styles.js";import{groupStyles}from"./radio-group.styles.js";import{dispatchNativeEvent,dispatchNativeInputEvent}from"../../../internal/native-event-relay.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{attachInternalsSafely,getFormOwner,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{omittedEmptyStringConverter}from"../../../internal/converters.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_open,LYRA_DEFAULT_radioRequired,LYRA_DEFAULT_restore}from"../../../internal/default-strings.generated.js";const RADIO_TAGS=()=>[tag("radio"),tag("radio-button")];class LyraRadioGroup extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,open:LYRA_DEFAULT_open,radioRequired:LYRA_DEFAULT_radioRequired,restore:LYRA_DEFAULT_restore}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,sizes,groupStyles]}static{this.properties={name:{reflect:true,noAccessor:true,converter:omittedEmptyStringConverter},value:{attribute:false,noAccessor:true},defaultValue:{attribute:"value",reflect:true,useDefault:true,noAccessor:true},customError:{attribute:"custom-error",reflect:true,noAccessor:true},required:{type:Boolean,reflect:true,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true},orientation:{reflect:true},form:{noAccessor:true}}}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.syncFormState();this.requestUpdate("name",old)}get value(){return this._value}set value(next){this._valueDirty=true;this.selectValue(next??"")}get defaultValue(){return this._defaultValue}set defaultValue(next){if(this.reflectingDefaultValue)return;const old=this._defaultValue;this._defaultValue=next??"";this.reflectingDefaultValue=true;try{if(this._defaultValue)this.setAttribute("value",this._defaultValue);else this.removeAttribute("value")}finally{this.reflectingDefaultValue=false}if(!this._valueDirty){this.selectValue(this._defaultValue);this._valueDirty=false}this.requestUpdate("defaultValue",old)}get customError(){return this.validityController?.customValidityMessage||null}set customError(next){if(this.reflectingCustomError)return;const old=this.customError;const message=next??"";this.reflectingCustomError=true;try{if(next==null)this.removeAttribute("custom-error");else this.setAttribute("custom-error",message)}finally{this.reflectingCustomError=false}this.setCustomValidity(message);this.requestUpdate("customError",old)}get required(){return this._required}set required(next){const old=this._required;this._required=Boolean(next);this.toggleAttribute("required",this._required);this.syncRadios();this.updateValidity();this.requestUpdate("required",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.syncRadios();this.updateValidity();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}constructor(){super();this.size="m";this.orientation="vertical";this.label="";this.hint="";this.helpText="";this.shoelaceDefaultValue="";this.withLabel=false;this.withHint=false;this.errorText="";this.accessibleLabel="";this.hasLabelSlot=false;this.hasHintSlot=false;this.hasHelpTextSlot=false;this.hasErrorSlot=false;this.labelId=nextId("radio-group-label");this.hintId=nextId("radio-group-hint");this.errorId=nextId("radio-group-error");this.managedRadios=new Set;this.authorNames=new Map;this.syncingRadios=false;this.membershipObserverGeneration=0;this._name="";this._value="";this._defaultValue="";this._valueDirty=false;this.reflectingDefaultValue=false;this.reflectingCustomError=false;this._required=false;this._disabled=false;this._fieldsetDisabled=false;this.hasInteracted=false;this.hadShoelaceDefaultValue=false;this.onInvalid=event=>{const target=event.target;if(target!==this&&!(target?.nodeType===1&&this.ownsRadio(target))){return}const alias=this.emit("lr-invalid",void 0,{cancelable:true});if(alias.defaultPrevented)event.preventDefault()};this.onKeyDown=event=>{const arrows=this.orientation==="horizontal"?["ArrowRight","ArrowLeft"]:["ArrowDown","ArrowUp"];if(![...arrows,"Home","End"].includes(event.key))return;if(this.effectiveDisabled)return;const radios=this.radios().filter(radio=>!radio.effectiveDisabled);const current=event.target;if(current.effectiveDisabled)return;const index=radios.indexOf(current);if(index<0||radios.length===0)return;event.preventDefault();const rtl=this.effectiveDirection==="rtl";const forward=this.orientation==="vertical"?event.key==="ArrowDown":rtl?event.key==="ArrowLeft":event.key==="ArrowRight";const backward=this.orientation==="vertical"?event.key==="ArrowUp":rtl?event.key==="ArrowRight":event.key==="ArrowLeft";const nextIndex=event.key==="Home"?0:event.key==="End"?radios.length-1:forward?(index+1)%radios.length:backward?(index-1+radios.length)%radios.length:index;const next=radios[nextIndex];next.focus();next.activateFromGroup()};this.onSlotChange=event=>{const slot=event.target;const elements=slot.assignedElements({flatten:true});if(slot.name==="label")this.hasLabelSlot=elements.length>0;if(slot.name==="hint")this.hasHintSlot=elements.length>0;if(slot.name==="help-text")this.hasHelpTextSlot=elements.length>0;if(slot.name==="error")this.hasErrorSlot=elements.length>0};this.onRadioSlotChange=()=>{this.syncRadios();const ownerDocument=this.ownerDocument;const generation=this.membershipObserverGeneration;const ownerWindow=ownerDocument.defaultView;if(!ownerWindow)return;ownerWindow.queueMicrotask(()=>{if(this.membershipObserverGeneration===generation&&this.isConnected&&this.ownerDocument===ownerDocument){this.syncRadios()}})};this.internals=attachInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());this.addEventListener("invalid",this.onInvalid,true);this.syncFormState();this.updateValidity()}connectedCallback(){super.connectedCallback();this.syncSupportSlots();this.syncRadios();this.armMembershipObserver()}armMembershipObserver(){const ownerDocument=this.ownerDocument;if(!this.isConnected)return;if(this.membershipObserver&&this.membershipObserverDocument===ownerDocument)return;this.resetMembershipObserver();const ownerWindow=ownerDocument.defaultView;const MutationObserverCtor=ownerWindow?.MutationObserver;if(!ownerWindow||!MutationObserverCtor)return;const generation=this.membershipObserverGeneration;const observer=new MutationObserverCtor(()=>{if(this.membershipObserver!==observer||this.membershipObserverDocument!==ownerDocument||this.membershipObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument){return}ownerWindow.queueMicrotask(()=>{if(this.membershipObserver!==observer||this.membershipObserverDocument!==ownerDocument||this.membershipObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument){return}this.syncRadios()})});this.membershipObserver=observer;this.membershipObserverDocument=ownerDocument;observer.observe(this,{attributes:true,childList:true,subtree:true,attributeFilter:["slot","checked","disabled","value","size"]})}disconnectedCallback(){this.resetMembershipObserver();this.releaseRadios(this.managedRadios);this.managedRadios.clear();super.disconnectedCallback()}adoptedCallback(){this.resetMembershipObserver()}resetMembershipObserver(){this.membershipObserverGeneration+=1;this.membershipObserver?.disconnect();this.membershipObserver=void 0;this.membershipObserverDocument=void 0}willUpdate(changed){super.willUpdate(changed);if(changed.has("shoelaceDefaultValue")&&(this.hasAttribute("default-value")||this.hadShoelaceDefaultValue)){this.defaultValue=this.shoelaceDefaultValue;this.hadShoelaceDefaultValue=this.hasAttribute("default-value")}}updated(changed){super.updated(changed);this.syncRadios()}syncSupportSlots(){this.hasLabelSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="label");this.hasHintSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="hint");this.hasHelpTextSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="help-text");this.hasErrorSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="error")}radioGroupOwner(element){const group=element.closest(tag("radio-group"));if(!group)return null;let topLevelChild=element;while(topLevelChild.parentElement&&topLevelChild.parentElement!==group){topLevelChild=topLevelChild.parentElement}if(topLevelChild.parentElement!==group)return null;const slot=topLevelChild.getAttribute("slot");return slot==="label"||slot==="hint"||slot==="help-text"||slot==="error"?null:group}ownsRadio(element){return RADIO_TAGS().includes(element.localName)&&this.radioGroupOwner(element)===this}radios(){const querySelectorAll=this.querySelectorAll;if(typeof querySelectorAll!=="function")return[];return[...querySelectorAll.call(this,RADIO_TAGS().join(","))].filter(radio=>this.ownsRadio(radio)&&typeof radio.setGroupOwner==="function")}selectValue(next){const desired=next??"";const radios=this.radios();if(radios.length===0){const old=this._value;this._value=desired;this.pendingSelection=desired;this.syncFormState();this.updateValidity();this.requestUpdate("value",old);return}const match=radios.find(radio=>radio.value===desired);this.syncingRadios=true;try{for(const radio of radios)radio.checked=radio===match}finally{this.syncingRadios=false}this.pendingSelection=void 0;this.syncRadios(match)}syncRadios(preferred){if(this.syncingRadios)return;this.syncingRadios=true;try{const radios=this.radios();const current=new Set(radios);this.releaseRadios([...this.managedRadios].filter(radio=>!current.has(radio)));for(const radio of radios){radio.setGroupOwner(this);if(!this.managedRadios.has(radio)){this.authorNames.set(radio,radio.name)}}this.managedRadios=current;for(const radio of radios)radio.setGroupDisabled(this.effectiveDisabled);const enabled=radios.filter(radio=>!radio.effectiveDisabled);let checked=radios.filter(radio=>radio.checked);let checkedRadio;if(this.pendingSelection!==void 0&&radios.length>0){checkedRadio=radios.find(radio=>radio.value===this.pendingSelection);for(const radio of radios)radio.checked=radio===checkedRadio;checked=checkedRadio?[checkedRadio]:[];this.pendingSelection=void 0}else{checkedRadio=preferred?.checked&&current.has(preferred)?preferred:checked[checked.length-1]}for(const radio of checked){if(radio!==checkedRadio)radio.checked=false}const tabbableRadio=checkedRadio&&!checkedRadio.effectiveDisabled?checkedRadio:enabled[0];for(const radio of radios){radio.name=this.name||this.authorNames.get(radio)||"";radio.size=this.size;radio.setGroupRequired(this.required&&!this.effectiveDisabled);radio.setGroupTabbable(radio===tabbableRadio)}const oldValue=this._value;this._value=checkedRadio?.value??"";this.syncFormState();this.updateValidity();if(oldValue!==this._value)this.requestUpdate("value",oldValue)}finally{this.syncingRadios=false}}releaseRadios(radios){for(const radio of radios){const authorName=this.authorNames.get(radio)??radio.name;this.authorNames.delete(radio);radio.releaseGroupOwner(this,authorName)}}reconcileRadio(radio){if(!this.ownsRadio(radio))return false;this.syncRadios(radio.checked?radio:void 0);return true}releaseRadio(radio){if(!this.managedRadios.has(radio)&&!this.authorNames.has(radio))return;this.releaseRadios([radio]);this.managedRadios.delete(radio);this.syncRadios()}radioCheckedChanged(radio){if(this.syncingRadios||!this.ownsRadio(radio))return;this._valueDirty=true;this.syncRadios(radio.checked?radio:void 0)}selectRadio(radio){if(this.effectiveDisabled||radio.effectiveDisabled||!this.ownsRadio(radio))return false;this._valueDirty=true;this.hasInteracted=true;this.syncingRadios=true;try{for(const candidate of this.radios())candidate.checked=candidate===radio}finally{this.syncingRadios=false}this.syncRadios();dispatchNativeInputEvent(this);this.emit("lr-input",{value:radio.value,radio});dispatchNativeEvent(this,"change");this.emit("lr-change",{value:radio.value,radio});return true}focus(options){const enabled=this.radios().filter(radio=>!radio.effectiveDisabled);(enabled.find(radio=>radio.checked)??enabled[0])?.focus(options)}[VALIDITY_ANCHOR](){return this.renderRoot?.querySelector('[part~="base"]')??null}syncFormState(){if(!this.internals)return;this.internals.setFormValue(this.name&&this.value?this.value:null,this.value)}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}updateValidity(){if(!this.validityController)return;const missing=!this.barredFromValidation&&this.required&&!this.value;this.validityController.setValidity(missing?{valueMissing:true}:{},missing?this.localize("radioRequired"):"");this.reflectValidityStates()}reflectValidityStates(){syncValidityStates(this.internals,{required:this.required,hasInteracted:this.hasInteracted,barred:this.barredFromValidation})}checkValidity(){return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.updateValidity();return this.internals.reportValidity()}setCustomValidity(message=""){this.validityController.setCustomValidity(message??"");this.reflectValidityStates();this.requestUpdate()}resetValidity(){this.validityController.setCustomValidity("");this.updateValidity();this.requestUpdate()}formResetCallback(){this._valueDirty=false;this.pendingSelection=void 0;this.syncingRadios=true;try{for(const radio of this.radios())radio.resetFromGroup()}finally{this.syncingRadios=false}if(this.defaultValue)this.pendingSelection=this.defaultValue;this.hasInteracted=false;this.syncRadios()}formStateRestoreCallback(state2,reason){void reason;this._valueDirty=true;this.hasInteracted=false;this.pendingSelection=typeof state2==="string"?state2:"";this.selectValue(this.pendingSelection)}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.syncRadios();this.updateValidity();this.requestUpdate()}render(){const hasLabel=this.hasLabelSlot||Boolean(this.label)||this.withLabel;const hasHint=this.hasHintSlot||this.hasHelpTextSlot||Boolean(this.hint||this.helpText)||this.withHint;const hasError=this.hasErrorSlot||Boolean(this.errorText);const described=[hasHint?this.hintId:"",hasError?this.errorId:""].filter(Boolean).join(" ")||nothing;return html`
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{tag}from"../../../internal/prefix.js";import{sizes}from"../../../internal/sizes.styles.js";import{groupStyles}from"./radio-group.styles.js";import{dispatchNativeEvent,dispatchNativeInputEvent}from"../../../internal/native-event-relay.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{attachInternalsSafely,getFormOwner,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{omittedEmptyStringConverter}from"../../../internal/converters.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_open,LYRA_DEFAULT_radioRequired,LYRA_DEFAULT_restore}from"../../../internal/default-strings.generated.js";const RADIO_TAGS=()=>[tag("radio"),tag("radio-button")];class LyraRadioGroup extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,open:LYRA_DEFAULT_open,radioRequired:LYRA_DEFAULT_radioRequired,restore:LYRA_DEFAULT_restore}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,sizes,groupStyles]}static{this.properties={name:{reflect:true,noAccessor:true,converter:omittedEmptyStringConverter},value:{attribute:false,noAccessor:true},defaultValue:{attribute:"value",reflect:true,useDefault:true,noAccessor:true},customError:{attribute:"custom-error",reflect:true,noAccessor:true},required:{type:Boolean,reflect:true,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true},orientation:{reflect:true},form:{noAccessor:true}}}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.syncFormState();this.requestUpdate("name",old)}get value(){return this._value}set value(next){this._valueDirty=true;this.selectValue(next??"")}get defaultValue(){return this._defaultValue}set defaultValue(next){if(this.reflectingDefaultValue)return;const old=this._defaultValue;this._defaultValue=next??"";this.reflectingDefaultValue=true;try{if(this._defaultValue)this.setAttribute("value",this._defaultValue);else this.removeAttribute("value")}finally{this.reflectingDefaultValue=false}if(!this._valueDirty){this.selectValue(this._defaultValue);this._valueDirty=false}this.requestUpdate("defaultValue",old)}get customError(){return this.validityController?.customValidityMessage||null}set customError(next){if(this.reflectingCustomError)return;const old=this.customError;const message=next??"";this.reflectingCustomError=true;try{if(next==null)this.removeAttribute("custom-error");else this.setAttribute("custom-error",message)}finally{this.reflectingCustomError=false}this.setCustomValidity(message);this.requestUpdate("customError",old)}get required(){return this._required}set required(next){const old=this._required;this._required=Boolean(next);this.toggleAttribute("required",this._required);this.syncRadios();this.updateValidity();this.requestUpdate("required",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.syncRadios();this.updateValidity();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}constructor(){super();this.size="m";this.orientation="vertical";this.label="";this.hint="";this.helpText="";this.shoelaceDefaultValue="";this.withLabel=false;this.withHint=false;this.errorText="";this.accessibleLabel="";this.hasLabelSlot=false;this.hasHintSlot=false;this.hasHelpTextSlot=false;this.hasErrorSlot=false;this.labelId=nextId("radio-group-label");this.hintId=nextId("radio-group-hint");this.errorId=nextId("radio-group-error");this.managedRadios=new Set;this.authorNames=new Map;this.syncingRadios=false;this.membershipObserverGeneration=0;this._name="";this._value="";this._defaultValue="";this._valueDirty=false;this.reflectingDefaultValue=false;this.reflectingCustomError=false;this._required=false;this._disabled=false;this._fieldsetDisabled=false;this.hasInteracted=false;this.hadShoelaceDefaultValue=false;this.onInvalid=event=>{const target=event.target;if(target!==this&&!(target?.nodeType===1&&this.ownsRadio(target))){return}const alias=this.emit("lr-invalid",void 0,{cancelable:true});if(alias.defaultPrevented)event.preventDefault()};this.onKeyDown=event=>{const arrows=this.orientation==="horizontal"?["ArrowRight","ArrowLeft"]:["ArrowDown","ArrowUp"];if(![...arrows,"Home","End"].includes(event.key))return;if(this.effectiveDisabled)return;const radios=this.radios().filter(radio=>!radio.effectiveDisabled);const current=event.target;if(current.effectiveDisabled)return;const index=radios.indexOf(current);if(index<0||radios.length===0)return;event.preventDefault();const rtl=this.effectiveDirection==="rtl";const forward=this.orientation==="vertical"?event.key==="ArrowDown":rtl?event.key==="ArrowLeft":event.key==="ArrowRight";const backward=this.orientation==="vertical"?event.key==="ArrowUp":rtl?event.key==="ArrowRight":event.key==="ArrowLeft";const nextIndex=event.key==="Home"?0:event.key==="End"?radios.length-1:forward?(index+1)%radios.length:backward?(index-1+radios.length)%radios.length:index;const next=radios[nextIndex];next.focus();next.activateFromGroup()};this.onSlotChange=event=>{const slot=event.target;const elements=slot.assignedElements({flatten:true});if(slot.name==="label")this.hasLabelSlot=elements.length>0;if(slot.name==="hint")this.hasHintSlot=elements.length>0;if(slot.name==="help-text")this.hasHelpTextSlot=elements.length>0;if(slot.name==="error")this.hasErrorSlot=elements.length>0};this.onRadioSlotChange=()=>{this.syncRadios();const ownerDocument=this.ownerDocument;const generation=this.membershipObserverGeneration;const ownerWindow=ownerDocument.defaultView;if(!ownerWindow)return;ownerWindow.queueMicrotask(()=>{if(this.membershipObserverGeneration===generation&&this.isConnected&&this.ownerDocument===ownerDocument){this.syncRadios()}})};this.internals=attachInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());this.addEventListener("invalid",this.onInvalid,true);this.syncFormState();this.updateValidity()}connectedCallback(){super.connectedCallback();this.syncSupportSlots();this.syncRadios();this.armMembershipObserver()}armMembershipObserver(){const ownerDocument=this.ownerDocument;if(!this.isConnected)return;if(this.membershipObserver&&this.membershipObserverDocument===ownerDocument)return;this.resetMembershipObserver();const ownerWindow=ownerDocument.defaultView;const MutationObserverCtor=ownerWindow?.MutationObserver;if(!ownerWindow||!MutationObserverCtor)return;const generation=this.membershipObserverGeneration;const observer=new MutationObserverCtor(()=>{if(this.membershipObserver!==observer||this.membershipObserverDocument!==ownerDocument||this.membershipObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument){return}ownerWindow.queueMicrotask(()=>{if(this.membershipObserver!==observer||this.membershipObserverDocument!==ownerDocument||this.membershipObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument){return}this.syncRadios()})});this.membershipObserver=observer;this.membershipObserverDocument=ownerDocument;observer.observe(this,{attributes:true,childList:true,subtree:true,attributeFilter:["slot","checked","disabled","value","size"]})}disconnectedCallback(){this.resetMembershipObserver();this.releaseRadios(this.managedRadios);this.managedRadios.clear();super.disconnectedCallback()}adoptedCallback(){this.resetMembershipObserver()}resetMembershipObserver(){this.membershipObserverGeneration+=1;this.membershipObserver?.disconnect();this.membershipObserver=void 0;this.membershipObserverDocument=void 0}willUpdate(changed){super.willUpdate(changed);if(changed.has("shoelaceDefaultValue")&&(this.hasAttribute("default-value")||this.hadShoelaceDefaultValue)){this.defaultValue=this.shoelaceDefaultValue;this.hadShoelaceDefaultValue=this.hasAttribute("default-value")}}updated(changed){super.updated(changed);this.syncRadios()}syncSupportSlots(){this.hasLabelSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="label");this.hasHintSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="hint");this.hasHelpTextSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="help-text");this.hasErrorSlot=Array.from(this.children).some(element=>element.getAttribute("slot")==="error")}radioGroupOwner(element){const group=element.closest(tag("radio-group"));if(!group)return null;let topLevelChild=element;while(topLevelChild.parentElement&&topLevelChild.parentElement!==group){topLevelChild=topLevelChild.parentElement}if(topLevelChild.parentElement!==group)return null;const slot=topLevelChild.getAttribute("slot");return slot==="label"||slot==="hint"||slot==="help-text"||slot==="error"?null:group}ownsRadio(element){return RADIO_TAGS().includes(element.localName)&&this.radioGroupOwner(element)===this}radios(){const querySelectorAll=this.querySelectorAll;if(typeof querySelectorAll!=="function")return[];return[...querySelectorAll.call(this,RADIO_TAGS().join(","))].filter(radio=>this.ownsRadio(radio)&&typeof radio.setGroupOwner==="function")}selectValue(next){const desired=next??"";const radios=this.radios();if(radios.length===0){const old=this._value;this._value=desired;this.pendingSelection=desired;this.syncFormState();this.updateValidity();this.requestUpdate("value",old);return}const match=radios.find(radio=>radio.value===desired);this.syncingRadios=true;try{for(const radio of radios)radio.checked=radio===match}finally{this.syncingRadios=false}this.pendingSelection=void 0;this.syncRadios(match)}syncRadios(preferred){if(this.syncingRadios)return;this.syncingRadios=true;try{const radios=this.radios();const current=new Set(radios);this.releaseRadios([...this.managedRadios].filter(radio=>!current.has(radio)));for(const radio of radios){radio.setGroupOwner(this);if(!this.managedRadios.has(radio)){this.authorNames.set(radio,radio.name)}}this.managedRadios=current;for(const radio of radios)radio.setGroupDisabled(this.effectiveDisabled);const enabled=radios.filter(radio=>!radio.effectiveDisabled);let checked=radios.filter(radio=>radio.checked);let checkedRadio;if(this.pendingSelection!==void 0&&radios.length>0){checkedRadio=radios.find(radio=>radio.value===this.pendingSelection);for(const radio of radios)radio.checked=radio===checkedRadio;checked=checkedRadio?[checkedRadio]:[];this.pendingSelection=void 0}else{checkedRadio=preferred?.checked&&current.has(preferred)?preferred:checked[checked.length-1]}for(const radio of checked){if(radio!==checkedRadio)radio.checked=false}const tabbableRadio=checkedRadio&&!checkedRadio.effectiveDisabled?checkedRadio:enabled[0];for(const radio of radios){radio.name=this.name||this.authorNames.get(radio)||"";radio.size=this.size;radio.setGroupRequired(this.required&&!this.effectiveDisabled);radio.setGroupTabbable(radio===tabbableRadio)}const oldValue=this._value;this._value=checkedRadio?.value??"";this.syncFormState();this.updateValidity();if(oldValue!==this._value)this.requestUpdate("value",oldValue)}finally{this.syncingRadios=false}}releaseRadios(radios){for(const radio of radios){const authorName=this.authorNames.get(radio)??radio.name;this.authorNames.delete(radio);radio.releaseGroupOwner(this,authorName)}}reconcileRadio(radio){if(!this.ownsRadio(radio))return false;this.syncRadios(radio.checked?radio:void 0);return true}releaseRadio(radio){if(!this.managedRadios.has(radio)&&!this.authorNames.has(radio))return;this.releaseRadios([radio]);this.managedRadios.delete(radio);this.syncRadios()}radioCheckedChanged(radio){if(this.syncingRadios||!this.ownsRadio(radio))return;this._valueDirty=true;this.syncRadios(radio.checked?radio:void 0)}selectRadio(radio){if(this.effectiveDisabled||radio.effectiveDisabled||!this.ownsRadio(radio))return false;this._valueDirty=true;this.hasInteracted=true;this.syncingRadios=true;try{for(const candidate of this.radios())candidate.checked=candidate===radio}finally{this.syncingRadios=false}this.syncRadios();dispatchNativeInputEvent(this);this.emit("lr-input",{value:radio.value,radio});dispatchNativeEvent(this,"change");this.emit("lr-change",{value:radio.value,radio});return true}focus(options){const enabled=this.radios().filter(radio=>!radio.effectiveDisabled);(enabled.find(radio=>radio.checked)??enabled[0])?.focus(options)}click(){if(this.effectiveDisabled)return;const enabled=this.radios().filter(radio=>!radio.effectiveDisabled);(enabled.find(radio=>radio.checked)??enabled[0])?.click()}[VALIDITY_ANCHOR](){return this.renderRoot?.querySelector('[part~="base"]')??null}syncFormState(){if(!this.internals)return;this.internals.setFormValue(this.name&&this.value?this.value:null,this.value)}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}updateValidity(){if(!this.validityController)return;const missing=!this.barredFromValidation&&this.required&&!this.value;this.validityController.setValidity(missing?{valueMissing:true}:{},missing?this.localize("radioRequired"):"");this.reflectValidityStates()}reflectValidityStates(){syncValidityStates(this.internals,{required:this.required,hasInteracted:this.hasInteracted,barred:this.barredFromValidation})}checkValidity(){return this.internals.checkValidity()}reportValidity(){this.hasInteracted=true;this.updateValidity();return this.internals.reportValidity()}setCustomValidity(message=""){this.validityController.setCustomValidity(message??"");this.reflectValidityStates();this.requestUpdate()}resetValidity(){this.validityController.setCustomValidity("");this.updateValidity();this.requestUpdate()}formResetCallback(){this._valueDirty=false;this.pendingSelection=void 0;this.syncingRadios=true;try{for(const radio of this.radios())radio.resetFromGroup()}finally{this.syncingRadios=false}if(this.defaultValue)this.pendingSelection=this.defaultValue;this.hasInteracted=false;this.syncRadios()}formStateRestoreCallback(state2,reason){void reason;this._valueDirty=true;this.hasInteracted=false;this.pendingSelection=typeof state2==="string"?state2:"";this.selectValue(this.pendingSelection)}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.syncRadios();this.updateValidity();this.requestUpdate()}render(){const hasLabel=this.hasLabelSlot||Boolean(this.label)||this.withLabel;const hasHint=this.hasHintSlot||this.hasHelpTextSlot||Boolean(this.hint||this.helpText)||this.withHint;const hasError=this.hasErrorSlot||Boolean(this.errorText);const described=[hasHint?this.hintId:"",hasError?this.errorId:""].filter(Boolean).join(" ")||nothing;return html`
2
2
  <div part="base" role="radiogroup"
3
3
  aria-label=${this.accessibleLabel||nothing}
4
4
  aria-labelledby=${!this.accessibleLabel&&hasLabel?this.labelId:nothing}
@@ -258,6 +258,9 @@ export declare class LyraRubricForm extends LyraElement<LyraRubricFormEventMap>
258
258
  private submit;
259
259
  private skip;
260
260
  private focusFirstControl;
261
+ /** Forwards host clicks to the first rendered field, so programmatic and `<label>`-driven
262
+ * interactions target the active rubric field. */
263
+ click(): void;
261
264
  protected updated(changed: PropertyValues): void;
262
265
  private renderScoreControl;
263
266
  private renderCategoryControl;
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{state}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{styles}from"./rubric-form.styles.js";import"../../layout/segmented/segmented.class.js";import"../slider/slider.class.js";import"../select/select.class.js";import"../combobox/option.class.js";import"../checkbox/checkbox.class.js";import"../checkbox-group/checkbox-group.class.js";import"../textarea/textarea.class.js";import{getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_rubricSkip,LYRA_DEFAULT_rubricSubmit,LYRA_DEFAULT_rubricSubmitAndNext,LYRA_DEFAULT_unsupportedFieldType}from"../../../internal/default-strings.generated.js";const EMPTY_KEYS=[];const EMPTY_VALUE={};class LyraRubricForm extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,rubricSkip:LYRA_DEFAULT_rubricSkip,rubricSubmit:LYRA_DEFAULT_rubricSubmit,rubricSubmitAndNext:LYRA_DEFAULT_rubricSubmitAndNext,unsupportedFieldType:LYRA_DEFAULT_unsupportedFieldType}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},keys:{attribute:false,noAccessor:true},value:{attribute:false,noAccessor:true},itemId:{attribute:"item-id",reflect:true,noAccessor:true},hasNext:{type:Boolean,attribute:"has-next",noAccessor:true},skippable:{type:Boolean,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true}}}constructor(){super();this._errors={};this.touchedFields=new Set;this.baseId=nextId("rubric-form");this._fieldsetDisabled=false;this._name="";this._keys=EMPTY_KEYS;this._value=EMPTY_VALUE;this._itemId="";this._hasNext=false;this._skippable=false;this._disabled=false;this.pendingFocusFirst=false;this.onFormKeyDown=e=>{if(e.key==="Enter"&&(e.ctrlKey||e.metaKey)){e.preventDefault();this.submit()}};this.stopChildEvent=event=>{event.stopPropagation()};this.internals=this.safeAttachInternals();this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,()=>this.emit("lr-invalid"));this.addEventListener("keydown",this.onFormKeyDown);this.syncFormState()}safeAttachInternals(){if(typeof globalThis.ElementInternals==="undefined"){return this.inertInternals()}try{return this.attachInternals()}catch{return this.inertInternals()}}inertInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue:()=>{},setValidity:()=>{},checkValidity:()=>true,reportValidity:()=>true,states:new Set}}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}get keys(){return this._keys}set keys(next){const old=this._keys;this._keys=next??EMPTY_KEYS;this.syncFormState();this.requestUpdate("keys",old)}get value(){return this._value}set value(next){const old=this._value;this._value=next??EMPTY_VALUE;this.syncFormState();this.requestUpdate("value",old)}get itemId(){return this._itemId}set itemId(next){const old=this._itemId;this._itemId=next??"";if(old!==this._itemId){this.touchedFields=new Set;if(this.hasUpdated)this.pendingFocusFirst=true}if(this._itemId)this.setAttribute("item-id",this._itemId);else this.removeAttribute("item-id");this.requestUpdate("itemId",old)}get hasNext(){return this._hasNext}set hasNext(next){const old=this._hasNext;this._hasNext=Boolean(next);this.toggleAttribute("has-next",this._hasNext);this.requestUpdate("hasNext",old)}get skippable(){return this._skippable}set skippable(next){const old=this._skippable;this._skippable=Boolean(next);this.requestUpdate("skippable",old)}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.requestUpdate("name",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);if(this.validityController)this.syncFormState();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get errors(){return{...this._errors}}fieldElement(key){const root=this.renderRoot;const ownerCss=this.ownerDocument.defaultView?.CSS;if(typeof ownerCss?.escape==="function"){try{const candidate=root.querySelector(`[part="field"][data-key="${ownerCss.escape(key)}"]`);if(candidate?.getAttribute("data-key")===key)return candidate}catch{}}return Array.from(root.querySelectorAll('[part="field"][data-key]')).find(candidate=>candidate.getAttribute("data-key")===key)??null}[VALIDITY_ANCHOR](){const firstInvalidKey=Object.keys(this._errors)[0];if(!firstInvalidKey||!this.renderRoot)return void 0;const field=this.fieldElement(firstInvalidKey);return field?.querySelector(".control")??void 0}isSegmentedScore(k){const min=k.min??0;const max=k.max??5;const step=k.step??1;if(step<=0||!Number.isInteger(min)||!Number.isInteger(max)||!Number.isInteger(step))return false;const count=(max-min)/step;return Number.isInteger(count)&&count>=0&&count<=10}scoreValues(k){if(!this.isSegmentedScore(k))return[];const min=k.min??0;const max=k.max??5;const step=k.step??1;const count=Math.round((max-min)/step);return Array.from({length:count+1},(_,index)=>index===count?max:min+index*step)}computeValidation(){const errors={};const flags={};for(const k of this._keys){if(k.type!=="score"&&k.type!=="category"&&k.type!=="comment"){errors[k.key]=this.localize("unsupportedFieldType",void 0,{type:String(k.type)});flags.customError=true;continue}if(!k.required)continue;const v=this._value[k.key];const present=k.type==="category"&&k.multiple?Array.isArray(v)&&v.length>0:v!==void 0&&v!=="";if(!present){errors[k.key]=this.localize("fieldRequired");flags.valueMissing=true}}return{errors,flags}}syncFormState(){const{errors,flags}=this.computeValidation();this._errors=errors;let formValue=null;try{formValue=JSON.stringify(this._value)}catch{formValue=null}this.internals.setFormValue(formValue,formValue);if(this.barredFromValidation||Object.keys(flags).length===0){this.validityController.setValidity({})}else{const message=Object.values(errors)[0]??"";this.validityController.setValidity(flags,message)}this.syncCustomStates()}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}syncCustomStates(){syncValidityStates(this.internals,{required:this._keys.some(key=>Boolean(key.required)),hasInteracted:this.touchedFields.size>0,barred:this.barredFromValidation})}checkValidity(){this.syncFormState();return this.internals.checkValidity()}reportValidity(){this.syncFormState();if(Object.keys(this._errors).length>0){this.touchedFields=new Set([...this.touchedFields,...Object.keys(this._errors)]);this.syncCustomStates()}return this.internals.reportValidity()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncCustomStates();this.requestUpdate()}formResetCallback(){this.value={};this.touchedFields=new Set;this.syncCustomStates()}formStateRestoreCallback(state2,_mode){let restored={};if(typeof state2==="string"){try{const parsed=JSON.parse(state2);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed))restored=parsed}catch{}}this.value=restored}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.syncFormState();this.requestUpdate()}setFieldValue(key,val){if(this.effectiveDisabled)return;this.value={...this._value,[key]:val};this.emit("lr-input",{value:{...this._value}})}markTouched(key){if(this.touchedFields.has(key))return;this.touchedFields=new Set(this.touchedFields).add(key);this.syncCustomStates()}submit(){if(this.effectiveDisabled)return;if(!this.reportValidity())return;this.emit("lr-submit",{value:{...this._value},itemId:this.itemId})}skip(){if(this.effectiveDisabled)return;this.emit("lr-skip",{itemId:this.itemId})}focusFirstControl(){const firstKey=this._keys[0];if(!firstKey)return;const field=this.fieldElement(firstKey.key);const control=field?.querySelector(".control");if(!control)return;if(firstKey.type==="score"&&this.isSegmentedScore(firstKey)){control.shadowRoot?.querySelector('[part="segment"][tabindex="0"]')?.focus()}else if(firstKey.type==="score"){control.shadowRoot?.querySelector('[part="thumb"]')?.focus()}else if(firstKey.type==="category"&&firstKey.multiple){control.querySelector("lr-checkbox")?.focus()}else{control.focus()}}updated(changed){super.updated(changed);if(changed.has("value")||changed.has("keys")||changed.has("_errors")){const valid=Object.keys(this._errors).length===0;const key=JSON.stringify({valid,errors:this._errors});if(key!==this.lastValidityKey){this.lastValidityKey=key;this.emit("lr-validity-change",{valid,errors:{...this._errors}})}}if(this.pendingFocusFirst){this.pendingFocusFirst=false;this.focusFirstControl()}}renderScoreControl(k,fieldId,current,hasError){const min=k.min??0;const max=k.max??5;const step=k.step??1;const disabled=this.effectiveDisabled;const accessibleLabel=[k.label??k.key,k.description,hasError?this._errors[k.key]:void 0].filter(value=>Boolean(value)).join(". ");if(this.isSegmentedScore(k)){const items=this.scoreValues(k).map(score=>({value:String(score),label:String(score),disabled}));const value=typeof current==="number"?String(current):"";return html`<lr-segmented
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{state}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{LyraElement}from"../../../internal/lyra-element.js";import{nextId}from"../../../internal/a11y.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{syncValidityStates}from"../../../internal/custom-states.js";import{styles}from"./rubric-form.styles.js";import"../../layout/segmented/segmented.class.js";import"../slider/slider.class.js";import"../select/select.class.js";import"../combobox/option.class.js";import"../checkbox/checkbox.class.js";import"../checkbox-group/checkbox-group.class.js";import"../textarea/textarea.class.js";import{getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_rubricSkip,LYRA_DEFAULT_rubricSubmit,LYRA_DEFAULT_rubricSubmitAndNext,LYRA_DEFAULT_unsupportedFieldType}from"../../../internal/default-strings.generated.js";const EMPTY_KEYS=[];const EMPTY_VALUE={};class LyraRubricForm extends LyraElement{static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,rubricSkip:LYRA_DEFAULT_rubricSkip,rubricSubmit:LYRA_DEFAULT_rubricSubmit,rubricSubmitAndNext:LYRA_DEFAULT_rubricSubmitAndNext,unsupportedFieldType:LYRA_DEFAULT_unsupportedFieldType}}static{this.formAssociated=true}static{this.styles=[LyraElement.styles,styles]}static{this.properties={customError:{attribute:"custom-error",reflect:true,noAccessor:true},name:{reflect:true,noAccessor:true},keys:{attribute:false,noAccessor:true},value:{attribute:false,noAccessor:true},itemId:{attribute:"item-id",reflect:true,noAccessor:true},hasNext:{type:Boolean,attribute:"has-next",noAccessor:true},skippable:{type:Boolean,noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true}}}constructor(){super();this._errors={};this.touchedFields=new Set;this.baseId=nextId("rubric-form");this._fieldsetDisabled=false;this._name="";this._keys=EMPTY_KEYS;this._value=EMPTY_VALUE;this._itemId="";this._hasNext=false;this._skippable=false;this._disabled=false;this.pendingFocusFirst=false;this.onFormKeyDown=e=>{if(e.key==="Enter"&&(e.ctrlKey||e.metaKey)){e.preventDefault();this.submit()}};this.stopChildEvent=event=>{event.stopPropagation()};this.internals=this.safeAttachInternals();this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());installCustomErrorProperty(this,()=>this.validityController.customValidityMessage);installInvalidEventAlias(this,()=>this.emit("lr-invalid"));this.addEventListener("keydown",this.onFormKeyDown);this.syncFormState()}safeAttachInternals(){if(typeof globalThis.ElementInternals==="undefined"){return this.inertInternals()}try{return this.attachInternals()}catch{return this.inertInternals()}}inertInternals(){return{form:null,labels:[],validity:{},validationMessage:"",willValidate:false,setFormValue:()=>{},setValidity:()=>{},checkValidity:()=>true,reportValidity:()=>true,states:new Set}}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}get keys(){return this._keys}set keys(next){const old=this._keys;this._keys=next??EMPTY_KEYS;this.syncFormState();this.requestUpdate("keys",old)}get value(){return this._value}set value(next){const old=this._value;this._value=next??EMPTY_VALUE;this.syncFormState();this.requestUpdate("value",old)}get itemId(){return this._itemId}set itemId(next){const old=this._itemId;this._itemId=next??"";if(old!==this._itemId){this.touchedFields=new Set;if(this.hasUpdated)this.pendingFocusFirst=true}if(this._itemId)this.setAttribute("item-id",this._itemId);else this.removeAttribute("item-id");this.requestUpdate("itemId",old)}get hasNext(){return this._hasNext}set hasNext(next){const old=this._hasNext;this._hasNext=Boolean(next);this.toggleAttribute("has-next",this._hasNext);this.requestUpdate("hasNext",old)}get skippable(){return this._skippable}set skippable(next){const old=this._skippable;this._skippable=Boolean(next);this.requestUpdate("skippable",old)}get name(){return this._name}set name(next){const old=this._name;this._name=next??"";if(this._name)this.setAttribute("name",this._name);else this.removeAttribute("name");this.requestUpdate("name",old)}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);if(this.validityController)this.syncFormState();this.requestUpdate("disabled",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}get errors(){return{...this._errors}}fieldElement(key){const root=this.renderRoot;const ownerCss=this.ownerDocument.defaultView?.CSS;if(typeof ownerCss?.escape==="function"){try{const candidate=root.querySelector(`[part="field"][data-key="${ownerCss.escape(key)}"]`);if(candidate?.getAttribute("data-key")===key)return candidate}catch{}}return Array.from(root.querySelectorAll('[part="field"][data-key]')).find(candidate=>candidate.getAttribute("data-key")===key)??null}[VALIDITY_ANCHOR](){const firstInvalidKey=Object.keys(this._errors)[0];if(!firstInvalidKey||!this.renderRoot)return void 0;const field=this.fieldElement(firstInvalidKey);return field?.querySelector(".control")??void 0}isSegmentedScore(k){const min=k.min??0;const max=k.max??5;const step=k.step??1;if(step<=0||!Number.isInteger(min)||!Number.isInteger(max)||!Number.isInteger(step))return false;const count=(max-min)/step;return Number.isInteger(count)&&count>=0&&count<=10}scoreValues(k){if(!this.isSegmentedScore(k))return[];const min=k.min??0;const max=k.max??5;const step=k.step??1;const count=Math.round((max-min)/step);return Array.from({length:count+1},(_,index)=>index===count?max:min+index*step)}computeValidation(){const errors={};const flags={};for(const k of this._keys){if(k.type!=="score"&&k.type!=="category"&&k.type!=="comment"){errors[k.key]=this.localize("unsupportedFieldType",void 0,{type:String(k.type)});flags.customError=true;continue}if(!k.required)continue;const v=this._value[k.key];const present=k.type==="category"&&k.multiple?Array.isArray(v)&&v.length>0:v!==void 0&&v!=="";if(!present){errors[k.key]=this.localize("fieldRequired");flags.valueMissing=true}}return{errors,flags}}syncFormState(){const{errors,flags}=this.computeValidation();this._errors=errors;let formValue=null;try{formValue=JSON.stringify(this._value)}catch{formValue=null}this.internals.setFormValue(formValue,formValue);if(this.barredFromValidation||Object.keys(flags).length===0){this.validityController.setValidity({})}else{const message=Object.values(errors)[0]??"";this.validityController.setValidity(flags,message)}this.syncCustomStates()}get barredFromValidation(){return isBarredFromValidation(this,this.internals)}syncCustomStates(){syncValidityStates(this.internals,{required:this._keys.some(key=>Boolean(key.required)),hasInteracted:this.touchedFields.size>0,barred:this.barredFromValidation})}checkValidity(){this.syncFormState();return this.internals.checkValidity()}reportValidity(){this.syncFormState();if(Object.keys(this._errors).length>0){this.touchedFields=new Set([...this.touchedFields,...Object.keys(this._errors)]);this.syncCustomStates()}return this.internals.reportValidity()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncCustomStates();this.requestUpdate()}formResetCallback(){this.value={};this.touchedFields=new Set;this.syncCustomStates()}formStateRestoreCallback(state2,_mode){let restored={};if(typeof state2==="string"){try{const parsed=JSON.parse(state2);if(parsed!==null&&typeof parsed==="object"&&!Array.isArray(parsed))restored=parsed}catch{}}this.value=restored}formDisabledCallback(disabled){this._fieldsetDisabled=disabled;this.syncFormState();this.requestUpdate()}setFieldValue(key,val){if(this.effectiveDisabled)return;this.value={...this._value,[key]:val};this.emit("lr-input",{value:{...this._value}})}markTouched(key){if(this.touchedFields.has(key))return;this.touchedFields=new Set(this.touchedFields).add(key);this.syncCustomStates()}submit(){if(this.effectiveDisabled)return;if(!this.reportValidity())return;this.emit("lr-submit",{value:{...this._value},itemId:this.itemId})}skip(){if(this.effectiveDisabled)return;this.emit("lr-skip",{itemId:this.itemId})}focusFirstControl(){const firstKey=this._keys[0];if(!firstKey)return;const field=this.fieldElement(firstKey.key);const control=field?.querySelector(".control");if(!control)return;if(firstKey.type==="score"&&this.isSegmentedScore(firstKey)){control.shadowRoot?.querySelector('[part="segment"][tabindex="0"]')?.focus()}else if(firstKey.type==="score"){control.shadowRoot?.querySelector('[part="thumb"]')?.focus()}else if(firstKey.type==="category"&&firstKey.multiple){control.querySelector("lr-checkbox")?.focus()}else{control.focus()}}click(){if(this.effectiveDisabled)return;this.focusFirstControl()}updated(changed){super.updated(changed);if(changed.has("value")||changed.has("keys")||changed.has("_errors")){const valid=Object.keys(this._errors).length===0;const key=JSON.stringify({valid,errors:this._errors});if(key!==this.lastValidityKey){this.lastValidityKey=key;this.emit("lr-validity-change",{valid,errors:{...this._errors}})}}if(this.pendingFocusFirst){this.pendingFocusFirst=false;this.focusFirstControl()}}renderScoreControl(k,fieldId,current,hasError){const min=k.min??0;const max=k.max??5;const step=k.step??1;const disabled=this.effectiveDisabled;const accessibleLabel=[k.label??k.key,k.description,hasError?this._errors[k.key]:void 0].filter(value=>Boolean(value)).join(". ");if(this.isSegmentedScore(k)){const items=this.scoreValues(k).map(score=>({value:String(score),label:String(score),disabled}));const value=typeof current==="number"?String(current):"";return html`<lr-segmented
2
2
  id=${fieldId}
3
3
  class="control"
4
4
  part="scale"
@@ -3,4 +3,4 @@
3
3
  * Run `pnpm package-metadata` after changing package identity or version.
4
4
  */
5
5
  export declare const LYRA_PACKAGE_NAME: "@aceshooting/lyra-ui";
6
- export declare const LYRA_PACKAGE_VERSION: "8.1.0";
6
+ export declare const LYRA_PACKAGE_VERSION: "8.2.0";
@@ -1 +1 @@
1
- const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.1.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
1
+ const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.2.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
@@ -40,6 +40,8 @@ goes back to `valueMissing`. It survives every child toggle, slot change and for
40
40
  Session restore uses a `FormData` state containing the repeated selected strings; it is independent
41
41
  of the control's current `name`, preserves duplicate-value cardinality, waits for early-arriving
42
42
  option children, and falls back to an empty selection for malformed state. Restoration is silent.
43
+ `click()` forwards focus to the first enabled checkbox, so the host behaves like a single control
44
+ rather than a no-op under a `<label>`-driven or programmatic click.
43
45
  **CSS parts:** `form-control`, `form-control-label`, `options` / `form-control-input`, `hint`,
44
46
  `error`.
45
47
  **The required marker.** `required` with a non-empty group `label` paints the library's shared
@@ -33,7 +33,9 @@ restores the control's own computed validity rather than forcing it valid — a
33
33
  field edit) and `form.reset()`, exactly like a native control, where only another
34
34
  `setCustomValidity('')` clears it. The message is caller-supplied and is used verbatim, never
35
35
  localized, and it is whole-control state: it does not land in `errors`, which is keyed by the
36
- csspart of the field a message belongs to.
36
+ csspart of the field a message belongs to. `click()` forwards focus to the first rendered field
37
+ (start/end/hop-limit/direction/save-name, in that order), so the host behaves like a single
38
+ control rather than a no-op under a `<label>`-driven or programmatic click.
37
39
 
38
40
  **Events:** `lr-input`, `lr-validity-change`, `lr-invalid` (no detail; one bubbling/composed alias
39
41
  when the complete builder fails a native validity check),
@@ -71,4 +71,6 @@ options and its messages, scaled by `size` through the shared control ladder.
71
71
  **Methods:** `setCustomValidity(message = '')` sets or clears a group-level consumer error. A
72
72
  non-empty message raises `customError` and blocks submission; `setCustomValidity('')` and
73
73
  `resetValidity()` restore the group's computed validity, including `valueMissing` when a required
74
- group has no selected radio.
74
+ group has no selected radio. `focus()` moves focus to the selected (or first enabled) radio;
75
+ `click()` mirrors it by activating that same radio, so the group behaves like a single control
76
+ under both APIs rather than leaving `click()` a no-op.
@@ -46,6 +46,8 @@ express ("this item was already annotated by someone else"): a non-empty message
46
46
  required keys, and any key with an unsupported `type`, still hold it invalid. It is independent of
47
47
  the per-key `errors` map, which stays a read-out of this rubric's own field rules, so a message set
48
48
  here is never attributed to one key. It survives every `value`/`keys` write and a form reset.
49
+ `click()` forwards to the active field (the same one a submit-and-next transition auto-focuses),
50
+ so the host behaves like a single control under both a `<label>`-driven and a programmatic click.
49
51
 
50
52
  **CSS parts:** `base` (the outer `role="group"` wrapper), `field` (one key's wrapper), `label`, `description`,
51
53
  `scale` (the rendered score/category/comment control's wrapper), `error` (a field-level validation
@@ -87,6 +87,9 @@ and makes the form invalid instead of being silently accepted.
87
87
  re-runs the validity sync) and a `form.reset()`, matching a native control. The message is
88
88
  whole-control state, so it is deliberately absent from `errors`, which is keyed by schema
89
89
  property; it is caller-supplied content and is used verbatim, never localized.
90
+ - `click(): void` — forwards a host click to the first generated field's control, so the form
91
+ behaves like a single control under both a `<label>`-driven and a programmatic click; a no-op
92
+ while `disabled`.
90
93
 
91
94
  **Events:** `lr-input` (`detail: { value: Record<string, unknown> }` — the full current value
92
95
  object, every property with defaults resolved, not just the field that changed), `lr-validity-change`
package/llms/peers.md CHANGED
@@ -53,7 +53,7 @@ changes the component library version without installing a supported SheetJS rel
53
53
  | `postal-mime` | `^2.7.5` | `lr-email-viewer` |
54
54
  | `qrcode` | `^1.5.4` | `lr-qr-code` |
55
55
  | `react` | `>=19 <20` | type-only `@aceshooting/lyra-ui/custom-elements-jsx` entry (no runtime import) |
56
- | `shiki` | `^4.4.1` | `lr-code-block`, `lr-code-block-core`, `lr-diff-view`, `lr-document-compare`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-widget-renderer` |
56
+ | `shiki` | `^4.4.2` | `lr-code-block`, `lr-code-block-core`, `lr-diff-view`, `lr-document-compare`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-widget-renderer` |
57
57
  | `svelte` | `>=5 <6` | type-only `@aceshooting/lyra-ui/svelte` entry (no runtime import) |
58
58
  | `vue` | `>=3.5 <4` | type-only `@aceshooting/lyra-ui/vue` entry (no runtime import) |
59
59
  | `xlsx` | `>=0.20.3 <0.21.0` | `lr-spreadsheet-viewer` |
package/llms-full.txt CHANGED
@@ -5277,7 +5277,9 @@ options and its messages, scaled by `size` through the shared control ladder.
5277
5277
  **Methods:** `setCustomValidity(message = '')` sets or clears a group-level consumer error. A
5278
5278
  non-empty message raises `customError` and blocks submission; `setCustomValidity('')` and
5279
5279
  `resetValidity()` restore the group's computed validity, including `valueMissing` when a required
5280
- group has no selected radio.
5280
+ group has no selected radio. `focus()` moves focus to the selected (or first enabled) radio;
5281
+ `click()` mirrors it by activating that same radio, so the group behaves like a single control
5282
+ under both APIs rather than leaving `click()` a no-op.
5281
5283
 
5282
5284
  ## `lr-checkbox-group`
5283
5285
 
@@ -5306,6 +5308,8 @@ goes back to `valueMissing`. It survives every child toggle, slot change and for
5306
5308
  Session restore uses a `FormData` state containing the repeated selected strings; it is independent
5307
5309
  of the control's current `name`, preserves duplicate-value cardinality, waits for early-arriving
5308
5310
  option children, and falls back to an empty selection for malformed state. Restoration is silent.
5311
+ `click()` forwards focus to the first enabled checkbox, so the host behaves like a single control
5312
+ rather than a no-op under a `<label>`-driven or programmatic click.
5309
5313
  **CSS parts:** `form-control`, `form-control-label`, `options` / `form-control-input`, `hint`,
5310
5314
  `error`.
5311
5315
  **The required marker.** `required` with a non-empty group `label` paints the library's shared
@@ -5932,6 +5936,8 @@ express ("this item was already annotated by someone else"): a non-empty message
5932
5936
  required keys, and any key with an unsupported `type`, still hold it invalid. It is independent of
5933
5937
  the per-key `errors` map, which stays a read-out of this rubric's own field rules, so a message set
5934
5938
  here is never attributed to one key. It survives every `value`/`keys` write and a form reset.
5939
+ `click()` forwards to the active field (the same one a submit-and-next transition auto-focuses),
5940
+ so the host behaves like a single control under both a `<label>`-driven and a programmatic click.
5935
5941
 
5936
5942
  **CSS parts:** `base` (the outer `role="group"` wrapper), `field` (one key's wrapper), `label`, `description`,
5937
5943
  `scale` (the rendered score/category/comment control's wrapper), `error` (a field-level validation
@@ -8532,7 +8538,9 @@ restores the control's own computed validity rather than forcing it valid — a
8532
8538
  field edit) and `form.reset()`, exactly like a native control, where only another
8533
8539
  `setCustomValidity('')` clears it. The message is caller-supplied and is used verbatim, never
8534
8540
  localized, and it is whole-control state: it does not land in `errors`, which is keyed by the
8535
- csspart of the field a message belongs to.
8541
+ csspart of the field a message belongs to. `click()` forwards focus to the first rendered field
8542
+ (start/end/hop-limit/direction/save-name, in that order), so the host behaves like a single
8543
+ control rather than a no-op under a `<label>`-driven or programmatic click.
8536
8544
 
8537
8545
  **Events:** `lr-input`, `lr-validity-change`, `lr-invalid` (no detail; one bubbling/composed alias
8538
8546
  when the complete builder fails a native validity check),
@@ -22936,6 +22944,9 @@ and makes the form invalid instead of being silently accepted.
22936
22944
  re-runs the validity sync) and a `form.reset()`, matching a native control. The message is
22937
22945
  whole-control state, so it is deliberately absent from `errors`, which is keyed by schema
22938
22946
  property; it is caller-supplied content and is used verbatim, never localized.
22947
+ - `click(): void` — forwards a host click to the first generated field's control, so the form
22948
+ behaves like a single control under both a `<label>`-driven and a programmatic click; a no-op
22949
+ while `disabled`.
22939
22950
 
22940
22951
  **Events:** `lr-input` (`detail: { value: Record<string, unknown> }` — the full current value
22941
22952
  object, every property with defaults resolved, not just the field that changed), `lr-validity-change`