@aceshooting/lyra-ui 18.4.0 → 19.0.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/custom-elements.json +1 -1
  3. package/dist/cli/migration-contract.json +1 -1
  4. package/dist/components/agent-tools/mcp-app/mcp-app.class.d.ts +6 -2
  5. package/dist/components/agent-tools/mcp-app/mcp-app.class.js +1 -1
  6. package/dist/components/agent-tools/tool-timeline/tool-timeline.class.js +1 -1
  7. package/dist/components/charts/chart/chart.class.d.ts +11 -2
  8. package/dist/components/charts/chart/chart.class.js +1 -1
  9. package/dist/components/conversation/agent-workspace/agent-workspace.class.d.ts +2 -2
  10. package/dist/components/conversation/agent-workspace/agent-workspace.class.js +3 -3
  11. package/dist/components/conversation/checkpoint/checkpoint.class.js +1 -1
  12. package/dist/components/forms/date-picker/calendar-core.js +1 -1
  13. package/dist/components/forms/icon-button/icon-button.class.js +1 -1
  14. package/dist/components/media/drop-zone/drop-zone.class.js +2 -2
  15. package/dist/components/media/file-input/file-input.class.d.ts +6 -5
  16. package/dist/components/media/file-input/file-input.class.js +1 -1
  17. package/dist/components/media/image-viewer/image-viewer.class.d.ts +2 -2
  18. package/dist/components/media/lightbox/lightbox.class.d.ts +1 -1
  19. package/dist/components/media/pan-zoom/pan-zoom.class.d.ts +1 -1
  20. package/dist/components/media/pan-zoom/pan-zoom.d.ts +1 -1
  21. package/dist/components/overlays/dialog/dialog.class.d.ts +12 -6
  22. package/dist/components/overlays/dialog/dialog.class.js +3 -6
  23. package/dist/components/retrieval/retrieval-search/retrieval-search.class.d.ts +3 -4
  24. package/dist/components/retrieval/retrieval-search/retrieval-search.class.js +2 -2
  25. package/dist/components/utility/copy-button/copy-button.class.d.ts +9 -6
  26. package/dist/components/utility/copy-button/copy-button.class.js +1 -1
  27. package/dist/components/utility/icon/icon.class.d.ts +3 -2
  28. package/dist/components/utility/icon/icon.class.js +1 -1
  29. package/dist/internal/overlay-stack.js +1 -1
  30. package/dist/internal/package-metadata.d.ts +1 -1
  31. package/dist/internal/package-metadata.js +1 -1
  32. package/dist/internal/safe-svg.d.ts +15 -11
  33. package/dist/internal/safe-svg.js +1 -1
  34. package/llms/components/lr-agent-workspace.md +2 -2
  35. package/llms/components/lr-chart.md +13 -6
  36. package/llms/components/lr-copy-button.md +6 -6
  37. package/llms/components/lr-dialog.md +5 -3
  38. package/llms/components/lr-file-input.md +3 -2
  39. package/llms/components/lr-mcp-app.md +5 -0
  40. package/llms/components/lr-retrieval-search.md +2 -2
  41. package/llms-full.txt +37 -21
  42. package/package.json +2 -2
  43. package/vscode-html-data.json +1 -1
  44. 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--)(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}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import"../../forms/input/input.class.js";import"../../layout/segmented/segmented.class.js";import"../../overlays/chip/chip.class.js";import"../../overlays/chip/chip-group.class.js";import"../../overlays/spinner/spinner.class.js";import"../../overlays/empty/empty.class.js";import{styles}from"./retrieval-search.styles.js";import{contextualSizes}from"../../../internal/contextual-vocabulary.styles.js";import{normalizeReflectedOptionalSize,optionalSizeConverter}from"../../../internal/variants.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{formatBoundedRetrievalValue}from"../retrieval-value-format.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{announceAfterFirstPaint}from"../retrieval-announcements.js";import{literalSetConverter}from"../../../internal/converters.js";import{activeElementIn}from"../../../internal/active-element.js";import{canonicalIdentityList,isRecord}from"../retrieval-identity.js";import{LYRA_DEFAULT_cancel,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_noMatches,LYRA_DEFAULT_retrievalFilterChipLabel,LYRA_DEFAULT_retrievalFiltersLabel,LYRA_DEFAULT_retrievalModeHybrid,LYRA_DEFAULT_retrievalModeKeyword,LYRA_DEFAULT_retrievalModeLabel,LYRA_DEFAULT_retrievalModeVector,LYRA_DEFAULT_retrievalSearchEmptyDescription,LYRA_DEFAULT_retrievalSearchLabel,LYRA_DEFAULT_search,LYRA_DEFAULT_valueInvalid}from"../../../internal/default-strings.generated.js";const RETRIEVAL_MODE=literalSetConverter(["vector","keyword","hybrid"],"hybrid");class LyraRetrievalSearch extends LyraElement{constructor(){super(...arguments),this.query="",this._mode="hybrid",this.filters={},this.scope=[],this.loading=!1,this.errorText="",this.empty=!1,this.announce=!1,this.placeholder="",this.accessibleLabel=null,this.isMounting=!0,this.initialStateAnnounced=!1,this.connectionGeneration=0,this.wasEmptyPresented=!1,this.chipFocusGeneration=0,this.onQueryInput=e=>{e.stopPropagation(),this.query=e.detail.value},this.onQueryKeyDown=e=>{e.key==="Enter"&&(e.isComposing||e.keyCode===229||(e.preventDefault(),this.submit()))},this.onModeChange=e=>{e.stopPropagation(),this.mode=e.detail.value},this.containModeEvent=e=>{e.stopPropagation()},this.onSubmitClick=()=>{if(this.loading){this.cancel();return}this.submit()}}static{this.defaultStrings={...super.defaultStrings,cancel:LYRA_DEFAULT_cancel,fieldRequired:LYRA_DEFAULT_fieldRequired,noMatches:LYRA_DEFAULT_noMatches,retrievalFilterChipLabel:LYRA_DEFAULT_retrievalFilterChipLabel,retrievalFiltersLabel:LYRA_DEFAULT_retrievalFiltersLabel,retrievalModeHybrid:LYRA_DEFAULT_retrievalModeHybrid,retrievalModeKeyword:LYRA_DEFAULT_retrievalModeKeyword,retrievalModeLabel:LYRA_DEFAULT_retrievalModeLabel,retrievalModeVector:LYRA_DEFAULT_retrievalModeVector,retrievalSearchEmptyDescription:LYRA_DEFAULT_retrievalSearchEmptyDescription,retrievalSearchLabel:LYRA_DEFAULT_retrievalSearchLabel,search:LYRA_DEFAULT_search,valueInvalid:LYRA_DEFAULT_valueInvalid}}static{this.ownedCollectionProperties=Object.freeze(["filters","scope"])}static{this.styles=[LyraElement.styles,contextualSizes,styles]}static{this.immutableEventDetails=Object.freeze(["lr-search","lr-filters-change"])}get size(){return this._size}set size(next){const normalized=normalizeReflectedOptionalSize(this,next),old=this._size;old!==normalized&&(this._size=normalized,this.requestUpdate("size",old))}get mode(){return this._mode}set mode(next){const normalized=RETRIEVAL_MODE.normalize(next),old=this._mode;old!==normalized&&(this._mode=normalized,this.requestUpdate("mode",old))}connectedCallback(){super.connectedCallback(),this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this}),this.emptyAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this});const generation=++this.connectionGeneration;announceAfterFirstPaint(this,()=>generation===this.connectionGeneration,()=>{!this.announce||this.initialStateAnnounced||(this.initialStateAnnounced=!0,this.announcePresentedState())})}disconnectedCallback(){this.isMounting=!0,this.connectionGeneration+=1,this.errorAnnouncementSink?.release(),this.errorAnnouncementSink=void 0,this.emptyAnnouncementSink?.release(),this.emptyAnnouncementSink=void 0,this.wasEmptyPresented=!1,super.disconnectedCallback()}updated(changed){super.updated(changed);const wasMounting=this.isMounting;this.isMounting=!1,!wasMounting&&changed.has("errorText")&&this.errorText!==""&&this.isConnected&&(this.initialStateAnnounced=!0,this.errorAnnouncementSink?.announce(this.errorText));const emptyPresented=this.empty&&!this.loading&&this.errorText==="";!wasMounting&&!this.wasEmptyPresented&&emptyPresented&&this.isConnected&&(this.initialStateAnnounced=!0,this.emptyAnnouncementSink?.announce(this.localize("noMatches"))),this.wasEmptyPresented=emptyPresented}announcePresentedState(){if(this.errorText!==""){this.errorAnnouncementSink?.announce(this.errorText);return}this.empty&&!this.loading&&this.emptyAnnouncementSink?.announce(this.localize("noMatches"))}modeItems(){return[{value:"vector",label:this.localize("retrievalModeVector")},{value:"keyword",label:this.localize("retrievalModeKeyword")},{value:"hybrid",label:this.localize("retrievalModeHybrid")}]}formatFilterValue(value){const sentinel=this.localize("valueInvalid");return formatBoundedRetrievalValue(value,{locale:this.effectiveLocale,invalid:sentinel,truncated:sentinel})}get normalizedFilters(){return isRecord(this.filters)?this.filters:{}}get normalizedScope(){return canonicalIdentityList(this.scope)}buildQuery(){return{text:this.query,mode:this.mode,filters:{...this.normalizedFilters},scope:[...this.normalizedScope]}}submit(){this.loading&&this.emit("lr-cancel",{reason:"superseded"}),this.emit("lr-search",this.buildQuery())}cancel(){this.emit("lr-cancel",{})}emitFiltersChange(){this.emit("lr-filters-change",{filters:{...this.normalizedFilters},scope:[...this.normalizedScope]})}repairFocusAfterChipRemoval(index,shouldRepair){const generation=++this.chipFocusGeneration;shouldRepair&&this.updateComplete.then(()=>{if(!this.isConnected||generation!==this.chipFocusGeneration)return;const chips=this.renderRoot.querySelectorAll('[part="filters"] lr-chip'),target=chips[Math.min(index,chips.length-1)];if(target){target.focus();return}this.renderRoot.querySelector('[part="query"]')?.focus()})}removeScope(value,shouldRepairFocus=!1){const scope=this.normalizedScope,index=scope.indexOf(value);this.scope=scope.filter(s=>s!==value),this.emitFiltersChange(),this.repairFocusAfterChipRemoval(Math.max(0,index),shouldRepairFocus)}removeFilter(key,shouldRepairFocus=!1){const filters=this.normalizedFilters,index=this.normalizedScope.length+Object.keys(filters).indexOf(key),next={...filters};delete next[key],this.filters=next,this.emitFiltersChange(),this.repairFocusAfterChipRemoval(Math.max(0,index),shouldRepairFocus)}render(){const label=retrievalSemanticLabel(this,this.accessibleLabel??(this.label==null?this.localize("retrievalSearchLabel"):this.label)),searchRole=retrievalSemanticRole(this,"search"),filters=this.normalizedFilters,scope=this.normalizedScope,hasFilters=Object.keys(filters).length>0||scope.length>0;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--)(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}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import"../../forms/input/input.class.js";import"../../layout/segmented/segmented.class.js";import"../../overlays/chip/chip.class.js";import"../../overlays/chip/chip-group.class.js";import"../../overlays/spinner/spinner.class.js";import"../../overlays/empty/empty.class.js";import{styles}from"./retrieval-search.styles.js";import{contextualSizes}from"../../../internal/contextual-vocabulary.styles.js";import{normalizeReflectedOptionalSize,optionalSizeConverter}from"../../../internal/variants.js";import{retrievalSemanticLabel,retrievalSemanticRole}from"../retrieval-semantic-owner.js";import{formatBoundedRetrievalValue}from"../retrieval-value-format.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{announceAfterFirstPaint}from"../retrieval-announcements.js";import{literalSetConverter}from"../../../internal/converters.js";import{activeElementIn}from"../../../internal/active-element.js";import{canonicalIdentityList,isRecord}from"../retrieval-identity.js";import{LYRA_DEFAULT_cancel,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_noMatches,LYRA_DEFAULT_retrievalFilterChipLabel,LYRA_DEFAULT_retrievalFiltersLabel,LYRA_DEFAULT_retrievalModeHybrid,LYRA_DEFAULT_retrievalModeKeyword,LYRA_DEFAULT_retrievalModeLabel,LYRA_DEFAULT_retrievalModeVector,LYRA_DEFAULT_retrievalSearchEmptyDescription,LYRA_DEFAULT_retrievalSearchLabel,LYRA_DEFAULT_search,LYRA_DEFAULT_valueInvalid}from"../../../internal/default-strings.generated.js";const RETRIEVAL_MODE=literalSetConverter(["vector","keyword","hybrid"],"hybrid");class LyraRetrievalSearch extends LyraElement{constructor(){super(...arguments),this.query="",this._mode="hybrid",this.filters={},this.scope=[],this.loading=!1,this.errorText="",this.empty=!1,this.announce=!1,this.accessibleLabel=null,this.isMounting=!0,this.initialStateAnnounced=!1,this.connectionGeneration=0,this.wasEmptyPresented=!1,this.chipFocusGeneration=0,this.onQueryInput=e=>{e.stopPropagation(),this.query=e.detail.value},this.onQueryKeyDown=e=>{e.key==="Enter"&&(e.isComposing||e.keyCode===229||(e.preventDefault(),this.submit()))},this.onModeChange=e=>{e.stopPropagation(),this.mode=e.detail.value},this.containModeEvent=e=>{e.stopPropagation()},this.onSubmitClick=()=>{if(this.loading){this.cancel();return}this.submit()}}static{this.defaultStrings={...super.defaultStrings,cancel:LYRA_DEFAULT_cancel,fieldRequired:LYRA_DEFAULT_fieldRequired,noMatches:LYRA_DEFAULT_noMatches,retrievalFilterChipLabel:LYRA_DEFAULT_retrievalFilterChipLabel,retrievalFiltersLabel:LYRA_DEFAULT_retrievalFiltersLabel,retrievalModeHybrid:LYRA_DEFAULT_retrievalModeHybrid,retrievalModeKeyword:LYRA_DEFAULT_retrievalModeKeyword,retrievalModeLabel:LYRA_DEFAULT_retrievalModeLabel,retrievalModeVector:LYRA_DEFAULT_retrievalModeVector,retrievalSearchEmptyDescription:LYRA_DEFAULT_retrievalSearchEmptyDescription,retrievalSearchLabel:LYRA_DEFAULT_retrievalSearchLabel,search:LYRA_DEFAULT_search,valueInvalid:LYRA_DEFAULT_valueInvalid}}static{this.ownedCollectionProperties=Object.freeze(["filters","scope"])}static{this.styles=[LyraElement.styles,contextualSizes,styles]}static{this.immutableEventDetails=Object.freeze(["lr-search","lr-filters-change"])}get size(){return this._size}set size(next){const normalized=normalizeReflectedOptionalSize(this,next),old=this._size;old!==normalized&&(this._size=normalized,this.requestUpdate("size",old))}get mode(){return this._mode}set mode(next){const normalized=RETRIEVAL_MODE.normalize(next),old=this._mode;old!==normalized&&(this._mode=normalized,this.requestUpdate("mode",old))}connectedCallback(){super.connectedCallback(),this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this}),this.emptyAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this});const generation=++this.connectionGeneration;announceAfterFirstPaint(this,()=>generation===this.connectionGeneration,()=>{!this.announce||this.initialStateAnnounced||(this.initialStateAnnounced=!0,this.announcePresentedState())})}disconnectedCallback(){this.isMounting=!0,this.connectionGeneration+=1,this.errorAnnouncementSink?.release(),this.errorAnnouncementSink=void 0,this.emptyAnnouncementSink?.release(),this.emptyAnnouncementSink=void 0,this.wasEmptyPresented=!1,super.disconnectedCallback()}updated(changed){super.updated(changed);const wasMounting=this.isMounting;this.isMounting=!1,!wasMounting&&changed.has("errorText")&&this.errorText!==""&&this.isConnected&&(this.initialStateAnnounced=!0,this.errorAnnouncementSink?.announce(this.errorText));const emptyPresented=this.empty&&!this.loading&&this.errorText==="";!wasMounting&&!this.wasEmptyPresented&&emptyPresented&&this.isConnected&&(this.initialStateAnnounced=!0,this.emptyAnnouncementSink?.announce(this.localize("noMatches"))),this.wasEmptyPresented=emptyPresented}announcePresentedState(){if(this.errorText!==""){this.errorAnnouncementSink?.announce(this.errorText);return}this.empty&&!this.loading&&this.emptyAnnouncementSink?.announce(this.localize("noMatches"))}modeItems(){return[{value:"vector",label:this.localize("retrievalModeVector")},{value:"keyword",label:this.localize("retrievalModeKeyword")},{value:"hybrid",label:this.localize("retrievalModeHybrid")}]}formatFilterValue(value){const sentinel=this.localize("valueInvalid");return formatBoundedRetrievalValue(value,{locale:this.effectiveLocale,invalid:sentinel,truncated:sentinel})}get normalizedFilters(){return isRecord(this.filters)?this.filters:{}}get normalizedScope(){return canonicalIdentityList(this.scope)}buildQuery(){return{text:this.query,mode:this.mode,filters:{...this.normalizedFilters},scope:[...this.normalizedScope]}}submit(){this.loading&&this.emit("lr-cancel",{reason:"superseded"}),this.emit("lr-search",this.buildQuery())}cancel(){this.emit("lr-cancel",{})}emitFiltersChange(){this.emit("lr-filters-change",{filters:{...this.normalizedFilters},scope:[...this.normalizedScope]})}repairFocusAfterChipRemoval(index,shouldRepair){const generation=++this.chipFocusGeneration;shouldRepair&&this.updateComplete.then(()=>{if(!this.isConnected||generation!==this.chipFocusGeneration)return;const chips=this.renderRoot.querySelectorAll('[part="filters"] lr-chip'),target=chips[Math.min(index,chips.length-1)];if(target){target.focus();return}this.renderRoot.querySelector('[part="query"]')?.focus()})}removeScope(value,shouldRepairFocus=!1){const scope=this.normalizedScope,index=scope.indexOf(value);this.scope=scope.filter(s=>s!==value),this.emitFiltersChange(),this.repairFocusAfterChipRemoval(Math.max(0,index),shouldRepairFocus)}removeFilter(key,shouldRepairFocus=!1){const filters=this.normalizedFilters,index=this.normalizedScope.length+Object.keys(filters).indexOf(key),next={...filters};delete next[key],this.filters=next,this.emitFiltersChange(),this.repairFocusAfterChipRemoval(Math.max(0,index),shouldRepairFocus)}render(){const label=retrievalSemanticLabel(this,this.accessibleLabel??(this.label==null?this.localize("retrievalSearchLabel"):this.label)),searchRole=retrievalSemanticRole(this,"search"),filters=this.normalizedFilters,scope=this.normalizedScope,hasFilters=Object.keys(filters).length>0||scope.length>0;return html`
