@aceshooting/lyra-ui 8.2.0 → 8.2.1
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 +28 -0
- package/dist/components/conversation/chat-composer/chat-composer.class.js +1 -1
- package/dist/components/conversation/model-select/model-select.class.js +1 -1
- package/dist/components/conversation/voice-picker/voice-picker.class.js +1 -1
- package/dist/components/forms/checkbox/checkbox.class.js +1 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
- package/dist/components/forms/code-editor/code-editor.class.js +1 -1
- package/dist/components/forms/combobox/combobox.class.js +1 -1
- package/dist/components/forms/date-picker/date-input.class.js +1 -1
- package/dist/components/forms/emoji-picker/emoji-picker.class.js +1 -1
- package/dist/components/forms/input/input.class.js +1 -1
- package/dist/components/forms/input/time-input.class.js +1 -1
- package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
- package/dist/components/forms/otp-input/otp-input.class.js +1 -1
- package/dist/components/forms/phone-input/phone-input.class.js +1 -1
- package/dist/components/forms/select/select.class.js +1 -1
- package/dist/components/forms/switch/switch.class.js +1 -1
- package/dist/components/forms/textarea/textarea.class.js +1 -1
- package/dist/components/forms/token-input/token-input.class.js +1 -1
- package/dist/components/media/file-input/file-input.class.js +1 -1
- package/dist/components/utility/known-date/known-date.class.js +1 -1
- package/dist/internal/form-associated.js +1 -1
- package/dist/internal/localization-runtime.d.ts +13 -0
- package/dist/internal/localization-runtime.js +1 -1
- package/dist/internal/lyra-element.d.ts +15 -0
- package/dist/internal/lyra-element.js +1 -1
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/dist/testing/happy-dom-shims.d.ts +1 -1
- package/dist/testing/happy-dom-shims.js +1 -1
- package/package.json +2 -2
- package/web-types.json +1 -1
|
@@ -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,query,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{FormAssociated,isBarredFromValidation}from"../../../internal/form-associated.js";import{SET_ANCHORED_VALIDITY}from"../../../internal/anchored-validity.js";import{composedParentElement,isAccessibilitySubtreeExcluded,isAccessibilityVisible,isAccessibilityVisibilityHidden,nextId}from"../../../internal/a11y.js";import{sizes}from"../../../internal/sizes.styles.js";import{styles}from"./known-date.styles.js";import{getDateTimeFormat,getNumberFormat}from"../../../internal/intl-cache.js";import{activeElementIn}from"../../../internal/active-element.js";import{isImplicitSubmission,submitOnEnter}from"../../../internal/submit-on-enter.js";import{setCustomState}from"../../../internal/custom-states.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_date,LYRA_DEFAULT_dateInputInvalid,LYRA_DEFAULT_dateInputMaxMessage,LYRA_DEFAULT_dateInputMinMessage,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_knownDateDay,LYRA_DEFAULT_knownDateMonth,LYRA_DEFAULT_knownDateYear,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_search}from"../../../internal/default-strings.generated.js";const EMPTY_PARTS={day:"",month:"",year:""};function parseISO(value){const match=/^(\d{4})-(\d{2})-(\d{2})$/.exec(value);if(!match)return null;const year=Number(match[1]);const month=Number(match[2]);const day=Number(match[3]);const date=new Date(year,month-1,day);if(isNaN(date.getTime()))return null;if(date.getFullYear()!==year||date.getMonth()!==month-1||date.getDate()!==day)return null;return date}function formatISO(date){const mm=String(date.getMonth()+1).padStart(2,"0");const dd=String(date.getDate()).padStart(2,"0");return`${date.getFullYear()}-${mm}-${dd}`}function localeDateOrder(locale){try{const parts=getDateTimeFormat(locale||void 0,{year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(new Date(2026,0,2));const order=parts.filter(p=>p.type==="day"||p.type==="month"||p.type==="year").map(p=>p.type);return order.length===3?order:["month","day","year"]}catch{return["month","day","year"]}}class LyraKnownDateBase extends LyraElement{}function addCompatibilityDetail(event,detail){Object.defineProperty(event,"detail",{configurable:true,value:detail});return event}class LyraKnownDate extends FormAssociated(LyraKnownDateBase){static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,date:LYRA_DEFAULT_date,dateInputInvalid:LYRA_DEFAULT_dateInputInvalid,dateInputMaxMessage:LYRA_DEFAULT_dateInputMaxMessage,dateInputMinMessage:LYRA_DEFAULT_dateInputMinMessage,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,knownDateDay:LYRA_DEFAULT_knownDateDay,knownDateMonth:LYRA_DEFAULT_knownDateMonth,knownDateYear:LYRA_DEFAULT_knownDateYear,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,search:LYRA_DEFAULT_search}}static{this.styles=[LyraElement.styles,sizes,styles]}static{this.properties={min:{reflect:true,noAccessor:true},max:{reflect:true,noAccessor:true},readonly:{type:Boolean,reflect:true,noAccessor:true},parts:{attribute:false,noAccessor:true}}}constructor(){super();this.size="m";this.appearance="outlined";this.pill=false;this.label="";this.hint="";this.errorText="";this.locale="";this.autocomplete="";this.withLabel=false;this.withHint=false;this.accessibleLabel=null;this.dayLabel="Day";this.monthLabel="Month";this.yearLabel="Year";this._parts={...EMPTY_PARTS};this.touched=false;this.hasLabelSlot=false;this.hasHintSlot=false;this.hasErrorSlot=false;this._min="";this._max="";this._readonly=false;this.lastCommittedValue="";this.lastEditedField="day";this.errorAnnouncementsArmed=false;this.lastVisibleError="";this.connectionGeneration=0;this.onForwardedSlotChange=event=>{const target=event.target;if(target?.nodeType!==1||target.localName!=="slot")return;this.bindErrorObserverTargets();this.announceVisibleError()};this.hintId=nextId("known-date-hint");this.errorId=nextId("known-date-error");this.dayId=nextId("known-date-day");this.monthId=nextId("known-date-month");this.yearId=nextId("known-date-year");this.onLabelSlotChange=e=>{this.hasLabelSlot=e.target.assignedElements({flatten:true}).length>0};this.onHintSlotChange=e=>{this.hasHintSlot=e.target.assignedElements({flatten:true}).length>0};this.onErrorSlotChange=e=>{this.hasErrorSlot=e.target.assignedElements({flatten:true}).length>0};this.onFieldInput=(field,e)=>{e.stopPropagation();const input=e.target;const maxLength=field==="year"?4:2;const digits=this.normalizeFieldDigits(input.value).slice(0,maxLength);if(input.value!==digits)input.value=digits;this.setFieldText(field,digits);this.lastEditedField=field;this.commitFromFields();const InputEventConstructor=this.ownerDocument.defaultView?.InputEvent??InputEvent;const event=addCompatibilityDetail(new InputEventConstructor("input",{bubbles:true,composed:true,inputType:"insertText"}),this.detailFor(field));this.dispatchEvent(event);if(field!=="year"&&digits.length===maxLength)this.focusAdjacentField(field,1)};this.onFieldKeydown=(field,e)=>{const input=e.currentTarget;if(isImplicitSubmission(e)){if(this.effectiveDisabled||this.readonly)return;submitOnEnter(this,e,{beforeSubmit:()=>this.commitChangeIfNeeded()});return}if(e.key==="Backspace"&&this.textFor(field)===""){e.preventDefault();this.focusAdjacentField(field,-1);return}if(e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;const atStart=input.selectionStart===0&&input.selectionEnd===0;const atEnd=input.selectionStart===input.value.length&&input.selectionEnd===input.value.length;const rtl=this.effectiveDirection==="rtl";if(e.key==="ArrowLeft"&&atStart){e.preventDefault();this.focusAdjacentField(field,rtl?1:-1)}else if(e.key==="ArrowRight"&&atEnd){e.preventDefault();this.focusAdjacentField(field,rtl?-1:1)}};this.onFieldFocus=e=>{e.stopPropagation();this.emit("focus")};this.onFieldBlur=e=>{e.stopPropagation();this.commitChangeIfNeeded();const related=e.relatedTarget;const active=activeElementIn(this.shadowRoot);const staysInsideControl=e.isTrusted&&(this.isRenderedFieldTarget(related)||active!==e.target&&this.isRenderedFieldTarget(active));if(staysInsideControl)return;this.touched=true;this.emit("blur")};this.addEventListener("invalid",()=>{this.touched=true})}connectedCallback(){super.connectedCallback();this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this});const MutationObserverCtor=this.ownerDocument.defaultView?.MutationObserver;this.errorObserver=MutationObserverCtor?new MutationObserverCtor(()=>{this.bindErrorObserverTargets();this.announceVisibleError()}):void 0;this.addEventListener("slotchange",this.onForwardedSlotChange);this.bindErrorObserverTargets();this.errorAnnouncementsArmed=false;const generation=++this.connectionGeneration;void this.updateComplete.then(()=>{const view=this.ownerDocument.defaultView;return typeof view?.requestAnimationFrame==="function"?new Promise(resolve=>view.requestAnimationFrame(()=>resolve())):Promise.resolve()}).then(()=>this.updateComplete).then(()=>{if(!this.isConnected||generation!==this.connectionGeneration)return;this.lastVisibleError=this.visibleErrorText();this.errorAnnouncementsArmed=true})}observeErrorNode(node){if(!this.errorObserver)return;if(node.nodeType===3){this.errorObserver.observe(node,{characterData:true});return}if(node.nodeType!==1)return;this.errorObserver.observe(node,{attributes:true,attributeFilter:["aria-hidden","aria-label","class","hidden","inert","slot","style"],characterData:true,childList:true,subtree:true})}bindErrorObserverTargets(){if(!this.errorObserver)return;this.errorObserver.disconnect();this.observeErrorNode(this);let ancestor=composedParentElement(this);while(ancestor){this.errorObserver.observe(ancestor,{attributes:true,attributeFilter:["aria-hidden","class","hidden","inert","style"]});ancestor=composedParentElement(ancestor)}const errorBranches=Array.from(this.children).filter(element=>element.getAttribute("slot")==="error");const forwardedSlots=errorBranches.flatMap(branch=>[...branch.localName==="slot"?[branch]:[],...branch.querySelectorAll("slot")]);for(const slot of forwardedSlots){for(const assigned of slot.assignedNodes({flatten:true}))this.observeErrorNode(assigned)}}disconnectedCallback(){this.connectionGeneration+=1;this.errorAnnouncementsArmed=false;this.lastVisibleError="";this.removeEventListener("slotchange",this.onForwardedSlotChange);this.errorObserver?.disconnect();this.errorObserver=void 0;this.errorAnnouncementSink?.release();this.errorAnnouncementSink=void 0;super.disconnectedCallback()}get min(){return this._min}set min(next){const old=this._min;this._min=next??"";this.updateValidity();this.requestUpdate("min",old)}get max(){return this._max}set max(next){const old=this._max;this._max=next??"";this.updateValidity();this.requestUpdate("max",old)}get readonly(){return this._readonly}set readonly(next){const old=this._readonly;this._readonly=Boolean(next);this.toggleAttribute("readonly",this._readonly);this.updateValidity();this.requestUpdate("readonly",old)}get parts(){return this._parts}set parts(next){this.setParts(next,true)}setParts(next,programmatic){const old=this._parts;this._parts={day:String(next?.day??""),month:String(next?.month??""),year:String(next?.year??"")};if(programmatic){this.commitFromFields();this.lastCommittedValue=this.value}this.requestUpdate("parts",old)}get value(){return super.value}set value(next){const parsed=this.parseStrictISO(next??"");if(parsed){this.setParts({day:String(parsed.getDate()),month:String(parsed.getMonth()+1),year:String(parsed.getFullYear())},false);super.value=formatISO(parsed)}else{this.setParts({day:"",month:"",year:""},false);super.value=""}this.lastCommittedValue=super.value}get valueAsDate(){return this.value?parseISO(this.value):null}set valueAsDate(next){this.value=next?formatISO(next):""}parseStrictISO(value){if(!/^\d{4}-\d{2}-\d{2}$/.test(value))return null;return parseISO(value)}get fieldOrder(){return localeDateOrder(this.effectiveLocale)}textFor(field){return this._parts[field]}setFieldText(field,text){this.setParts({...this._parts,[field]:text},false)}idFor(field){if(field==="day")return this.dayId;if(field==="month")return this.monthId;return this.yearId}get effectiveDayLabel(){return this.localize("knownDateDay",this.dayLabel==="Day"?void 0:this.dayLabel)}get effectiveMonthLabel(){return this.localize("knownDateMonth",this.monthLabel==="Month"?void 0:this.monthLabel)}get effectiveYearLabel(){return this.localize("knownDateYear",this.yearLabel==="Year"?void 0:this.yearLabel)}labelFor(field){if(field==="day")return this.effectiveDayLabel;if(field==="month")return this.effectiveMonthLabel;return this.effectiveYearLabel}autocompleteFor(field){if(!this.autocomplete)return"";if(this.autocomplete==="bday")return`bday-${field}`;if(this.autocomplete==="on"||this.autocomplete==="off")return this.autocomplete;return field==="year"?this.autocomplete:""}computeCanonicalValue(){if(!this._parts.day||!this._parts.month||!this._parts.year)return"";const iso=`${this._parts.year.padStart(4,"0")}-${this._parts.month.padStart(2,"0")}-${this._parts.day.padStart(2,"0")}`;return parseISO(iso)?iso:""}commitFromFields(){super.value=this.computeCanonicalValue()}get eventDetail(){return{value:this.value,...this._parts}}detailFor(field){return{...this.eventDetail,field}}commitChangeIfNeeded(){if(this.value===this.lastCommittedValue)return;this.lastCommittedValue=this.value;const EventConstructor=this.ownerDocument.defaultView?.Event??Event;const event=addCompatibilityDetail(new EventConstructor("change",{bubbles:true,composed:true}),this.detailFor(this.lastEditedField));this.dispatchEvent(event)}fieldInputElement(field){return this.renderRoot.querySelector(`input[data-field="${field}"]`)}isRenderedFieldTarget(target){if(!target||typeof target!=="object")return false;const field=target.dataset?.field;if(field!=="day"&&field!=="month"&&field!=="year")return false;return this.fieldInputElement(field)===target}focusAdjacentField(field,delta){const order=this.fieldOrder;const targetIndex=order.indexOf(field)+delta;if(targetIndex<0||targetIndex>=order.length)return;this.fieldInputElement(order[targetIndex])?.focus()}updateValidity(){if(isBarredFromValidation(this,this.internals)){this[SET_ANCHORED_VALIDITY]({});return}const flags={};let message="";const blank=this._parts.day===""&&this._parts.month===""&&this._parts.year==="";if(this.value===""){if(this.required&&blank){flags.valueMissing=true;message=this.localize("fieldRequired")}else if(!blank){flags.badInput=true;message=this.localize("dateInputInvalid")}}else{const date=parseISO(this.value);const min=this.parseStrictISO(this.min);const max=this.parseStrictISO(this.max);if(min&&date<min){flags.rangeUnderflow=true;message=this.localize("dateInputMinMessage",void 0,{min:this.min})}if(max&&date>max){flags.rangeOverflow=true;message||=this.localize("dateInputMaxMessage",void 0,{max:this.max})}}this[SET_ANCHORED_VALIDITY](flags,message)}willUpdate(changed){super.willUpdate(changed);if(!this.hasUpdated){this.hasLabelSlot=Array.from(this.children).some(el=>el.getAttribute("slot")==="label");this.hasHintSlot=Array.from(this.children).some(el=>el.getAttribute("slot")==="hint");this.hasErrorSlot=Array.from(this.children).some(el=>el.getAttribute("slot")==="error")}}updated(changed){super.updated(changed);setCustomState(this.internals,"blank",this.value==="");setCustomState(this.internals,"disabled",this.effectiveDisabled);if(changed.has("touched")||changed.has("required")||changed.has("value")||changed.has("min")||changed.has("max")||changed.has("readonly")){this.toggleAttribute("data-invalid",this.touched&&!this.internals.validity.valid)}this.announceVisibleError()}formResetCallback(){super.formResetCallback();this.touched=false}formStateRestoreCallback(state2){this.value=typeof state2==="string"?state2:""}setCustomValidity(message){super.setCustomValidity(message);this.requestUpdate()}resetValidity(){this.setCustomValidity("");this.updateValidity()}visibleErrorText(){const slottedElements=Array.from(this.children).filter(element=>element.getAttribute("slot")==="error");if(slottedElements.length>0){return slottedElements.map(element=>this.accessibleVisibleText(element)).join(" ").replace(/\s+/g," ").trim()}return(this.errorText||(this.touched?this.validationMessage:"")).trim()}accessibleVisibleText(node){if(node.nodeType===3)return node.textContent??"";if(node.nodeType!==1)return"";const element=node;if(isAccessibilitySubtreeExcluded(element))return"";const visibilityHidden=isAccessibilityVisibilityHidden(element);const accessibleLabel=visibilityHidden?null:element.getAttribute("aria-label");if(accessibleLabel?.trim())return accessibleLabel;const assigned=element.localName==="slot"?element.assignedNodes({flatten:true}):[];const children=assigned.length>0?assigned:Array.from(element.childNodes);return children.map(child=>child.nodeType===3&&visibilityHidden?"":this.accessibleVisibleText(child)).join(" ")}announceVisibleError(){if(!this.errorAnnouncementsArmed||!isAccessibilityVisible(this))return;const message=this.visibleErrorText();if(message===this.lastVisibleError)return;this.lastVisibleError=message;if(message)this.errorAnnouncementSink?.announce(message)}normalizeFieldDigits(value){const digitMap=new Map([["\u0660","0"],["\u0661","1"],["\u0662","2"],["\u0663","3"],["\u0664","4"],["\u0665","5"],["\u0666","6"],["\u0667","7"],["\u0668","8"],["\u0669","9"],["\u06F0","0"],["\u06F1","1"],["\u06F2","2"],["\u06F3","3"],["\u06F4","4"],["\u06F5","5"],["\u06F6","6"],["\u06F7","7"],["\u06F8","8"],["\u06F9","9"]]);try{const formatter=getNumberFormat(this.effectiveLocale||void 0,{useGrouping:false});for(let digit=0;digit<=9;digit++)digitMap.set(formatter.format(digit),String(digit))}catch{}let normalized="";for(const character of value){if(character>="0"&&character<="9")normalized+=character;else normalized+=digitMap.get(character)??""}return normalized}focus(options){const target=this.fieldOrder.find(field=>this.textFor(field)==="")??this.fieldOrder[0];this.fieldInputElement(target)?.focus(options)}blur(){this.renderRoot.querySelector("input:focus")?.blur()}click(){this.fieldInputElement(this.fieldOrder[0])?.click()}renderField(field,describedBy,invalid){const id=this.idFor(field);const maxLength=field==="year"?4:2;const fieldPart=field==="day"?"field field-day":field==="month"?"field field-month":"field field-year";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,query,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{FormAssociated,isBarredFromValidation}from"../../../internal/form-associated.js";import{SET_ANCHORED_VALIDITY}from"../../../internal/anchored-validity.js";import{composedParentElement,isAccessibilitySubtreeExcluded,isAccessibilityVisible,isAccessibilityVisibilityHidden,nextId}from"../../../internal/a11y.js";import{sizes}from"../../../internal/sizes.styles.js";import{styles}from"./known-date.styles.js";import{getDateTimeFormat,getNumberFormat}from"../../../internal/intl-cache.js";import{activeElementIn}from"../../../internal/active-element.js";import{isImplicitSubmission,submitOnEnter}from"../../../internal/submit-on-enter.js";import{setCustomState}from"../../../internal/custom-states.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_date,LYRA_DEFAULT_dateInputInvalid,LYRA_DEFAULT_dateInputMaxMessage,LYRA_DEFAULT_dateInputMinMessage,LYRA_DEFAULT_details,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_knownDateDay,LYRA_DEFAULT_knownDateMonth,LYRA_DEFAULT_knownDateYear,LYRA_DEFAULT_open,LYRA_DEFAULT_restore,LYRA_DEFAULT_search}from"../../../internal/default-strings.generated.js";const EMPTY_PARTS={day:"",month:"",year:""};function parseISO(value){const match=/^(\d{4})-(\d{2})-(\d{2})$/.exec(value);if(!match)return null;const year=Number(match[1]);const month=Number(match[2]);const day=Number(match[3]);const date=new Date(year,month-1,day);if(isNaN(date.getTime()))return null;if(date.getFullYear()!==year||date.getMonth()!==month-1||date.getDate()!==day)return null;return date}function formatISO(date){const mm=String(date.getMonth()+1).padStart(2,"0");const dd=String(date.getDate()).padStart(2,"0");return`${date.getFullYear()}-${mm}-${dd}`}function localeDateOrder(locale){try{const parts=getDateTimeFormat(locale||void 0,{year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(new Date(2026,0,2));const order=parts.filter(p=>p.type==="day"||p.type==="month"||p.type==="year").map(p=>p.type);return order.length===3?order:["month","day","year"]}catch{return["month","day","year"]}}class LyraKnownDateBase extends LyraElement{}function addCompatibilityDetail(event,detail){Object.defineProperty(event,"detail",{configurable:true,value:detail});return event}class LyraKnownDate extends FormAssociated(LyraKnownDateBase){static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,date:LYRA_DEFAULT_date,dateInputInvalid:LYRA_DEFAULT_dateInputInvalid,dateInputMaxMessage:LYRA_DEFAULT_dateInputMaxMessage,dateInputMinMessage:LYRA_DEFAULT_dateInputMinMessage,details:LYRA_DEFAULT_details,fieldRequired:LYRA_DEFAULT_fieldRequired,knownDateDay:LYRA_DEFAULT_knownDateDay,knownDateMonth:LYRA_DEFAULT_knownDateMonth,knownDateYear:LYRA_DEFAULT_knownDateYear,open:LYRA_DEFAULT_open,restore:LYRA_DEFAULT_restore,search:LYRA_DEFAULT_search}}static{this.styles=[LyraElement.styles,sizes,styles]}static{this.properties={min:{reflect:true,noAccessor:true},max:{reflect:true,noAccessor:true},readonly:{type:Boolean,reflect:true,noAccessor:true},parts:{attribute:false,noAccessor:true}}}constructor(){super();this.size="m";this.appearance="outlined";this.pill=false;this.label="";this.hint="";this.errorText="";this.locale="";this.autocomplete="";this.withLabel=false;this.withHint=false;this.accessibleLabel=null;this.dayLabel="Day";this.monthLabel="Month";this.yearLabel="Year";this._parts={...EMPTY_PARTS};this.touched=false;this.hasLabelSlot=false;this.hasHintSlot=false;this.hasErrorSlot=false;this._min="";this._max="";this._readonly=false;this.lastCommittedValue="";this.lastEditedField="day";this.errorAnnouncementsArmed=false;this.lastVisibleError="";this.connectionGeneration=0;this.onForwardedSlotChange=event=>{const target=event.target;if(target?.nodeType!==1||target.localName!=="slot")return;this.bindErrorObserverTargets();this.announceVisibleError()};this.hintId=nextId("known-date-hint");this.errorId=nextId("known-date-error");this.dayId=nextId("known-date-day");this.monthId=nextId("known-date-month");this.yearId=nextId("known-date-year");this.onLabelSlotChange=e=>{this.hasLabelSlot=e.target.assignedElements({flatten:true}).length>0};this.onHintSlotChange=e=>{this.hasHintSlot=e.target.assignedElements({flatten:true}).length>0};this.onErrorSlotChange=e=>{this.hasErrorSlot=e.target.assignedElements({flatten:true}).length>0};this.onFieldInput=(field,e)=>{e.stopPropagation();const input=e.target;const maxLength=field==="year"?4:2;const digits=this.normalizeFieldDigits(input.value).slice(0,maxLength);if(input.value!==digits)input.value=digits;this.setFieldText(field,digits);this.lastEditedField=field;this.commitFromFields();const InputEventConstructor=this.ownerDocument.defaultView?.InputEvent??InputEvent;const event=addCompatibilityDetail(new InputEventConstructor("input",{bubbles:true,composed:true,inputType:"insertText"}),this.detailFor(field));this.dispatchEvent(event);if(field!=="year"&&digits.length===maxLength)this.focusAdjacentField(field,1)};this.onFieldKeydown=(field,e)=>{const input=e.currentTarget;if(isImplicitSubmission(e)){if(this.effectiveDisabled||this.readonly)return;submitOnEnter(this,e,{beforeSubmit:()=>this.commitChangeIfNeeded()});return}if(e.key==="Backspace"&&this.textFor(field)===""){e.preventDefault();this.focusAdjacentField(field,-1);return}if(e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;const atStart=input.selectionStart===0&&input.selectionEnd===0;const atEnd=input.selectionStart===input.value.length&&input.selectionEnd===input.value.length;const rtl=this.effectiveDirection==="rtl";if(e.key==="ArrowLeft"&&atStart){e.preventDefault();this.focusAdjacentField(field,rtl?1:-1)}else if(e.key==="ArrowRight"&&atEnd){e.preventDefault();this.focusAdjacentField(field,rtl?-1:1)}};this.onFieldFocus=e=>{e.stopPropagation();this.emit("focus")};this.onFieldBlur=e=>{e.stopPropagation();this.commitChangeIfNeeded();const related=e.relatedTarget;const active=activeElementIn(this.shadowRoot);const staysInsideControl=e.isTrusted&&(this.isRenderedFieldTarget(related)||active!==e.target&&this.isRenderedFieldTarget(active));if(staysInsideControl)return;if(!this.effectiveDisabled)this.touched=true;this.emit("blur")};this.addEventListener("invalid",()=>{this.touched=true})}connectedCallback(){super.connectedCallback();this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this});const MutationObserverCtor=this.ownerDocument.defaultView?.MutationObserver;this.errorObserver=MutationObserverCtor?new MutationObserverCtor(()=>{this.bindErrorObserverTargets();this.announceVisibleError()}):void 0;this.addEventListener("slotchange",this.onForwardedSlotChange);this.bindErrorObserverTargets();this.errorAnnouncementsArmed=false;const generation=++this.connectionGeneration;void this.updateComplete.then(()=>{const view=this.ownerDocument.defaultView;return typeof view?.requestAnimationFrame==="function"?new Promise(resolve=>view.requestAnimationFrame(()=>resolve())):Promise.resolve()}).then(()=>this.updateComplete).then(()=>{if(!this.isConnected||generation!==this.connectionGeneration)return;this.lastVisibleError=this.visibleErrorText();this.errorAnnouncementsArmed=true})}observeErrorNode(node){if(!this.errorObserver)return;if(node.nodeType===3){this.errorObserver.observe(node,{characterData:true});return}if(node.nodeType!==1)return;this.errorObserver.observe(node,{attributes:true,attributeFilter:["aria-hidden","aria-label","class","hidden","inert","slot","style"],characterData:true,childList:true,subtree:true})}bindErrorObserverTargets(){if(!this.errorObserver)return;this.errorObserver.disconnect();this.observeErrorNode(this);let ancestor=composedParentElement(this);while(ancestor){this.errorObserver.observe(ancestor,{attributes:true,attributeFilter:["aria-hidden","class","hidden","inert","style"]});ancestor=composedParentElement(ancestor)}const errorBranches=Array.from(this.children).filter(element=>element.getAttribute("slot")==="error");const forwardedSlots=errorBranches.flatMap(branch=>[...branch.localName==="slot"?[branch]:[],...branch.querySelectorAll("slot")]);for(const slot of forwardedSlots){for(const assigned of slot.assignedNodes({flatten:true}))this.observeErrorNode(assigned)}}disconnectedCallback(){this.connectionGeneration+=1;this.errorAnnouncementsArmed=false;this.lastVisibleError="";this.removeEventListener("slotchange",this.onForwardedSlotChange);this.errorObserver?.disconnect();this.errorObserver=void 0;this.errorAnnouncementSink?.release();this.errorAnnouncementSink=void 0;super.disconnectedCallback()}get min(){return this._min}set min(next){const old=this._min;this._min=next??"";this.updateValidity();this.requestUpdate("min",old)}get max(){return this._max}set max(next){const old=this._max;this._max=next??"";this.updateValidity();this.requestUpdate("max",old)}get readonly(){return this._readonly}set readonly(next){const old=this._readonly;this._readonly=Boolean(next);this.toggleAttribute("readonly",this._readonly);this.updateValidity();this.requestUpdate("readonly",old)}get parts(){return this._parts}set parts(next){this.setParts(next,true)}setParts(next,programmatic){const old=this._parts;this._parts={day:String(next?.day??""),month:String(next?.month??""),year:String(next?.year??"")};if(programmatic){this.commitFromFields();this.lastCommittedValue=this.value}this.requestUpdate("parts",old)}get value(){return super.value}set value(next){const parsed=this.parseStrictISO(next??"");if(parsed){this.setParts({day:String(parsed.getDate()),month:String(parsed.getMonth()+1),year:String(parsed.getFullYear())},false);super.value=formatISO(parsed)}else{this.setParts({day:"",month:"",year:""},false);super.value=""}this.lastCommittedValue=super.value}get valueAsDate(){return this.value?parseISO(this.value):null}set valueAsDate(next){this.value=next?formatISO(next):""}parseStrictISO(value){if(!/^\d{4}-\d{2}-\d{2}$/.test(value))return null;return parseISO(value)}get fieldOrder(){return localeDateOrder(this.effectiveLocale)}textFor(field){return this._parts[field]}setFieldText(field,text){this.setParts({...this._parts,[field]:text},false)}idFor(field){if(field==="day")return this.dayId;if(field==="month")return this.monthId;return this.yearId}get effectiveDayLabel(){return this.localize("knownDateDay",this.dayLabel==="Day"?void 0:this.dayLabel)}get effectiveMonthLabel(){return this.localize("knownDateMonth",this.monthLabel==="Month"?void 0:this.monthLabel)}get effectiveYearLabel(){return this.localize("knownDateYear",this.yearLabel==="Year"?void 0:this.yearLabel)}labelFor(field){if(field==="day")return this.effectiveDayLabel;if(field==="month")return this.effectiveMonthLabel;return this.effectiveYearLabel}autocompleteFor(field){if(!this.autocomplete)return"";if(this.autocomplete==="bday")return`bday-${field}`;if(this.autocomplete==="on"||this.autocomplete==="off")return this.autocomplete;return field==="year"?this.autocomplete:""}computeCanonicalValue(){if(!this._parts.day||!this._parts.month||!this._parts.year)return"";const iso=`${this._parts.year.padStart(4,"0")}-${this._parts.month.padStart(2,"0")}-${this._parts.day.padStart(2,"0")}`;return parseISO(iso)?iso:""}commitFromFields(){super.value=this.computeCanonicalValue()}get eventDetail(){return{value:this.value,...this._parts}}detailFor(field){return{...this.eventDetail,field}}commitChangeIfNeeded(){if(this.value===this.lastCommittedValue)return;this.lastCommittedValue=this.value;const EventConstructor=this.ownerDocument.defaultView?.Event??Event;const event=addCompatibilityDetail(new EventConstructor("change",{bubbles:true,composed:true}),this.detailFor(this.lastEditedField));this.dispatchEvent(event)}fieldInputElement(field){return this.renderRoot.querySelector(`input[data-field="${field}"]`)}isRenderedFieldTarget(target){if(!target||typeof target!=="object")return false;const field=target.dataset?.field;if(field!=="day"&&field!=="month"&&field!=="year")return false;return this.fieldInputElement(field)===target}focusAdjacentField(field,delta){const order=this.fieldOrder;const targetIndex=order.indexOf(field)+delta;if(targetIndex<0||targetIndex>=order.length)return;this.fieldInputElement(order[targetIndex])?.focus()}updateValidity(){if(isBarredFromValidation(this,this.internals)){this[SET_ANCHORED_VALIDITY]({});return}const flags={};let message="";const blank=this._parts.day===""&&this._parts.month===""&&this._parts.year==="";if(this.value===""){if(this.required&&blank){flags.valueMissing=true;message=this.localize("fieldRequired")}else if(!blank){flags.badInput=true;message=this.localize("dateInputInvalid")}}else{const date=parseISO(this.value);const min=this.parseStrictISO(this.min);const max=this.parseStrictISO(this.max);if(min&&date<min){flags.rangeUnderflow=true;message=this.localize("dateInputMinMessage",void 0,{min:this.min})}if(max&&date>max){flags.rangeOverflow=true;message||=this.localize("dateInputMaxMessage",void 0,{max:this.max})}}this[SET_ANCHORED_VALIDITY](flags,message)}willUpdate(changed){super.willUpdate(changed);if(!this.hasUpdated){this.hasLabelSlot=Array.from(this.children).some(el=>el.getAttribute("slot")==="label");this.hasHintSlot=Array.from(this.children).some(el=>el.getAttribute("slot")==="hint");this.hasErrorSlot=Array.from(this.children).some(el=>el.getAttribute("slot")==="error")}}updated(changed){super.updated(changed);setCustomState(this.internals,"blank",this.value==="");setCustomState(this.internals,"disabled",this.effectiveDisabled);if(changed.has("touched")||changed.has("required")||changed.has("value")||changed.has("min")||changed.has("max")||changed.has("readonly")){this.toggleAttribute("data-invalid",this.touched&&!this.internals.validity.valid)}this.announceVisibleError()}formResetCallback(){super.formResetCallback();this.touched=false}formStateRestoreCallback(state2){this.value=typeof state2==="string"?state2:""}setCustomValidity(message){super.setCustomValidity(message);this.requestUpdate()}resetValidity(){this.setCustomValidity("");this.updateValidity()}visibleErrorText(){const slottedElements=Array.from(this.children).filter(element=>element.getAttribute("slot")==="error");if(slottedElements.length>0){return slottedElements.map(element=>this.accessibleVisibleText(element)).join(" ").replace(/\s+/g," ").trim()}return(this.errorText||(this.touched?this.validationMessage:"")).trim()}accessibleVisibleText(node){if(node.nodeType===3)return node.textContent??"";if(node.nodeType!==1)return"";const element=node;if(isAccessibilitySubtreeExcluded(element))return"";const visibilityHidden=isAccessibilityVisibilityHidden(element);const accessibleLabel=visibilityHidden?null:element.getAttribute("aria-label");if(accessibleLabel?.trim())return accessibleLabel;const assigned=element.localName==="slot"?element.assignedNodes({flatten:true}):[];const children=assigned.length>0?assigned:Array.from(element.childNodes);return children.map(child=>child.nodeType===3&&visibilityHidden?"":this.accessibleVisibleText(child)).join(" ")}announceVisibleError(){if(!this.errorAnnouncementsArmed||!isAccessibilityVisible(this))return;const message=this.visibleErrorText();if(message===this.lastVisibleError)return;this.lastVisibleError=message;if(message)this.errorAnnouncementSink?.announce(message)}normalizeFieldDigits(value){const digitMap=new Map([["\u0660","0"],["\u0661","1"],["\u0662","2"],["\u0663","3"],["\u0664","4"],["\u0665","5"],["\u0666","6"],["\u0667","7"],["\u0668","8"],["\u0669","9"],["\u06F0","0"],["\u06F1","1"],["\u06F2","2"],["\u06F3","3"],["\u06F4","4"],["\u06F5","5"],["\u06F6","6"],["\u06F7","7"],["\u06F8","8"],["\u06F9","9"]]);try{const formatter=getNumberFormat(this.effectiveLocale||void 0,{useGrouping:false});for(let digit=0;digit<=9;digit++)digitMap.set(formatter.format(digit),String(digit))}catch{}let normalized="";for(const character of value){if(character>="0"&&character<="9")normalized+=character;else normalized+=digitMap.get(character)??""}return normalized}focus(options){const target=this.fieldOrder.find(field=>this.textFor(field)==="")??this.fieldOrder[0];this.fieldInputElement(target)?.focus(options)}blur(){this.renderRoot.querySelector("input:focus")?.blur()}click(){this.fieldInputElement(this.fieldOrder[0])?.click()}renderField(field,describedBy,invalid){const id=this.idFor(field);const maxLength=field==="year"?4:2;const fieldPart=field==="day"?"field field-day":field==="month"?"field field-month":"field field-year";return html`
|
|
2
2
|
<div part=${fieldPart} data-field=${field}>
|
|
3
3
|
<label part="field-label" for=${id}>${this.labelFor(field)}</label>
|
|
4
4
|
<input
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LYRA_DEFAULT_fieldRequired}from"./default-strings.generated.js";import{resolveLyraString}from"./localization-runtime.js";import{AnchoredValidityController,SET_ANCHORED_VALIDITY,VALIDITY_ANCHOR}from"./anchored-validity.js";import{syncValidityStates}from"./custom-states.js";import{installInvalidEventAlias}from"./invalid-event-alias.js";import{omittedEmptyStringConverter}from"./converters.js";const FORM_ASSOCIATED_DEFAULT_STRINGS=Object.freeze({fieldRequired:LYRA_DEFAULT_fieldRequired});function setFormOwner(host,owner){const id=typeof owner==="string"?owner:owner?.id??"";if(id)host.setAttribute("form",id);else host.removeAttribute("form")}function getFormOwner(internals){return internals.form}function createStringArrayFormDataState(name,values){const state=new FormData;const key=name||"value";for(const value of values)state.append(key,value);return state}function readStringArrayFormDataState(state){if(typeof FormData!=="function")return[];let entries;try{entries=[...FormData.prototype.values.call(state)]}catch{return[]}if(entries.some(entry=>typeof entry!=="string"))return[];return entries}function isEmptyFormValue(value){if(value==null)return true;if(typeof value==="string")return value==="";if(Array.isArray(value))return value.length===0;if(typeof value==="object"){const prototype=Object.getPrototypeOf(value);if(prototype===null)return Object.keys(value).length===0;if(Object.getPrototypeOf(prototype)===null){const constructor=Object.getOwnPropertyDescriptor(prototype,"constructor")?.value;if(typeof constructor==="function"&&constructor.name==="Object"&&constructor.prototype===prototype){return Object.keys(value).length===0}}}return false}const stringFormValueAdapter={empty:"",toFormValue:value=>value,isEmpty:value=>value==="",fromAttribute:attribute=>attribute,toAttribute:value=>value,fromFormState:state=>typeof state==="string"?state:""};function resolveFormValueAdapter(adapter){if(adapter===void 0){return stringFormValueAdapter}return{empty:adapter.empty,toFormValue:value=>adapter.toFormValue(value),...adapter.toFormState?{toFormState:value=>adapter.toFormState(value)}:{},isEmpty:adapter.isEmpty?value=>adapter.isEmpty(value):isEmptyFormValue,fromAttribute:adapter.fromAttribute?attribute=>adapter.fromAttribute(attribute):attribute=>attribute,toAttribute:adapter.toAttribute?value=>adapter.toAttribute(value):value=>value==null?null:String(value),fromFormState:adapter.fromFormState?state=>adapter.fromFormState(state):state=>typeof state==="string"?state:adapter.empty}}function isBarredFromValidation(host,internals){if(host.effectiveDisabled??host.disabled)return true;if(host.readonly)return true;if(internals){const willValidate=readNativeWillValidate(internals);if(willValidate!==void 0)return!willValidate}return false}function readNativeWillValidate(internals){if(typeof ElementInternals!=="function")return void 0;const getter=Object.getOwnPropertyDescriptor(ElementInternals.prototype,"willValidate")?.get;if(typeof getter!=="function")return void 0;try{const value=getter.call(internals);return typeof value==="boolean"?value:void 0}catch{return void 0}}function installCustomErrorProperty(host,getCustomValidityMessage){if(Object.prototype.hasOwnProperty.call(host,"customError"))return;let reflecting=false;Object.defineProperty(host,"customError",{configurable:true,enumerable:true,get:()=>getCustomValidityMessage()||null,set:next=>{if(reflecting)return;const old=getCustomValidityMessage()||null;const message=next??"";reflecting=true;try{if(next==null){if(host.hasAttribute("custom-error"))host.removeAttribute("custom-error")}else if(host.getAttribute("custom-error")!==message){host.setAttribute("custom-error",message)}}finally{reflecting=false}host.setCustomValidity(message);host.requestUpdate("customError",old)}})}function createFallbackInternals(){let flags={};let message="";const validity={};const validityKeys=["badInput","customError","patternMismatch","rangeOverflow","rangeUnderflow","stepMismatch","tooLong","tooShort","typeMismatch","valueMissing"];for(const key of validityKeys){Object.defineProperty(validity,key,{enumerable:true,get:()=>Boolean(flags[key])})}Object.defineProperty(validity,"valid",{enumerable:true,get:()=>validityKeys.every(key=>!flags[key])});const states=new Set;return{form:null,labels:[],validity,get validationMessage(){return message},willValidate:false,states,setFormValue(){},setValidity(next={},nextMessage=""){flags={...next};message=nextMessage},checkValidity(){return validity.valid},reportValidity(){return validity.valid}}}function attachInternalsSafely(host){if(typeof host.attachInternals!=="function")return createFallbackInternals();try{return host.attachInternals()??createFallbackInternals()}catch{return createFallbackInternals()}}function FormAssociated(Base,valueAdapter){const adapter=resolveFormValueAdapter(valueAdapter);const defaultValueConverter={fromAttribute:attribute=>attribute===null?null:adapter.fromAttribute(attribute),toAttribute:value=>value==null?null:adapter.toAttribute(value)};class FormAssociatedElement extends Base{static{this.formAssociated=true}static{this.properties={name:{reflect:true,noAccessor:true,converter:omittedEmptyStringConverter},value:{attribute:false,noAccessor:true},defaultValue:{attribute:"value",reflect:true,useDefault:true,noAccessor:true,...valueAdapter?{converter:defaultValueConverter}:{}},customError:{attribute:"custom-error",reflect:true,noAccessor:true},form:{noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true},required:{type:Boolean,reflect:true,noAccessor:true}}}constructor(...args){super(...args);this._fieldsetDisabled=false;this._disabled=false;this._name="";this._value=adapter.empty;this._defaultValue=adapter.empty;this._valueDirty=false;this.settingDefaultValue=false;this.reflectingDefaultValue=false;this.reflectingCustomError=false;this.reflectingFormOwner=false;this._required=false;this._hasInteracted=false;this.internals=attachInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());this.commitFormValue(this._value);installInvalidEventAlias(this,init=>this.emit("lr-invalid",void 0,init));const markInteracted=()=>{if(this._hasInteracted)return;this._hasInteracted=true;this.syncValidityStates()};this.addEventListener("input",markInteracted);this.addEventListener("change",markInteracted);this.addEventListener("focusout",markInteracted);this.syncValidityStates()}get form(){return getFormOwner(this.internals)}set form(owner){if(this.reflectingFormOwner)return;this.reflectingFormOwner=true;try{setFormOwner(this,owner)}finally{this.reflectingFormOwner=false}}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](){return this.renderRoot?.querySelector("input:not([type='hidden']), textarea, select, button, [tabindex]:not([tabindex='-1'])")??null}[SET_ANCHORED_VALIDITY](flags,message=""){this.validityController.setValidity(flags,message);this.syncValidityStates()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncValidityStates()}resetValidity(){this.validityController.setCustomValidity("");this.updateValidity();this.syncValidityStates()}syncValidityStates(){syncValidityStates(this.internals,{required:this.required,hasInteracted:this._hasInteracted,barred:this.isBarredFromValidation()})}isBarredFromValidation(){return isBarredFromValidation(this,this.internals)}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)}commitFormValue(value){const submitted=adapter.toFormValue(value);if(adapter.toFormState)this.internals.setFormValue(submitted,adapter.toFormState(value));else this.internals.setFormValue(submitted)}get value(){return this._value}set value(next){const old=this._value;this._value=next??adapter.empty;if(!this.settingDefaultValue)this._valueDirty=true;this.commitFormValue(this._value);this.updateValidity();this.requestUpdate("value",old)}get defaultValue(){return this._defaultValue}set defaultValue(next){if(this.reflectingDefaultValue)return;const old=this._defaultValue;this._defaultValue=next??adapter.empty;this.reflectingDefaultValue=true;try{const attribute=next==null?null:adapter.toAttribute(this._defaultValue);if(attribute==null)this.removeAttribute("value");else this.setAttribute("value",attribute)}finally{this.reflectingDefaultValue=false}if(!this._valueDirty)this.restoreLiveValueFromDefault();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 disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.updateValidity();this.syncValidityStates();this.requestUpdate("disabled",old)}get required(){return this._required}set required(next){const old=this._required;this._required=next;this.toggleAttribute("required",next);this.updateValidity();this.syncValidityStates();this.requestUpdate("required",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}setFormValue(next){this.value=next}updateValidity(){if(this.isBarredFromValidation()){this[SET_ANCHORED_VALIDITY]({});return}if(this.required&&adapter.isEmpty(this._value)){const overrides=this.strings;const message=resolveLyraString(this,"fieldRequired",overrides,void 0,void 0,FORM_ASSOCIATED_DEFAULT_STRINGS);this[SET_ANCHORED_VALIDITY]({valueMissing:true},message)}else{this[SET_ANCHORED_VALIDITY]({})}}syncConstraintsToNative(){const host=this;if(!host.hasUpdated)return;host.performUpdate()}checkValidity(){this.syncConstraintsToNative();this.updateValidity();return this.internals.checkValidity()}reportValidity(){this.syncConstraintsToNative();this.updateValidity();this._hasInteracted=true;this.syncValidityStates();return this.internals.reportValidity()}formResetCallback(){this._valueDirty=false;this.restoreLiveValueFromDefault();this._hasInteracted=false;this.syncValidityStates()}restoreLiveValueFromDefault(){this.settingDefaultValue=true;try{this.value=this._defaultValue}finally{this.settingDefaultValue=false}this._valueDirty=false}formStateRestoreCallback(state,reason){void reason;this.value=adapter.fromFormState(state)}formDisabledCallback(fieldsetDisabled){this._fieldsetDisabled=fieldsetDisabled;this.updateValidity();this.syncValidityStates();this.requestUpdate()}updated(changed){super.updated(changed);if(!changed.has("readonly")&&!changed.has("disabled"))return;this.updateValidity();this.syncValidityStates()}connectedCallback(){super.connectedCallback();this.updateValidity();this.syncValidityStates()}}return FormAssociatedElement}export{FormAssociated,attachInternalsSafely,createFallbackInternals,createStringArrayFormDataState,getFormOwner,installCustomErrorProperty,isBarredFromValidation,isEmptyFormValue,readStringArrayFormDataState,setFormOwner,stringFormValueAdapter};
|
|
1
|
+
import{LYRA_DEFAULT_fieldRequired}from"./default-strings.generated.js";import{resolveLyraString}from"./localization-runtime.js";import{AnchoredValidityController,SET_ANCHORED_VALIDITY,VALIDITY_ANCHOR}from"./anchored-validity.js";import{syncValidityStates}from"./custom-states.js";import{installInvalidEventAlias}from"./invalid-event-alias.js";import{omittedEmptyStringConverter}from"./converters.js";const FORM_ASSOCIATED_DEFAULT_STRINGS=Object.freeze({fieldRequired:LYRA_DEFAULT_fieldRequired});function setFormOwner(host,owner){const id=typeof owner==="string"?owner:owner?.id??"";if(id)host.setAttribute("form",id);else host.removeAttribute("form")}function getFormOwner(internals){return internals.form}function createStringArrayFormDataState(name,values){const state=new FormData;const key=name||"value";for(const value of values)state.append(key,value);return state}function readStringArrayFormDataState(state){if(typeof FormData!=="function")return[];let entries;try{entries=[...FormData.prototype.values.call(state)]}catch{return[]}if(entries.some(entry=>typeof entry!=="string"))return[];return entries}function isEmptyFormValue(value){if(value==null)return true;if(typeof value==="string")return value==="";if(Array.isArray(value))return value.length===0;if(typeof value==="object"){const prototype=Object.getPrototypeOf(value);if(prototype===null)return Object.keys(value).length===0;if(Object.getPrototypeOf(prototype)===null){const constructor=Object.getOwnPropertyDescriptor(prototype,"constructor")?.value;if(typeof constructor==="function"&&constructor.name==="Object"&&constructor.prototype===prototype){return Object.keys(value).length===0}}}return false}const stringFormValueAdapter={empty:"",toFormValue:value=>value,isEmpty:value=>value==="",fromAttribute:attribute=>attribute,toAttribute:value=>value,fromFormState:state=>typeof state==="string"?state:""};function resolveFormValueAdapter(adapter){if(adapter===void 0){return stringFormValueAdapter}return{empty:adapter.empty,toFormValue:value=>adapter.toFormValue(value),...adapter.toFormState?{toFormState:value=>adapter.toFormState(value)}:{},isEmpty:adapter.isEmpty?value=>adapter.isEmpty(value):isEmptyFormValue,fromAttribute:adapter.fromAttribute?attribute=>adapter.fromAttribute(attribute):attribute=>attribute,toAttribute:adapter.toAttribute?value=>adapter.toAttribute(value):value=>value==null?null:String(value),fromFormState:adapter.fromFormState?state=>adapter.fromFormState(state):state=>typeof state==="string"?state:adapter.empty}}function isBarredFromValidation(host,internals){if(host.effectiveDisabled??host.disabled)return true;if(host.readonly)return true;if(internals){const willValidate=readNativeWillValidate(internals);if(willValidate!==void 0)return!willValidate}return false}function readNativeWillValidate(internals){if(typeof ElementInternals!=="function")return void 0;const getter=Object.getOwnPropertyDescriptor(ElementInternals.prototype,"willValidate")?.get;if(typeof getter!=="function")return void 0;try{const value=getter.call(internals);return typeof value==="boolean"?value:void 0}catch{return void 0}}function installCustomErrorProperty(host,getCustomValidityMessage){if(Object.prototype.hasOwnProperty.call(host,"customError"))return;let reflecting=false;Object.defineProperty(host,"customError",{configurable:true,enumerable:true,get:()=>getCustomValidityMessage()||null,set:next=>{if(reflecting)return;const old=getCustomValidityMessage()||null;const message=next??"";reflecting=true;try{if(next==null){if(host.hasAttribute("custom-error"))host.removeAttribute("custom-error")}else if(host.getAttribute("custom-error")!==message){host.setAttribute("custom-error",message)}}finally{reflecting=false}host.setCustomValidity(message);host.requestUpdate("customError",old)}})}function createFallbackInternals(){let flags={};let message="";const validity={};const validityKeys=["badInput","customError","patternMismatch","rangeOverflow","rangeUnderflow","stepMismatch","tooLong","tooShort","typeMismatch","valueMissing"];for(const key of validityKeys){Object.defineProperty(validity,key,{enumerable:true,get:()=>Boolean(flags[key])})}Object.defineProperty(validity,"valid",{enumerable:true,get:()=>validityKeys.every(key=>!flags[key])});const states=new Set;return{form:null,labels:[],validity,get validationMessage(){return message},willValidate:false,states,setFormValue(){},setValidity(next={},nextMessage=""){flags={...next};message=nextMessage},checkValidity(){return validity.valid},reportValidity(){return validity.valid}}}function attachInternalsSafely(host){if(typeof host.attachInternals!=="function")return createFallbackInternals();try{return host.attachInternals()??createFallbackInternals()}catch{return createFallbackInternals()}}function FormAssociated(Base,valueAdapter){const adapter=resolveFormValueAdapter(valueAdapter);const defaultValueConverter={fromAttribute:attribute=>attribute===null?null:adapter.fromAttribute(attribute),toAttribute:value=>value==null?null:adapter.toAttribute(value)};class FormAssociatedElement extends Base{static{this.formAssociated=true}static{this.properties={name:{reflect:true,noAccessor:true,converter:omittedEmptyStringConverter},value:{attribute:false,noAccessor:true},defaultValue:{attribute:"value",reflect:true,useDefault:true,noAccessor:true,...valueAdapter?{converter:defaultValueConverter}:{}},customError:{attribute:"custom-error",reflect:true,noAccessor:true},form:{noAccessor:true},disabled:{type:Boolean,reflect:true,noAccessor:true},required:{type:Boolean,reflect:true,noAccessor:true}}}constructor(...args){super(...args);this._fieldsetDisabled=false;this._disabled=false;this._reflectingDisabledAttribute=false;this._name="";this._value=adapter.empty;this._defaultValue=adapter.empty;this._valueDirty=false;this.settingDefaultValue=false;this.reflectingDefaultValue=false;this.reflectingCustomError=false;this.reflectingFormOwner=false;this._required=false;this._hasInteracted=false;this.internals=attachInternalsSafely(this);this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]());this.commitFormValue(this._value);installInvalidEventAlias(this,init=>this.emit("lr-invalid",void 0,init));const markInteracted=()=>{if(this._hasInteracted)return;this._hasInteracted=true;this.syncValidityStates()};this.addEventListener("input",markInteracted);this.addEventListener("change",markInteracted);this.addEventListener("focusout",markInteracted);this.syncValidityStates()}get form(){return getFormOwner(this.internals)}set form(owner){if(this.reflectingFormOwner)return;this.reflectingFormOwner=true;try{setFormOwner(this,owner)}finally{this.reflectingFormOwner=false}}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](){return this.renderRoot?.querySelector("input:not([type='hidden']), textarea, select, button, [tabindex]:not([tabindex='-1'])")??null}[SET_ANCHORED_VALIDITY](flags,message=""){this.validityController.setValidity(flags,message);this.syncValidityStates()}setCustomValidity(message){this.validityController.setCustomValidity(message??"");this.syncValidityStates()}resetValidity(){this.validityController.setCustomValidity("");this.updateValidity();this.syncValidityStates()}syncValidityStates(){syncValidityStates(this.internals,{required:this.required,hasInteracted:this._hasInteracted,barred:this.isBarredFromValidation()})}isBarredFromValidation(){return isBarredFromValidation(this,this.internals)}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)}commitFormValue(value){const submitted=adapter.toFormValue(value);if(adapter.toFormState)this.internals.setFormValue(submitted,adapter.toFormState(value));else this.internals.setFormValue(submitted)}get value(){return this._value}set value(next){const old=this._value;this._value=next??adapter.empty;if(!this.settingDefaultValue)this._valueDirty=true;this.commitFormValue(this._value);this.updateValidity();this.requestUpdate("value",old)}get defaultValue(){return this._defaultValue}set defaultValue(next){if(this.reflectingDefaultValue)return;const old=this._defaultValue;this._defaultValue=next??adapter.empty;this.reflectingDefaultValue=true;try{const attribute=next==null?null:adapter.toAttribute(this._defaultValue);if(attribute==null)this.removeAttribute("value");else this.setAttribute("value",attribute)}finally{this.reflectingDefaultValue=false}if(!this._valueDirty)this.restoreLiveValueFromDefault();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 disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=Boolean(next);this.toggleAttribute("disabled",this._disabled);this.updateValidity();this.syncValidityStates();this.requestUpdate("disabled",old)}toggleAttribute(qualifiedName,force){if(qualifiedName!=="disabled")return super.toggleAttribute(qualifiedName,force);this._reflectingDisabledAttribute=true;try{return super.toggleAttribute(qualifiedName,force)}finally{queueMicrotask(()=>{this._reflectingDisabledAttribute=false})}}setAttribute(qualifiedName,value){if(qualifiedName!=="disabled"){super.setAttribute(qualifiedName,value);return}this._reflectingDisabledAttribute=true;try{super.setAttribute(qualifiedName,value)}finally{queueMicrotask(()=>{this._reflectingDisabledAttribute=false})}}removeAttribute(qualifiedName){if(qualifiedName!=="disabled"){super.removeAttribute(qualifiedName);return}this._reflectingDisabledAttribute=true;try{super.removeAttribute(qualifiedName)}finally{queueMicrotask(()=>{this._reflectingDisabledAttribute=false})}}get required(){return this._required}set required(next){const old=this._required;this._required=next;this.toggleAttribute("required",next);this.updateValidity();this.syncValidityStates();this.requestUpdate("required",old)}get effectiveDisabled(){return this.disabled||this._fieldsetDisabled}setFormValue(next){this.value=next}updateValidity(){if(this.isBarredFromValidation()){this[SET_ANCHORED_VALIDITY]({});return}if(this.required&&adapter.isEmpty(this._value)){const overrides=this.strings;const message=resolveLyraString(this,"fieldRequired",overrides,void 0,void 0,FORM_ASSOCIATED_DEFAULT_STRINGS);this[SET_ANCHORED_VALIDITY]({valueMissing:true},message)}else{this[SET_ANCHORED_VALIDITY]({})}}syncConstraintsToNative(){const host=this;if(!host.hasUpdated)return;host.performUpdate()}checkValidity(){this.syncConstraintsToNative();this.updateValidity();return this.internals.checkValidity()}reportValidity(){this.syncConstraintsToNative();this.updateValidity();this._hasInteracted=true;this.syncValidityStates();return this.internals.reportValidity()}formResetCallback(){this._valueDirty=false;this.restoreLiveValueFromDefault();this._hasInteracted=false;this.syncValidityStates()}restoreLiveValueFromDefault(){this.settingDefaultValue=true;try{this.value=this._defaultValue}finally{this.settingDefaultValue=false}this._valueDirty=false}formStateRestoreCallback(state,reason){void reason;this.value=adapter.fromFormState(state)}formDisabledCallback(fieldsetDisabled){if(this._reflectingDisabledAttribute)return;const before=this.effectiveDisabled;this._fieldsetDisabled=fieldsetDisabled;if(this.effectiveDisabled===before)return;this.updateValidity();this.syncValidityStates();this.requestUpdate()}updated(changed){super.updated(changed);if(!changed.has("readonly")&&!changed.has("disabled"))return;this.updateValidity();this.syncValidityStates()}connectedCallback(){super.connectedCallback();this.updateValidity();this.syncValidityStates()}}return FormAssociatedElement}export{FormAssociated,attachInternalsSafely,createFallbackInternals,createStringArrayFormDataState,getFormOwner,installCustomErrorProperty,isBarredFromValidation,isEmptyFormValue,readStringArrayFormDataState,setFormOwner,stringFormValueAdapter};
|
|
@@ -47,6 +47,19 @@ export declare function invalidateLyraLocaleCache(host: Element): void;
|
|
|
47
47
|
export declare function resolveLyraLocale(host: Element): string;
|
|
48
48
|
/** Resolve the direction inherited by a component host. */
|
|
49
49
|
export declare function resolveLyraDirection(host: Element): 'ltr' | 'rtl';
|
|
50
|
+
/**
|
|
51
|
+
* Reads a host's already-memoized locale/direction without resolving anything -- in particular,
|
|
52
|
+
* without `resolveLyraDirection()`'s `getComputedStyle()` call. `undefined` when the host was
|
|
53
|
+
* never opted into caching, or opted in but never actually read `effectiveLocale`/
|
|
54
|
+
* `effectiveDirection` (so its own render never populated the memo). Lets a caller establish a
|
|
55
|
+
* "what's currently rendered" baseline for free, piggybacking on whatever the host's own last
|
|
56
|
+
* render already computed, instead of forcing a fresh (potentially expensive or, for
|
|
57
|
+
* `getComputedStyle()` specifically, disruptive -- see `observeInheritedContext()`) resolution
|
|
58
|
+
* purely to seed a comparison.
|
|
59
|
+
*/
|
|
60
|
+
export declare function peekLyraLocale(host: Element): string | undefined;
|
|
61
|
+
/** @see peekLyraLocale */
|
|
62
|
+
export declare function peekLyraDirection(host: Element): 'ltr' | 'rtl' | undefined;
|
|
50
63
|
/**
|
|
51
64
|
* Resolve a message for a component. An explicit per-component override wins,
|
|
52
65
|
* followed by a non-empty component property fallback, registered locale
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getPluralRules}from"./intl-cache.js";const locales=new Map;const localeMeta=new Map;const exactOnlyLocales=new Set;const listeners=new Set;const registryListeners=new Set;let activeLocale="";function normalizeLocale(locale){return locale.trim().replace(/_/g,"-").toLowerCase()}function regionalFallbacks(subtags){const language=subtags[0];if(!language)return[];const requested=new Set(subtags);const score=key=>key.split("-").filter(subtag=>requested.has(subtag)).length;return[...locales.keys()].filter(key=>!exactOnlyLocales.has(key)&&key.split("-")[0]===language&&!isPrefixOf(key,subtags)).sort((a,b)=>score(b)-score(a)||(a<b?-1:a>b?1:0))}function isPrefixOf(key,subtags){const parts=key.split("-");return parts.length<=subtags.length&&parts.every((part,index)=>part===subtags[index])}function localeCandidates(locale){const normalized=normalizeLocale(locale);const subtags=normalized.split("-").filter(Boolean);const candidates=[];for(let length=subtags.length;length>0;length--){candidates.push(subtags.slice(0,length).join("-"))}candidates.push(...regionalFallbacks(subtags));if(!candidates.includes("en"))candidates.push("en");return candidates}function notify(){for(const listener of[...listeners])listener()}function getRegisteredLyraLocales(){const keys=new Set(["en",...locales.keys()]);return[...keys].sort()}function subscribeLyraLocaleRegistry(listener){registryListeners.add(listener);return()=>registryListeners.delete(listener)}function registerLocale(locale,strings,meta,exactOnly){const key=normalizeLocale(locale);if(!key)throw new TypeError("A locale is required.");if(exactOnly)exactOnlyLocales.add(key);locales.set(key,{...locales.get(key)??{},...strings});if(meta)localeMeta.set(key,{...localeMeta.get(key)??{},...meta});pluralLocaleCache.clear();notify();for(const listener of[...registryListeners])listener()}function registerLyraLocale(locale,strings,meta){registerLocale(locale,strings,meta,false)}function registerLyraExactLocale(locale,strings,meta){registerLocale(locale,strings,meta,true)}function getLyraLocaleDirection(locale){const normalized=normalizeLocale(locale);if(!normalized)return"ltr";for(const candidate of localeCandidates(normalized)){const declared=localeMeta.get(candidate)?.dir;if(declared)return declared}try{const resolved=new Intl.Locale(normalized);const direction=resolved.textInfo?.direction??resolved.getTextInfo?.().direction;return direction==="rtl"?"rtl":"ltr"}catch{return"ltr"}}function setLyraLocale(locale){const next=locale.trim();if(activeLocale===next)return;activeLocale=next;notify()}function getLyraLocale(){return activeLocale}function subscribeLyraLocale(listener){listeners.add(listener);return()=>listeners.delete(listener)}function inheritedLocale(host){const explicit=host.getAttribute("locale")||host.getAttribute("lang");if(explicit)return explicit;const composedParent=element=>{if(element.parentElement)return element.parentElement;const root=element.getRootNode();const candidate=root.host;return root.nodeType===11&&candidate!==null&&typeof candidate==="object"&&typeof candidate.getAttribute==="function"?candidate:null};let parent=composedParent(host);while(parent){const locale=parent.getAttribute("locale")||parent.getAttribute("lang");if(locale)return locale;parent=composedParent(parent)}const documentLocale=host.ownerDocument?.documentElement?.getAttribute("lang");if(documentLocale)return documentLocale;return activeLocale||"en"}const cacheableLocaleHosts=new WeakSet;const resolvedLocaleCache=new WeakMap;const resolvedDirectionCache=new WeakMap;function enableLyraLocaleCache(host){cacheableLocaleHosts.add(host)}function invalidateLyraLocaleCache(host){resolvedLocaleCache.delete(host);resolvedDirectionCache.delete(host)}function resolveLyraLocale(host){if(!cacheableLocaleHosts.has(host))return inheritedLocale(host);let locale=resolvedLocaleCache.get(host);if(locale===void 0){locale=inheritedLocale(host);resolvedLocaleCache.set(host,locale)}return locale}function inheritedDirection(host){const explicit=host.getAttribute("dir");if(explicit==="rtl"||explicit==="ltr")return explicit;const view=host.ownerDocument?.defaultView;if(view)return view.getComputedStyle(host).direction==="rtl"?"rtl":"ltr";return"ltr"}function resolveLyraDirection(host){if(!cacheableLocaleHosts.has(host))return inheritedDirection(host);let direction=resolvedDirectionCache.get(host);if(direction===void 0){direction=inheritedDirection(host);resolvedDirectionCache.set(host,direction)}return direction}const PLURAL_CATEGORY_FALLBACKS={zero:["zero","other"],one:["one","other"],two:["two","few","many","other"],few:["few","many","other"],many:["many","few","other"],other:["other"]};function isPluralMessage(message){return typeof message==="object"}function pluralSelector(values){const raw=values["pluralCount"]??values["count"];return typeof raw==="number"&&Number.isFinite(raw)?raw:void 0}const pluralLocaleCache=new Map;const MAX_PLURAL_LOCALE_ENTRIES=64;function pluralLocale(locale){const cached=pluralLocaleCache.get(locale);if(cached!==void 0||pluralLocaleCache.has(locale))return cached;let resolved;for(const candidate of localeCandidates(locale)){try{getPluralRules(candidate);resolved=candidate;break}catch{}}if(pluralLocaleCache.size>=MAX_PLURAL_LOCALE_ENTRIES)pluralLocaleCache.clear();pluralLocaleCache.set(locale,resolved);return resolved}function selectPluralMessage(message,locale,count){if(count===void 0)return message.other;const tag=pluralLocale(locale);if(tag===void 0)return message.other;const category=getPluralRules(tag).select(count);for(const candidate of PLURAL_CATEGORY_FALLBACKS[category]??PLURAL_CATEGORY_FALLBACKS.other){const text=message[candidate];if(text!==void 0)return text}return message.other}function resolveLyraString(host,key,overrides,fallback,values,defaults){const own=overrides?.[key];let message=own??fallback;let locale;if(message===void 0){locale=resolveLyraLocale(host);for(const candidate of localeCandidates(locale)){const registered=locales.get(candidate)?.[key];if(registered!==void 0){message=registered;break}}}message??=defaults?.[key]??key;let text;if(isPluralMessage(message)){locale??=resolveLyraLocale(host);text=selectPluralMessage(message,locale,values?pluralSelector(values):void 0)}else{text=message}if(!values)return text;return text.replace(/\{(\w+)\}/g,(_match,name)=>String(values[name]??`{${name}}`))}function resolveLocalizedParts(template,interpolate){let marker="\uE000";while(template.includes(marker))marker+="\uE001";return interpolate(marker).split(marker)}export{enableLyraLocaleCache,getLyraLocale,getLyraLocaleDirection,getRegisteredLyraLocales,invalidateLyraLocaleCache,registerLyraExactLocale,registerLyraLocale,resolveLocalizedParts,resolveLyraDirection,resolveLyraLocale,resolveLyraString,setLyraLocale,subscribeLyraLocale,subscribeLyraLocaleRegistry};
|
|
1
|
+
import{getPluralRules}from"./intl-cache.js";const locales=new Map;const localeMeta=new Map;const exactOnlyLocales=new Set;const listeners=new Set;const registryListeners=new Set;let activeLocale="";function normalizeLocale(locale){return locale.trim().replace(/_/g,"-").toLowerCase()}function regionalFallbacks(subtags){const language=subtags[0];if(!language)return[];const requested=new Set(subtags);const score=key=>key.split("-").filter(subtag=>requested.has(subtag)).length;return[...locales.keys()].filter(key=>!exactOnlyLocales.has(key)&&key.split("-")[0]===language&&!isPrefixOf(key,subtags)).sort((a,b)=>score(b)-score(a)||(a<b?-1:a>b?1:0))}function isPrefixOf(key,subtags){const parts=key.split("-");return parts.length<=subtags.length&&parts.every((part,index)=>part===subtags[index])}function localeCandidates(locale){const normalized=normalizeLocale(locale);const subtags=normalized.split("-").filter(Boolean);const candidates=[];for(let length=subtags.length;length>0;length--){candidates.push(subtags.slice(0,length).join("-"))}candidates.push(...regionalFallbacks(subtags));if(!candidates.includes("en"))candidates.push("en");return candidates}function notify(){for(const listener of[...listeners])listener()}function getRegisteredLyraLocales(){const keys=new Set(["en",...locales.keys()]);return[...keys].sort()}function subscribeLyraLocaleRegistry(listener){registryListeners.add(listener);return()=>registryListeners.delete(listener)}function registerLocale(locale,strings,meta,exactOnly){const key=normalizeLocale(locale);if(!key)throw new TypeError("A locale is required.");if(exactOnly)exactOnlyLocales.add(key);locales.set(key,{...locales.get(key)??{},...strings});if(meta)localeMeta.set(key,{...localeMeta.get(key)??{},...meta});pluralLocaleCache.clear();notify();for(const listener of[...registryListeners])listener()}function registerLyraLocale(locale,strings,meta){registerLocale(locale,strings,meta,false)}function registerLyraExactLocale(locale,strings,meta){registerLocale(locale,strings,meta,true)}function getLyraLocaleDirection(locale){const normalized=normalizeLocale(locale);if(!normalized)return"ltr";for(const candidate of localeCandidates(normalized)){const declared=localeMeta.get(candidate)?.dir;if(declared)return declared}try{const resolved=new Intl.Locale(normalized);const direction=resolved.textInfo?.direction??resolved.getTextInfo?.().direction;return direction==="rtl"?"rtl":"ltr"}catch{return"ltr"}}function setLyraLocale(locale){const next=locale.trim();if(activeLocale===next)return;activeLocale=next;notify()}function getLyraLocale(){return activeLocale}function subscribeLyraLocale(listener){listeners.add(listener);return()=>listeners.delete(listener)}function inheritedLocale(host){const explicit=host.getAttribute("locale")||host.getAttribute("lang");if(explicit)return explicit;const composedParent=element=>{if(element.parentElement)return element.parentElement;const root=element.getRootNode();const candidate=root.host;return root.nodeType===11&&candidate!==null&&typeof candidate==="object"&&typeof candidate.getAttribute==="function"?candidate:null};let parent=composedParent(host);while(parent){const locale=parent.getAttribute("locale")||parent.getAttribute("lang");if(locale)return locale;parent=composedParent(parent)}const documentLocale=host.ownerDocument?.documentElement?.getAttribute("lang");if(documentLocale)return documentLocale;return activeLocale||"en"}const cacheableLocaleHosts=new WeakSet;const resolvedLocaleCache=new WeakMap;const resolvedDirectionCache=new WeakMap;function enableLyraLocaleCache(host){cacheableLocaleHosts.add(host)}function invalidateLyraLocaleCache(host){resolvedLocaleCache.delete(host);resolvedDirectionCache.delete(host)}function resolveLyraLocale(host){if(!cacheableLocaleHosts.has(host))return inheritedLocale(host);let locale=resolvedLocaleCache.get(host);if(locale===void 0){locale=inheritedLocale(host);resolvedLocaleCache.set(host,locale)}return locale}function inheritedDirection(host){const explicit=host.getAttribute("dir");if(explicit==="rtl"||explicit==="ltr")return explicit;const view=host.ownerDocument?.defaultView;if(view)return view.getComputedStyle(host).direction==="rtl"?"rtl":"ltr";return"ltr"}function resolveLyraDirection(host){if(!cacheableLocaleHosts.has(host))return inheritedDirection(host);let direction=resolvedDirectionCache.get(host);if(direction===void 0){direction=inheritedDirection(host);resolvedDirectionCache.set(host,direction)}return direction}function peekLyraLocale(host){return resolvedLocaleCache.get(host)}function peekLyraDirection(host){return resolvedDirectionCache.get(host)}const PLURAL_CATEGORY_FALLBACKS={zero:["zero","other"],one:["one","other"],two:["two","few","many","other"],few:["few","many","other"],many:["many","few","other"],other:["other"]};function isPluralMessage(message){return typeof message==="object"}function pluralSelector(values){const raw=values["pluralCount"]??values["count"];return typeof raw==="number"&&Number.isFinite(raw)?raw:void 0}const pluralLocaleCache=new Map;const MAX_PLURAL_LOCALE_ENTRIES=64;function pluralLocale(locale){const cached=pluralLocaleCache.get(locale);if(cached!==void 0||pluralLocaleCache.has(locale))return cached;let resolved;for(const candidate of localeCandidates(locale)){try{getPluralRules(candidate);resolved=candidate;break}catch{}}if(pluralLocaleCache.size>=MAX_PLURAL_LOCALE_ENTRIES)pluralLocaleCache.clear();pluralLocaleCache.set(locale,resolved);return resolved}function selectPluralMessage(message,locale,count){if(count===void 0)return message.other;const tag=pluralLocale(locale);if(tag===void 0)return message.other;const category=getPluralRules(tag).select(count);for(const candidate of PLURAL_CATEGORY_FALLBACKS[category]??PLURAL_CATEGORY_FALLBACKS.other){const text=message[candidate];if(text!==void 0)return text}return message.other}function resolveLyraString(host,key,overrides,fallback,values,defaults){const own=overrides?.[key];let message=own??fallback;let locale;if(message===void 0){locale=resolveLyraLocale(host);for(const candidate of localeCandidates(locale)){const registered=locales.get(candidate)?.[key];if(registered!==void 0){message=registered;break}}}message??=defaults?.[key]??key;let text;if(isPluralMessage(message)){locale??=resolveLyraLocale(host);text=selectPluralMessage(message,locale,values?pluralSelector(values):void 0)}else{text=message}if(!values)return text;return text.replace(/\{(\w+)\}/g,(_match,name)=>String(values[name]??`{${name}}`))}function resolveLocalizedParts(template,interpolate){let marker="\uE000";while(template.includes(marker))marker+="\uE001";return interpolate(marker).split(marker)}export{enableLyraLocaleCache,getLyraLocale,getLyraLocaleDirection,getRegisteredLyraLocales,invalidateLyraLocaleCache,peekLyraDirection,peekLyraLocale,registerLyraExactLocale,registerLyraLocale,resolveLocalizedParts,resolveLyraDirection,resolveLyraLocale,resolveLyraString,setLyraLocale,subscribeLyraLocale,subscribeLyraLocaleRegistry};
|
|
@@ -68,6 +68,21 @@ export declare class LyraElement<Events = LyraEventMap> extends LitElement {
|
|
|
68
68
|
*/
|
|
69
69
|
requestUpdate(name?: PropertyKey, oldValue?: unknown, options?: PropertyDeclaration): void;
|
|
70
70
|
attributeChangedCallback(name: string, oldValue: string | null, value: string | null): void;
|
|
71
|
+
/**
|
|
72
|
+
* `class`/`style` sit in {@link INHERITED_CONTEXT_ATTRIBUTES} so a CSS-only ancestor direction
|
|
73
|
+
* change (`.rtl-context { direction: rtl }`, an inline `style="direction: rtl"`) is still
|
|
74
|
+
* picked up with no `dir` attribute anywhere — see the "reads computed direction live after
|
|
75
|
+
* ancestor style and class changes" test. But `class`/`style` also cover every OTHER reason an
|
|
76
|
+
* ancestor's inline style or class list might change, most of which have nothing to do with
|
|
77
|
+
* direction or locale (an overlay's own `--lr-overlay-stack-index` custom property, a consumer's
|
|
78
|
+
* unrelated theming class, …). A MutationObserver callback is its own microtask, scheduled
|
|
79
|
+
* independently of Lit's update batching, so an unconditional `requestUpdate()` here could land
|
|
80
|
+
* inside another in-flight update's `updated()`/`hostUpdated()` window purely because of a
|
|
81
|
+
* direction-irrelevant style write on some unrelated ancestor — Lit's dev-mode "scheduled an
|
|
82
|
+
* update after an update completed" warning, for a re-render that was never actually warranted
|
|
83
|
+
* (fr_asxOgk4UhNB07xevCWwFVQ). Comparing the freshly resolved direction/locale against the last
|
|
84
|
+
* observed pair keeps the feature intact while dropping every spurious trigger.
|
|
85
|
+
*/
|
|
71
86
|
private observeInheritedContext;
|
|
72
87
|
/**
|
|
73
88
|
* Runs `seed` before the first render — except while hydrating a server-rendered shadow root,
|
|
@@ -1 +1 @@
|
|
|
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{LitElement}from"lit";import{property}from"lit/decorators.js";import{captureFormInternals,ExternalLabelController}from"./form-control-labels.js";import{tokens}from"./tokens.styles.js";import{palette}from"./tokens/palette.styles.js";import{resolveIntlLocale}from"./intl-cache.js";import{enableLyraLocaleCache,invalidateLyraLocaleCache,resolveLyraDirection,resolveLyraString,resolveLyraLocale,subscribeLyraLocale}from"./localization-runtime.js";const REACTIVE_HOST_ATTRIBUTES=["aria-label","aria-describedby","lang","dir"];const DIRECTION_HOST_ATTRIBUTES=["class","style"];const INHERITED_CONTEXT_ATTRIBUTES=["locale","lang","dir","class","style"];function composedParentElement(element){if(element.parentElement)return element.parentElement;const root=element.getRootNode();const candidate=root.host;return root.nodeType===11&&candidate!==null&&typeof candidate==="object"&&typeof candidate.getAttribute==="function"?candidate:null}class LyraElement extends LitElement{static{this.styles=[palette,tokens]}static{this.defaultStrings=Object.freeze({})}static get observedAttributes(){return[...new Set([...super.observedAttributes,...REACTIVE_HOST_ATTRIBUTES,...DIRECTION_HOST_ATTRIBUTES])]}constructor(){super();this.locale="";this.strings={};if(this.constructor.formAssociated){this.addController(new ExternalLabelController(this))}}attachInternals(){const internals=super.attachInternals();captureFormInternals(this,internals);return internals}connectedCallback(){this.hydratingServerShadow??=!this.hasUpdated&&this.shadowRoot!==null;super.connectedCallback();enableLyraLocaleCache(this);invalidateLyraLocaleCache(this);this.observeInheritedContext();this.stopLocaleSubscription=subscribeLyraLocale(()=>this.requestUpdate());const deferred=this.deferredAfterUpdate;if(deferred){this.deferredAfterUpdate=void 0;for(const[key,callback]of deferred)this.scheduleAfterUpdate(callback,key)}}disconnectedCallback(){this.pendingLoadController?.abort();this.pendingLoadController=void 0;this.stopLocaleSubscription?.();this.stopLocaleSubscription=void 0;this.inheritedContextObserver?.disconnect();this.inheritedContextObserver=void 0;invalidateLyraLocaleCache(this);super.disconnectedCallback()}requestUpdate(name,oldValue,options){invalidateLyraLocaleCache(this);super.requestUpdate(name,oldValue,options)}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value);if(oldValue!==value&&REACTIVE_HOST_ATTRIBUTES.includes(name)){this.requestUpdate()}else if(oldValue!==value&&DIRECTION_HOST_ATTRIBUTES.includes(name)){invalidateLyraLocaleCache(this)}}observeInheritedContext(){this.inheritedContextObserver?.disconnect();const Observer=this.ownerDocument?.defaultView?.MutationObserver;if(!Observer)return;const observer=new Observer(()
|
|
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{LitElement}from"lit";import{property}from"lit/decorators.js";import{captureFormInternals,ExternalLabelController}from"./form-control-labels.js";import{tokens}from"./tokens.styles.js";import{palette}from"./tokens/palette.styles.js";import{resolveIntlLocale}from"./intl-cache.js";import{enableLyraLocaleCache,invalidateLyraLocaleCache,peekLyraDirection,peekLyraLocale,resolveLyraDirection,resolveLyraString,resolveLyraLocale,subscribeLyraLocale}from"./localization-runtime.js";const REACTIVE_HOST_ATTRIBUTES=["aria-label","aria-describedby","lang","dir"];const DIRECTION_HOST_ATTRIBUTES=["class","style"];const INHERITED_CONTEXT_ATTRIBUTES=["locale","lang","dir","class","style"];function composedParentElement(element){if(element.parentElement)return element.parentElement;const root=element.getRootNode();const candidate=root.host;return root.nodeType===11&&candidate!==null&&typeof candidate==="object"&&typeof candidate.getAttribute==="function"?candidate:null}const STYLE_DIRECTION_PATTERN=/(?:^|[;\s])direction\s*:\s*([^;]+)/i;function styleDirectionDeclaration(styleText){return STYLE_DIRECTION_PATTERN.exec(styleText)?.[1]?.trim()}class LyraElement extends LitElement{static{this.styles=[palette,tokens]}static{this.defaultStrings=Object.freeze({})}static get observedAttributes(){return[...new Set([...super.observedAttributes,...REACTIVE_HOST_ATTRIBUTES,...DIRECTION_HOST_ATTRIBUTES])]}constructor(){super();this.locale="";this.strings={};if(this.constructor.formAssociated){this.addController(new ExternalLabelController(this))}}attachInternals(){const internals=super.attachInternals();captureFormInternals(this,internals);return internals}connectedCallback(){this.hydratingServerShadow??=!this.hasUpdated&&this.shadowRoot!==null;super.connectedCallback();enableLyraLocaleCache(this);invalidateLyraLocaleCache(this);this.observeInheritedContext();this.stopLocaleSubscription=subscribeLyraLocale(()=>this.requestUpdate());const deferred=this.deferredAfterUpdate;if(deferred){this.deferredAfterUpdate=void 0;for(const[key,callback]of deferred)this.scheduleAfterUpdate(callback,key)}}disconnectedCallback(){this.pendingLoadController?.abort();this.pendingLoadController=void 0;this.stopLocaleSubscription?.();this.stopLocaleSubscription=void 0;this.inheritedContextObserver?.disconnect();this.inheritedContextObserver=void 0;invalidateLyraLocaleCache(this);super.disconnectedCallback()}requestUpdate(name,oldValue,options){invalidateLyraLocaleCache(this);super.requestUpdate(name,oldValue,options)}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value);if(oldValue!==value&&REACTIVE_HOST_ATTRIBUTES.includes(name)){this.requestUpdate()}else if(oldValue!==value&&DIRECTION_HOST_ATTRIBUTES.includes(name)){invalidateLyraLocaleCache(this)}}observeInheritedContext(){this.inheritedContextObserver?.disconnect();const Observer=this.ownerDocument?.defaultView?.MutationObserver;if(!Observer)return;let lastLocale;let lastDirection;let checkQueued=false;let recheckDirection=false;const check=()=>{checkQueued=false;const resolveDirection=recheckDirection;recheckDirection=false;lastLocale??=peekLyraLocale(this);if(resolveDirection)lastDirection??=peekLyraDirection(this);const priorLocale=lastLocale;const priorDirection=lastDirection;invalidateLyraLocaleCache(this);const locale=resolveLyraLocale(this);lastLocale=locale;const localeChanged=priorLocale!==void 0&&locale!==priorLocale;let directionChanged=false;if(resolveDirection){const direction=resolveLyraDirection(this);directionChanged=priorDirection!==void 0&&direction!==priorDirection;lastDirection=direction}if(localeChanged||directionChanged)this.requestUpdate()};const observer=new Observer(records=>{for(const record of records){if(record.attributeName==="dir"||record.attributeName==="class"){recheckDirection=true;break}if(record.attributeName==="style"){const target=record.target;const before=record.oldValue??"";const after=target.getAttribute("style")??"";if(styleDirectionDeclaration(before)!==styleDirectionDeclaration(after)){recheckDirection=true;break}}}if(checkQueued)return;checkQueued=true;queueMicrotask(check)});let ancestor=composedParentElement(this);while(ancestor){observer.observe(ancestor,{attributes:true,attributeOldValue:true,attributeFilter:[...INHERITED_CONTEXT_ATTRIBUTES]});ancestor=composedParentElement(ancestor)}this.inheritedContextObserver=observer}seedFirstRenderState(seed){if(this.hasUpdated)return;if(!this.hydratingServerShadow){seed();return}void this.updateComplete.then(()=>{this.hydratingServerShadow=false;seed()},()=>{this.hydratingServerShadow=false})}beginAbortableLoad(){this.pendingLoadController?.abort();this.pendingLoadController=void 0;const AbortControllerCtor=this.ownerDocument.defaultView?.AbortController;if(!AbortControllerCtor)return void 0;this.pendingLoadController=new AbortControllerCtor;return this.pendingLoadController.signal}scheduleAfterUpdate(callback,key="load"){const pending=this.afterUpdateCallbacks??=new Map;if(pending.has(key))return;pending.set(key,callback);if(pending.size>1)return;queueMicrotask(()=>{const due=this.afterUpdateCallbacks;this.afterUpdateCallbacks=void 0;if(!due)return;if(this.isConnected){for(const due_callback of due.values())due_callback();return}const held=this.deferredAfterUpdate??=new Map;for(const[heldKey,heldCallback]of due)if(!held.has(heldKey))held.set(heldKey,heldCallback)})}localize(key,fallback,values){return resolveLyraString(this,key,this.strings,fallback,values,this.constructor.defaultStrings)}get effectiveMessageLocale(){return this.locale||resolveLyraLocale(this)}get effectiveLocale(){return resolveIntlLocale(this.effectiveMessageLocale)}get effectiveIntlLocale(){return this.effectiveLocale}get effectiveDirection(){return resolveLyraDirection(this)}addEventListener(type,listener,options){super.addEventListener(type,listener,options)}removeEventListener(type,listener,options){super.removeEventListener(type,listener,options)}emit(name,...args){const[detail,options]=args;const ownerDocument=this.ownerDocument;let CustomEventCtor=ownerDocument?.defaultView?.CustomEvent;if(!CustomEventCtor&&ownerDocument){try{const candidate=ownerDocument.createEvent("CustomEvent").constructor;if(typeof candidate==="function"){CustomEventCtor=candidate}}catch{}}CustomEventCtor??=globalThis.CustomEvent;const event=new CustomEventCtor(name,{detail,bubbles:true,composed:true,cancelable:options?.cancelable??false});this.dispatchEvent(event);return event}}__decorate([property({reflect:true})],LyraElement.prototype,"locale",void 0);__decorate([property({attribute:false})],LyraElement.prototype,"strings",void 0);export{LyraElement};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.2.
|
|
1
|
+
const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.2.1";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
|
|
@@ -45,5 +45,5 @@ export declare function installHappyDomFormAssociatedShims(): void;
|
|
|
45
45
|
/** Test-only: returns a fresh stub `ElementInternals`-shaped object, independent of whether
|
|
46
46
|
* `attachInternals` already exists natively -- exists purely so this module's own test can
|
|
47
47
|
* verify the stub's call-shape coverage without needing to run under happy-dom itself. */
|
|
48
|
-
export declare function installStubInternalsForTest(
|
|
48
|
+
export declare function installStubInternalsForTest(host: Element): StubElementInternals;
|
|
49
49
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function createStubInternals(){return{form
|
|
1
|
+
function createStubInternals(host){return{get form(){return host.closest("form")},labels:document.createDocumentFragment().querySelectorAll("label"),states:new Set,validity:{valid:true},validationMessage:"",willValidate:true,setFormValue(){},checkValidity(){return true},reportValidity(){return true},setValidity(){}}}function installHappyDomFormAssociatedShims(){if(typeof HTMLElement==="undefined")return;if(typeof HTMLElement.prototype.attachInternals==="function")return;HTMLElement.prototype.attachInternals=function attachInternals(){return createStubInternals(this)}}function installStubInternalsForTest(host){return createStubInternals(host)}export{installHappyDomFormAssociatedShims,installStubInternalsForTest};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aceshooting/lyra-ui",
|
|
3
|
-
"version": "8.2.
|
|
3
|
+
"version": "8.2.1",
|
|
4
4
|
"description": "Free, independent Lit web components: an open-source alternative to Shoelace and Web Awesome with accessible forms, dashboards, charts, and agent UI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web-components",
|
|
@@ -1524,7 +1524,7 @@
|
|
|
1524
1524
|
"shiki": "^4.4.2",
|
|
1525
1525
|
"svelte": "^5.56.8",
|
|
1526
1526
|
"typescript": "^7.0.2",
|
|
1527
|
-
"vue": "^3.5.
|
|
1527
|
+
"vue": "^3.5.41",
|
|
1528
1528
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
|
|
1529
1529
|
},
|
|
1530
1530
|
"customElements": "custom-elements.json",
|