@aceshooting/lyra-ui 12.0.0 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/custom-elements.json +1 -1
- package/dist/autoloader.js +1 -1
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.d.ts +0 -1
- package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
- package/dist/components/charts/chart/histogram-bin.d.ts +0 -1
- package/dist/components/charts/chart/histogram-bin.js +1 -1
- package/dist/components/charts/chart/lite-chart.class.d.ts +22 -9
- package/dist/components/charts/chart/lite-chart.class.js +6 -6
- package/dist/components/conversation/code-block/code-block-shared.d.ts +4 -54
- package/dist/components/conversation/code-block/code-block-shared.js +1 -1
- package/dist/components/conversation/code-block/shiki-types.d.ts +2 -1
- package/dist/components/conversation/generation-metrics/generation-metrics.class.js +1 -1
- package/dist/components/conversation/model-select/model-select.class.d.ts +0 -3
- package/dist/components/conversation/model-select/model-select.class.js +1 -1
- package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
- package/dist/components/conversation/voice-picker/voice-picker.class.d.ts +0 -1
- package/dist/components/conversation/voice-picker/voice-picker.class.js +1 -1
- package/dist/components/data/data-grid/data-grid.class.js +1 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +0 -1
- package/dist/components/data/graph-query-builder/graph-query-builder.class.js +1 -1
- package/dist/components/data/heatmap/heatmap.class.d.ts +4 -1
- package/dist/components/data/heatmap/heatmap.class.js +2 -2
- package/dist/components/data/table/table.class.d.ts +18 -4
- package/dist/components/data/table/table.class.js +2 -2
- package/dist/components/data/table/table.styles.js +2 -1
- package/dist/components/data/timeline/timeline-cluster.d.ts +1 -0
- package/dist/components/data/timeline/timeline-cluster.js +1 -0
- package/dist/components/data/timeline/timeline-item.class.d.ts +17 -2
- package/dist/components/data/timeline/timeline-item.class.js +13 -2
- package/dist/components/data/timeline/timeline-item.styles.js +65 -0
- package/dist/components/data/timeline/timeline.class.d.ts +83 -27
- package/dist/components/data/timeline/timeline.class.js +3 -3
- package/dist/components/data/timeline/timeline.d.ts +1 -0
- package/dist/components/data/timeline/timeline.js +1 -1
- package/dist/components/data/timeline/timeline.styles.js +14 -0
- package/dist/components/forms/button/button.class.js +1 -1
- package/dist/components/forms/checkbox/checkbox.class.d.ts +0 -1
- package/dist/components/forms/checkbox/checkbox.class.js +1 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +0 -1
- package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
- package/dist/components/forms/code-editor/code-editor.class.js +1 -1
- package/dist/components/forms/color-picker/color-picker.class.js +1 -1
- package/dist/components/forms/combobox/combobox.class.d.ts +7 -1
- package/dist/components/forms/combobox/combobox.class.js +3 -2
- package/dist/components/forms/combobox/combobox.styles.js +1 -1
- package/dist/components/forms/date-picker/date-input.class.js +1 -1
- package/dist/components/forms/emoji-picker/emoji-data-loader.d.ts +0 -1
- package/dist/components/forms/input/native-time-input.class.js +1 -1
- package/dist/components/forms/input/time-input-shared.d.ts +2 -1
- package/dist/components/forms/input/time-input.class.js +1 -1
- package/dist/components/forms/locale-picker/locale-picker.class.d.ts +0 -1
- package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
- package/dist/components/forms/radio/radio-button.styles.d.ts +0 -1
- package/dist/components/forms/radio/radio-button.styles.js +1 -1
- package/dist/components/forms/radio/radio-group.class.d.ts +0 -1
- package/dist/components/forms/radio/radio-group.class.js +1 -1
- package/dist/components/forms/radio/radio.class.d.ts +0 -1
- package/dist/components/forms/radio/radio.class.js +1 -1
- package/dist/components/forms/rubric-form/rubric-form.class.d.ts +0 -1
- package/dist/components/forms/rubric-form/rubric-form.class.js +1 -1
- package/dist/components/forms/select/select.class.d.ts +0 -1
- package/dist/components/forms/select/select.class.js +1 -1
- package/dist/components/forms/slider/slider.class.d.ts +0 -1
- package/dist/components/forms/slider/slider.class.js +1 -1
- package/dist/components/forms/switch/switch.class.d.ts +0 -1
- package/dist/components/forms/switch/switch.class.js +1 -1
- package/dist/components/forms/time-range/time-range.class.d.ts +0 -1
- package/dist/components/forms/time-range/time-range.class.js +1 -1
- package/dist/components/forms/token-input/token-input.class.d.ts +0 -1
- package/dist/components/forms/token-input/token-input.class.js +1 -1
- package/dist/components/layout/dashboard-grid/layout-internal.d.ts +0 -1
- package/dist/components/layout/dashboard-grid/layout-internal.js +1 -1
- package/dist/components/layout/details/accordion-owner.d.ts +1 -1
- package/dist/components/layout/filter-bar/filter-bar.class.js +1 -1
- package/dist/components/layout/menu/menu-item.class.js +1 -1
- package/dist/components/layout/virtual-list/virtual-list.class.js +1 -1
- package/dist/components/media/av-player/av-metadata.d.ts +0 -2
- package/dist/components/media/av-player/av-metadata.js +1 -1
- package/dist/components/media/file-input/file-input.class.d.ts +0 -1
- package/dist/components/media/file-input/file-input.class.js +1 -1
- package/dist/components/media/map/map-loader.d.ts +4 -1
- package/dist/components/media/map/map.class.d.ts +50 -12
- package/dist/components/media/map/map.class.js +2 -2
- package/dist/components/overlays/overlay/popover.class.d.ts +7 -1
- package/dist/components/overlays/overlay/popover.class.js +1 -1
- package/dist/components/overlays/overlay/tooltip.class.d.ts +1 -0
- package/dist/components/overlays/overlay/tooltip.class.js +1 -1
- package/dist/components/overlays/progress/progress-shared.d.ts +0 -2
- package/dist/components/overlays/progress/progress-shared.js +1 -1
- package/dist/components/overlays/rating/rating.class.js +1 -1
- package/dist/components/retrieval/graph/graph-canvas.d.ts +10 -9
- package/dist/components/retrieval/mind-map/mind-map-layout.d.ts +0 -4
- package/dist/components/retrieval/mind-map/mind-map-layout.js +1 -1
- package/dist/components/utility/format/format-options.d.ts +0 -2
- package/dist/components/utility/format/format-options.js +1 -1
- package/dist/components/utility/icon/icon-resource.d.ts +0 -2
- package/dist/components/utility/icon/icon-resource.js +1 -1
- package/dist/components/viewers/archive-viewer/zip-resource-guard.d.ts +2 -1
- package/dist/components/viewers/docx-viewer/docx-resource-guard.d.ts +0 -3
- package/dist/components/viewers/docx-viewer/docx-resource-guard.js +1 -1
- package/dist/components/viewers/ebook-viewer/ebook-loader.d.ts +2 -1
- package/dist/components/viewers/ebook-viewer/epub-resource-guard.d.ts +0 -3
- package/dist/components/viewers/ebook-viewer/epub-resource-guard.js +1 -1
- package/dist/components/viewers/pdf-viewer/pdf-loader.d.ts +2 -2
- package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +2 -2
- package/dist/components/viewers/pptx-viewer/pptx-resource-guard.d.ts +0 -2
- package/dist/components/viewers/pptx-viewer/pptx-resource-guard.js +1 -1
- package/dist/components/viewers/spreadsheet-viewer/xlsx-resource-guard.d.ts +0 -5
- package/dist/components/viewers/spreadsheet-viewer/xlsx-resource-guard.js +1 -1
- package/dist/custom-elements-jsx.d.ts +4 -4
- package/dist/events.d.ts +15 -0
- package/dist/internal/accessibility-visibility.d.ts +1 -1
- package/dist/internal/anchor-target.d.ts +1 -3
- package/dist/internal/anchor-target.js +2 -2
- package/dist/internal/anchored-overlay-runtime.d.ts +7 -0
- package/dist/internal/anchored-overlay-runtime.js +1 -0
- package/dist/internal/announcement-text.d.ts +1 -1
- package/dist/internal/ansi.d.ts +0 -4
- package/dist/internal/ansi.js +1 -1
- package/dist/internal/aria-ownership.d.ts +2 -1
- package/dist/internal/default-strings.generated.d.ts +1 -0
- package/dist/internal/default-strings.generated.js +1 -1
- package/dist/internal/focus-navigation.d.ts +3 -2
- package/dist/internal/form-associated.d.ts +0 -1
- package/dist/internal/form-associated.js +1 -1
- package/dist/internal/form-control-labels.d.ts +0 -3
- package/dist/internal/form-control-labels.js +1 -1
- package/dist/internal/localization-runtime.js +1 -1
- package/dist/internal/localization-types.d.ts +1 -1
- package/dist/internal/localization.js +1 -1
- package/dist/internal/lyra-element.d.ts +0 -13
- package/dist/internal/nonmodal-overlay-manager.d.ts +9 -0
- package/dist/internal/nonmodal-overlay-manager.js +1 -0
- package/dist/internal/overlay-manager.d.ts +4 -20
- package/dist/internal/overlay-manager.js +1 -1
- package/dist/internal/overlay-stack.d.ts +66 -0
- package/dist/internal/overlay-stack.js +1 -0
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/dist/internal/positioner.js +1 -1
- package/dist/internal/text-quote.d.ts +1 -1
- package/dist/lyra.d.ts +2 -3
- package/dist/svelte.d.ts +4 -4
- package/dist/translations/ar.js +1 -1
- package/dist/translations/de.js +1 -1
- package/dist/translations/es.js +1 -1
- package/dist/translations/fa.js +1 -1
- package/dist/translations/fr.js +1 -1
- package/dist/translations/he.js +1 -1
- package/dist/translations/ja.js +1 -1
- package/dist/translations/pt-BR.js +1 -1
- package/dist/translations/ru.js +1 -1
- package/dist/translations/zh-CN.js +1 -1
- package/dist/utilities/localization.js +1 -1
- package/dist/vue.d.ts +4 -4
- package/llms/components/lr-combobox.md +42 -0
- package/llms/components/lr-heatmap.md +4 -1
- package/llms/components/lr-lite-chart.md +20 -8
- package/llms/components/lr-map.md +51 -21
- package/llms/components/lr-option.md +42 -0
- package/llms/components/lr-popover.md +39 -0
- package/llms/components/lr-table.md +7 -3
- package/llms/components/lr-timeline-item.md +49 -24
- package/llms/components/lr-timeline.md +49 -24
- package/llms-full.txt +220 -56
- package/package.json +3 -4
- package/vscode-css-data.json +21 -0
- package/vscode-html-data.json +12 -6
- package/web-types.json +47 -16
|
@@ -16,7 +16,8 @@ import{css}from"lit";const styles=css`
|
|
|
16
16
|
contain-intrinsic-inline-size: var(--lr-size-20rem);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
:host([scroll-mode='page']) [part='base']
|
|
19
|
+
:host([scroll-mode='page']) [part='base'],
|
|
20
|
+
:host([scroll-mode='auto']) [part='base']:not([data-scroll-overflow]) {
|
|
20
21
|
overflow: visible;
|
|
21
22
|
max-block-size: none;
|
|
22
23
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const SET_TIMELINE_CLUSTER_PRESENTATION=Symbol.for("@aceshooting/lyra-ui/timeline/cluster-presentation/v1"),OBSERVE_TIMELINE_ITEM_TIMESTAMP=Symbol.for("@aceshooting/lyra-ui/timeline/timestamp-observer/v1");function isTimelineClusterItemContract(value){const candidate=value;return typeof candidate[SET_TIMELINE_CLUSTER_PRESENTATION]=="function"&&typeof candidate[OBSERVE_TIMELINE_ITEM_TIMESTAMP]=="function"}export{OBSERVE_TIMELINE_ITEM_TIMESTAMP,SET_TIMELINE_CLUSTER_PRESENTATION,isTimelineClusterItemContract};
|
|
@@ -21,8 +21,12 @@ import type { LyraVariant } from '../../../internal/variants.js';
|
|
|
21
21
|
* `::slotted(:last-child)` rule (see that component's stylesheet) — no JS coordination between the
|
|
22
22
|
* two components is needed anywhere in this mechanism.
|
|
23
23
|
*
|
|
24
|
-
* A pure display row: no events, no keyboard interaction, and no selection/expansion
|
|
25
|
-
* own — a deliberate scope decision, not an oversight.
|
|
24
|
+
* A pure display row by default: no events, no keyboard interaction, and no selection/expansion
|
|
25
|
+
* state of its own — a deliberate scope decision, not an oversight. When a parent timeline opts
|
|
26
|
+
* into collision clustering, the first item in each author-ordered group temporarily represents
|
|
27
|
+
* that group with a native count button in this item's list position; activation still belongs to
|
|
28
|
+
* the parent timeline and emits its `lr-cluster-activate` event. An earlier "interactive row"
|
|
29
|
+
* design (mirroring
|
|
26
30
|
* `<lr-conversation-item>`'s clickable `role="button"` row) was considered and dropped: this
|
|
27
31
|
* component's `title` and `description` are slots that routinely contain focusable content of their
|
|
28
32
|
* own (a link, a button) — wrapping them in an ancestor `role="button"` would trip axe's
|
|
@@ -63,6 +67,9 @@ import type { LyraVariant } from '../../../internal/variants.js';
|
|
|
63
67
|
* fallback. Hidden entirely when there's nothing to show.
|
|
64
68
|
* @csspart description - Wrapper around the `description` slot. Hidden entirely when the slot is
|
|
65
69
|
* empty.
|
|
70
|
+
* @csspart cluster - The native count-marker button rendered while this item represents a parent
|
|
71
|
+
* timeline collision cluster; retains the shared 40px minimum action surface.
|
|
72
|
+
* @csspart cluster-count - The painted count pill inside a representative cluster button.
|
|
66
73
|
* @cssprop [--lr-timeline-marker-size=var(--lr-size-1-25rem)] - Diameter of the marker circle
|
|
67
74
|
* (both inline-size and block-size, so the default dot stays circular). Inherits from theme
|
|
68
75
|
* ancestors.
|
|
@@ -79,6 +86,11 @@ import type { LyraVariant } from '../../../internal/variants.js';
|
|
|
79
86
|
* @cssprop [--lr-timeline-active-ring-color=var(--lr-timeline-marker-color)] - Static outline color
|
|
80
87
|
* for the current/in-progress marker. The outline remains visible when reduced motion disables
|
|
81
88
|
* the optional pulse animation.
|
|
89
|
+
* @cssprop [--lr-timeline-cluster-size=var(--lr-size-2rem)] - Minimum inline and block size of the
|
|
90
|
+
* painted cluster count pill. Its containing button retains the shared 40px minimum action
|
|
91
|
+
* surface.
|
|
92
|
+
* @cssprop [--lr-timeline-cluster-bg=var(--lr-color-brand)] - Cluster count pill background.
|
|
93
|
+
* @cssprop [--lr-timeline-cluster-color=var(--lr-color-on-brand)] - Cluster count pill foreground.
|
|
82
94
|
* @status stable
|
|
83
95
|
* @since 4.0.0
|
|
84
96
|
*/
|
|
@@ -110,6 +122,9 @@ export declare class LyraTimelineItem extends LyraElement {
|
|
|
110
122
|
private hasIconSlot;
|
|
111
123
|
private hasTimestampSlot;
|
|
112
124
|
private hasDescriptionSlot;
|
|
125
|
+
private clusterPresentation?;
|
|
126
|
+
private readonly timestampObservers;
|
|
127
|
+
private timestampObserversReady;
|
|
113
128
|
connectedCallback(): void;
|
|
114
129
|
protected willUpdate(changed: PropertyValues): void;
|
|
115
130
|
protected updated(changed: PropertyValues): void;
|
|
@@ -1,4 +1,15 @@
|
|
|
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,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{styles}from"./timeline-item.styles.js";import{getDateTimeFormat}from"../../../internal/intl-cache.js";const timelineItemVariantConverter={fromAttribute(value){return normalizeTimelineItemVariant(value)},toAttribute(value){return value==="neutral"?null:value}},normalizeTimelineItemVariant=value=>value==="brand"||value==="success"||value==="warning"||value==="danger"?value:"neutral";class LyraTimelineItem extends LyraElement{constructor(){super(...arguments),this.sync=!1,this._variant="neutral",this.active=!1,this.hasIconSlot=!1,this.hasTimestampSlot=!1,this.hasDescriptionSlot=!1,this.onIconSlotChange=()=>{const markerIconSlot=this.renderRoot.querySelector('slot[name="marker-icon"]');this.hasIconSlot=!!markerIconSlot?.assignedElements({flatten:!0}).length},this.onTimestampSlotChange=e=>{this.hasTimestampSlot=e.target.assignedElements({flatten:!0}).length>0},this.onDescriptionSlotChange=e=>{this.hasDescriptionSlot=e.target.assignedElements({flatten:!0}).length>0}}static{this.styles=[LyraElement.styles,styles]}get variant(){return this._variant}set variant(value){const normalized=normalizeTimelineItemVariant(value),previous=this._variant;if(previous===normalized){value!==normalized&&this.requestUpdate("variant",previous);return}this._variant=normalized,this.requestUpdate("variant",previous)}connectedCallback(){super.connectedCallback(),this.setAttribute("role","listitem")}willUpdate(changed){super.willUpdate(changed),this.setAttribute("aria-current",String(this.active))}updated(changed){if(super.updated(changed),changed.has("variant")){const reflected=timelineItemVariantConverter.toAttribute(this.variant);reflected===null?this.removeAttribute("variant"):this.getAttribute("variant")!==reflected&&this.setAttribute("variant",reflected)}}get normalizedTimestamp(){if(this.timestamp===void 0)return;const date=this.timestamp instanceof Date?this.timestamp:new Date(this.timestamp);return Number.isNaN(date.getTime())?void 0:date}render(){
|
|
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,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{styles}from"./timeline-item.styles.js";import{getDateTimeFormat}from"../../../internal/intl-cache.js";import{OBSERVE_TIMELINE_ITEM_TIMESTAMP,SET_TIMELINE_CLUSTER_PRESENTATION}from"./timeline-cluster.js";const timelineItemVariantConverter={fromAttribute(value){return normalizeTimelineItemVariant(value)},toAttribute(value){return value==="neutral"?null:value}},normalizeTimelineItemVariant=value=>value==="brand"||value==="success"||value==="warning"||value==="danger"?value:"neutral";class LyraTimelineItem extends LyraElement{constructor(){super(...arguments),this.sync=!1,this._variant="neutral",this.active=!1,this.hasIconSlot=!1,this.hasTimestampSlot=!1,this.hasDescriptionSlot=!1,this.timestampObservers=new Set,this.timestampObserversReady=!1,this.onIconSlotChange=()=>{const markerIconSlot=this.renderRoot.querySelector('slot[name="marker-icon"]');this.hasIconSlot=!!markerIconSlot?.assignedElements({flatten:!0}).length},this.onTimestampSlotChange=e=>{this.hasTimestampSlot=e.target.assignedElements({flatten:!0}).length>0},this.onDescriptionSlotChange=e=>{this.hasDescriptionSlot=e.target.assignedElements({flatten:!0}).length>0}}static{this.styles=[LyraElement.styles,styles]}get variant(){return this._variant}set variant(value){const normalized=normalizeTimelineItemVariant(value),previous=this._variant;if(previous===normalized){value!==normalized&&this.requestUpdate("variant",previous);return}this._variant=normalized,this.requestUpdate("variant",previous)}[SET_TIMELINE_CLUSTER_PRESENTATION](presentation){const current=this.clusterPresentation;current===presentation||current!==void 0&&presentation!==void 0&¤t.accessibleLabel===presentation.accessibleLabel&¤t.countText===presentation.countText&¤t.activate===presentation.activate||(this.clusterPresentation=presentation)}[OBSERVE_TIMELINE_ITEM_TIMESTAMP](observer,observe){observe?this.timestampObservers.add(observer):this.timestampObservers.delete(observer)}connectedCallback(){super.connectedCallback(),this.setAttribute("role","listitem")}willUpdate(changed){super.willUpdate(changed),this.clusterPresentation?this.removeAttribute("aria-current"):this.setAttribute("aria-current",String(this.active))}updated(changed){if(super.updated(changed),changed.has("variant")){const reflected=timelineItemVariantConverter.toAttribute(this.variant);reflected===null?this.removeAttribute("variant"):this.getAttribute("variant")!==reflected&&this.setAttribute("variant",reflected)}this.timestampObserversReady&&changed.has("timestamp")&&this.scheduleAfterUpdate(()=>{for(const observer of[...this.timestampObservers])observer()},"timeline-item-timestamp-observers"),this.timestampObserversReady=!0}get normalizedTimestamp(){if(this.timestamp===void 0)return;const date=this.timestamp instanceof Date?this.timestamp:new Date(this.timestamp);return Number.isNaN(date.getTime())?void 0:date}render(){if(this.clusterPresentation)return html`
|
|
2
|
+
<button
|
|
3
|
+
part="cluster"
|
|
4
|
+
type="button"
|
|
5
|
+
aria-label=${this.clusterPresentation.accessibleLabel}
|
|
6
|
+
@click=${this.clusterPresentation.activate}
|
|
7
|
+
>
|
|
8
|
+
<span part="cluster-count" aria-hidden="true"
|
|
9
|
+
>${this.clusterPresentation.countText}</span
|
|
10
|
+
>
|
|
11
|
+
</button>
|
|
12
|
+
`;const ts=this.normalizedTimestamp,showTimestampFallback=!this.hasTimestampSlot&&ts!==void 0,showTimestamp=this.hasTimestampSlot||ts!==void 0,absolute=ts?getDateTimeFormat(this.effectiveLocale||void 0,{dateStyle:"long",timeStyle:"short"}).format(ts):"";return html`
|
|
2
13
|
<div part="base">
|
|
3
14
|
<div part="track">
|
|
4
15
|
<span
|
|
@@ -37,4 +48,4 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
37
48
|
</span>
|
|
38
49
|
</div>
|
|
39
50
|
</div>
|
|
40
|
-
`}}__decorate([property({attribute:!1})],LyraTimelineItem.prototype,"timestamp",void 0),__decorate([property({type:Boolean})],LyraTimelineItem.prototype,"sync",void 0),__decorate([property({reflect:!0,converter:timelineItemVariantConverter})],LyraTimelineItem.prototype,"variant",null),__decorate([property({type:Boolean,reflect:!0})],LyraTimelineItem.prototype,"active",void 0),__decorate([state()],LyraTimelineItem.prototype,"hasIconSlot",void 0),__decorate([state()],LyraTimelineItem.prototype,"hasTimestampSlot",void 0),__decorate([state()],LyraTimelineItem.prototype,"hasDescriptionSlot",void 0);export{LyraTimelineItem};
|
|
51
|
+
`}}__decorate([property({attribute:!1})],LyraTimelineItem.prototype,"timestamp",void 0),__decorate([property({type:Boolean})],LyraTimelineItem.prototype,"sync",void 0),__decorate([property({reflect:!0,converter:timelineItemVariantConverter})],LyraTimelineItem.prototype,"variant",null),__decorate([property({type:Boolean,reflect:!0})],LyraTimelineItem.prototype,"active",void 0),__decorate([state()],LyraTimelineItem.prototype,"hasIconSlot",void 0),__decorate([state()],LyraTimelineItem.prototype,"hasTimestampSlot",void 0),__decorate([state()],LyraTimelineItem.prototype,"hasDescriptionSlot",void 0),__decorate([state()],LyraTimelineItem.prototype,"clusterPresentation",void 0);export{LyraTimelineItem};
|
|
@@ -128,4 +128,69 @@ import{css}from"lit";const styles=css`
|
|
|
128
128
|
[part='description'][hidden] {
|
|
129
129
|
display: none;
|
|
130
130
|
}
|
|
131
|
+
|
|
132
|
+
[part='cluster'] {
|
|
133
|
+
display: inline-flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
box-sizing: border-box;
|
|
137
|
+
min-inline-size: var(--lr-icon-button-size);
|
|
138
|
+
min-block-size: var(--lr-icon-button-size);
|
|
139
|
+
margin: 0;
|
|
140
|
+
padding: 0;
|
|
141
|
+
border: 0;
|
|
142
|
+
background: transparent;
|
|
143
|
+
color: inherit;
|
|
144
|
+
font: inherit;
|
|
145
|
+
cursor: pointer;
|
|
146
|
+
-webkit-tap-highlight-color: transparent;
|
|
147
|
+
}
|
|
148
|
+
[part='cluster-count'] {
|
|
149
|
+
display: inline-flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
box-sizing: border-box;
|
|
153
|
+
min-inline-size: var(--lr-timeline-cluster-size, var(--lr-size-2rem));
|
|
154
|
+
min-block-size: var(--lr-timeline-cluster-size, var(--lr-size-2rem));
|
|
155
|
+
padding-inline: var(--lr-space-xs);
|
|
156
|
+
border-radius: var(--lr-radius-pill);
|
|
157
|
+
background: var(--lr-timeline-cluster-bg, var(--lr-color-brand));
|
|
158
|
+
color: var(--lr-timeline-cluster-color, var(--lr-color-on-brand));
|
|
159
|
+
font-size: var(--lr-font-size-sm);
|
|
160
|
+
font-weight: var(--lr-font-weight-semibold);
|
|
161
|
+
line-height: var(--lr-line-height-snug);
|
|
162
|
+
}
|
|
163
|
+
[part='cluster']:hover [part='cluster-count'] {
|
|
164
|
+
background: color-mix(
|
|
165
|
+
in oklab,
|
|
166
|
+
var(--lr-timeline-cluster-bg, var(--lr-color-brand)),
|
|
167
|
+
var(--lr-color-mix-partner) var(--lr-color-mix-hover)
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
[part='cluster']:active [part='cluster-count'] {
|
|
171
|
+
background: color-mix(
|
|
172
|
+
in oklab,
|
|
173
|
+
var(--lr-timeline-cluster-bg, var(--lr-color-brand)),
|
|
174
|
+
var(--lr-color-mix-partner) var(--lr-color-mix-active)
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
[part='cluster']:focus-visible {
|
|
178
|
+
outline: var(--lr-focus-ring-width) solid var(--lr-focus-ring-color);
|
|
179
|
+
outline-offset: var(--lr-focus-ring-offset);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@media (forced-colors: active) {
|
|
183
|
+
[part='cluster-count'] {
|
|
184
|
+
border: var(--lr-border-width-medium) solid ButtonText;
|
|
185
|
+
background: ButtonFace;
|
|
186
|
+
color: ButtonText;
|
|
187
|
+
forced-color-adjust: auto;
|
|
188
|
+
}
|
|
189
|
+
[part='cluster']:hover [part='cluster-count'] {
|
|
190
|
+
border-color: Highlight;
|
|
191
|
+
}
|
|
192
|
+
[part='cluster']:focus-visible {
|
|
193
|
+
outline-color: Highlight;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
131
196
|
`;export{styles};
|
|
@@ -1,30 +1,46 @@
|
|
|
1
1
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../../internal/lyra-element.js';
|
|
3
3
|
import type { LyraOrientation } from '../../../internal/shared-unions.js';
|
|
4
|
+
import type { LyraTimelineItem } from './timeline-item.class.js';
|
|
4
5
|
/** How a timeline distributes its items along the main axis. */
|
|
5
6
|
export type LyraTimelineScale = 'flow' | 'time';
|
|
6
7
|
/** How `scale="time"` handles items that land on (nearly) the same position. */
|
|
7
|
-
export type LyraTimelineCollision = 'overlap' | 'stack';
|
|
8
|
+
export type LyraTimelineCollision = 'overlap' | 'stack' | 'cluster';
|
|
9
|
+
export interface LyraTimelineClusterActivateDetail {
|
|
10
|
+
/** The clustered `<lr-timeline-item>` elements, as a frozen snapshot in document order. */
|
|
11
|
+
readonly items: readonly LyraTimelineItem[];
|
|
12
|
+
}
|
|
13
|
+
export interface LyraTimelineEventMap {
|
|
14
|
+
'lr-cluster-activate': CustomEvent<LyraTimelineClusterActivateDetail>;
|
|
15
|
+
}
|
|
8
16
|
/**
|
|
9
17
|
* `<lr-timeline>` — an ordered, connected sequence of past-event rows (an audit trail, an agent
|
|
10
18
|
* action history, a changelog) composed from `<lr-timeline-item>` light-DOM children, joined by a
|
|
11
19
|
* continuous connecting rail. First-party invention: no Web Awesome/Shoelace counterpart exists, so
|
|
12
20
|
* this follows the library's own established conventions rather than mirroring an upstream API.
|
|
13
21
|
*
|
|
14
|
-
* A
|
|
15
|
-
* `<lr-avatar>`/`<lr-skeleton>`.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
22
|
+
* A read-only declarative display by default — same zero-interaction shape as `<lr-badge>`/
|
|
23
|
+
* `<lr-avatar>`/`<lr-skeleton>`. The opt-in `scale="time" collision="cluster"` presentation is the
|
|
24
|
+
* one exception: overlapping events collapse behind a native count button and activation emits
|
|
25
|
+
* their exact element identities so the consumer can open its own popover, dialog, or detail
|
|
26
|
+
* view. The component does not select, expand, reorder, or mutate the content of those items.
|
|
19
27
|
*
|
|
20
|
-
* No
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
28
|
+
* No roving-tabindex or per-event selection model is introduced. Timeline items remain passive;
|
|
29
|
+
* each cluster marker is an independent native `<button>` in the normal Tab sequence, so pointer,
|
|
30
|
+
* Enter, and Space activation require no custom keyboard model. Not a form-associated control —
|
|
31
|
+
* no value to submit, no label/hint/error chrome.
|
|
32
|
+
*
|
|
33
|
+
* The first member in document order represents a cluster: its ordinary shadow row is temporarily
|
|
34
|
+
* replaced by the count action while the remaining members are hidden. This preserves the author's
|
|
35
|
+
* list and Tab order instead of appending visually positioned controls after the slot. The action
|
|
36
|
+
* exposes `cluster` and `cluster-count` parts on that representative `<lr-timeline-item>`.
|
|
25
37
|
*
|
|
26
38
|
* @customElement lr-timeline
|
|
27
39
|
* @slot - `<lr-timeline-item>` children, in display order.
|
|
40
|
+
* @event lr-cluster-activate - A `collision="cluster"` count marker was activated by pointer,
|
|
41
|
+
* Enter, or Space. `detail: { items }` contains a fresh frozen snapshot of the member
|
|
42
|
+
* `<lr-timeline-item>` elements in document order. Non-cancelable notification; the timeline has
|
|
43
|
+
* no built-in expansion or selection action to veto.
|
|
28
44
|
* @csspart base - The root wrapper. `role="list"` lives here directly (a timeline isn't a navigation
|
|
29
45
|
* landmark, so it doesn't need a two-layer `base`+`list` split). Flex container: `flex-direction:
|
|
30
46
|
* column` in `vertical` orientation (the default), `flex-direction: row` (with `overflow-x: auto`,
|
|
@@ -38,6 +54,10 @@ export type LyraTimelineCollision = 'overlap' | 'stack';
|
|
|
38
54
|
* stacked by `collision="stack"`. Each collision lane is indented one step further, so a wider
|
|
39
55
|
* marker can claim more room without the lanes overlapping again. Ignored unless both
|
|
40
56
|
* `scale="time"` and `collision="stack"` are set.
|
|
57
|
+
* @cssprop [--lr-timeline-cluster-size=var(--lr-size-2rem)] - Minimum inline and block size of the
|
|
58
|
+
* painted count pill. Its containing button retains the shared 40px minimum action surface.
|
|
59
|
+
* @cssprop [--lr-timeline-cluster-bg=var(--lr-color-brand)] - Cluster count pill background.
|
|
60
|
+
* @cssprop [--lr-timeline-cluster-color=var(--lr-color-on-brand)] - Cluster count pill foreground.
|
|
41
61
|
* @cssprop [--lr-timeline-time-extent=var(--lr-size-20rem)] - Distance the `scale="time"` axis
|
|
42
62
|
* distributes items along: `block-size` when vertical, `inline-size` when horizontal. Time-scaled
|
|
43
63
|
* items are absolutely positioned, and a percentage offset against an auto-sized track resolves
|
|
@@ -48,7 +68,11 @@ export type LyraTimelineCollision = 'overlap' | 'stack';
|
|
|
48
68
|
* @status stable
|
|
49
69
|
* @since 4.0.0
|
|
50
70
|
*/
|
|
51
|
-
export declare class LyraTimeline extends LyraElement {
|
|
71
|
+
export declare class LyraTimeline extends LyraElement<LyraTimelineEventMap> {
|
|
72
|
+
protected static readonly immutableEventDetails: readonly string[];
|
|
73
|
+
protected static readonly identityEventDetailProperties: Readonly<{
|
|
74
|
+
'lr-cluster-activate': readonly string[];
|
|
75
|
+
}>;
|
|
52
76
|
static styles: import("lit").CSSResultGroup[];
|
|
53
77
|
/** `'vertical'` (the default) lays items out in a column, the primary/most-common use case — an
|
|
54
78
|
* audit trail or agent history reads top-to-bottom. `'horizontal'` lays them out in a row.
|
|
@@ -67,9 +91,8 @@ export declare class LyraTimeline extends LyraElement {
|
|
|
67
91
|
*
|
|
68
92
|
* `'time'` needs a definite extent to distribute along, which comes from
|
|
69
93
|
* `--lr-timeline-time-extent` (default `20rem` block-size when vertical, inline-size when
|
|
70
|
-
* horizontal). Items are absolutely positioned within it
|
|
71
|
-
*
|
|
72
|
-
* per-event selection is a different component than this deliberately passive one.
|
|
94
|
+
* horizontal). Items are absolutely positioned within it. The `collision` property controls
|
|
95
|
+
* whether nearby items overlap, fan into lanes, or collapse behind an activatable count marker.
|
|
73
96
|
*
|
|
74
97
|
* An item with no `timestamp` this component can parse (including one whose timestamp comes only
|
|
75
98
|
* from the `timestamp` slot, which carries no machine-readable instant) keeps document order and
|
|
@@ -83,13 +106,13 @@ export declare class LyraTimeline extends LyraElement {
|
|
|
83
106
|
*
|
|
84
107
|
* `'overlap'` (the default, and the only previous behavior) leaves them stacked on top of one
|
|
85
108
|
* another. `'stack'` offsets each colliding item along the **cross** axis instead, so a dense
|
|
86
|
-
* chronology
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
109
|
+
* chronology with many same-period events stays readable. `'cluster'` represents each group of
|
|
110
|
+
* overlapping items with one author-ordered member's count marker. Its collision window grows
|
|
111
|
+
* from the ordinary 1.5%
|
|
112
|
+
* floor to the rendered count button's footprint on the currently allocated axis, preventing
|
|
113
|
+
* interactive markers from overlapping after an allocation or themed-size change. Activating it
|
|
114
|
+
* emits `lr-cluster-activate` with the member elements but does not select or expand them. Ignored
|
|
115
|
+
* unless `scale="time"`.
|
|
93
116
|
*/
|
|
94
117
|
private _collision;
|
|
95
118
|
get collision(): LyraTimelineCollision;
|
|
@@ -107,6 +130,14 @@ export declare class LyraTimeline extends LyraElement {
|
|
|
107
130
|
* `aria-label` stays empty. */
|
|
108
131
|
accessibleLabel?: string;
|
|
109
132
|
private slottedCount;
|
|
133
|
+
private collisionClusters;
|
|
134
|
+
private readonly managedClusterHiddenItems;
|
|
135
|
+
private readonly managedClusterRepresentatives;
|
|
136
|
+
private readonly clusterActivations;
|
|
137
|
+
private readonly timestampObservedItems;
|
|
138
|
+
private clusterMeasurementFrame?;
|
|
139
|
+
private clusterMeasurementView?;
|
|
140
|
+
private focusRepairGeneration;
|
|
110
141
|
/** Gates the horizontal [part='base'] edge fade on the strip genuinely overflowing, with
|
|
111
142
|
* one-sided/RTL-aware logical-edge state -- see --lr-scroll-fade-size and timeline.styles.ts.
|
|
112
143
|
* Harmless in the vertical default, where the strip never scrolls inline and the attribute
|
|
@@ -115,14 +146,19 @@ export declare class LyraTimeline extends LyraElement {
|
|
|
115
146
|
* below -- an item's own intrinsic content (a longer title, an icon loading in) can grow
|
|
116
147
|
* scrollWidth without [part='base']'s own border box changing at all. */
|
|
117
148
|
private scrollOverflow;
|
|
149
|
+
connectedCallback(): void;
|
|
150
|
+
disconnectedCallback(): void;
|
|
118
151
|
protected willUpdate(changed: PropertyValues): void;
|
|
119
152
|
protected updated(changed: PropertyValues): void;
|
|
120
153
|
private countTimelineItems;
|
|
121
154
|
firstUpdated(changed: PropertyValues): void;
|
|
122
|
-
/** Read-only, live-updated count of
|
|
123
|
-
* for building a `"{count} events"` header without
|
|
155
|
+
/** Read-only, live-updated count of default-slot `<lr-timeline-item>` assignments, including
|
|
156
|
+
* flattened forwarding slots — handy for building a `"{count} events"` header without
|
|
157
|
+
* hand-counting DOM children. */
|
|
124
158
|
get itemCount(): number;
|
|
125
159
|
private onSlotChange;
|
|
160
|
+
private onTimelineItemTimestampChange;
|
|
161
|
+
private syncTimestampObservers;
|
|
126
162
|
/** The slotted `<lr-timeline-item>` children, in document order. */
|
|
127
163
|
private timelineItems;
|
|
128
164
|
/** The axis bounds: an explicitly pinned pair when both ends are finite and ordered, otherwise
|
|
@@ -134,9 +170,8 @@ export declare class LyraTimeline extends LyraElement {
|
|
|
134
170
|
* timeline.styles.ts's `scale="time"` rules.
|
|
135
171
|
*
|
|
136
172
|
* Deliberately a style write on the light-DOM child rather than a wrapper element per item: the
|
|
137
|
-
* component
|
|
138
|
-
*
|
|
139
|
-
* property is removed again in `'flow'`, so toggling back leaves no residue.
|
|
173
|
+
* component never mutates its children's content or structure. The private position properties
|
|
174
|
+
* and cluster visibility marker are presentation-only and are removed when their modes end.
|
|
140
175
|
*/
|
|
141
176
|
private applyTimeScale;
|
|
142
177
|
/**
|
|
@@ -149,6 +184,27 @@ export declare class LyraTimeline extends LyraElement {
|
|
|
149
184
|
* clears every lane rather than leaving stale offsets on some children.
|
|
150
185
|
*/
|
|
151
186
|
private applyCollisionLanes;
|
|
187
|
+
/** Groups sorted offsets into bounded collision windows. Each window is anchored at its first
|
|
188
|
+
* item rather than chained transitively through every adjacent neighbour, so a large uniformly
|
|
189
|
+
* dense history becomes a sequence of useful count markers instead of one axis-wide group. */
|
|
190
|
+
private buildCollisionClusters;
|
|
191
|
+
/** The minimum fraction shared with stack mode, widened when the rendered native actions need
|
|
192
|
+
* more of the allocated axis to avoid overlapping hit targets. Re-evaluated after every cluster
|
|
193
|
+
* render and by the existing owner-realm ResizeObserver attached to the base and actions. */
|
|
194
|
+
private clusterCollisionThreshold;
|
|
195
|
+
/** Coalesces ResizeObserver-driven membership writes into the next owner-realm frame. Updating
|
|
196
|
+
* observed cluster actions synchronously inside their observer callback would create a resize
|
|
197
|
+
* notification loop whenever a larger count changes the action's footprint. */
|
|
198
|
+
private scheduleClusterMeasurement;
|
|
199
|
+
private cancelClusterMeasurement;
|
|
200
|
+
private sameClusters;
|
|
201
|
+
private captureClusterFocusRepair;
|
|
202
|
+
private scheduleClusterFocusRepair;
|
|
203
|
+
private applyCollisionClusters;
|
|
204
|
+
private syncClusterPresentations;
|
|
205
|
+
private restoreClusterPresentation;
|
|
206
|
+
private restoreClusterVisibility;
|
|
207
|
+
private activateCluster;
|
|
152
208
|
render(): TemplateResult;
|
|
153
209
|
}
|
|
154
210
|
declare global {
|
|
@@ -1,5 +1,5 @@
|
|
|
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}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{tag}from"../../../internal/prefix.js";import{observeScrollOverflow}from"../../../internal/scroll-overflow.js";import{styles}from"./timeline.styles.js";import{LYRA_DEFAULT_timeline}from"../../../internal/default-strings.generated.js";const normalizeTimelineOrientation=value=>value==="horizontal"?"horizontal":"vertical",normalizeTimelineScale=value=>value==="time"?"time":"flow",normalizeTimelineCollision=value=>value==="stack"?"stack":"overlap",TIMELINE_COLLISION_THRESHOLD=.015;function itemEpochMs(element){const raw=element.timestamp;if(raw==null)return null;const ms=(raw instanceof Date?raw:typeof raw=="number"?new Date(raw):new Date(String(raw))).getTime();return Number.isFinite(ms)?ms:null}class LyraTimeline extends LyraElement{constructor(){super(...arguments),this._orientation="vertical",this._scale="flow",this._collision="overlap",this.slottedCount=0,this.scrollOverflow=observeScrollOverflow(this,()=>this.renderRoot.querySelector("[part='base']")),this.onSlotChange=e=>{this.slottedCount=this.countTimelineItems(e.target),this.applyTimeScale()}}static{this.defaultStrings={...super.defaultStrings,timeline:LYRA_DEFAULT_timeline}}static{this.styles=[LyraElement.styles,styles]}get orientation(){return this._orientation}set orientation(value){const normalized=normalizeTimelineOrientation(value),previous=this._orientation;if(previous===normalized){value!==normalized&&this.requestUpdate("orientation",previous);return}this._orientation=normalized,this.requestUpdate("orientation",previous)}get scale(){return this._scale}set scale(value){const normalized=normalizeTimelineScale(value),previous=this._scale;if(previous===normalized){value!==normalized&&this.requestUpdate("scale",previous);return}this._scale=normalized,this.requestUpdate("scale",previous)}get collision(){return this._collision}set collision(value){const normalized=normalizeTimelineCollision(value),previous=this._collision;if(previous===normalized){value!==normalized&&this.requestUpdate("collision",previous);return}this._collision=normalized,this.requestUpdate("collision",previous)}willUpdate(changed){super.willUpdate(changed),this.hasUpdated||(this.slottedCount=Array.from(this.children).filter(element=>!element.getAttribute("slot")&&element.localName===tag("timeline-item")).length)}updated(changed){super.updated(changed),this.scrollOverflow.observeExtra(this.timelineItems()),changed.has("orientation")&&this.getAttribute("orientation")!==this.orientation&&this.setAttribute("orientation",this.orientation),(changed.has("scale")||changed.has("collision")||changed.has("rangeStart")||changed.has("rangeEnd"))&&this.applyTimeScale()}countTimelineItems(slot){return slot.assignedElements({flatten:!0}).filter(element=>element.localName===tag("timeline-item")).length}firstUpdated(changed){super.firstUpdated(changed);const slot=this.shadowRoot.querySelector("slot");this.slottedCount=this.countTimelineItems(slot),this.applyTimeScale()}get itemCount(){return this.slottedCount}timelineItems(){const slot=this.shadowRoot?.querySelector("slot");return slot?slot.assignedElements({flatten:!0}).filter(element=>element.localName===tag("timeline-item")):[]}timeRange(stamps){const pinnedStart=this.rangeStart==null?null:itemEpochMs({timestamp:this.rangeStart}),pinnedEnd=this.rangeEnd==null?null:itemEpochMs({timestamp:this.rangeEnd});if(pinnedStart!==null&&pinnedEnd!==null&&pinnedEnd>pinnedStart)return[pinnedStart,pinnedEnd];const finite=stamps.filter(value=>value!==null);if(finite.length<2)return null;const lo=Math.min(...finite),hi=Math.max(...finite);return hi>lo?[lo,hi]:null}applyTimeScale(){const items=this.timelineItems();if(this.scale!=="time"){for(const item of items)item.style.removeProperty("--_lr-timeline-item-offset"),item.style.removeProperty("--_lr-timeline-item-lane");return}const stamps=items.map(item=>itemEpochMs(item)),range=this.timeRange(stamps),lastIndex=Math.max(1,items.length-1),offsets=new Array(items.length).fill(0);items.forEach((item,index)=>{const stamp=stamps[index]??null,ratio=range&&stamp!==null?(stamp-range[0])/(range[1]-range[0]):index/lastIndex,clamped=Math.min(1,Math.max(0,ratio));offsets[index]=clamped,item.style.setProperty("--_lr-timeline-item-offset",`${clamped*100}%`)}),this.applyCollisionLanes(items,offsets)}applyCollisionLanes(items,offsets){if(this.collision!=="stack"){for(const item of items)item.style.removeProperty("--_lr-timeline-item-lane");return}const order=items.map((_,index)=>index).sort((a,b)=>(offsets[a]??0)-(offsets[b]??0)),laneTails=[],lanes=new Array(items.length).fill(0);for(const index of order){const offset=offsets[index]??0;let lane=laneTails.findIndex(tail=>offset-tail>=TIMELINE_COLLISION_THRESHOLD);lane===-1&&(lane=laneTails.length),laneTails[lane]=offset,lanes[index]=lane}items.forEach((item,index)=>{item.style.setProperty("--_lr-timeline-item-lane",String(lanes[index]??0))})}render(){return html`
|
|
2
|
-
<div part="base" role="list" aria-label=${this.accessibleLabel==null?this.localize("timeline"):this.accessibleLabel}>
|
|
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}from"lit";import{property,state}from"lit/decorators.js";import{applyComposedFocusRepair,captureComposedFocusRepair,collectComposedFocusTargets}from"../../../internal/focus-navigation.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{LyraElement}from"../../../internal/lyra-element.js";import{tag}from"../../../internal/prefix.js";import{observeScrollOverflow}from"../../../internal/scroll-overflow.js";import{OBSERVE_TIMELINE_ITEM_TIMESTAMP,SET_TIMELINE_CLUSTER_PRESENTATION,isTimelineClusterItemContract}from"./timeline-cluster.js";import{styles}from"./timeline.styles.js";import{LYRA_DEFAULT_timeline,LYRA_DEFAULT_timelineClusterCount}from"../../../internal/default-strings.generated.js";const normalizeTimelineOrientation=value=>value==="horizontal"?"horizontal":"vertical",normalizeTimelineScale=value=>value==="time"?"time":"flow",normalizeTimelineCollision=value=>value==="stack"||value==="cluster"?value:"overlap",EMPTY_TIMELINE_CLUSTERS=Object.freeze([]),CLUSTER_HIDDEN_ATTRIBUTE="data-lr-timeline-cluster-hidden",TIMELINE_COLLISION_THRESHOLD=.015;function timelineEpochMs(raw){if(raw==null)return null;const ms=(raw instanceof Date?raw:typeof raw=="number"?new Date(raw):new Date(String(raw))).getTime();return Number.isFinite(ms)?ms:null}function itemEpochMs(element){return timelineEpochMs(element.timestamp)}class LyraTimeline extends LyraElement{constructor(){super(...arguments),this._orientation="vertical",this._scale="flow",this._collision="overlap",this.slottedCount=0,this.collisionClusters=EMPTY_TIMELINE_CLUSTERS,this.managedClusterHiddenItems=new Set,this.managedClusterRepresentatives=new Set,this.clusterActivations=new Map,this.timestampObservedItems=new Set,this.focusRepairGeneration=0,this.scrollOverflow=observeScrollOverflow(this,()=>this.renderRoot.querySelector('[part="base"]'),()=>{this.scale==="time"&&this.collision==="cluster"&&this.scheduleClusterMeasurement()}),this.onSlotChange=e=>{this.updateBrowserDerivedState(()=>{this.slottedCount=this.countTimelineItems(e.target),this.applyTimeScale()})},this.onTimelineItemTimestampChange=()=>{this.isConnected&&this.scheduleAfterUpdate(()=>this.applyTimeScale(),"timeline-item-timestamps")}}static{this.defaultStrings={...super.defaultStrings,timeline:LYRA_DEFAULT_timeline,timelineClusterCount:LYRA_DEFAULT_timelineClusterCount}}static{this.immutableEventDetails=Object.freeze(["lr-cluster-activate"])}static{this.identityEventDetailProperties=Object.freeze({"lr-cluster-activate":Object.freeze(["items"])})}static{this.styles=[LyraElement.styles,styles]}get orientation(){return this._orientation}set orientation(value){const normalized=normalizeTimelineOrientation(value),previous=this._orientation;if(previous===normalized){value!==normalized&&this.requestUpdate("orientation",previous);return}this._orientation=normalized,this.requestUpdate("orientation",previous)}get scale(){return this._scale}set scale(value){const normalized=normalizeTimelineScale(value),previous=this._scale;if(previous===normalized){value!==normalized&&this.requestUpdate("scale",previous);return}this._scale=normalized,this.requestUpdate("scale",previous)}get collision(){return this._collision}set collision(value){const normalized=normalizeTimelineCollision(value),previous=this._collision;if(previous===normalized){value!==normalized&&this.requestUpdate("collision",previous);return}this._collision=normalized,this.requestUpdate("collision",previous)}connectedCallback(){super.connectedCallback(),this.hasUpdated&&this.scheduleAfterUpdate(()=>this.applyTimeScale(),"timeline-clusters")}disconnectedCallback(){this.cancelClusterMeasurement(),this.focusRepairGeneration+=1,this.restoreClusterPresentation(),this.restoreClusterVisibility(),this.syncTimestampObservers([]),this.collisionClusters.length>0&&(this.collisionClusters=EMPTY_TIMELINE_CLUSTERS),super.disconnectedCallback()}willUpdate(changed){super.willUpdate(changed),this.hasUpdated||(this.slottedCount=Array.from(this.children).filter(element=>!element.getAttribute("slot")&&element.localName===tag("timeline-item")).length),this.hasUpdated?(changed.has("scale")||changed.has("collision")||changed.has("rangeStart")||changed.has("rangeEnd"))&&this.applyTimeScale():this.seedFirstRenderState(()=>this.applyTimeScale())}updated(changed){super.updated(changed),this.scrollOverflow.observeExtra(this.timelineItems()),changed.has("orientation")&&this.getAttribute("orientation")!==this.orientation&&this.setAttribute("orientation",this.orientation),(changed.has("collisionClusters")||changed.has("orientation"))&&this.collisionClusters.length>0&&this.scheduleAfterUpdate(()=>this.applyTimeScale(),"timeline-cluster-measurement"),this.collisionClusters.length>0&&this.syncClusterPresentations(this.collisionClusters)}countTimelineItems(slot){return slot.assignedElements({flatten:!0}).filter(element=>element.localName===tag("timeline-item")).length}firstUpdated(changed){super.firstUpdated(changed),this.scheduleAfterUpdate(()=>this.updateBrowserDerivedState(()=>{const slot=this.shadowRoot.querySelector("slot");this.slottedCount=this.countTimelineItems(slot),this.applyTimeScale()}),"timeline-first-slot-reconciliation")}get itemCount(){return this.slottedCount}syncTimestampObservers(items){const current=new Set(items);for(const item of this.timestampObservedItems)current.has(item)||(isTimelineClusterItemContract(item)&&item[OBSERVE_TIMELINE_ITEM_TIMESTAMP](this.onTimelineItemTimestampChange,!1),this.timestampObservedItems.delete(item));for(const item of current)this.timestampObservedItems.has(item)||isTimelineClusterItemContract(item)&&(item[OBSERVE_TIMELINE_ITEM_TIMESTAMP](this.onTimelineItemTimestampChange,!0),this.timestampObservedItems.add(item))}timelineItems(){const slot=this.shadowRoot?.querySelector("slot");return(slot?slot.assignedElements({flatten:!0}):Array.from(this.children).filter(element=>!element.getAttribute("slot"))).filter(element=>element.localName===tag("timeline-item"))}timeRange(stamps){const pinnedStart=timelineEpochMs(this.rangeStart),pinnedEnd=timelineEpochMs(this.rangeEnd);if(pinnedStart!==null&&pinnedEnd!==null&&pinnedEnd>pinnedStart)return[pinnedStart,pinnedEnd];const finite=stamps.filter(value=>value!==null);if(finite.length<2)return null;const lo=Math.min(...finite),hi=Math.max(...finite);return hi>lo?[lo,hi]:null}applyTimeScale(){const items=this.timelineItems();if(this.syncTimestampObservers(items),this.scale!=="time"){for(const item of items)item.style.removeProperty("--_lr-timeline-item-offset"),item.style.removeProperty("--_lr-timeline-item-lane");this.applyCollisionClusters([]);return}const stamps=items.map(item=>itemEpochMs(item)),range=this.timeRange(stamps),lastIndex=Math.max(1,items.length-1),offsets=new Array(items.length).fill(0);items.forEach((item,index)=>{const stamp=stamps[index]??null,ratio=range&&stamp!==null?(stamp-range[0])/(range[1]-range[0]):this.collision==="cluster"&&stamp!==null?0:index/lastIndex,clamped=Math.min(1,Math.max(0,ratio));offsets[index]=clamped,item.style.setProperty("--_lr-timeline-item-offset",`${clamped*100}%`)}),this.applyCollisionLanes(items,offsets),this.applyCollisionClusters(this.collision==="cluster"?this.buildCollisionClusters(items,offsets,this.clusterCollisionThreshold()):[])}applyCollisionLanes(items,offsets){if(this.collision!=="stack"){for(const item of items)item.style.removeProperty("--_lr-timeline-item-lane");return}const order=items.map((_,index)=>index).sort((a,b)=>(offsets[a]??0)-(offsets[b]??0)),laneTails=[],lanes=new Array(items.length).fill(0);for(const index of order){const offset=offsets[index]??0;let lane=laneTails.findIndex(tail=>offset-tail>=TIMELINE_COLLISION_THRESHOLD);lane===-1&&(lane=laneTails.length),laneTails[lane]=offset,lanes[index]=lane}items.forEach((item,index)=>{item.style.setProperty("--_lr-timeline-item-lane",String(lanes[index]??0))})}buildCollisionClusters(items,offsets,threshold){const order=items.map((_,index)=>index).sort((a,b)=>(offsets[a]??0)-(offsets[b]??0)||a-b),clusters=[];let window=[],windowStart=0;const flush=()=>{if(window.length<2){window=[];return}const memberIndexes=[...window].sort((a,b)=>a-b);clusters.push({offset:windowStart,items:memberIndexes.map(index=>items[index])}),window=[]};for(const index of order){const offset=offsets[index]??0;window.length>0&&offset-windowStart>=threshold&&flush(),window.length===0&&(windowStart=offset),window.push(index)}return flush(),clusters}clusterCollisionThreshold(){const base=this.renderRoot.querySelector('[part="base"]');if(!base)return TIMELINE_COLLISION_THRESHOLD;const axisExtent=this.orientation==="horizontal"?base.clientWidth:base.clientHeight;if(!Number.isFinite(axisExtent)||axisExtent<=0)return TIMELINE_COLLISION_THRESHOLD;let markerExtent=0;for(const item of this.managedClusterRepresentatives){const marker=item.shadowRoot?.querySelector('[part="cluster"]');if(!marker)continue;const rect=marker.getBoundingClientRect();markerExtent=Math.max(markerExtent,this.orientation==="horizontal"?rect.width:rect.height)}return!Number.isFinite(markerExtent)||markerExtent<=0?TIMELINE_COLLISION_THRESHOLD:Math.max(TIMELINE_COLLISION_THRESHOLD,markerExtent/axisExtent)}scheduleClusterMeasurement(){const view=this.ownerDocument.defaultView;view&&(this.clusterMeasurementFrame!==void 0&&this.clusterMeasurementView===view||(this.cancelClusterMeasurement(),this.clusterMeasurementView=view,this.clusterMeasurementFrame=view.requestAnimationFrame(()=>{this.clusterMeasurementFrame=void 0,this.clusterMeasurementView=void 0,this.isConnected&&this.ownerDocument.defaultView===view&&this.scale==="time"&&this.collision==="cluster"&&this.applyTimeScale()})))}cancelClusterMeasurement(){this.clusterMeasurementFrame!==void 0&&this.clusterMeasurementView&&this.clusterMeasurementView.cancelAnimationFrame(this.clusterMeasurementFrame),this.clusterMeasurementFrame=void 0,this.clusterMeasurementView=void 0}sameClusters(left,right){return left.length===right.length&&left.every((cluster,index)=>cluster.offset===right[index]?.offset&&cluster.items.length===right[index]?.items.length&&cluster.items.every((item,itemIndex)=>item===right[index]?.items[itemIndex]))}captureClusterFocusRepair(clusters){const active=this.ownerDocument.activeElement;if(!active)return;const focusedItem=this.timelineItems().find(item=>item===active||item.contains(active)||!!item.shadowRoot?.activeElement);if(!focusedItem)return;const wasRepresentative=this.managedClusterRepresentatives.has(focusedItem),nextCluster=clusters.find(cluster=>cluster.items.includes(focusedItem)),nextRepresentative=nextCluster?.items[0],mode=nextCluster?"cluster":"item";if(mode==="cluster"&&wasRepresentative&&nextRepresentative===focusedItem||mode==="item"&&!wasRepresentative)return;const base=this.renderRoot.querySelector('[part="base"]'),snapshot=captureComposedFocusRepair(focusedItem,base);if(snapshot)return{item:mode==="cluster"?nextRepresentative:focusedItem,mode,snapshot}}scheduleClusterFocusRepair(repair){const generation=++this.focusRepairGeneration;repair&&repair.item.updateComplete.then(()=>{if(generation!==this.focusRepairGeneration||!this.isConnected)return;const base=this.renderRoot.querySelector('[part="base"]'),target=repair.mode==="cluster"?repair.item.shadowRoot?.querySelector('[part="cluster"]')??null:collectComposedFocusTargets(repair.item).elements[0]??base;applyComposedFocusRepair(repair.snapshot,target)})}applyCollisionClusters(clusters){const frozen=Object.freeze(clusters.map(cluster=>Object.freeze({offset:cluster.offset,items:Object.freeze([...cluster.items])}))),changed=!this.sameClusters(this.collisionClusters,frozen),focusRepair=changed?this.captureClusterFocusRepair(frozen):void 0,representatives=new Set(frozen.map(cluster=>cluster.items[0])),hiddenItems=new Set(frozen.flatMap(cluster=>cluster.items.filter(item=>!representatives.has(item))));for(const item of this.managedClusterHiddenItems){if(hiddenItems.has(item)){item.hasAttribute(CLUSTER_HIDDEN_ATTRIBUTE)||item.setAttribute(CLUSTER_HIDDEN_ATTRIBUTE,"");continue}item.getAttribute(CLUSTER_HIDDEN_ATTRIBUTE)===""&&item.removeAttribute(CLUSTER_HIDDEN_ATTRIBUTE),this.managedClusterHiddenItems.delete(item)}for(const item of hiddenItems)this.managedClusterHiddenItems.has(item)||item.hasAttribute(CLUSTER_HIDDEN_ATTRIBUTE)||(item.setAttribute(CLUSTER_HIDDEN_ATTRIBUTE,""),this.managedClusterHiddenItems.add(item));if(changed){this.restoreClusterPresentation();for(const cluster of frozen){const representative=cluster.items[0];this.clusterActivations.set(representative,()=>this.activateCluster(cluster.items)),this.managedClusterRepresentatives.add(representative)}this.collisionClusters=frozen,this.syncClusterPresentations(frozen),this.scheduleClusterFocusRepair(focusRepair)}for(const cluster of frozen)cluster.items[0].style.setProperty("--_lr-timeline-item-offset",`${cluster.offset*100}%`)}syncClusterPresentations(clusters){for(const cluster of clusters){const representative=cluster.items[0],activate=this.clusterActivations.get(representative);if(!activate)continue;const countText=getNumberFormat(this.effectiveLocale).format(cluster.items.length);isTimelineClusterItemContract(representative)&&representative[SET_TIMELINE_CLUSTER_PRESENTATION]({accessibleLabel:this.localize("timelineClusterCount",void 0,{count:countText}),countText,activate})}}restoreClusterPresentation(){for(const item of this.managedClusterRepresentatives)isTimelineClusterItemContract(item)&&item[SET_TIMELINE_CLUSTER_PRESENTATION](void 0);this.managedClusterRepresentatives.clear(),this.clusterActivations.clear()}restoreClusterVisibility(){for(const item of this.managedClusterHiddenItems)item.getAttribute(CLUSTER_HIDDEN_ATTRIBUTE)===""&&item.removeAttribute(CLUSTER_HIDDEN_ATTRIBUTE);this.managedClusterHiddenItems.clear()}activateCluster(items){const snapshot=this.ownerDocument.defaultView?.Array.from(items)??[...items];this.emit("lr-cluster-activate",Object.freeze({items:Object.freeze(snapshot)}))}render(){return html`
|
|
2
|
+
<div part="base" role="list" tabindex="-1" aria-label=${this.accessibleLabel==null?this.localize("timeline"):this.accessibleLabel}>
|
|
3
3
|
<slot @slotchange=${this.onSlotChange}></slot>
|
|
4
4
|
</div>
|
|
5
|
-
`}}__decorate([property({reflect:!0})],LyraTimeline.prototype,"orientation",null),__decorate([property({reflect:!0})],LyraTimeline.prototype,"scale",null),__decorate([property({reflect:!0})],LyraTimeline.prototype,"collision",null),__decorate([property({attribute:!1})],LyraTimeline.prototype,"rangeStart",void 0),__decorate([property({attribute:!1})],LyraTimeline.prototype,"rangeEnd",void 0),__decorate([property({attribute:"aria-label"})],LyraTimeline.prototype,"accessibleLabel",void 0),__decorate([state()],LyraTimeline.prototype,"slottedCount",void 0);export{LyraTimeline};
|
|
5
|
+
`}}__decorate([property({reflect:!0})],LyraTimeline.prototype,"orientation",null),__decorate([property({reflect:!0})],LyraTimeline.prototype,"scale",null),__decorate([property({reflect:!0})],LyraTimeline.prototype,"collision",null),__decorate([property({attribute:!1})],LyraTimeline.prototype,"rangeStart",void 0),__decorate([property({attribute:!1})],LyraTimeline.prototype,"rangeEnd",void 0),__decorate([property({attribute:"aria-label"})],LyraTimeline.prototype,"accessibleLabel",void 0),__decorate([state()],LyraTimeline.prototype,"slottedCount",void 0),__decorate([state()],LyraTimeline.prototype,"collisionClusters",void 0);export{LyraTimeline};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./timeline.class.js";import{LyraTimeline}from"./timeline.class.js";import{defineElement}from"../../../internal/prefix.js";defineElement("timeline",LyraTimeline);
|
|
1
|
+
export*from"./timeline.class.js";import{LyraTimeline}from"./timeline.class.js";import{defineElement}from"../../../internal/prefix.js";import"./timeline-item.js";defineElement("timeline",LyraTimeline);
|
|
@@ -54,6 +54,20 @@ import{css}from"lit";const styles=css`
|
|
|
54
54
|
inset-inline-start: var(--_lr-timeline-item-offset, 0%);
|
|
55
55
|
inline-size: auto;
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
:host([scale='time'][collision='cluster'])
|
|
59
|
+
::slotted([data-lr-timeline-cluster-hidden]) {
|
|
60
|
+
display: none !important;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
:host([scale='time'][collision='cluster'][orientation='horizontal'])
|
|
64
|
+
[part='base'] {
|
|
65
|
+
min-block-size: max(
|
|
66
|
+
var(--lr-icon-button-size),
|
|
67
|
+
var(--lr-timeline-cluster-size, var(--lr-size-2rem))
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
57
71
|
:host([orientation='horizontal']) [part='base'] {
|
|
58
72
|
flex-direction: row;
|
|
59
73
|
overflow-x: auto;
|
|
@@ -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,query,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{chevronIcon,spinnerIcon}from"../../../internal/icons.js";import{safeDownloadHref,safeLinkHref}from"../../../internal/safe-url.js";import{syncAriaControlsElements,syncAriaDescribedByElements}from"../../../internal/aria-controls.js";import{sizes}from"../../../internal/sizes.styles.js";import{variants}from"../../../internal/variants.styles.js";import{styles}from"./button.styles.js";import{relayNativeEvent}from"../../../internal/native-event-relay.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{attachInternalsSafely,getFormOwner,installCustomErrorProperty,setFormOwner}from"../../../internal/form-associated.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{setCustomState}from"../../../internal/custom-states.js";import{EXTERNAL_LABEL_ACTIVATION}from"../../../internal/form-control-labels.js";import{omittedEmptyStringConverter}from"../../../internal/converters.js";import{currentValidityValidator}from"../form-validator.js";import{LYRA_DEFAULT_fieldRequired}from"../../../internal/default-strings.generated.js";class LyraButton extends LyraElement{static{this.defaultStrings={...super.defaultStrings,fieldRequired:LYRA_DEFAULT_fieldRequired}}static get validators(){return[currentValidityValidator("required","disabled","loading","href","value")]}static{this.styles=[LyraElement.styles,sizes,variants,styles]}static{this.formAssociated=!0}static{this.properties={disabled:{type:Boolean,reflect:!0,noAccessor:!0},name:{reflect:!0,noAccessor:!0,converter:omittedEmptyStringConverter},customError:{attribute:"custom-error",reflect:!0,noAccessor:!0}}}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=!!next,this.toggleAttribute("disabled",this._disabled),this.requestUpdate("disabled",old),this.updateValidity()}get name(){return this._name}set name(next){const old=this._name;this._name=next??"",this._name?this.setAttribute("name",this._name):this.removeAttribute("name"),this.requestUpdate("name",old)}get effectiveDisabled(){return this._disabled||this._fieldsetDisabled}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}constructor(){super(),this._fieldsetDisabled=!1,this._disabled=!1,this._name="",this._value="",this._required=!1,this._variant="neutral",this.hasSyncedDescribedByElements=!1,this.customValidityMessage="",this.reflectingCustomError=!1,this.accessibleLabel=null,this.triggerHasPopup=null,this.triggerExpanded=null,this.triggerControls=null,this.triggerDescribedBy=null,this.appearance="accent",this.size="m",this.pill=!1,this.circle=!1,this.outline=!1,this.withCaret=!1,this.withStart=!1,this.withEnd=!1,this.type="button",this.formNoValidate=!1,this.loading=!1,this.hasStartSlot=!1,this.hasEndSlot=!1,this.isIconButton=!1,this.onClick=event=>{if(this.type!=="submit"&&this.type!=="reset")return;const ownerWindow=this.ownerDocument.defaultView;let settled=!1;const finish=()=>{settled||(settled=!0,ownerWindow?.removeEventListener("click",finishAtWindow),!(event.defaultPrevented||this.effectiveDisabled||this.loading)&&this.runClickDefaultAction())},finishAtWindow=candidate=>{candidate===event&&finish()};ownerWindow?.addEventListener("click",finishAtWindow),queueMicrotask(finish)},this.onFocus=event=>{relayNativeEvent(this,event)},this.onBlur=event=>{relayNativeEvent(this,event)},this.onStartSlotChange=()=>{this.syncAdornmentSlots()},this.onEndSlotChange=()=>{this.syncAdornmentSlots()},this.onDefaultSlotChange=()=>{this.isIconButton=this.hasIconOnlyDefaultContent(),this.syncButtonStates()},installInvalidEventAlias(this,init=>this.emit("lr-invalid",null,init)),this.internals=attachInternalsSafely(this),this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]()),installCustomErrorProperty(this,()=>this.customValidityMessage),this.updateValidity(),this.syncButtonStates()}get variant(){return this._variant}set variant(next){next==="primary"?this._variant="brand":next==="default"||next==="text"?this._variant="neutral":this._variant=next,next==="text"&&(this.appearance="plain")}get caret(){return this.withCaret}set caret(next){this.withCaret=!!next}get value(){return this._value}set value(next){this._value=next??"",this.updateValidity()}get required(){return this._required}set required(next){this._required=!!next,this.updateValidity()}get resolvedRel(){const authored=(this.rel??"").split(/\s+/).filter(token=>token!==""&&token.toLowerCase()!=="opener"),tokens=new Set(authored);return this.target&&(tokens.add("noopener"),tokens.add("noreferrer")),tokens.size>0?[...tokens].join(" "):void 0}click(){this.effectiveDisabled||this.loading||this.baseEl?.click()}focus(options){!this.effectiveDisabled&&!this.loading&&this.baseEl?.focus(options)}blur(){this.baseEl?.blur()}[VALIDITY_ANCHOR](){return this.baseEl??null}[EXTERNAL_LABEL_ACTIVATION](){return"activate"}checkValidity(){return this.internals.checkValidity()}reportValidity(){return this.internals.reportValidity()}setCustomValidity(message){const old=this.customValidityMessage||null,next=message??"";if(this.customValidityMessage=next,this.validityController.setCustomValidity(this.isValidationBarred?"":next),!this.reflectingCustomError){this.reflectingCustomError=!0;try{next?this.setAttribute("custom-error",next):this.removeAttribute("custom-error")}finally{this.reflectingCustomError=!1}}this.requestUpdate("customError",old)}resetValidity(){this.customValidityMessage="",this.validityController.setCustomValidity(""),this.updateValidity()}formStateRestoreCallback(state2,reason){this.value=typeof state2=="string"?state2:""}runClickDefaultAction(){if(this.type==="submit"){const form=this.getForm();if(!form)return;this.hasSubmitterOverrides?this.submitAsNamedSubmitter(form):form.requestSubmit()}else this.type==="reset"&&this.getForm()?.reset()}get hasSubmitterOverrides(){return!!(this.name||this.value||this.formNoValidate)||this.formAction!==void 0||this.formEnctype!==void 0||this.formMethod!==void 0||this.formTarget!==void 0}submitAsNamedSubmitter(form){const submitter=this.ownerDocument.createElement("button");submitter.type="submit",submitter.hidden=!0,submitter.tabIndex=-1,this.name&&(submitter.name=this.name,submitter.value=this.value),this.formAction!==void 0&&submitter.setAttribute("formaction",this.formAction),this.formEnctype!==void 0&&submitter.setAttribute("formenctype",this.formEnctype),this.formMethod!==void 0&&submitter.setAttribute("formmethod",this.formMethod),this.formNoValidate&&(submitter.formNoValidate=!0),this.formTarget!==void 0&&submitter.setAttribute("formtarget",this.formTarget),this.parentElement&&this.closest("form")===form?this.insertAdjacentElement("afterend",submitter):form.append(submitter);try{form.requestSubmit(submitter)}finally{submitter.remove()}}formDisabledCallback(disabled){this._fieldsetDisabled=disabled,this.updateValidity(),this.syncButtonStates(),this.requestUpdate()}connectedCallback(){super.connectedCallback(),this.updateValidity(),this.syncButtonStates()}willUpdate(changed){super.willUpdate(changed),this.hasUpdated||(this.syncAdornmentSlots(),this.isIconButton=this.hasIconOnlyDefaultContent())}syncAdornmentSlots(){const collection=this.children,children=collection?Array.from(collection):[];this.hasStartSlot=children.some(element=>{const slot=element.getAttribute("slot");return slot==="start"||slot==="prefix"}),this.hasEndSlot=children.some(element=>{const slot=element.getAttribute("slot");return slot==="end"||slot==="suffix"})}hasIconOnlyDefaultContent(){const childElements=this.children,elements=(childElements?Array.from(childElements):[]).filter(element=>!element.getAttribute("slot"));if(elements.length!==1)return!1;const childNodes=this.childNodes;return(childNodes?Array.from(childNodes):[]).filter(node=>node.nodeType===3).map(node=>node.textContent??"").join("").trim()===""&&(elements[0]?.textContent??"").trim()===""}updated(changed){super.updated(changed),syncAriaControlsElements(this,this.baseEl,this.triggerControls),this.syncDescribedByElements(),this.updateValidity(),this.syncButtonStates()}updateValidity(){if(this.validityController){if(this.isValidationBarred){this.validityController.setCustomValidity(""),this.validityController.setValidity({});return}this.required&&!this.value?this.validityController.setValidity({valueMissing:!0},this.localize("fieldRequired")):this.validityController.setValidity({}),this.validityController.setCustomValidity(this.customValidityMessage)}}get isValidationBarred(){return this.effectiveDisabled||this.loading||this.baseEl?.localName==="a"}syncButtonStates(){this.internals&&(setCustomState(this.internals,"disabled",this.effectiveDisabled||this.loading),setCustomState(this.internals,"icon-button",this.isIconButton),setCustomState(this.internals,"link",this.baseEl?.localName==="a"),setCustomState(this.internals,"loading",this.loading))}syncDescribedByElements(){!this.triggerDescribedBy&&!this.hasSyncedDescribedByElements||(this.hasSyncedDescribedByElements=syncAriaDescribedByElements(this,this.baseEl,this.triggerDescribedBy))}render(){const content=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,query,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{chevronIcon,spinnerIcon}from"../../../internal/icons.js";import{safeDownloadHref,safeLinkHref}from"../../../internal/safe-url.js";import{syncAriaControlsElements,syncAriaDescribedByElements}from"../../../internal/aria-controls.js";import{sizes}from"../../../internal/sizes.styles.js";import{variants}from"../../../internal/variants.styles.js";import{styles}from"./button.styles.js";import{relayNativeEvent}from"../../../internal/native-event-relay.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{attachInternalsSafely,getFormOwner,installCustomErrorProperty,setFormOwner}from"../../../internal/form-associated.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{setCustomState}from"../../../internal/custom-states.js";import{EXTERNAL_LABEL_ACTIVATION,installFormControlLabelSupport}from"../../../internal/form-control-labels.js";installFormControlLabelSupport();import{omittedEmptyStringConverter}from"../../../internal/converters.js";import{currentValidityValidator}from"../form-validator.js";import{LYRA_DEFAULT_fieldRequired}from"../../../internal/default-strings.generated.js";class LyraButton extends LyraElement{static{this.defaultStrings={...super.defaultStrings,fieldRequired:LYRA_DEFAULT_fieldRequired}}static get validators(){return[currentValidityValidator("required","disabled","loading","href","value")]}static{this.styles=[LyraElement.styles,sizes,variants,styles]}static{this.formAssociated=!0}static{this.properties={disabled:{type:Boolean,reflect:!0,noAccessor:!0},name:{reflect:!0,noAccessor:!0,converter:omittedEmptyStringConverter},customError:{attribute:"custom-error",reflect:!0,noAccessor:!0}}}get disabled(){return this._disabled}set disabled(next){const old=this._disabled;this._disabled=!!next,this.toggleAttribute("disabled",this._disabled),this.requestUpdate("disabled",old),this.updateValidity()}get name(){return this._name}set name(next){const old=this._name;this._name=next??"",this._name?this.setAttribute("name",this._name):this.removeAttribute("name"),this.requestUpdate("name",old)}get effectiveDisabled(){return this._disabled||this._fieldsetDisabled}get form(){return getFormOwner(this.internals)}set form(owner){setFormOwner(this,owner)}getForm(){return getFormOwner(this.internals)}get labels(){return this.internals.labels}get validity(){return this.internals.validity}get validationMessage(){return this.internals.validationMessage}get willValidate(){return this.internals.willValidate}constructor(){super(),this._fieldsetDisabled=!1,this._disabled=!1,this._name="",this._value="",this._required=!1,this._variant="neutral",this.hasSyncedDescribedByElements=!1,this.customValidityMessage="",this.reflectingCustomError=!1,this.accessibleLabel=null,this.triggerHasPopup=null,this.triggerExpanded=null,this.triggerControls=null,this.triggerDescribedBy=null,this.appearance="accent",this.size="m",this.pill=!1,this.circle=!1,this.outline=!1,this.withCaret=!1,this.withStart=!1,this.withEnd=!1,this.type="button",this.formNoValidate=!1,this.loading=!1,this.hasStartSlot=!1,this.hasEndSlot=!1,this.isIconButton=!1,this.onClick=event=>{if(this.type!=="submit"&&this.type!=="reset")return;const ownerWindow=this.ownerDocument.defaultView;let settled=!1;const finish=()=>{settled||(settled=!0,ownerWindow?.removeEventListener("click",finishAtWindow),!(event.defaultPrevented||this.effectiveDisabled||this.loading)&&this.runClickDefaultAction())},finishAtWindow=candidate=>{candidate===event&&finish()};ownerWindow?.addEventListener("click",finishAtWindow),queueMicrotask(finish)},this.onFocus=event=>{relayNativeEvent(this,event)},this.onBlur=event=>{relayNativeEvent(this,event)},this.onStartSlotChange=()=>{this.syncAdornmentSlots()},this.onEndSlotChange=()=>{this.syncAdornmentSlots()},this.onDefaultSlotChange=()=>{this.isIconButton=this.hasIconOnlyDefaultContent(),this.syncButtonStates()},installInvalidEventAlias(this,init=>this.emit("lr-invalid",null,init)),this.internals=attachInternalsSafely(this),this.validityController=new AnchoredValidityController(this,this.internals,()=>this[VALIDITY_ANCHOR]()),installCustomErrorProperty(this,()=>this.customValidityMessage),this.updateValidity(),this.syncButtonStates()}get variant(){return this._variant}set variant(next){next==="primary"?this._variant="brand":next==="default"||next==="text"?this._variant="neutral":this._variant=next,next==="text"&&(this.appearance="plain")}get caret(){return this.withCaret}set caret(next){this.withCaret=!!next}get value(){return this._value}set value(next){this._value=next??"",this.updateValidity()}get required(){return this._required}set required(next){this._required=!!next,this.updateValidity()}get resolvedRel(){const authored=(this.rel??"").split(/\s+/).filter(token=>token!==""&&token.toLowerCase()!=="opener"),tokens=new Set(authored);return this.target&&(tokens.add("noopener"),tokens.add("noreferrer")),tokens.size>0?[...tokens].join(" "):void 0}click(){this.effectiveDisabled||this.loading||this.baseEl?.click()}focus(options){!this.effectiveDisabled&&!this.loading&&this.baseEl?.focus(options)}blur(){this.baseEl?.blur()}[VALIDITY_ANCHOR](){return this.baseEl??null}[EXTERNAL_LABEL_ACTIVATION](){return"activate"}checkValidity(){return this.internals.checkValidity()}reportValidity(){return this.internals.reportValidity()}setCustomValidity(message){const old=this.customValidityMessage||null,next=message??"";if(this.customValidityMessage=next,this.validityController.setCustomValidity(this.isValidationBarred?"":next),!this.reflectingCustomError){this.reflectingCustomError=!0;try{next?this.setAttribute("custom-error",next):this.removeAttribute("custom-error")}finally{this.reflectingCustomError=!1}}this.requestUpdate("customError",old)}resetValidity(){this.customValidityMessage="",this.validityController.setCustomValidity(""),this.updateValidity()}formStateRestoreCallback(state2,reason){this.value=typeof state2=="string"?state2:""}runClickDefaultAction(){if(this.type==="submit"){const form=this.getForm();if(!form)return;this.hasSubmitterOverrides?this.submitAsNamedSubmitter(form):form.requestSubmit()}else this.type==="reset"&&this.getForm()?.reset()}get hasSubmitterOverrides(){return!!(this.name||this.value||this.formNoValidate)||this.formAction!==void 0||this.formEnctype!==void 0||this.formMethod!==void 0||this.formTarget!==void 0}submitAsNamedSubmitter(form){const submitter=this.ownerDocument.createElement("button");submitter.type="submit",submitter.hidden=!0,submitter.tabIndex=-1,this.name&&(submitter.name=this.name,submitter.value=this.value),this.formAction!==void 0&&submitter.setAttribute("formaction",this.formAction),this.formEnctype!==void 0&&submitter.setAttribute("formenctype",this.formEnctype),this.formMethod!==void 0&&submitter.setAttribute("formmethod",this.formMethod),this.formNoValidate&&(submitter.formNoValidate=!0),this.formTarget!==void 0&&submitter.setAttribute("formtarget",this.formTarget),this.parentElement&&this.closest("form")===form?this.insertAdjacentElement("afterend",submitter):form.append(submitter);try{form.requestSubmit(submitter)}finally{submitter.remove()}}formDisabledCallback(disabled){this._fieldsetDisabled=disabled,this.updateValidity(),this.syncButtonStates(),this.requestUpdate()}connectedCallback(){super.connectedCallback(),this.updateValidity(),this.syncButtonStates()}willUpdate(changed){super.willUpdate(changed),this.hasUpdated||(this.syncAdornmentSlots(),this.isIconButton=this.hasIconOnlyDefaultContent())}syncAdornmentSlots(){const collection=this.children,children=collection?Array.from(collection):[];this.hasStartSlot=children.some(element=>{const slot=element.getAttribute("slot");return slot==="start"||slot==="prefix"}),this.hasEndSlot=children.some(element=>{const slot=element.getAttribute("slot");return slot==="end"||slot==="suffix"})}hasIconOnlyDefaultContent(){const childElements=this.children,elements=(childElements?Array.from(childElements):[]).filter(element=>!element.getAttribute("slot"));if(elements.length!==1)return!1;const childNodes=this.childNodes;return(childNodes?Array.from(childNodes):[]).filter(node=>node.nodeType===3).map(node=>node.textContent??"").join("").trim()===""&&(elements[0]?.textContent??"").trim()===""}updated(changed){super.updated(changed),syncAriaControlsElements(this,this.baseEl,this.triggerControls),this.syncDescribedByElements(),this.updateValidity(),this.syncButtonStates()}updateValidity(){if(this.validityController){if(this.isValidationBarred){this.validityController.setCustomValidity(""),this.validityController.setValidity({});return}this.required&&!this.value?this.validityController.setValidity({valueMissing:!0},this.localize("fieldRequired")):this.validityController.setValidity({}),this.validityController.setCustomValidity(this.customValidityMessage)}}get isValidationBarred(){return this.effectiveDisabled||this.loading||this.baseEl?.localName==="a"}syncButtonStates(){this.internals&&(setCustomState(this.internals,"disabled",this.effectiveDisabled||this.loading),setCustomState(this.internals,"icon-button",this.isIconButton),setCustomState(this.internals,"link",this.baseEl?.localName==="a"),setCustomState(this.internals,"loading",this.loading))}syncDescribedByElements(){!this.triggerDescribedBy&&!this.hasSyncedDescribedByElements||(this.hasSyncedDescribedByElements=syncAriaDescribedByElements(this,this.baseEl,this.triggerDescribedBy))}render(){const content=html`
|
|
2
2
|
<span
|
|
3
3
|
part="start prefix"
|
|
4
4
|
?hidden=${!(this.hasStartSlot||this.withStart)}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../../internal/lyra-element.js';
|
|
3
|
-
import '../../../internal/form-control-labels.js';
|
|
4
3
|
import type { LyraSize } from '../../../internal/variants.js';
|
|
5
4
|
import { type FormOwnerValue } from '../../../internal/form-associated.js';
|
|
6
5
|
import { type LyraFormValidator } from '../form-validator.js';
|
|
@@ -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,svg,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import"../../../internal/form-control-labels.js";import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{setCustomState,syncValidityStates}from"../../../internal/custom-states.js";import{syncAriaDescribedByElements}from"../../../internal/aria-controls.js";import{sizes}from"../../../internal/sizes.styles.js";import{styles}from"./checkbox.styles.js";import{dispatchNativeEvent,relayNativeEvent}from"../../../internal/native-event-relay.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{omittedEmptyStringConverter}from"../../../internal/converters.js";import{hasRealContent}from"../../../internal/a11y.js";import{isActionableElement}from"../../../internal/focus-navigation.js";import{attachInternalsSafely,getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{currentValidityValidator}from"../form-validator.js";import{LYRA_DEFAULT_checkboxRequired,LYRA_DEFAULT_fieldRequired}from"../../../internal/default-strings.generated.js";const GLYPH_VIEW_BOX="0 0 24 24",GLYPH_STROKE_WIDTH="1.75";function checkmarkGlyph(){return 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,svg,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{installFormControlLabelSupport}from"../../../internal/form-control-labels.js";installFormControlLabelSupport();import{AnchoredValidityController,VALIDITY_ANCHOR}from"../../../internal/anchored-validity.js";import{setCustomState,syncValidityStates}from"../../../internal/custom-states.js";import{syncAriaDescribedByElements}from"../../../internal/aria-controls.js";import{sizes}from"../../../internal/sizes.styles.js";import{styles}from"./checkbox.styles.js";import{dispatchNativeEvent,relayNativeEvent}from"../../../internal/native-event-relay.js";import{installInvalidEventAlias}from"../../../internal/invalid-event-alias.js";import{omittedEmptyStringConverter}from"../../../internal/converters.js";import{hasRealContent}from"../../../internal/a11y.js";import{isActionableElement}from"../../../internal/focus-navigation.js";import{attachInternalsSafely,getFormOwner,installCustomErrorProperty,isBarredFromValidation,setFormOwner}from"../../../internal/form-associated.js";import{currentValidityValidator}from"../form-validator.js";import{LYRA_DEFAULT_checkboxRequired,LYRA_DEFAULT_fieldRequired}from"../../../internal/default-strings.generated.js";const GLYPH_VIEW_BOX="0 0 24 24",GLYPH_STROKE_WIDTH="1.75";function checkmarkGlyph(){return svg`
|
|
2
2
|
<svg
|
|
3
3
|
part="checkmark checked-icon"
|
|
4
4
|
width="1em"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../../internal/lyra-element.js';
|
|
3
|
-
import '../../../internal/form-control-labels.js';
|
|
4
3
|
import type { LyraSize } from '../../../internal/variants.js';
|
|
5
4
|
import { type FormOwnerValue } from '../../../internal/form-associated.js';
|
|
6
5
|
export interface LyraCheckboxGroupEventMap {
|