2
2
  <div
3
3
  part="base"
4
4
  role=${searchRole??nothing}
@@ -10,7 +10,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
10
10
  type="search"
11
11
  clearable
12
12
  .size=${this.size??"m"}
13
- placeholder=${this.placeholder||this.localize("search")}
13
+ placeholder=${this.placeholder==null?this.localize("search"):this.placeholder}
14
14
  .value=${this.query}
15
15
  @lr-input=${this.onQueryInput}
16
16
  @keydown=${this.onQueryKeyDown}
@@ -85,12 +85,15 @@ value:string;
85
85
  /** Id-based source expression. Takes precedence over `value`; supports `id`, `id[attr]`, and
86
86
  * `id.property`. */
87
87
  from:string;
88
- /** Accessible name and resting tooltip text. Empty uses the localized Copy string. */
89
- copyLabel:string;
90
- /** Confirmation accessible name and tooltip text. Empty uses the localized Copied string. */
91
- successLabel:string;
92
- /** Failure accessible name and tooltip text. Empty uses the localized failure string. */
93
- errorLabel:string;
88
+ /** Accessible name and resting tooltip text. When omitted, uses localized Copy; an explicit
89
+ * empty string intentionally suppresses that fallback. */
90
+ copyLabel?:string;
91
+ /** Confirmation accessible name and tooltip text. When omitted, uses localized Copied; an
92
+ * explicit empty string intentionally suppresses that fallback. */
93
+ successLabel?:string;
94
+ /** Failure accessible name and tooltip text. When omitted, uses localized failure copy; an
95
+ * explicit empty string intentionally suppresses that fallback. */
96
+ errorLabel?:string;
94
97
  /** Tooltip behavior: normal hover/focus plus feedback, feedback only, or disabled. */
95
98
  tooltip:LyraCopyButtonTooltip;
96
99
  /** Side on which the tooltip appears. */
@@ -37,7 +37,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
37
37
  aria-hidden="true"
38
38
  focusable="false"
39
39
  ><circle cx="12" cy="12" r="9"></circle><path d="M12 7.25v5.5"></path><path d="M12 16.4v.01"></path></svg>
