@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.
- package/CHANGELOG.md +11 -0
- package/custom-elements.json +1 -1
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.d.ts +5 -0
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
- package/dist/components/charts/chart/chart.class.js +1 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +4 -0
- package/dist/components/data/graph-query-builder/graph-query-builder.class.js +1 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +3 -0
- package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
- package/dist/components/forms/radio/radio-group.class.d.ts +3 -0
- package/dist/components/forms/radio/radio-group.class.js +1 -1
- package/dist/components/forms/rubric-form/rubric-form.class.d.ts +3 -0
- package/dist/components/forms/rubric-form/rubric-form.class.js +1 -1
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/llms/components/lr-checkbox-group.md +2 -0
- package/llms/components/lr-graph-query-builder.md +3 -1
- package/llms/components/lr-radio-group.md +3 -1
- package/llms/components/lr-rubric-form.md +2 -0
- package/llms/components/lr-tool-param-form.md +3 -0
- package/llms/peers.md +1 -1
- package/llms-full.txt +13 -2
- package/package.json +3 -3
- package/web-types.json +1 -1
|
@@ -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&¤t.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&¤t.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"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.
|
|
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.
|
|
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`
|