40
- `}function isElementValue(value){if(value===null||typeof value!="object")return!1;const candidate=value;return candidate.nodeType===1&&typeof candidate.getAttribute=="function"}function isHtmlElementValue(value){if(!isElementValue(value))return!1;const candidate=value;return candidate.namespaceURI==="http://www.w3.org/1999/xhtml"&&typeof candidate.focus=="function"&&typeof candidate.blur=="function"&&typeof candidate.click=="function"}class CopySourceError extends Error{constructor(message){super(message),this.name="CopySourceError"}}class LyraCopyButton extends LyraElement{static{this.defaultStrings={...super.defaultStrings,copied:LYRA_DEFAULT_copied,copy:LYRA_DEFAULT_copy,copyFailed:LYRA_DEFAULT_copyFailed,fieldRequired:LYRA_DEFAULT_fieldRequired}}static{this.styles=[LyraElement.styles,styles]}constructor(){super(),this.value="",this.from="",this.copyLabel="",this.successLabel="",this.errorLabel="",this.tooltip="full",this.tooltipPlacement="top",this.hoist=!1,this.accessibleLabel=null,this.disabled=!1,this.feedbackDuration=DEFAULT_FEEDBACK_DURATION,this.status="rest",this.hasCustomTrigger=!1,this.triggerCollected=!1,this.internals=attachInternalsSafely(this),this.toolbarAction=this.createToolbarAction(),this.copyGeneration=0,this.onClick=()=>{this.copy()},this.onDefaultSlotChange=event=>{this.onDefaultSlotChangeFromSlot(event.currentTarget)},this.onCustomTriggerClick=()=>{this.hasCustomTrigger&&this.copy()},this.stopInternalTooltipEvent=event=>{event.stopPropagation()},this.internals.role="group"}willUpdate(changed){super.willUpdate(changed),this.hasUpdated&&(changed.has("value")||changed.has("from"))&&this.resetFeedback()}updated(changed){super.updated(changed),(changed.has("disabled")||changed.has("hasCustomTrigger"))&&this.emit("lr-toolbar-actions-change")}firstUpdated(changed){super.firstUpdated(changed);const slot=this.defaultSlot;queueMicrotask(()=>{collectInitialSlotAssignment(slot,s=>this.onDefaultSlotChangeFromSlot(s))})}connectedCallback(){super.connectedCallback(),this.hasAttribute("role")||this.setAttribute("role","group"),this.sink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.toolbarAction.releaseTabIndex?.(),super.disconnectedCallback(),this.resetFeedback(),this.sink?.release(),this.sink=void 0}adoptedCallback(){this.toolbarAction.releaseTabIndex?.(),super.adoptedCallback(),this.resetFeedback(),this.sink?.release(),this.sink=void 0}cancelFeedbackTimer(){const timer=this.copyTimer;this.copyTimer=void 0,timer&&timer.owner.clearTimeout(timer.handle)}resetFeedback(){this.copyGeneration+=1,this.cancelFeedbackTimer(),this.setStatus("rest")}setStatus(status){this.status=status,setCustomState(this.internals,"success",status==="success"),setCustomState(this.internals,"error",status==="error")}customTrigger(){return this.defaultSlot?.assignedElements({flatten:!0}).find(isHtmlElementValue)}activeTrigger(){return this.hasCustomTrigger?this.customTrigger():this.buttonEl}composedTriggerAction(){if(this.hasCustomTrigger)return;const[action]=this.buttonEl?.getToolbarActions()??[];return action}createToolbarAction(){const host=this;let leasedTrigger,authoredTabIndex=null,lastManagedTabIndex=null,consumerOwnsTabIndex=!1,delegated;const releaseDelegated=()=>{const previous=delegated;delegated=void 0,previous?.releaseTabIndex?.()},releaseTabIndex=()=>{releaseDelegated();const target=leasedTrigger;target&&target.getAttribute("tabindex")===lastManagedTabIndex&&(authoredTabIndex===null?target.removeAttribute("tabindex"):target.setAttribute("tabindex",authoredTabIndex)),leasedTrigger=void 0,authoredTabIndex=null,lastManagedTabIndex=null,consumerOwnsTabIndex=!1};return{id:"copy",get disabled(){const trigger=host.activeTrigger();return!trigger||host.disabled||trigger.disabled===!0},focus(options){host.activeTrigger()?.focus(options)},setTabIndex(tabIndex){const composed=host.composedTriggerAction();if(composed){delegated!==composed&&(releaseTabIndex(),delegated=composed),composed.setTabIndex(tabIndex);return}releaseDelegated();const trigger=host.activeTrigger();if(!trigger){releaseTabIndex();return}if(leasedTrigger!==trigger&&(releaseTabIndex(),leasedTrigger=trigger,authoredTabIndex=trigger.getAttribute("tabindex")),consumerOwnsTabIndex||lastManagedTabIndex!==null&&trigger.getAttribute("tabindex")!==lastManagedTabIndex){consumerOwnsTabIndex=!0;return}trigger.tabIndex=tabIndex,lastManagedTabIndex=trigger.getAttribute("tabindex")},releaseTabIndex,matchesEventPath(path){const trigger=host.activeTrigger();return trigger!=null&&path.includes(trigger)}}}getToolbarActions(){return[this.toolbarAction]}focus(options){this.activeTrigger()?.focus(options)}blur(){this.activeTrigger()?.blur()}click(){this.activeTrigger()?.click()}sourceById(id){const root=this.getRootNode();if((root.nodeType===9||root.nodeType===11)&&typeof root.getElementById=="function"){const source=root.getElementById(id);if(isElementValue(source))return source}const documentSource=this.ownerDocument.getElementById(id);return isElementValue(documentSource)?documentSource:null}resolveCopyText(){if(!this.from){if(!this.value)throw new CopySourceError("The copy value is empty.");return this.value}const expression=this.from.trim(),attributeMatch=/^(.*?)\[([^\]]+)\]$/.exec(expression),propertyMatch=attributeMatch?null:/^(.*?)\.([^.]*)$/.exec(expression),id=(attributeMatch?.[1]??propertyMatch?.[1]??expression).trim(),source=id?this.sourceById(id):null;if(!source)throw new CopySourceError(`The copy source "${id}" was not found.`);let resolved;if(attributeMatch){const attribute=attributeMatch[2].trim();resolved=attribute?source.getAttribute(attribute):null}else if(propertyMatch){const propertyName=propertyMatch[2].trim();resolved=propertyName?source[propertyName]:void 0}else resolved=source.textContent;const text=resolved==null?"":String(resolved);if(!text)throw new CopySourceError(`The copy source "${expression}" resolved to an empty value.`);return text}showStatus(status){const owner=this.ownerDocument.defaultView;if(!this.isConnected||!owner)return;this.setStatus(status),this.sink?.announce(this.statusLabel(status)),this.cancelFeedbackTimer();const duration=finiteDuration(this.feedbackDuration,DEFAULT_FEEDBACK_DURATION,0),generation=this.copyGeneration;let handle=0;handle=owner.setTimeout(()=>{const timer=this.copyTimer;timer?.owner!==owner||timer.handle!==handle||timer.generation!==generation||generation!==this.copyGeneration||!this.isConnected||this.ownerDocument.defaultView!==owner||(this.copyTimer=void 0,this.setStatus("rest"))},duration),this.copyTimer={owner,handle,generation}}reportFailure(outcome){this.showStatus("error"),this.emit("lr-error"),this.emit("lr-copy-error",outcome)}async copy(){if(this.disabled)return;const generation=++this.copyGeneration,owner=this.isConnected?this.ownerDocument.defaultView:null;let text="";try{text=this.resolveCopyText()}catch(error){this.isCurrentCopy(generation)&&this.reportFailure(Object.freeze({ok:!1,text,reason:"failed",error}));return}if(!owner)return;const outcome=await writeClipboardText(owner,text);if(this.isCurrentCopy(generation,owner)){if(!outcome.ok){this.reportFailure(outcome);return}this.showStatus("success"),this.emit("lr-copy",outcome)}}isCurrentCopy(generation,owner){return this.isConnected&&generation===this.copyGeneration&&(owner===void 0||this.ownerDocument.defaultView===owner)}onDefaultSlotChangeFromSlot(slot){const trigger=slot.assignedElements({flatten:!0}).find(isHtmlElementValue);if(this.triggerCollected&&trigger===this.lastObservedTrigger)return;this.triggerCollected=!0,this.lastObservedTrigger=trigger;const hasCustomTrigger=trigger!==void 0;if(hasCustomTrigger!==this.hasCustomTrigger){this.hasCustomTrigger=hasCustomTrigger;return}this.emit("lr-toolbar-actions-change")}statusLabel(status){return status==="success"?this.successLabel||this.localize("copied"):status==="error"?this.errorLabel||this.localize("copyFailed"):this.copyLabel||this.localize("copy")}renderIcon(){return this.status==="error"?html`<span part="error-icon" aria-hidden="true"><slot name="error-icon">${errorIcon()}</slot></span>`:this.status==="success"?html`<span part="success-icon" aria-hidden="true"><slot name="success-icon">${checkIcon()}</slot></span>`:html`<span part="copy-icon" aria-hidden="true"><slot name="copy-icon">${copyIcon()}</slot></span>`}render(){const statusLabel=this.statusLabel(this.status),feedback=this.status==="rest"?"":statusLabel,part=this.status==="success"?"base button base-success":this.status==="error"?"base button base-error":"base button",tooltipDisabled=this.tooltip==="none",tooltipOpen=!tooltipDisabled&&this.status!=="rest",buttonLabel=this.accessibleLabel?.trim()?this.accessibleLabel:statusLabel;return html`
40
+ `}function isElementValue(value){if(value===null||typeof value!="object")return!1;const candidate=value;return candidate.nodeType===1&&typeof candidate.getAttribute=="function"}function isHtmlElementValue(value){if(!isElementValue(value))return!1;const candidate=value;return candidate.namespaceURI==="http://www.w3.org/1999/xhtml"&&typeof candidate.focus=="function"&&typeof candidate.blur=="function"&&typeof candidate.click=="function"}class CopySourceError extends Error{constructor(message){super(message),this.name="CopySourceError"}}class LyraCopyButton extends LyraElement{static{this.defaultStrings={...super.defaultStrings,copied:LYRA_DEFAULT_copied,copy:LYRA_DEFAULT_copy,copyFailed:LYRA_DEFAULT_copyFailed,fieldRequired:LYRA_DEFAULT_fieldRequired}}static{this.styles=[LyraElement.styles,styles]}constructor(){super(),this.value="",this.from="",this.tooltip="full",this.tooltipPlacement="top",this.hoist=!1,this.accessibleLabel=null,this.disabled=!1,this.feedbackDuration=DEFAULT_FEEDBACK_DURATION,this.status="rest",this.hasCustomTrigger=!1,this.triggerCollected=!1,this.internals=attachInternalsSafely(this),this.toolbarAction=this.createToolbarAction(),this.copyGeneration=0,this.onClick=()=>{this.copy()},this.onDefaultSlotChange=event=>{this.onDefaultSlotChangeFromSlot(event.currentTarget)},this.onCustomTriggerClick=()=>{this.hasCustomTrigger&&this.copy()},this.stopInternalTooltipEvent=event=>{event.stopPropagation()},this.internals.role="group"}willUpdate(changed){super.willUpdate(changed),this.hasUpdated&&(changed.has("value")||changed.has("from"))&&this.resetFeedback()}updated(changed){super.updated(changed),(changed.has("disabled")||changed.has("hasCustomTrigger"))&&this.emit("lr-toolbar-actions-change")}firstUpdated(changed){super.firstUpdated(changed);const slot=this.defaultSlot;queueMicrotask(()=>{collectInitialSlotAssignment(slot,s=>this.onDefaultSlotChangeFromSlot(s))})}connectedCallback(){super.connectedCallback(),this.hasAttribute("role")||this.setAttribute("role","group"),this.sink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.toolbarAction.releaseTabIndex?.(),super.disconnectedCallback(),this.resetFeedback(),this.sink?.release(),this.sink=void 0}adoptedCallback(){this.toolbarAction.releaseTabIndex?.(),super.adoptedCallback(),this.resetFeedback(),this.sink?.release(),this.sink=void 0}cancelFeedbackTimer(){const timer=this.copyTimer;this.copyTimer=void 0,timer&&timer.owner.clearTimeout(timer.handle)}resetFeedback(){this.copyGeneration+=1,this.cancelFeedbackTimer(),this.setStatus("rest")}setStatus(status){this.status=status,setCustomState(this.internals,"success",status==="success"),setCustomState(this.internals,"error",status==="error")}customTrigger(){return this.defaultSlot?.assignedElements({flatten:!0}).find(isHtmlElementValue)}activeTrigger(){return this.hasCustomTrigger?this.customTrigger():this.buttonEl}composedTriggerAction(){if(this.hasCustomTrigger)return;const[action]=this.buttonEl?.getToolbarActions()??[];return action}createToolbarAction(){const host=this;let leasedTrigger,authoredTabIndex=null,lastManagedTabIndex=null,consumerOwnsTabIndex=!1,delegated;const releaseDelegated=()=>{const previous=delegated;delegated=void 0,previous?.releaseTabIndex?.()},releaseTabIndex=()=>{releaseDelegated();const target=leasedTrigger;target&&target.getAttribute("tabindex")===lastManagedTabIndex&&(authoredTabIndex===null?target.removeAttribute("tabindex"):target.setAttribute("tabindex",authoredTabIndex)),leasedTrigger=void 0,authoredTabIndex=null,lastManagedTabIndex=null,consumerOwnsTabIndex=!1};return{id:"copy",get disabled(){const trigger=host.activeTrigger();return!trigger||host.disabled||trigger.disabled===!0},focus(options){host.activeTrigger()?.focus(options)},setTabIndex(tabIndex){const composed=host.composedTriggerAction();if(composed){delegated!==composed&&(releaseTabIndex(),delegated=composed),composed.setTabIndex(tabIndex);return}releaseDelegated();const trigger=host.activeTrigger();if(!trigger){releaseTabIndex();return}if(leasedTrigger!==trigger&&(releaseTabIndex(),leasedTrigger=trigger,authoredTabIndex=trigger.getAttribute("tabindex")),consumerOwnsTabIndex||lastManagedTabIndex!==null&&trigger.getAttribute("tabindex")!==lastManagedTabIndex){consumerOwnsTabIndex=!0;return}trigger.tabIndex=tabIndex,lastManagedTabIndex=trigger.getAttribute("tabindex")},releaseTabIndex,matchesEventPath(path){const trigger=host.activeTrigger();return trigger!=null&&path.includes(trigger)}}}getToolbarActions(){return[this.toolbarAction]}focus(options){this.activeTrigger()?.focus(options)}blur(){this.activeTrigger()?.blur()}click(){this.activeTrigger()?.click()}sourceById(id){const root=this.getRootNode();if((root.nodeType===9||root.nodeType===11)&&typeof root.getElementById=="function"){const source=root.getElementById(id);if(isElementValue(source))return source}const documentSource=this.ownerDocument.getElementById(id);return isElementValue(documentSource)?documentSource:null}resolveCopyText(){if(!this.from){if(!this.value)throw new CopySourceError("The copy value is empty.");return this.value}const expression=this.from.trim(),attributeMatch=/^(.*?)\[([^\]]+)\]$/.exec(expression),propertyMatch=attributeMatch?null:/^(.*?)\.([^.]*)$/.exec(expression),id=(attributeMatch?.[1]??propertyMatch?.[1]??expression).trim(),source=id?this.sourceById(id):null;if(!source)throw new CopySourceError(`The copy source "${id}" was not found.`);let resolved;if(attributeMatch){const attribute=attributeMatch[2].trim();resolved=attribute?source.getAttribute(attribute):null}else if(propertyMatch){const propertyName=propertyMatch[2].trim();resolved=propertyName?source[propertyName]:void 0}else resolved=source.textContent;const text=resolved==null?"":String(resolved);if(!text)throw new CopySourceError(`The copy source "${expression}" resolved to an empty value.`);return text}showStatus(status){const owner=this.ownerDocument.defaultView;if(!this.isConnected||!owner)return;this.setStatus(status),this.sink?.announce(this.statusLabel(status)),this.cancelFeedbackTimer();const duration=finiteDuration(this.feedbackDuration,DEFAULT_FEEDBACK_DURATION,0),generation=this.copyGeneration;let handle=0;handle=owner.setTimeout(()=>{const timer=this.copyTimer;timer?.owner!==owner||timer.handle!==handle||timer.generation!==generation||generation!==this.copyGeneration||!this.isConnected||this.ownerDocument.defaultView!==owner||(this.copyTimer=void 0,this.setStatus("rest"))},duration),this.copyTimer={owner,handle,generation}}reportFailure(outcome){this.showStatus("error"),this.emit("lr-error"),this.emit("lr-copy-error",outcome)}async copy(){if(this.disabled)return;const generation=++this.copyGeneration,owner=this.isConnected?this.ownerDocument.defaultView:null;let text="";try{text=this.resolveCopyText()}catch(error){this.isCurrentCopy(generation)&&this.reportFailure(Object.freeze({ok:!1,text,reason:"failed",error}));return}if(!owner)return;const outcome=await writeClipboardText(owner,text);if(this.isCurrentCopy(generation,owner)){if(!outcome.ok){this.reportFailure(outcome);return}this.showStatus("success"),this.emit("lr-copy",outcome)}}isCurrentCopy(generation,owner){return this.isConnected&&generation===this.copyGeneration&&(owner===void 0||this.ownerDocument.defaultView===owner)}onDefaultSlotChangeFromSlot(slot){const trigger=slot.assignedElements({flatten:!0}).find(isHtmlElementValue);if(this.triggerCollected&&trigger===this.lastObservedTrigger)return;this.triggerCollected=!0,this.lastObservedTrigger=trigger;const hasCustomTrigger=trigger!==void 0;if(hasCustomTrigger!==this.hasCustomTrigger){this.hasCustomTrigger=hasCustomTrigger;return}this.emit("lr-toolbar-actions-change")}statusLabel(status){return status==="success"?this.successLabel==null?this.localize("copied"):this.successLabel:status==="error"?this.errorLabel==null?this.localize("copyFailed"):this.errorLabel:this.copyLabel==null?this.localize("copy"):this.copyLabel}renderIcon(){return this.status==="error"?html`<span part="error-icon" aria-hidden="true"><slot name="error-icon">${errorIcon()}</slot></span>`:this.status==="success"?html`<span part="success-icon" aria-hidden="true"><slot name="success-icon">${checkIcon()}</slot></span>`:html`<span part="copy-icon" aria-hidden="true"><slot name="copy-icon">${copyIcon()}</slot></span>`}render(){const statusLabel=this.statusLabel(this.status),feedback=this.status==="rest"?"":statusLabel,part=this.status==="success"?"base button base-success":this.status==="error"?"base button base-error":"base button",tooltipDisabled=this.tooltip==="none",tooltipOpen=!tooltipDisabled&&this.status!=="rest",buttonLabel=this.accessibleLabel?.trim()?this.accessibleLabel:statusLabel;return html`
41
41
  <lr-tooltip
42
42
  .content=${statusLabel}
43
43
  .trigger=${this.tooltip==="full"?"hover focus":"manual"}
@@ -118,8 +118,9 @@ fixedWidth:boolean;private fetchState;private svgEl?;private customSlot?;private
118
118
  private generation;connectedCallback():void;disconnectedCallback():void;protected updated(changed:PropertyValues):void;private onCustomSlotChange;
119
119
  /**
120
120
  * SVG geometry distributed through a shadow-DOM slot does not paint reliably in Chromium when
121
- * the slot itself is inside an SVG. Keep the public custom-content slot, but clone its trusted
122
- * SVG nodes into the component-owned SVG so path/circle/group content has a real SVG parent.
121
+ * the slot itself is inside an SVG. Keep the public custom-content slot, but clone its
122
+ * consumer-supplied SVG nodes into the component-owned SVG so path/circle/group content has a
123
+ * real SVG parent; the clone boundary applies the shared SVG safety filters first.
123
124
  */
124
125
  private syncCustomNodes;private observeCustomContent;private cloneSvgNode;private accessibleLabel;private hasRemoteSource;private releaseResourceLease;private load;private fail;private errorMessage;
125
126
  /** Applies presentation semantics to the fetched node. The stable wrapper rendered by
@@ -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--)(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,svg}from"lit";import{property,query,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAccessibilityVisible,srOnly}from"../../../internal/a11y.js";import{finiteNumber}from"../../../internal/numbers.js";import{safeFetchUrl}from"../../../internal/safe-url.js";import{isUnsafeSvgCloneAttribute}from"../../../internal/safe-svg.js";import{isAbortError,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getIconLibrary,subscribeIconLibrary}from"./icon-library.js";import{acquireSanitizedIconResource,IconResourceError}from"./icon-resource.js";import{styles}from"./icon.styles.js";import{LYRA_DEFAULT_iconLoadError,LYRA_DEFAULT_iconSanitizerMissing,LYRA_DEFAULT_iconTooLarge}from"../../../internal/default-strings.generated.js";const PATHS={add:"M12 5v14M5 12h14",check:"m5 12 4 4L19 6",close:"m6 6 12 12M18 6 6 18",search:"m21 21-4.35-4.35M10.5 18a7.5 7.5 0 1 1 0-15 7.5 7.5 0 0 1 0 15Z",menu:"M4 6h16M4 12h16M4 18h16","chevron-left":"m15 18-6-6 6-6","chevron-right":"m9 18 6-6-6-6","chevron-down":"m6 9 6 6 6-6",calendar:"M6 3v3M18 3v3M4 9h16M5 5h14a1 1 0 0 1 1 1v13H4V6a1 1 0 0 1 1-1Z",command:"M6 6h4v4H6zM14 6h4v4h-4zM6 14h4v4H6zM14 14h4v4h-4z",trash:"M4 7h16M10 11v6M14 11v6M6 7l1 14h10l1-14M9 7V4h6v3"};class LyraIcon extends LyraElement{constructor(){super(...arguments),this._name="",this.path="",this.label="",this.library="default",this.family="",this.variant="",this._src="",this.rotate=0,this.autoWidth=!1,this.swapOpacity=!1,this.fixedWidth=!1,this.fetchState={kind:"idle"},this.generation=0,this.onCustomSlotChange=()=>{this.syncCustomNodes()}}static{this.defaultStrings={...super.defaultStrings,iconLoadError:LYRA_DEFAULT_iconLoadError,iconSanitizerMissing:LYRA_DEFAULT_iconSanitizerMissing,iconTooLarge:LYRA_DEFAULT_iconTooLarge}}static{this.styles=[LyraElement.styles,styles,srOnly]}get name(){return this._name}set name(value){const old=this._name;this._name=value??"",this.requestUpdate("name",old)}get src(){return this._src}set src(value){const old=this._src;this._src=value??"",this.requestUpdate("src",old)}connectedCallback(){super.connectedCallback(),this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this}),this.stopLibrarySubscription??=subscribeIconLibrary(name=>{name===this.library&&this.load()}),this.hasUpdated&&(queueMicrotask(()=>{this.isConnected&&this.syncCustomNodes()}),this.hasRemoteSource()&&this.scheduleAfterUpdate(()=>{this.load()}))}disconnectedCallback(){this.generation++,this.releaseResourceLease(),this.stopLibrarySubscription?.(),this.stopLibrarySubscription=void 0,this.customContentObserver?.disconnect(),this.customContentObserver=void 0,this.errorAnnouncementSink?.release(),this.errorAnnouncementSink=void 0,this.fetchState.kind!=="idle"&&(this.fetchState={kind:"idle"}),super.disconnectedCallback()}updated(changed){if(super.updated(changed),changed.has("rotate")){const angle=finiteNumber(this.rotate??0,0);angle?this.style.setProperty("--lr-icon-rotate",`${angle}deg`):this.style.removeProperty("--lr-icon-rotate")}this.applyRemoteA11y(),this.syncCustomNodes(),(changed.has("src")||changed.has("library")||changed.has("name")||changed.has("family")||changed.has("variant"))&&this.scheduleAfterUpdate(()=>{this.load()})}syncCustomNodes(){if(this.fetchState.kind!=="idle")return;const svgEl=this.svgEl;if(!svgEl)return;svgEl.querySelectorAll("[data-lr-custom-copy]").forEach(node=>node.remove()),this.customContentObserver?.disconnect();const slot=this.customSlot;if(slot){for(const node of slot.assignedNodes({flatten:!0})){const copy=this.cloneSvgNode(node);copy&&(copy.setAttribute("data-lr-custom-copy",""),svgEl.append(copy))}this.observeCustomContent(slot)}}observeCustomContent(slot){if(this.customContentObserver?.disconnect(),!this.isConnected)return;const MutationObserverCtor=this.ownerDocument.defaultView?.MutationObserver;if(MutationObserverCtor){this.customContentObserver??=new MutationObserverCtor(()=>{this.isConnected&&this.syncCustomNodes()});for(const node of slot.assignedNodes({flatten:!0}))node.nodeType===1&&this.customContentObserver.observe(node,{attributes:!0,childList:!0,subtree:!0})}}cloneSvgNode(node){if(node.nodeType!==1)return null;const element=node;if(element.localName.includes("-"))return null;const copy=this.ownerDocument.createElementNS("http://www.w3.org/2000/svg",element.localName);for(const attribute of element.attributes)isUnsafeSvgCloneAttribute(attribute.name)||copy.setAttribute(attribute.name,attribute.value);for(const child of element.childNodes){const childCopy=this.cloneSvgNode(child);childCopy?copy.append(childCopy):child.nodeType===3&&copy.append(this.ownerDocument.createTextNode(child.textContent??""))}return copy}accessibleLabel(){return this.getAttribute("aria-label")??this.label}hasRemoteSource(){return!!(this.src||this.name&&this.library&&getIconLibrary(this.library))}releaseResourceLease(){this.resourceLease?.release(),this.resourceLease=void 0}async load(){const generation=++this.generation;this.releaseResourceLease();const library=this.name&&this.library?getIconLibrary(this.library):void 0;if(!library&&!this.src){this.fetchState.kind!=="idle"&&(this.fetchState={kind:"idle"});return}this.fetchState={kind:"loading"};let source=this.src;try{if(library){if(source=await library.resolver(this.name,this.family,this.variant),!this.isConnected||generation!==this.generation)return;if(typeof source!="string")throw new TypeError("icon resolver did not return a URL")}}catch(error){await this.fail("load",generation,this.name,error);return}if(!source){this.isConnected&&generation===this.generation&&(this.fetchState={kind:"idle"});return}const safeSource=safeFetchUrl(source);if(!safeSource){await this.fail("load",generation,source,new Error("icon URL is not allowed"));return}const fetchTarget=resolveOwnerFetchTarget(this,safeSource);if(!fetchTarget){await this.fail("load",generation,safeSource,new Error("icon URL is not available"));return}let lease;try{lease=acquireSanitizedIconResource(fetchTarget),this.resourceLease=lease;const canonical=await lease.promise;if(!this.isConnected||generation!==this.generation)return;if(!canonical){if(this.fetchState={kind:"empty"},await this.updateComplete,!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource});return}const node=this.ownerDocument.importNode(canonical,!0);if(library?.mutator?.(node),this.fetchState={kind:"loaded",node},await this.updateComplete,!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource})}catch(error){if(isAbortError(error))return;const reason=error instanceof IconResourceError?error.reason:"load";await this.fail(reason,generation,safeSource,error)}finally{this.resourceLease===lease&&(this.resourceLease=void 0),lease?.release()}}async fail(reason,generation,src,error){!this.isConnected||generation!==this.generation||(this.fetchState={kind:"error",reason},await this.updateComplete,!(!this.isConnected||generation!==this.generation)&&(isAccessibilityVisible(this)&&this.errorAnnouncementSink?.announce(this.errorMessage(reason)),this.emit("lr-error",{src,error})))}errorMessage(reason){return reason==="sanitizer"?this.localize("iconSanitizerMissing"):reason==="too-large"?this.localize("iconTooLarge"):this.localize("iconLoadError")}applyRemoteA11y(){const state2=this.fetchState;if(state2.kind==="loaded"){state2.node.setAttribute("part","svg"),state2.node.setAttribute("focusable","false"),state2.node.setAttribute("aria-hidden","true"),state2.node.removeAttribute("aria-label");for(const use of state2.node.querySelectorAll("use")){const parts=new Set((use.getAttribute("part")??"").split(/\s+/).filter(Boolean));parts.add("use"),use.setAttribute("part",[...parts].join(" "))}}}renderBuiltIn(){const path=this.path||PATHS[this.name]||"";return html`<svg
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--)(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,svg}from"lit";import{property,query,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAccessibilityVisible,srOnly}from"../../../internal/a11y.js";import{finiteNumber}from"../../../internal/numbers.js";import{safeFetchUrl}from"../../../internal/safe-url.js";import{isUnsafeSvgCloneAttribute,isUnsafeSvgCloneElement}from"../../../internal/safe-svg.js";import{isAbortError,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getIconLibrary,subscribeIconLibrary}from"./icon-library.js";import{acquireSanitizedIconResource,IconResourceError}from"./icon-resource.js";import{styles}from"./icon.styles.js";import{LYRA_DEFAULT_iconLoadError,LYRA_DEFAULT_iconSanitizerMissing,LYRA_DEFAULT_iconTooLarge}from"../../../internal/default-strings.generated.js";const PATHS={add:"M12 5v14M5 12h14",check:"m5 12 4 4L19 6",close:"m6 6 12 12M18 6 6 18",search:"m21 21-4.35-4.35M10.5 18a7.5 7.5 0 1 1 0-15 7.5 7.5 0 0 1 0 15Z",menu:"M4 6h16M4 12h16M4 18h16","chevron-left":"m15 18-6-6 6-6","chevron-right":"m9 18 6-6-6-6","chevron-down":"m6 9 6 6 6-6",calendar:"M6 3v3M18 3v3M4 9h16M5 5h14a1 1 0 0 1 1 1v13H4V6a1 1 0 0 1 1-1Z",command:"M6 6h4v4H6zM14 6h4v4h-4zM6 14h4v4H6zM14 14h4v4h-4z",trash:"M4 7h16M10 11v6M14 11v6M6 7l1 14h10l1-14M9 7V4h6v3"};class LyraIcon extends LyraElement{constructor(){super(...arguments),this._name="",this.path="",this.label="",this.library="default",this.family="",this.variant="",this._src="",this.rotate=0,this.autoWidth=!1,this.swapOpacity=!1,this.fixedWidth=!1,this.fetchState={kind:"idle"},this.generation=0,this.onCustomSlotChange=()=>{this.syncCustomNodes()}}static{this.defaultStrings={...super.defaultStrings,iconLoadError:LYRA_DEFAULT_iconLoadError,iconSanitizerMissing:LYRA_DEFAULT_iconSanitizerMissing,iconTooLarge:LYRA_DEFAULT_iconTooLarge}}static{this.styles=[LyraElement.styles,styles,srOnly]}get name(){return this._name}set name(value){const old=this._name;this._name=value??"",this.requestUpdate("name",old)}get src(){return this._src}set src(value){const old=this._src;this._src=value??"",this.requestUpdate("src",old)}connectedCallback(){super.connectedCallback(),this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this}),this.stopLibrarySubscription??=subscribeIconLibrary(name=>{name===this.library&&this.load()}),this.hasUpdated&&(queueMicrotask(()=>{this.isConnected&&this.syncCustomNodes()}),this.hasRemoteSource()&&this.scheduleAfterUpdate(()=>{this.load()}))}disconnectedCallback(){this.generation++,this.releaseResourceLease(),this.stopLibrarySubscription?.(),this.stopLibrarySubscription=void 0,this.customContentObserver?.disconnect(),this.customContentObserver=void 0,this.errorAnnouncementSink?.release(),this.errorAnnouncementSink=void 0,this.fetchState.kind!=="idle"&&(this.fetchState={kind:"idle"}),super.disconnectedCallback()}updated(changed){if(super.updated(changed),changed.has("rotate")){const angle=finiteNumber(this.rotate??0,0);angle?this.style.setProperty("--lr-icon-rotate",`${angle}deg`):this.style.removeProperty("--lr-icon-rotate")}this.applyRemoteA11y(),this.syncCustomNodes(),(changed.has("src")||changed.has("library")||changed.has("name")||changed.has("family")||changed.has("variant"))&&this.scheduleAfterUpdate(()=>{this.load()})}syncCustomNodes(){if(this.fetchState.kind!=="idle")return;const svgEl=this.svgEl;if(!svgEl)return;svgEl.querySelectorAll("[data-lr-custom-copy]").forEach(node=>node.remove()),this.customContentObserver?.disconnect();const slot=this.customSlot;if(slot){for(const node of slot.assignedNodes({flatten:!0})){const copy=this.cloneSvgNode(node);copy&&(copy.setAttribute("data-lr-custom-copy",""),svgEl.append(copy))}this.observeCustomContent(slot)}}observeCustomContent(slot){if(this.customContentObserver?.disconnect(),!this.isConnected)return;const MutationObserverCtor=this.ownerDocument.defaultView?.MutationObserver;if(MutationObserverCtor){this.customContentObserver??=new MutationObserverCtor(()=>{this.isConnected&&this.syncCustomNodes()});for(const node of slot.assignedNodes({flatten:!0}))node.nodeType===1&&this.customContentObserver.observe(node,{attributes:!0,childList:!0,subtree:!0})}}cloneSvgNode(node){if(node.nodeType!==1)return null;const element=node;if(element.localName.includes("-")||isUnsafeSvgCloneElement(element.localName))return null;const copy=this.ownerDocument.createElementNS("http://www.w3.org/2000/svg",element.localName);for(const attribute of element.attributes)isUnsafeSvgCloneAttribute(attribute.name,attribute.value)||copy.setAttribute(attribute.name,attribute.value);for(const child of element.childNodes){const childCopy=this.cloneSvgNode(child);childCopy?copy.append(childCopy):child.nodeType===3&&copy.append(this.ownerDocument.createTextNode(child.textContent??""))}return copy}accessibleLabel(){return this.getAttribute("aria-label")??this.label}hasRemoteSource(){return!!(this.src||this.name&&this.library&&getIconLibrary(this.library))}releaseResourceLease(){this.resourceLease?.release(),this.resourceLease=void 0}async load(){const generation=++this.generation;this.releaseResourceLease();const library=this.name&&this.library?getIconLibrary(this.library):void 0;if(!library&&!this.src){this.fetchState.kind!=="idle"&&(this.fetchState={kind:"idle"});return}this.fetchState={kind:"loading"};let source=this.src;try{if(library){if(source=await library.resolver(this.name,this.family,this.variant),!this.isConnected||generation!==this.generation)return;if(typeof source!="string")throw new TypeError("icon resolver did not return a URL")}}catch(error){await this.fail("load",generation,this.name,error);return}if(!source){this.isConnected&&generation===this.generation&&(this.fetchState={kind:"idle"});return}const safeSource=safeFetchUrl(source);if(!safeSource){await this.fail("load",generation,source,new Error("icon URL is not allowed"));return}const fetchTarget=resolveOwnerFetchTarget(this,safeSource);if(!fetchTarget){await this.fail("load",generation,safeSource,new Error("icon URL is not available"));return}let lease;try{lease=acquireSanitizedIconResource(fetchTarget),this.resourceLease=lease;const canonical=await lease.promise;if(!this.isConnected||generation!==this.generation)return;if(!canonical){if(this.fetchState={kind:"empty"},await this.updateComplete,!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource});return}const node=this.ownerDocument.importNode(canonical,!0);if(library?.mutator?.(node),this.fetchState={kind:"loaded",node},await this.updateComplete,!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource})}catch(error){if(isAbortError(error))return;const reason=error instanceof IconResourceError?error.reason:"load";await this.fail(reason,generation,safeSource,error)}finally{this.resourceLease===lease&&(this.resourceLease=void 0),lease?.release()}}async fail(reason,generation,src,error){!this.isConnected||generation!==this.generation||(this.fetchState={kind:"error",reason},await this.updateComplete,!(!this.isConnected||generation!==this.generation)&&(isAccessibilityVisible(this)&&this.errorAnnouncementSink?.announce(this.errorMessage(reason)),this.emit("lr-error",{src,error})))}errorMessage(reason){return reason==="sanitizer"?this.localize("iconSanitizerMissing"):reason==="too-large"?this.localize("iconTooLarge"):this.localize("iconLoadError")}applyRemoteA11y(){const state2=this.fetchState;if(state2.kind==="loaded"){state2.node.setAttribute("part","svg"),state2.node.setAttribute("focusable","false"),state2.node.setAttribute("aria-hidden","true"),state2.node.removeAttribute("aria-label");for(const use of state2.node.querySelectorAll("use")){const parts=new Set((use.getAttribute("part")??"").split(/\s+/).filter(Boolean));parts.add("use"),use.setAttribute("part",[...parts].join(" "))}}}renderBuiltIn(){const path=this.path||PATHS[this.name]||"";return html`<svg
2
2
  part="svg"
3
3
  viewBox="0 0 24 24"
4
4
  fill="none"
@@ -1 +1 @@
1
- import{takeOverlayOrder}from"./overlay-order.js";import{deepActiveElementIn}from"./active-element.js";import{collectComposedAutofocusElements,collectComposedFocusTargets,isComposedFocusAvailable}from"./focus-navigation.js";import{isHtmlElement}from"./dom-guards.js";import{leaseInlineStyleProperty}from"./style-property-lease.js";const STACK_PROPERTY="--lr-overlay-stack-index",STACK_BASE=1e3,STACK_STEP=2,states=new WeakMap,hostEntries=new WeakMap;function createInactiveOverlayHandle(){return{focusInitial:()=>{},focusAutofocus:()=>!1,updateRestoreFocusTo:()=>{},deactivate:()=>{},suspend:()=>{},resume:()=>{},isTopmost:()=>!1,isActive:()=>!1,dismissBackdrop:()=>!1}}function deepActiveElement(doc=typeof document>"u"?void 0:document){return deepActiveElementIn(doc)}function composedParent(element){return element.assignedSlot?element.assignedSlot:element.parentElement?element.parentElement:element.getRootNode().host??null}function composedContains(container,candidate){let current=candidate;for(;current;){if(current===container)return!0;current=composedParent(current)}return!1}function collectFocusableElements(root){return collectComposedFocusTargets(root).elements}function collectAutofocusElements(root){return collectComposedAutofocusElements(root).elements}function tryFocus(target){if(!target||!isComposedFocusAvailable(target))return!1;target.focus();const active=deepActiveElement(target.ownerDocument);return active===target||composedContains(target,active)}function focusAutofocusTarget(panel){for(const candidate of collectAutofocusElements(panel)){if(tryFocus(candidate))return!0;for(const inner of collectFocusableElements(candidate))if(tryFocus(inner))return!0}return!1}function focusEntry(entry,preserveCurrent=!0){const panel=entry.options.panel();if(!panel)return;const active=deepActiveElement(entry.state.document);if(preserveCurrent&&composedContains(panel,active)||(entry.initialFocusDecision===void 0&&(entry.initialFocusDecision=entry.options.beforeInitialFocus?.()!==!1),!entry.initialFocusDecision)||focusAutofocusTarget(panel))return;const preferred=entry.options.preferredInitialFocus?.()??null;if(!(preferred&&composedContains(panel,preferred)&&tryFocus(preferred))){for(const target of collectFocusableElements(panel))if(tryFocus(target))return;panel.focus()}}function handleTab(state,entry,event){const panel=entry.options.panel();if(!panel)return;const focusable=collectFocusableElements(panel);if(focusable.length===0){event.preventDefault(),panel.focus();return}const active=deepActiveElement(state.document),first=focusable[0],last=focusable[focusable.length-1];(active?focusable.indexOf(active):-1)===-1?(event.preventDefault(),(event.shiftKey?last:first).focus()):event.shiftKey&&active===first?(event.preventDefault(),last.focus()):!event.shiftKey&&active===last&&(event.preventDefault(),first.focus())}function snapshotFor(state){return{entries:state.stack.map(entry=>({host:entry.options.host,modal:entry.options.modal,modalRoot:entry.options.modalRoot}))}}function notifyStackObservers(state){if(state.observers.size===0)return;const snapshot=snapshotFor(state);for(const observer of state.observers)observer(snapshot)}function startState(state){state.started||(state.started=!0,state.document.addEventListener("keydown",state.onKeyDown))}function stopState(state){state.started&&(state.started=!1,state.document.removeEventListener("keydown",state.onKeyDown))}function stopStateIfIdle(state){state.stack.length===0&&stopState(state)}function createState(doc){const state={};return state.document=doc,state.stack=[],state.routingSuspensions=new Set,state.observers=new Set,state.started=!1,state.onKeyDown=event=>{if(event.defaultPrevented||event.isComposing||event.keyCode===229||state.routingSuspensions.size>0)return;const entry=state.stack[state.stack.length-1];entry&&(event.key==="Escape"?(event.preventDefault(),entry.options.onEscape()):event.key==="Tab"&&(entry.options.trapFocus===!1?entry.options.onTab?.():handleTab(state,entry,event)))},states.set(doc,state),state}function stateFor(doc){return states.get(doc)??createState(doc)}function observeOverlayStack(doc,observer){const state=stateFor(doc);return state.observers.add(observer),observer(snapshotFor(state)),()=>{state.observers.delete(observer)}}function acquireOverlayRoutingSuspension(doc){const state=stateFor(doc),token=Symbol();let active=!0;return state.routingSuspensions.add(token),()=>{active&&(active=!1,state.routingSuspensions.delete(token))}}function restoreStackStyle(entry){entry.stackStyleLease?.release(),entry.stackStyleLease=void 0}function updateStackStyles(state){state.stack.forEach((entry,index)=>{const value=String(STACK_BASE+index*STACK_STEP);entry.stackStyleLease?entry.stackStyleLease.set(value):entry.stackStyleLease=leaseInlineStyleProperty(entry.options.host,STACK_PROPERTY,value)})}function registerEntry(entry,state,preserveStackOrder=!1){if(entry.registered)return;startState(state),(!preserveStackOrder||entry.state!==state)&&(entry.stackOrder=takeOverlayOrder(state.document)),entry.state=state,entry.registered=!0,entry.options.onRegistered?.(state.document);const nextIndex=state.stack.findIndex(candidate=>candidate.stackOrder>entry.stackOrder);nextIndex===-1?state.stack.push(entry):state.stack.splice(nextIndex,0,entry),updateStackStyles(state),notifyStackObservers(state)}function unregisterEntry(entry,deferResourceRelease=!1){if(!entry.registered){const hasHigherEntry=entry.state.stack.some(candidate=>candidate.stackOrder>entry.stackOrder);return entry.state.routingSuspensions.size===0&&entry.wasTopmostOnSuspend&&!hasHigherEntry}const state=entry.state,index=state.stack.indexOf(entry),wasTopmost=state.routingSuspensions.size===0&&index===state.stack.length-1;return index!==-1&&state.stack.splice(index,1),entry.registered=!1,entry.wasTopmostOnSuspend=wasTopmost,entry.deferredResourceRelease=entry.options.onUnregistered?.(state.document,deferResourceRelease),restoreStackStyle(entry),updateStackStyles(state),notifyStackObservers(state),stopStateIfIdle(state),wasTopmost}function syncEntryRegistration(entry){if(!entry.active||entry.manuallySuspended){unregisterEntry(entry);return}const state=stateFor(entry.options.host.ownerDocument);registerEntry(entry,state,entry.state===state)}function validRestoreFocusElement(value,doc){return isHtmlElement(value)&&value.ownerDocument===doc?value:null}function resolveRestoreFocusTarget(entry){const source=entry.restoreFocusTo;if(typeof source!="function")return validRestoreFocusElement(source,entry.state.document);try{return validRestoreFocusElement(source(),entry.state.document)}catch{return null}}function rebaseReturnTargets(entry){for(const candidate of entry.state.stack){if(candidate===entry||candidate.stackOrder<=entry.stackOrder)continue;const candidateTarget=typeof candidate.restoreFocusTo=="function"?null:validRestoreFocusElement(candidate.restoreFocusTo,entry.state.document);candidateTarget&&composedContains(entry.options.host,candidateTarget)&&(candidate.restoreFocusTo=entry.restoreFocusTo)}}function restoreEntryFocus(entry){if(tryFocus(resolveRestoreFocusTarget(entry)))return;const next=entry.state.stack[entry.state.stack.length-1];next&&focusEntry(next,!1)}function deactivateEntry(entry,restoreFocus,deferResourceRelease=!1){if(!entry.active)return;rebaseReturnTargets(entry);const wasTopmost=unregisterEntry(entry,deferResourceRelease),deferredResourceRelease=entry.deferredResourceRelease;if(entry.deferredResourceRelease=void 0,entry.active=!1,entry.manuallySuspended=!1,entry.suspendGeneration++,entry.options.onDeactivate?.(),hostEntries.get(entry.options.host)===entry&&hostEntries.delete(entry.options.host),!wasTopmost)return deferredResourceRelease;if(restoreFocus)return restoreEntryFocus(entry),deferredResourceRelease;const next=entry.state.stack[entry.state.stack.length-1];return next&&focusEntry(next),deferredResourceRelease}function activateOverlayStack(options){const previous=hostEntries.get(options.host),inheritedReturnTarget=previous?.active?previous.restoreFocusTo:void 0;previous?.active&&previous.handle.deactivate({restoreFocus:!1});const doc=options.host.ownerDocument;if(!doc)return createInactiveOverlayHandle();const active=deepActiveElement(doc),captured=active&&typeof active.focus=="function"?active:null,entry={};return entry.options=options,entry.restoreFocusTo=options.restoreFocusTo!==void 0?options.restoreFocusTo:inheritedReturnTarget??captured,entry.active=!0,entry.registered=!1,entry.manuallySuspended=options.initiallySuspended===!0,entry.initialFocusDecision=void 0,entry.wasTopmostOnSuspend=!1,entry.suspendGeneration=0,entry.state=stateFor(doc),entry.stackOrder=takeOverlayOrder(doc,options.orderReservation),entry.handle={focusInitial:()=>{entry.active&&entry.registered&&entry.state.routingSuspensions.size===0&&entry.state.stack[entry.state.stack.length-1]===entry&&focusEntry(entry)},focusAutofocus:()=>{if(!entry.active||!entry.registered||entry.state.routingSuspensions.size>0)return!1;const panel=entry.options.panel();if(!panel)return!1;const active2=deepActiveElement(entry.state.document);return composedContains(panel,active2)?!1:focusAutofocusTarget(panel)},updateRestoreFocusTo:target=>{entry.active&&(entry.restoreFocusTo=target)},deactivate:(deactivateOptions={})=>deactivateEntry(entry,deactivateOptions.restoreFocus!==!1,deactivateOptions.deferScrollLockRelease===!0),suspend:()=>{if(!entry.active||entry.manuallySuspended)return;entry.manuallySuspended=!0,syncEntryRegistration(entry);const generation=++entry.suspendGeneration;queueMicrotask(()=>{entry.active&&!entry.registered&&entry.suspendGeneration===generation&&!entry.options.host.isConnected&&deactivateEntry(entry,!0)})},resume:()=>{!entry.active||!entry.manuallySuspended||(entry.suspendGeneration++,entry.manuallySuspended=!1,syncEntryRegistration(entry))},isTopmost:()=>entry.active&&entry.registered&&entry.state.routingSuspensions.size===0&&entry.state.stack[entry.state.stack.length-1]===entry,isActive:()=>entry.active,dismissBackdrop:()=>!entry.handle.isTopmost()||!entry.options.onBackdrop?!1:(entry.options.onBackdrop(),!0)},hostEntries.set(options.host,entry),entry.manuallySuspended||registerEntry(entry,entry.state,!0),entry.handle}export{acquireOverlayRoutingSuspension,activateOverlayStack,collectAutofocusElements,collectFocusableElements,composedContains,deepActiveElement,observeOverlayStack};
1
+ import{takeOverlayOrder}from"./overlay-order.js";import{deepActiveElementIn}from"./active-element.js";import{collectComposedAutofocusElements,collectComposedFocusTargets,isComposedFocusAvailable}from"./focus-navigation.js";import{isHtmlElement}from"./dom-guards.js";import{leaseInlineStyleProperty}from"./style-property-lease.js";const STACK_PROPERTY="--lr-overlay-stack-index",STACK_BASE=1e3,STACK_STEP=2,states=new WeakMap,hostEntries=new WeakMap;function createInactiveOverlayHandle(){return{focusInitial:()=>{},focusAutofocus:()=>!1,updateRestoreFocusTo:()=>{},deactivate:()=>{},suspend:()=>{},resume:()=>{},isTopmost:()=>!1,isActive:()=>!1,dismissBackdrop:()=>!1}}function deepActiveElement(doc=typeof document>"u"?void 0:document){return deepActiveElementIn(doc)}function composedParent(element){return element.assignedSlot?element.assignedSlot:element.parentElement?element.parentElement:element.getRootNode().host??null}function composedContains(container,candidate){let current=candidate;for(;current;){if(current===container)return!0;current=composedParent(current)}return!1}function collectFocusableElements(root){return collectComposedFocusTargets(root).elements}function collectAutofocusElements(root){return collectComposedAutofocusElements(root).elements}function tryFocus(target){if(!target||!isComposedFocusAvailable(target))return!1;target.focus();const active=deepActiveElement(target.ownerDocument);return active===target||composedContains(target,active)}function focusAutofocusTarget(panel){for(const candidate of collectAutofocusElements(panel)){if(tryFocus(candidate))return!0;for(const inner of collectFocusableElements(candidate))if(tryFocus(inner))return!0}return!1}function focusEntry(entry,preserveCurrent=!0){const panel=entry.options.panel();if(!panel)return;const active=deepActiveElement(entry.state.document);if(preserveCurrent&&composedContains(panel,active)||(entry.initialFocusDecision===void 0&&(entry.initialFocusDecision=entry.options.beforeInitialFocus?.()!==!1),!entry.initialFocusDecision)||focusAutofocusTarget(panel))return;const preferred=entry.options.preferredInitialFocus?.()??null;if(!(preferred&&composedContains(panel,preferred)&&tryFocus(preferred))){for(const target of collectFocusableElements(panel))if(tryFocus(target))return;panel.focus()}}function handleTab(state,entry,event){const panel=entry.options.panel();if(!panel)return;const focusable=collectFocusableElements(panel);if(focusable.length===0){event.preventDefault(),panel.focus();return}const active=deepActiveElement(state.document),first=focusable[0],last=focusable[focusable.length-1],activeIndex=active?focusable.indexOf(active):-1;if(activeIndex===-1)event.preventDefault(),(event.shiftKey?last:first).focus();else if(event.shiftKey&&active===first)event.preventDefault(),last.focus();else if(!event.shiftKey&&active===last)event.preventDefault(),first.focus();else{const next=focusable[activeIndex+(event.shiftKey?-1:1)];next&&next.tabIndex<0&&(event.preventDefault(),next.focus())}}function snapshotFor(state){return{entries:state.stack.map(entry=>({host:entry.options.host,modal:entry.options.modal,modalRoot:entry.options.modalRoot}))}}function notifyStackObservers(state){if(state.observers.size===0)return;const snapshot=snapshotFor(state);for(const observer of state.observers)observer(snapshot)}function startState(state){state.started||(state.started=!0,state.document.addEventListener("keydown",state.onKeyDown))}function stopState(state){state.started&&(state.started=!1,state.document.removeEventListener("keydown",state.onKeyDown))}function stopStateIfIdle(state){state.stack.length===0&&stopState(state)}function createState(doc){const state={};return state.document=doc,state.stack=[],state.routingSuspensions=new Set,state.observers=new Set,state.started=!1,state.onKeyDown=event=>{if(event.defaultPrevented||event.isComposing||event.keyCode===229||state.routingSuspensions.size>0)return;const entry=state.stack[state.stack.length-1];entry&&(event.key==="Escape"?(event.preventDefault(),entry.options.onEscape()):event.key==="Tab"&&(entry.options.trapFocus===!1?entry.options.onTab?.():handleTab(state,entry,event)))},states.set(doc,state),state}function stateFor(doc){return states.get(doc)??createState(doc)}function observeOverlayStack(doc,observer){const state=stateFor(doc);return state.observers.add(observer),observer(snapshotFor(state)),()=>{state.observers.delete(observer)}}function acquireOverlayRoutingSuspension(doc){const state=stateFor(doc),token=Symbol();let active=!0;return state.routingSuspensions.add(token),()=>{active&&(active=!1,state.routingSuspensions.delete(token))}}function restoreStackStyle(entry){entry.stackStyleLease?.release(),entry.stackStyleLease=void 0}function updateStackStyles(state){state.stack.forEach((entry,index)=>{const value=String(STACK_BASE+index*STACK_STEP);entry.stackStyleLease?entry.stackStyleLease.set(value):entry.stackStyleLease=leaseInlineStyleProperty(entry.options.host,STACK_PROPERTY,value)})}function registerEntry(entry,state,preserveStackOrder=!1){if(entry.registered)return;startState(state),(!preserveStackOrder||entry.state!==state)&&(entry.stackOrder=takeOverlayOrder(state.document)),entry.state=state,entry.registered=!0,entry.options.onRegistered?.(state.document);const nextIndex=state.stack.findIndex(candidate=>candidate.stackOrder>entry.stackOrder);nextIndex===-1?state.stack.push(entry):state.stack.splice(nextIndex,0,entry),updateStackStyles(state),notifyStackObservers(state)}function unregisterEntry(entry,deferResourceRelease=!1){if(!entry.registered){const hasHigherEntry=entry.state.stack.some(candidate=>candidate.stackOrder>entry.stackOrder);return entry.state.routingSuspensions.size===0&&entry.wasTopmostOnSuspend&&!hasHigherEntry}const state=entry.state,index=state.stack.indexOf(entry),wasTopmost=state.routingSuspensions.size===0&&index===state.stack.length-1;return index!==-1&&state.stack.splice(index,1),entry.registered=!1,entry.wasTopmostOnSuspend=wasTopmost,entry.deferredResourceRelease=entry.options.onUnregistered?.(state.document,deferResourceRelease),restoreStackStyle(entry),updateStackStyles(state),notifyStackObservers(state),stopStateIfIdle(state),wasTopmost}function syncEntryRegistration(entry){if(!entry.active||entry.manuallySuspended){unregisterEntry(entry);return}const state=stateFor(entry.options.host.ownerDocument);registerEntry(entry,state,entry.state===state)}function validRestoreFocusElement(value,doc){return isHtmlElement(value)&&value.ownerDocument===doc?value:null}function resolveRestoreFocusTarget(entry){const source=entry.restoreFocusTo;if(typeof source!="function")return validRestoreFocusElement(source,entry.state.document);try{return validRestoreFocusElement(source(),entry.state.document)}catch{return null}}function rebaseReturnTargets(entry){for(const candidate of entry.state.stack){if(candidate===entry||candidate.stackOrder<=entry.stackOrder)continue;const candidateTarget=typeof candidate.restoreFocusTo=="function"?null:validRestoreFocusElement(candidate.restoreFocusTo,entry.state.document);candidateTarget&&composedContains(entry.options.host,candidateTarget)&&(candidate.restoreFocusTo=entry.restoreFocusTo)}}function restoreEntryFocus(entry){if(tryFocus(resolveRestoreFocusTarget(entry)))return;const next=entry.state.stack[entry.state.stack.length-1];next&&focusEntry(next,!1)}function deactivateEntry(entry,restoreFocus,deferResourceRelease=!1){if(!entry.active)return;rebaseReturnTargets(entry);const wasTopmost=unregisterEntry(entry,deferResourceRelease),deferredResourceRelease=entry.deferredResourceRelease;if(entry.deferredResourceRelease=void 0,entry.active=!1,entry.manuallySuspended=!1,entry.suspendGeneration++,entry.options.onDeactivate?.(),hostEntries.get(entry.options.host)===entry&&hostEntries.delete(entry.options.host),!wasTopmost)return deferredResourceRelease;if(restoreFocus)return restoreEntryFocus(entry),deferredResourceRelease;const next=entry.state.stack[entry.state.stack.length-1];return next&&focusEntry(next),deferredResourceRelease}function activateOverlayStack(options){const previous=hostEntries.get(options.host),inheritedReturnTarget=previous?.active?previous.restoreFocusTo:void 0;previous?.active&&previous.handle.deactivate({restoreFocus:!1});const doc=options.host.ownerDocument;if(!doc)return createInactiveOverlayHandle();const active=deepActiveElement(doc),captured=active&&typeof active.focus=="function"?active:null,entry={};return entry.options=options,entry.restoreFocusTo=options.restoreFocusTo!==void 0?options.restoreFocusTo:inheritedReturnTarget??captured,entry.active=!0,entry.registered=!1,entry.manuallySuspended=options.initiallySuspended===!0,entry.initialFocusDecision=void 0,entry.wasTopmostOnSuspend=!1,entry.suspendGeneration=0,entry.state=stateFor(doc),entry.stackOrder=takeOverlayOrder(doc,options.orderReservation),entry.handle={focusInitial:()=>{entry.active&&entry.registered&&entry.state.routingSuspensions.size===0&&entry.state.stack[entry.state.stack.length-1]===entry&&focusEntry(entry)},focusAutofocus:()=>{if(!entry.active||!entry.registered||entry.state.routingSuspensions.size>0)return!1;const panel=entry.options.panel();if(!panel)return!1;const active2=deepActiveElement(entry.state.document);return composedContains(panel,active2)?!1:focusAutofocusTarget(panel)},updateRestoreFocusTo:target=>{entry.active&&(entry.restoreFocusTo=target)},deactivate:(deactivateOptions={})=>deactivateEntry(entry,deactivateOptions.restoreFocus!==!1,deactivateOptions.deferScrollLockRelease===!0),suspend:()=>{if(!entry.active||entry.manuallySuspended)return;entry.manuallySuspended=!0,syncEntryRegistration(entry);const generation=++entry.suspendGeneration;queueMicrotask(()=>{entry.active&&!entry.registered&&entry.suspendGeneration===generation&&!entry.options.host.isConnected&&deactivateEntry(entry,!0)})},resume:()=>{!entry.active||!entry.manuallySuspended||(entry.suspendGeneration++,entry.manuallySuspended=!1,syncEntryRegistration(entry))},isTopmost:()=>entry.active&&entry.registered&&entry.state.routingSuspensions.size===0&&entry.state.stack[entry.state.stack.length-1]===entry,isActive:()=>entry.active,dismissBackdrop:()=>!entry.handle.isTopmost()||!entry.options.onBackdrop?!1:(entry.options.onBackdrop(),!0)},hostEntries.set(options.host,entry),entry.manuallySuspended||registerEntry(entry,entry.state,!0),entry.handle}export{acquireOverlayRoutingSuspension,activateOverlayStack,collectAutofocusElements,collectFocusableElements,composedContains,deepActiveElement,observeOverlayStack};
@@ -2,4 +2,4 @@
2
2
  * Generated from package.json by scripts/generate-package-metadata.mjs.
3
3
  * Run `pnpm package-metadata` after changing package identity or version.
4
4
  */
5
- export declare const LYRA_PACKAGE_NAME:'@aceshooting/lyra-ui';export declare const LYRA_PACKAGE_VERSION:'18.4.0';
5
+ export declare const LYRA_PACKAGE_NAME:'@aceshooting/lyra-ui';export declare const LYRA_PACKAGE_VERSION:'19.0.0';
@@ -1 +1 @@
1
- const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui",LYRA_PACKAGE_VERSION="18.4.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
1
+ const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui",LYRA_PACKAGE_VERSION="19.0.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
@@ -1,13 +1,17 @@
1
1
  /**
2
- * Rejects an attribute name that should never survive a raw DOM clone of consumer-supplied SVG
3
- * content (`<lr-icon>`'s and `<lr-icon-button>`'s slotted custom-content path -- unlike a fetched
4
- * `src` document, which is sanitized through DOMPurify before it ever reaches the DOM, a slotted
5
- * clone has no sanitizer in the loop, so this predicate is that path's own trust boundary).
6
- * Event-handler content attributes (`on*`) execute as inline JS once connected; `href`/
7
- * `xlink:href` on an SVG `<a>`/`<use>`/`<image>` can carry a `javascript:` URI or reference an
8
- * external resource. Every other presentational attribute (`d`, `fill`, `stroke`, `viewBox`,
9
- * `transform`, gradient stops, …) is left untouched -- this is a denylist, not an allowlist,
10
- * because SVG's legitimate presentation-attribute vocabulary is too large to enumerate without
11
- * silently breaking real icon markup.
2
+ * Rejects an element that should never survive a raw DOM clone of consumer-supplied SVG content.
3
+ * Unlike a fetched `src` document, `<lr-icon>`'s and `<lr-icon-button>`'s slotted clone paths do
4
+ * not pass through DOMPurify, so this predicate is their own element trust boundary. The list is
5
+ * deliberately narrow enough to retain ordinary icon primitives, groups, definitions, gradients,
6
+ * masks, clipping paths, and `<use>` elements.
12
7
  */
13
- export declare function isUnsafeSvgCloneAttribute(name:string):boolean;
8
+ export declare function isUnsafeSvgCloneElement(name:string):boolean;
9
+ /**
10
+ * Rejects an attribute that should never survive a raw DOM clone of consumer-supplied SVG content.
11
+ * Event-handler attributes execute as inline JS once connected; style and secondary resource
12
+ * attributes can apply attacker-controlled CSS or initiate fetches; and href attributes can carry
13
+ * script URLs or external document references. URL-bearing presentation attributes retain only
14
+ * same-document fragment references, so ordinary icon geometry and local paint servers continue
15
+ * to work.
16
+ */
17
+ export declare function isUnsafeSvgCloneAttribute(name:string,value?:string):boolean;
@@ -1 +1 @@
1
- function isUnsafeSvgCloneAttribute(name){const lower=name.toLowerCase();return lower.startsWith("on")||lower==="href"||lower==="xlink:href"}export{isUnsafeSvgCloneAttribute};
1
+ const UNSAFE_SVG_CLONE_ELEMENTS=new Set(["script","style","foreignobject","animate","animatecolor","animatemotion","animatetransform","set","discard","mpath","feimage","image","iframe","object","embed"]),SVG_URL_PRESENTATION_ATTRIBUTES=new Set(["clip-path","cursor","fill","filter","marker","marker-end","marker-mid","marker-start","mask","stroke"]);function isLocalSvgFragment(value){return/^#[^\s"'()<>]+$/.test(value.trim())}function hasUnsafeCssResource(value){if(value.includes("\\"))return!0;const urls=[...value.matchAll(/url\(\s*(["']?)(.*?)\1\s*\)/gi)];return urls.length===0?!1:value.replace(/url\(\s*(["']?)(.*?)\1\s*\)/gi,"").trim()!==""||urls.some(match=>!isLocalSvgFragment(match[2]??""))}function isUnsafeSvgCloneElement(name){return UNSAFE_SVG_CLONE_ELEMENTS.has(name.toLowerCase())}function isUnsafeSvgCloneAttribute(name,value=""){const lower=name.toLowerCase();return lower.startsWith("on")||lower==="style"||lower==="src"||lower==="srcset"||lower==="poster"||lower==="href"||lower==="xlink:href"?!0:SVG_URL_PRESENTATION_ATTRIBUTES.has(lower)&&hasUnsafeCssResource(value)}export{isUnsafeSvgCloneAttribute,isUnsafeSvgCloneElement};
@@ -83,10 +83,10 @@ Citation; truncated?: boolean; omittedTokens?: number; redactions?: ContextInspe
83
83
  - `composerStatus: ChatComposerStatus = 'idle'` (attribute `composer-status`) — `'idle' | 'sending' |
84
84
  'streaming'`, `lr-chat-composer`'s own union; invalid values read as `idle` without rewriting the
85
85
  host attribute
86
- - `composerPlaceholder: string = ''` (attribute `composer-placeholder`)
86
+ - `composerPlaceholder?: string` (attribute `composer-placeholder`)
87
87
  - `composerMinRows: number = 1` (attribute `composer-min-rows`), `composerMaxRows: number = 8`
88
88
  (attribute `composer-max-rows`)
89
- - `label: string = ''` — accessible name and visible heading
89
+ - `label?: string` — accessible name and visible heading; omission uses the localized default and an explicit empty string suppresses it
90
90
  - `accessibleLabel: string | null = null` (attribute `aria-label`) — host-level accessible-name
91
91
  override for the internal `role="region"` root
92
92
 
@@ -100,10 +100,11 @@ structured points retain their y-value formatting.
100
100
  draws side by side with the first on that axis. Omitted series share one implicit group, so
101
101
  every chart written before `stack` existed sums exactly as it always did. Only meaningful on an
102
102
  axis that is actually stacked — see `stacked`/`stackedAxes` below.
103
- `LyraChartPoint { readonly x: number; readonly
104
- y: number; readonly r?: number; readonly label?: string }`: `r` is the bubble
105
- radius, and the optional per-point `label` is retained by events, CSV export, keyboard
106
- announcements, generated summaries, and the accessible table. Point wording is localized as
103
+ `LyraChartPoint { readonly x: number; readonly y: number; readonly r?: number; readonly id?:
104
+ string | number; readonly label?: string }`: `r` is the bubble radius, and the optional primitive
105
+ `id` is retained by activation events for application navigation or selection. Objects, symbols,
106
+ and non-finite numeric ids are omitted. The optional per-point `label` is retained by events, CSV
107
+ export, keyboard announcements, generated summaries, and the accessible table. Point wording is localized as
107
108
  whole messages: `chartPointCoordinates`, `chartBubblePointCoordinates`, and
108
109
  `chartLabeledPoint` own coordinate names, order, separators, and the label wrapper. A caller's
109
110
  point label is interpolated verbatim rather than translated or parsed. At runtime, non-record
@@ -381,9 +382,15 @@ const series = [
381
382
  point/segment, when a generated-table value is activated, or when Enter/Space activates the
382
383
  keyboard-current canvas datum; `detail: { datasetIndex: number, index: number, label: string |
383
384
  undefined, value: unknown }`). For scatter/bubble points, `label` prefers the per-point label and
384
- `value` is the complete `LyraChartPoint`, including optional `r` and `label`.
385
+ `value` is the complete `LyraChartPoint`, including optional `r`, `id`, and `label`. A primitive
386
+ `id` survives the same pointer, data-table, and keyboard activation paths; invalid ids are omitted.
385
387
  `lr-datum-activate` emits the same activation with `kind: 'bar'|'point'|'segment'|'slice'` for
386
- family-wide handling; `lr-point-click` remains as a compatibility event. Also
388
+ family-wide handling. For scatter/bubble, both events carry the same `LyraChartPoint` value,
389
+ including a string or finite-number `id` when supplied; invalid ids are omitted. The public
390
+ `LyraChartPoint.id` type is `string | number`, while the activation event's heterogeneous `value`
391
+ is typed `unknown`. Validate or explicitly narrow the value itself before reading point fields;
392
+ checking `detail.kind === 'point'` alone does not narrow `detail.value` in TypeScript.
393
+ `lr-point-click` remains as a compatibility event. Also
387
394
  `lr-before-legend-visibility-change` (cancelable proposal), and
388
395
  `lr-legend-visibility-change` (accepted commit). Both legend events carry
389
396
  `{ datasetIndex: number, visible: boolean, hiddenDatasets: readonly number[] }`; the latter is the
@@ -35,12 +35,12 @@ buttons.
35
35
  Resolution prefers an element in the button's own root, then falls back to the owner document;
36
36
  a duplicate same-root id therefore wins without preventing a shadow-contained button from
37
37
  targeting an otherwise valid document-owned source.
38
- - `copyLabel: string = ''` (attribute `copy-label`) — built-in button accessible name and resting
39
- tooltip text; empty uses localized `copy`.
40
- - `successLabel: string = ''` (attribute `success-label`) — confirmation name/tooltip text; empty
41
- uses localized `copied`.
42
- - `errorLabel: string = ''` (attribute `error-label`) — failure name/tooltip text; empty uses
43
- localized `copyFailed`.
38
+ - `copyLabel?: string` (attribute `copy-label`) — built-in button accessible name and resting
39
+ tooltip text; omission uses localized `copy`, while an explicit empty string suppresses it.
40
+ - `successLabel?: string` (attribute `success-label`) — confirmation name/tooltip text; omission
41
+ uses localized `copied`, while an explicit empty string suppresses it.
42
+ - `errorLabel?: string` (attribute `error-label`) — failure name/tooltip text; omission uses
43
+ localized `copyFailed`, while an explicit empty string suppresses it.
44
44
  - `tooltip: 'full' | 'copy' | 'none' = 'full'` (reflected) — `full` shows the resting tooltip on
45
45
  hover/focus and feedback after activation, `copy` shows feedback only, and `none` disables it.
46
46
  - `tooltipPlacement: 'top' | 'right' | 'bottom' | 'left' = 'top'` (attribute
@@ -178,10 +178,12 @@ painted surface sits one boundary deeper. `<lr-drawer>` inherits this control an
178
178
  `<lr-icon-button>` itself.
179
179
 
180
180
  **The body is keyboard-reachable while it overflows.** `[part="body"]` is the element that scrolls,
181
- so it carries `tabindex="-1"` and joins the focus order **only while its content actually
182
- overflows** — a dialog whose content is nothing but prose, a table, or a rendered document used to
181
+ so it carries `tabindex="0"` **only while its content actually overflows** — a dialog whose
182
+ content is nothing but prose, a table, or a rendered document used to
183
183
  be scrollable with a mouse and completely unreachable from the keyboard, because a scroll container
184
- with no focusable child is not a stop of its own. A short body never becomes a gratuitous stop.
184
+ with no focusable child is not a stop of its own. A short body keeps `tabindex="-1"` and never
185
+ becomes a gratuitous stop. Resize and content changes update the body's tabindex as its overflow
186
+ changes; `<lr-drawer>` uses the same behavior.
185
187
 
186
188
  It takes focus like any other stop, so it styles like one: `::part(body):focus-visible` draws the
187
189
  standard `--lr-focus-ring-*` ring, inset (`outline-offset` is negative) because the body is flush
@@ -87,8 +87,9 @@ enabled buttons retain pointer feedback.
87
87
  constrained spaces (a toolbar, a table cell) — the same convention as `lr-empty`'s `compact`. The
88
88
  dashed border stays; only the internal spacing shrinks. `false` (the default) keeps the full
89
89
  `--lr-space-l` dropzone.
90
- - `label: string = ''` and `hint: string = ''`; an empty `label` leaves the localized dropzone
91
- instruction (`fileInputDefaultLabel`) as the visible fallback
90
+ - `label?: string` — form-control label. Omission uses the localized dropzone instruction
91
+ (`fileInputDefaultLabel`); an explicit empty string suppresses that fallback. `hint: string = ''`
92
+ remains empty when omitted and can be supplied through the named slot as well
92
93
  - `errorText: string = ''` (attribute `error-text`) — plain-text owned validation feedback. When
93
94
  it is empty, a `customError` message is rendered when present; otherwise an intrinsic validation
94
95
  message appears after the control has been interacted with. Rich `error` slot content replaces
@@ -47,6 +47,11 @@ typed events. Capabilities are denied unless explicitly enabled in `resource.per
47
47
  request with exactly one of `{ frameGeneration, result }` or `{ frameGeneration, error }`. Missing,
48
48
  stale, or ambiguous correlation fails closed. Both methods are no-ops before a frame exists.
49
49
 
50
+ The initial `host-context` message includes a document-bound nonce and transfers a `MessagePort` to
51
+ the executable document. Frame requests and host messages after bootstrap use that port. A same-frame
52
+ navigation closes the port, invalidates the nonce and generation, and mounts a fresh sandbox before
53
+ host data can be delivered.
54
+
50
55
  **Exported types:** `McpAppResource`, `McpAppCsp`, `McpAppPermissions`,
51
56
  `McpAppToolCallDetail`, `McpAppToolResultOptions`, and `LyraMcpAppEventMap`.
52
57
 
@@ -60,8 +60,8 @@ at the same size tier, so the toolbar row renders as one flush line.
60
60
  Remove any host `role="status"`/`role="alert"` hand-added before this property existed once it
61
61
  is set — otherwise the initial state is announced twice, through the native role and again
62
62
  through the shared sink
63
- - `placeholder: string = ''` — falls back to the localized generic "Search" placeholder, which also
64
- becomes the field's accessible name
63
+ - `placeholder?: string` — query-field placeholder. Omission uses the localized generic "Search"
64
+ placeholder; an explicit empty string suppresses that fallback
65
65
  - `label?: string` — fallback name for the `role="search"` landmark; omission uses the localized
66
66
  retrieval-search label, while an explicit empty string stays empty
67
67
  - `accessibleLabel: string | null = null` (attribute `aria-label`) — as a JS-only property while
package/llms-full.txt CHANGED
@@ -22621,10 +22621,12 @@ painted surface sits one boundary deeper. `<lr-drawer>` inherits this control an
22621
22621
  `<lr-icon-button>` itself.
22622
22622
 
22623
22623
  **The body is keyboard-reachable while it overflows.** `[part="body"]` is the element that scrolls,
22624
- so it carries `tabindex="-1"` and joins the focus order **only while its content actually
22625
- overflows** — a dialog whose content is nothing but prose, a table, or a rendered document used to
22624
+ so it carries `tabindex="0"` **only while its content actually overflows** — a dialog whose
22625
+ content is nothing but prose, a table, or a rendered document used to
22626
22626
  be scrollable with a mouse and completely unreachable from the keyboard, because a scroll container
22627
- with no focusable child is not a stop of its own. A short body never becomes a gratuitous stop.
22627
+ with no focusable child is not a stop of its own. A short body keeps `tabindex="-1"` and never
22628
+ becomes a gratuitous stop. Resize and content changes update the body's tabindex as its overflow
22629
+ changes; `<lr-drawer>` uses the same behavior.
22628
22630
 
22629
22631
  It takes focus like any other stop, so it styles like one: `::part(body):focus-visible` draws the
22630
22632
  standard `--lr-focus-ring-*` ring, inset (`outline-offset` is negative) because the body is flush
@@ -25012,12 +25014,12 @@ buttons.
25012
25014
  Resolution prefers an element in the button's own root, then falls back to the owner document;
25013
25015
  a duplicate same-root id therefore wins without preventing a shadow-contained button from
25014
25016
  targeting an otherwise valid document-owned source.
25015
- - `copyLabel: string = ''` (attribute `copy-label`) — built-in button accessible name and resting
25016
- tooltip text; empty uses localized `copy`.
25017
- - `successLabel: string = ''` (attribute `success-label`) — confirmation name/tooltip text; empty
25018
- uses localized `copied`.
25019
- - `errorLabel: string = ''` (attribute `error-label`) — failure name/tooltip text; empty uses
25020
- localized `copyFailed`.
25017
+ - `copyLabel?: string` (attribute `copy-label`) — built-in button accessible name and resting
25018
+ tooltip text; omission uses localized `copy`, while an explicit empty string suppresses it.
25019
+ - `successLabel?: string` (attribute `success-label`) — confirmation name/tooltip text; omission
25020
+ uses localized `copied`, while an explicit empty string suppresses it.
25021
+ - `errorLabel?: string` (attribute `error-label`) — failure name/tooltip text; omission uses
25022
+ localized `copyFailed`, while an explicit empty string suppresses it.
25021
25023
  - `tooltip: 'full' | 'copy' | 'none' = 'full'` (reflected) — `full` shows the resting tooltip on
25022
25024
  hover/focus and feedback after activation, `copy` shows feedback only, and `none` disables it.
25023
25025
  - `tooltipPlacement: 'top' | 'right' | 'bottom' | 'left' = 'top'` (attribute
@@ -28153,8 +28155,9 @@ enabled buttons retain pointer feedback.
28153
28155
  constrained spaces (a toolbar, a table cell) — the same convention as `lr-empty`'s `compact`. The
28154
28156
  dashed border stays; only the internal spacing shrinks. `false` (the default) keeps the full
28155
28157
  `--lr-space-l` dropzone.
28156
- - `label: string = ''` and `hint: string = ''`; an empty `label` leaves the localized dropzone
28157
- instruction (`fileInputDefaultLabel`) as the visible fallback
28158
+ - `label?: string` — form-control label. Omission uses the localized dropzone instruction
28159
+ (`fileInputDefaultLabel`); an explicit empty string suppresses that fallback. `hint: string = ''`
28160
+ remains empty when omitted and can be supplied through the named slot as well
28158
28161
  - `errorText: string = ''` (attribute `error-text`) — plain-text owned validation feedback. When
28159
28162
  it is empty, a `customError` message is rendered when present; otherwise an intrinsic validation
28160
28163
  message appears after the control has been interacted with. Rich `error` slot content replaces
@@ -30802,10 +30805,11 @@ structured points retain their y-value formatting.
30802
30805
  draws side by side with the first on that axis. Omitted series share one implicit group, so
30803
30806
  every chart written before `stack` existed sums exactly as it always did. Only meaningful on an
30804
30807
  axis that is actually stacked — see `stacked`/`stackedAxes` below.
30805
- `LyraChartPoint { readonly x: number; readonly
30806
- y: number; readonly r?: number; readonly label?: string }`: `r` is the bubble
30807
- radius, and the optional per-point `label` is retained by events, CSV export, keyboard
30808
- announcements, generated summaries, and the accessible table. Point wording is localized as
30808
+ `LyraChartPoint { readonly x: number; readonly y: number; readonly r?: number; readonly id?:
30809
+ string | number; readonly label?: string }`: `r` is the bubble radius, and the optional primitive
30810
+ `id` is retained by activation events for application navigation or selection. Objects, symbols,
30811
+ and non-finite numeric ids are omitted. The optional per-point `label` is retained by events, CSV
30812
+ export, keyboard announcements, generated summaries, and the accessible table. Point wording is localized as
30809
30813
  whole messages: `chartPointCoordinates`, `chartBubblePointCoordinates`, and
30810
30814
  `chartLabeledPoint` own coordinate names, order, separators, and the label wrapper. A caller's
30811
30815
  point label is interpolated verbatim rather than translated or parsed. At runtime, non-record
@@ -31083,9 +31087,15 @@ const series = [
31083
31087
  point/segment, when a generated-table value is activated, or when Enter/Space activates the
31084
31088
  keyboard-current canvas datum; `detail: { datasetIndex: number, index: number, label: string |
31085
31089
  undefined, value: unknown }`). For scatter/bubble points, `label` prefers the per-point label and
31086
- `value` is the complete `LyraChartPoint`, including optional `r` and `label`.
31090
+ `value` is the complete `LyraChartPoint`, including optional `r`, `id`, and `label`. A primitive
31091
+ `id` survives the same pointer, data-table, and keyboard activation paths; invalid ids are omitted.
31087
31092
  `lr-datum-activate` emits the same activation with `kind: 'bar'|'point'|'segment'|'slice'` for
31088
- family-wide handling; `lr-point-click` remains as a compatibility event. Also
31093
+ family-wide handling. For scatter/bubble, both events carry the same `LyraChartPoint` value,
31094
+ including a string or finite-number `id` when supplied; invalid ids are omitted. The public
31095
+ `LyraChartPoint.id` type is `string | number`, while the activation event's heterogeneous `value`
31096
+ is typed `unknown`. Validate or explicitly narrow the value itself before reading point fields;
31097
+ checking `detail.kind === 'point'` alone does not narrow `detail.value` in TypeScript.
31098
+ `lr-point-click` remains as a compatibility event. Also
31089
31099
  `lr-before-legend-visibility-change` (cancelable proposal), and
31090
31100
  `lr-legend-visibility-change` (accepted commit). Both legend events carry
31091
31101
  `{ datasetIndex: number, visible: boolean, hiddenDatasets: readonly number[] }`; the latter is the
@@ -32249,6 +32259,7 @@ These named interfaces and helper signatures are available to typed integrations
32249
32259
  readonly x: number;
32250
32260
  readonly y: number;
32251
32261
  readonly r?: number;
32262
+ readonly id?: string | number;
32252
32263
  readonly label?: string;
32253
32264
  }`
32254
32265
  Import: `@aceshooting/lyra-ui/components/charts/chart/chart.class.js`.
@@ -38719,10 +38730,10 @@ Citation; truncated?: boolean; omittedTokens?: number; redactions?: ContextInspe
38719
38730
  - `composerStatus: ChatComposerStatus = 'idle'` (attribute `composer-status`) — `'idle' | 'sending' |
38720
38731
  'streaming'`, `lr-chat-composer`'s own union; invalid values read as `idle` without rewriting the
38721
38732
  host attribute
38722
- - `composerPlaceholder: string = ''` (attribute `composer-placeholder`)
38733
+ - `composerPlaceholder?: string` (attribute `composer-placeholder`)
38723
38734
  - `composerMinRows: number = 1` (attribute `composer-min-rows`), `composerMaxRows: number = 8`
38724
38735
  (attribute `composer-max-rows`)
38725
- - `label: string = ''` — accessible name and visible heading
38736
+ - `label?: string` — accessible name and visible heading; omission uses the localized default and an explicit empty string suppresses it
38726
38737
  - `accessibleLabel: string | null = null` (attribute `aria-label`) — host-level accessible-name
38727
38738
  override for the internal `role="region"` root
38728
38739
 
@@ -42630,6 +42641,11 @@ typed events. Capabilities are denied unless explicitly enabled in `resource.per
42630
42641
  request with exactly one of `{ frameGeneration, result }` or `{ frameGeneration, error }`. Missing,
42631
42642
  stale, or ambiguous correlation fails closed. Both methods are no-ops before a frame exists.
42632
42643
 
42644
+ The initial `host-context` message includes a document-bound nonce and transfers a `MessagePort` to
42645
+ the executable document. Frame requests and host messages after bootstrap use that port. A same-frame
42646
+ navigation closes the port, invalidates the nonce and generation, and mounts a fresh sandbox before
42647
+ host data can be delivered.
42648
+
42633
42649
  **Exported types:** `McpAppResource`, `McpAppCsp`, `McpAppPermissions`,
42634
42650
  `McpAppToolCallDetail`, `McpAppToolResultOptions`, and `LyraMcpAppEventMap`.
42635
42651
 
@@ -45731,8 +45747,8 @@ at the same size tier, so the toolbar row renders as one flush line.
45731
45747
  Remove any host `role="status"`/`role="alert"` hand-added before this property existed once it
45732
45748
  is set — otherwise the initial state is announced twice, through the native role and again
45733
45749
  through the shared sink
45734
- - `placeholder: string = ''` — falls back to the localized generic "Search" placeholder, which also
45735
- becomes the field's accessible name
45750
+ - `placeholder?: string` — query-field placeholder. Omission uses the localized generic "Search"
45751
+ placeholder; an explicit empty string suppresses that fallback
45736
45752
  - `label?: string` — fallback name for the `role="search"` landmark; omission uses the localized
45737
45753
  retrieval-search label, while an explicit empty string stays empty
45738
45754
  - `accessibleLabel: string | null = null` (attribute `aria-label`) — as a JS-only property while
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aceshooting/lyra-ui",
3
- "version": "18.4.0",
3
+ "version": "19.0.0",
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",
@@ -2890,7 +2890,7 @@
2890
2890
  "test:translation-slices": "node scripts/generate-translation-slices.test.mjs",
2891
2891
  "check:default-strings": "node scripts/check-default-strings.mjs",
2892
2892
  "test:default-strings": "node scripts/check-default-strings.test.mjs",
2893
- "test:tooling": "node scripts/build-llms.test.mjs && node --test scripts/create-component.test.mjs && node --test scripts/full-engine-shard.test.mjs && node --test scripts/coverage-shard-runner.test.mjs && node --test scripts/lint-ci-shard.test.mjs && node --test scripts/web-test-runner-config.test.mjs && node scripts/component-families.test.mjs && node scripts/maplibre-peer-range.test.mjs && node scripts/migrate-wa.test.mjs && node scripts/visual-regression-compare.test.mjs && node --test scripts/visual-regression-shard.test.mjs && node scripts/visual-regression-config.test.mjs && node --test scripts/check-source-policy.test.mjs scripts/check-test-assertions.test.mjs && node scripts/bundle-budgets.test.mjs && node scripts/compact-build-js.test.mjs && node scripts/compact-build-css.test.mjs && node scripts/compact-build-declarations.test.mjs && node --test scripts/normalize-mixin-declarations.test.mjs && node --test scripts/check-palette-freshness.test.mjs && node --test scripts/is-main-module.test.mjs && node scripts/manifest-compact.test.mjs && node --test scripts/viewer-fixture-generators.test.mjs && node --test scripts/strip-css-comments.test.mjs && node scripts/editor-web-types.test.mjs && node scripts/check-migration-coverage.test.mjs && node --test scripts/generate-theme-bootstrap.test.mjs",
2893
+ "test:tooling": "node scripts/build-llms.test.mjs && node --test scripts/build-testing-event-registry.test.mjs && node --test scripts/create-component.test.mjs && node --test scripts/full-engine-shard.test.mjs && node --test scripts/coverage-shard-runner.test.mjs && node --test scripts/lint-ci-shard.test.mjs && node --test scripts/web-test-runner-config.test.mjs && node scripts/component-families.test.mjs && node scripts/maplibre-peer-range.test.mjs && node scripts/migrate-wa.test.mjs && node scripts/visual-regression-compare.test.mjs && node --test scripts/visual-regression-shard.test.mjs && node scripts/visual-regression-config.test.mjs && node --test scripts/check-source-policy.test.mjs scripts/check-test-assertions.test.mjs && node scripts/bundle-budgets.test.mjs && node scripts/compact-build-js.test.mjs && node scripts/compact-build-css.test.mjs && node scripts/compact-build-declarations.test.mjs && node --test scripts/normalize-mixin-declarations.test.mjs && node --test scripts/check-palette-freshness.test.mjs && node --test scripts/is-main-module.test.mjs && node scripts/manifest-compact.test.mjs && node --test scripts/viewer-fixture-generators.test.mjs && node --test scripts/strip-css-comments.test.mjs && node scripts/editor-web-types.test.mjs && node scripts/check-migration-coverage.test.mjs && node --test scripts/generate-theme-bootstrap.test.mjs",
2894
2894
  "framework-types": "node scripts/generate-framework-types.mjs",
2895
2895
  "check:framework-types": "node scripts/check-framework-types.mjs",
2896
2896
  "test:framework-types": "node scripts/generate-framework-types.test.mjs",