@aceshooting/lyra-ui 2.0.0 → 2.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/README.md +87 -14
- package/custom-elements.json +11555 -5539
- package/dist/components/app-rail/app-rail-item.d.ts +30 -0
- package/dist/components/app-rail/app-rail-item.js +68 -0
- package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail-item.styles.js +65 -0
- package/dist/components/app-rail/app-rail.d.ts +21 -24
- package/dist/components/app-rail/app-rail.js +68 -132
- package/dist/components/app-rail/app-rail.styles.js +5 -2
- package/dist/components/attachment-chip/attachment-chip.d.ts +38 -11
- package/dist/components/attachment-chip/attachment-chip.js +73 -29
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +13 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +13 -1
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +28 -6
- package/dist/components/chart/bar-chart.js +2 -18
- package/dist/components/chart/box-plot.d.ts +25 -1
- package/dist/components/chart/box-plot.js +136 -6
- package/dist/components/chart/box-plot.styles.js +13 -0
- package/dist/components/chart/bubble-chart.js +2 -18
- package/dist/components/chart/chart.d.ts +54 -10
- package/dist/components/chart/chart.js +182 -39
- package/dist/components/chart/doughnut-chart.js +2 -18
- package/dist/components/chart/histogram-bin.d.ts +5 -2
- package/dist/components/chart/histogram-bin.js +12 -4
- package/dist/components/chart/histogram.js +8 -16
- package/dist/components/chart/line-chart.js +2 -18
- package/dist/components/chart/lite-chart.d.ts +80 -3
- package/dist/components/chart/lite-chart.js +250 -53
- package/dist/components/chart/pie-chart.js +2 -18
- package/dist/components/chart/polar-area-chart.js +2 -18
- package/dist/components/chart/radar-chart.js +2 -18
- package/dist/components/chart/scatter-chart.js +2 -18
- package/dist/components/chat-composer/chat-composer.d.ts +42 -1
- package/dist/components/chat-composer/chat-composer.js +84 -3
- package/dist/components/chat-composer/chat-composer.styles.js +11 -1
- package/dist/components/chat-message/chat-message.d.ts +32 -4
- package/dist/components/chat-message/chat-message.js +57 -17
- package/dist/components/checkbox/checkbox.d.ts +66 -8
- package/dist/components/checkbox/checkbox.js +173 -50
- package/dist/components/checkbox/checkbox.styles.js +9 -2
- package/dist/components/chip/chip-group.js +8 -2
- package/dist/components/chip/chip.js +9 -2
- package/dist/components/citation-badge/citation-badge.js +21 -3
- package/dist/components/code-block/code-block.d.ts +38 -0
- package/dist/components/code-block/code-block.js +72 -7
- package/dist/components/code-block/code-loader.d.ts +44 -1
- package/dist/components/code-block/code-loader.js +63 -0
- package/dist/components/combobox/combobox.d.ts +46 -5
- package/dist/components/combobox/combobox.js +175 -35
- package/dist/components/combobox/combobox.styles.js +3 -3
- package/dist/components/context-meter/context-meter.js +17 -8
- package/dist/components/context-meter/context-meter.styles.js +0 -6
- package/dist/components/conversation-item/conversation-item.d.ts +13 -16
- package/dist/components/conversation-item/conversation-item.js +29 -20
- package/dist/components/date-picker/calendar-core.d.ts +24 -0
- package/dist/components/date-picker/calendar-core.js +51 -4
- package/dist/components/date-picker/date-input.d.ts +77 -10
- package/dist/components/date-picker/date-input.js +278 -73
- package/dist/components/date-picker/date-picker.d.ts +28 -4
- package/dist/components/date-picker/date-picker.js +95 -37
- package/dist/components/dialog/confirm.js +3 -6
- package/dist/components/dialog/dialog.d.ts +75 -31
- package/dist/components/dialog/dialog.js +147 -131
- package/dist/components/dialog/dialog.styles.js +46 -2
- package/dist/components/dock-panel/dock-panel.d.ts +8 -0
- package/dist/components/dock-panel/dock-panel.js +15 -1
- package/dist/components/dock-panel/dock-panel.styles.js +15 -1
- package/dist/components/document-preview/document-preview.d.ts +15 -7
- package/dist/components/document-preview/document-preview.js +29 -13
- package/dist/components/empty/empty.d.ts +1 -2
- package/dist/components/empty/empty.js +18 -12
- package/dist/components/empty/empty.styles.js +0 -3
- package/dist/components/export-button/export-button.d.ts +12 -0
- package/dist/components/export-button/export-button.js +33 -5
- package/dist/components/export-button/export-button.styles.js +5 -1
- package/dist/components/file-input/accept.js +2 -0
- package/dist/components/file-input/file-input.d.ts +10 -1
- package/dist/components/file-input/file-input.js +36 -5
- package/dist/components/flag/flag.d.ts +1 -1
- package/dist/components/flag/flag.js +15 -1
- package/dist/components/flag/flag.styles.js +1 -1
- package/dist/components/flag/language-map.d.ts +4 -1
- package/dist/components/flag/language-map.js +6 -3
- package/dist/components/gauge/gauge.d.ts +10 -1
- package/dist/components/gauge/gauge.js +28 -9
- package/dist/components/generation-status/generation-status.d.ts +13 -5
- package/dist/components/generation-status/generation-status.js +59 -5
- package/dist/components/graph/graph.d.ts +37 -3
- package/dist/components/graph/graph.js +132 -20
- package/dist/components/heatmap/calendar-grid.d.ts +15 -6
- package/dist/components/heatmap/calendar-grid.js +17 -6
- package/dist/components/heatmap/heatmap-scale.d.ts +5 -1
- package/dist/components/heatmap/heatmap-scale.js +8 -2
- package/dist/components/heatmap/heatmap.d.ts +166 -25
- package/dist/components/heatmap/heatmap.js +372 -89
- package/dist/components/json-viewer/json-viewer.d.ts +22 -5
- package/dist/components/json-viewer/json-viewer.js +115 -37
- package/dist/components/json-viewer/json-viewer.styles.js +2 -1
- package/dist/components/kbd/kbd.js +24 -7
- package/dist/components/live-region/live-region.d.ts +10 -1
- package/dist/components/live-region/live-region.js +42 -6
- package/dist/components/map/map.d.ts +24 -1
- package/dist/components/map/map.js +89 -24
- package/dist/components/markdown/markdown-loader.d.ts +24 -0
- package/dist/components/markdown/markdown-loader.js +35 -1
- package/dist/components/markdown/markdown.d.ts +46 -8
- package/dist/components/markdown/markdown.js +136 -31
- package/dist/components/markdown/markdown.styles.js +7 -1
- package/dist/components/media-card/media-card.d.ts +25 -17
- package/dist/components/media-card/media-card.js +43 -65
- package/dist/components/mention-popover/mention-popover.d.ts +4 -1
- package/dist/components/mention-popover/mention-popover.js +23 -5
- package/dist/components/menu/menu-item.d.ts +32 -3
- package/dist/components/menu/menu-item.js +94 -7
- package/dist/components/menu/menu-item.styles.js +8 -0
- package/dist/components/menu/menu.d.ts +25 -1
- package/dist/components/menu/menu.js +99 -3
- package/dist/components/menu/menu.styles.js +3 -2
- package/dist/components/model-select/model-select.d.ts +48 -3
- package/dist/components/model-select/model-select.js +120 -22
- package/dist/components/model-select/model-select.styles.js +17 -3
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +25 -1
- package/dist/components/model-settings-panel/model-settings-panel.js +65 -1
- package/dist/components/playback/playback.d.ts +6 -2
- package/dist/components/playback/playback.js +72 -29
- package/dist/components/playback/playback.styles.js +6 -1
- package/dist/components/responsive-panel/responsive-panel.d.ts +29 -16
- package/dist/components/responsive-panel/responsive-panel.js +130 -132
- package/dist/components/responsive-panel/responsive-panel.styles.js +1 -1
- package/dist/components/result-card/result-card.d.ts +8 -2
- package/dist/components/result-card/result-card.js +9 -3
- package/dist/components/result-card/result-card.styles.js +0 -1
- package/dist/components/select/select.d.ts +59 -20
- package/dist/components/select/select.js +125 -43
- package/dist/components/skeleton/skeleton.d.ts +3 -0
- package/dist/components/skeleton/skeleton.js +7 -1
- package/dist/components/skeleton/skeleton.styles.js +5 -4
- package/dist/components/slider/slider.d.ts +57 -5
- package/dist/components/slider/slider.js +195 -80
- package/dist/components/source-card/source-card.d.ts +17 -5
- package/dist/components/source-card/source-card.js +55 -8
- package/dist/components/source-card/source-card.styles.js +1 -1
- package/dist/components/source-list/source-list.js +9 -1
- package/dist/components/sparkline/sparkline.js +34 -10
- package/dist/components/split/split.d.ts +141 -14
- package/dist/components/split/split.js +357 -52
- package/dist/components/split/split.styles.js +18 -1
- package/dist/components/stat/stat.d.ts +10 -4
- package/dist/components/stat/stat.js +46 -11
- package/dist/components/stream-status/stream-status.d.ts +27 -11
- package/dist/components/stream-status/stream-status.js +95 -13
- package/dist/components/streaming-text/streaming-text.d.ts +9 -3
- package/dist/components/streaming-text/streaming-text.js +25 -10
- package/dist/components/streaming-text/streaming-text.styles.js +3 -2
- package/dist/components/switch/switch.d.ts +52 -7
- package/dist/components/switch/switch.js +111 -40
- package/dist/components/switch/switch.styles.js +1 -1
- package/dist/components/table/table.d.ts +18 -3
- package/dist/components/table/table.js +88 -20
- package/dist/components/tabs/tabs.d.ts +23 -0
- package/dist/components/tabs/tabs.js +76 -12
- package/dist/components/tabs/tabs.styles.js +11 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +3 -1
- package/dist/components/thinking-panel/thinking-panel.js +34 -9
- package/dist/components/thinking-panel/thinking-panel.styles.js +6 -0
- package/dist/components/time-range/time-range.d.ts +59 -2
- package/dist/components/time-range/time-range.js +163 -67
- package/dist/components/toast/toast-item.d.ts +12 -3
- package/dist/components/toast/toast-item.js +90 -53
- package/dist/components/toast/toast-item.styles.js +59 -28
- package/dist/components/toast/toast.js +17 -5
- package/dist/components/toast/toaster.js +10 -1
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +11 -10
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +50 -124
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +1 -1
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +18 -2
- package/dist/components/tool-call-chip/tool-call-chip.js +86 -25
- package/dist/components/tool-param-form/tool-param-form.d.ts +89 -28
- package/dist/components/tool-param-form/tool-param-form.js +350 -106
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +27 -7
- package/dist/components/tool-result-dialog/tool-result-dialog.js +80 -115
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +1 -1
- package/dist/components/tool-result-view/registry.d.ts +0 -8
- package/dist/components/tool-result-view/registry.js +7 -2
- package/dist/components/tool-result-view/tool-result-view.d.ts +6 -3
- package/dist/components/tool-result-view/tool-result-view.js +18 -4
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +11 -11
- package/dist/components/tool-select-dialog/tool-select-dialog.js +44 -133
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +13 -4
- package/dist/components/tree/tree-node.d.ts +4 -1
- package/dist/components/tree/tree-node.js +4 -1
- package/dist/components/tree/tree.d.ts +17 -8
- package/dist/components/tree/tree.js +21 -20
- package/dist/components/typing-indicator/typing-indicator.d.ts +12 -2
- package/dist/components/typing-indicator/typing-indicator.js +16 -4
- package/dist/components/typing-indicator/typing-indicator.styles.js +2 -2
- package/dist/components/virtual-list/virtual-list.d.ts +56 -19
- package/dist/components/virtual-list/virtual-list.js +184 -38
- package/dist/components/virtual-list/virtual-list.styles.js +12 -0
- package/dist/components/widget/widget.d.ts +5 -4
- package/dist/components/widget/widget.js +54 -120
- package/dist/components/widget/widget.styles.js +8 -2
- package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
- package/dist/components/word-cloud/word-cloud-layout.js +20 -6
- package/dist/components/word-cloud/word-cloud.d.ts +22 -2
- package/dist/components/word-cloud/word-cloud.js +45 -6
- package/dist/components/word-cloud/word-cloud.styles.js +13 -1
- package/dist/internal/anchored-validity.d.ts +1 -0
- package/dist/internal/anchored-validity.js +86 -0
- package/dist/internal/form-associated.d.ts +7 -0
- package/dist/internal/form-associated.js +43 -4
- package/dist/internal/numbers.d.ts +12 -0
- package/dist/internal/numbers.js +26 -0
- package/dist/internal/overlay-manager.d.ts +51 -0
- package/dist/internal/overlay-manager.js +523 -0
- package/dist/internal/positioner.js +27 -3
- package/dist/internal/safe-url.d.ts +12 -0
- package/dist/internal/safe-url.js +41 -0
- package/dist/internal/tokens.styles.js +17 -11
- package/dist/lyra.d.ts +5 -2
- package/dist/lyra.js +3 -1
- package/llms-full.txt +970 -426
- package/llms.txt +5 -4
- package/package.json +19 -2
|
@@ -5,9 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { html, svg, nothing } from 'lit';
|
|
8
|
-
import {
|
|
8
|
+
import { state } from 'lit/decorators.js';
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
+
import { AnchoredValidityController, VALIDITY_ANCHOR } from '../../internal/anchored-validity.js';
|
|
11
12
|
import { styles } from './checkbox.styles.js';
|
|
12
13
|
// Mirrors the shared icon set's viewBox/stroke conventions
|
|
13
14
|
// (internal/icons.ts's chevronIcon()/closeIcon()/etc.) without importing
|
|
@@ -77,18 +78,85 @@ function indeterminateGlyph() {
|
|
|
77
78
|
export class LyraCheckbox extends LyraElement {
|
|
78
79
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
79
80
|
static { this.formAssociated = true; }
|
|
81
|
+
static { this.properties = {
|
|
82
|
+
checked: { type: Boolean, reflect: true, noAccessor: true },
|
|
83
|
+
indeterminate: { type: Boolean, reflect: true, noAccessor: true },
|
|
84
|
+
disabled: { type: Boolean, reflect: true, noAccessor: true },
|
|
85
|
+
name: { reflect: true, noAccessor: true },
|
|
86
|
+
required: { type: Boolean, reflect: true, noAccessor: true },
|
|
87
|
+
value: { noAccessor: true },
|
|
88
|
+
}; }
|
|
89
|
+
/** Whether the control is disabled explicitly or by an ancestor fieldset. */
|
|
90
|
+
get effectiveDisabled() {
|
|
91
|
+
return this.disabled || this._fieldsetDisabled;
|
|
92
|
+
}
|
|
93
|
+
get checked() {
|
|
94
|
+
return this._checked;
|
|
95
|
+
}
|
|
96
|
+
set checked(next) {
|
|
97
|
+
const old = this._checked;
|
|
98
|
+
this._checked = Boolean(next);
|
|
99
|
+
this.syncFormState();
|
|
100
|
+
this.requestUpdate('checked', old);
|
|
101
|
+
}
|
|
102
|
+
get indeterminate() {
|
|
103
|
+
return this._indeterminate;
|
|
104
|
+
}
|
|
105
|
+
set indeterminate(next) {
|
|
106
|
+
const old = this._indeterminate;
|
|
107
|
+
this._indeterminate = Boolean(next);
|
|
108
|
+
this.syncFormState();
|
|
109
|
+
this.requestUpdate('indeterminate', old);
|
|
110
|
+
}
|
|
111
|
+
get disabled() {
|
|
112
|
+
return this._disabled;
|
|
113
|
+
}
|
|
114
|
+
set disabled(next) {
|
|
115
|
+
const old = this._disabled;
|
|
116
|
+
this._disabled = Boolean(next);
|
|
117
|
+
this.toggleAttribute('disabled', this._disabled);
|
|
118
|
+
this.requestUpdate('disabled', old);
|
|
119
|
+
}
|
|
120
|
+
/** The form submission key, reflected synchronously for native form APIs. */
|
|
121
|
+
get name() {
|
|
122
|
+
return this._name;
|
|
123
|
+
}
|
|
124
|
+
set name(next) {
|
|
125
|
+
const old = this._name;
|
|
126
|
+
this._name = next ?? '';
|
|
127
|
+
if (this._name) {
|
|
128
|
+
this.setAttribute('name', this._name);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
this.removeAttribute('name');
|
|
132
|
+
}
|
|
133
|
+
this.requestUpdate('name', old);
|
|
134
|
+
}
|
|
135
|
+
get required() {
|
|
136
|
+
return this._required;
|
|
137
|
+
}
|
|
138
|
+
set required(next) {
|
|
139
|
+
const old = this._required;
|
|
140
|
+
this._required = Boolean(next);
|
|
141
|
+
this.toggleAttribute('required', this._required);
|
|
142
|
+
this.updateValidity();
|
|
143
|
+
this.requestUpdate('required', old);
|
|
144
|
+
}
|
|
145
|
+
get value() {
|
|
146
|
+
return this._value;
|
|
147
|
+
}
|
|
148
|
+
set value(next) {
|
|
149
|
+
const old = this._value;
|
|
150
|
+
this._value = next ?? 'on';
|
|
151
|
+
this.syncFormState();
|
|
152
|
+
this.requestUpdate('value', old);
|
|
153
|
+
}
|
|
80
154
|
constructor() {
|
|
81
155
|
super();
|
|
82
|
-
this.checked = false;
|
|
83
156
|
// Visual-only mixed state, matching native `<input type="checkbox">`
|
|
84
157
|
// semantics: it does not affect `checked`'s own value, and a user
|
|
85
158
|
// interaction (click/keyboard) clears it back to `false`, exactly like the
|
|
86
159
|
// native control does.
|
|
87
|
-
this.indeterminate = false;
|
|
88
|
-
this.disabled = false;
|
|
89
|
-
this.required = false;
|
|
90
|
-
this.name = '';
|
|
91
|
-
this.value = 'on';
|
|
92
160
|
// Tracks whether the default slot carries any real (non-whitespace)
|
|
93
161
|
// content, so the label wrapper — and the gap next to the box — can
|
|
94
162
|
// collapse to nothing for an icon-only/aria-label-only checkbox instead of
|
|
@@ -96,10 +164,14 @@ export class LyraCheckbox extends LyraElement {
|
|
|
96
164
|
// `assignedNodes` (not `assignedElements`) is checked — the common case is
|
|
97
165
|
// a bare slotted text label, e.g. `<lyra-checkbox>Accept terms</lyra-checkbox>`.
|
|
98
166
|
this.hasLabelSlot = false;
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
|
|
167
|
+
// Set on the control's first `blur`; gates the `data-invalid`/`aria-invalid`
|
|
168
|
+
// reflection below so validity styling never flashes on first render,
|
|
169
|
+
// mirroring `<lyra-combobox>`/`<lyra-select>`'s identical `touched` field.
|
|
170
|
+
this.touched = false;
|
|
171
|
+
// What `form.reset()` restores to — captured once from the declarative
|
|
172
|
+
// `checked` content attribute at first connect. A pre-connect `.checked`
|
|
173
|
+
// property assignment changes live state but not the reset default, matching
|
|
174
|
+
// native `checked`/`defaultChecked` semantics. `checked` reflects, so unlike `FormAssociated`'s
|
|
103
175
|
// non-reflecting `value` this can't be captured from
|
|
104
176
|
// `attributeChangedCallback` alone — that would also fire (and wrongly
|
|
105
177
|
// redefine the default) every time the property setter reflects a later
|
|
@@ -108,11 +180,18 @@ export class LyraCheckbox extends LyraElement {
|
|
|
108
180
|
// and `<lyra-switch>`'s identical `_defaultChecked`.
|
|
109
181
|
this._defaultChecked = false;
|
|
110
182
|
this._defaultCaptured = false;
|
|
183
|
+
this._fieldsetDisabled = false;
|
|
184
|
+
this._name = '';
|
|
185
|
+
this._checked = false;
|
|
186
|
+
this._indeterminate = false;
|
|
187
|
+
this._disabled = false;
|
|
188
|
+
this._required = false;
|
|
189
|
+
this._value = 'on';
|
|
111
190
|
this.onClick = () => {
|
|
112
191
|
this.toggle();
|
|
113
192
|
};
|
|
114
193
|
this.onKeyDown = (e) => {
|
|
115
|
-
if (this.
|
|
194
|
+
if (this.effectiveDisabled)
|
|
116
195
|
return;
|
|
117
196
|
// Space/Enter both activate, matching lyra-switch's onKeyDown (and
|
|
118
197
|
// lyra-table's sortable-header/row convention) for role-based clickable
|
|
@@ -123,19 +202,50 @@ export class LyraCheckbox extends LyraElement {
|
|
|
123
202
|
this.toggle();
|
|
124
203
|
}
|
|
125
204
|
};
|
|
126
|
-
this.onSlotChange = (
|
|
127
|
-
|
|
128
|
-
|
|
205
|
+
this.onSlotChange = () => {
|
|
206
|
+
this.recomputeHasLabelSlot();
|
|
207
|
+
};
|
|
208
|
+
this.onBlur = () => {
|
|
209
|
+
this.touched = true;
|
|
210
|
+
this.reflectInvalid();
|
|
129
211
|
};
|
|
130
212
|
this.internals = this.attachInternals();
|
|
213
|
+
this.validityController = new AnchoredValidityController(this, this.internals, () => this[VALIDITY_ANCHOR]());
|
|
214
|
+
this.syncFormState();
|
|
215
|
+
}
|
|
216
|
+
get form() {
|
|
217
|
+
return this.internals.form;
|
|
218
|
+
}
|
|
219
|
+
get labels() {
|
|
220
|
+
return this.internals.labels;
|
|
221
|
+
}
|
|
222
|
+
get validity() {
|
|
223
|
+
return this.internals.validity;
|
|
224
|
+
}
|
|
225
|
+
get validationMessage() {
|
|
226
|
+
return this.internals.validationMessage;
|
|
227
|
+
}
|
|
228
|
+
get willValidate() {
|
|
229
|
+
return this.internals.willValidate;
|
|
230
|
+
}
|
|
231
|
+
/** @internal */
|
|
232
|
+
[VALIDITY_ANCHOR]() {
|
|
233
|
+
return this.renderRoot?.querySelector('[part="base"]') ?? null;
|
|
131
234
|
}
|
|
132
235
|
connectedCallback() {
|
|
133
236
|
super.connectedCallback();
|
|
134
237
|
if (!this._defaultCaptured) {
|
|
135
238
|
this._defaultCaptured = true;
|
|
136
|
-
this._defaultChecked = this.checked;
|
|
239
|
+
this._defaultChecked = this.hasAttribute('checked');
|
|
137
240
|
}
|
|
138
241
|
this.updateValidity();
|
|
242
|
+
this.labelObserver = new MutationObserver(() => this.recomputeHasLabelSlot());
|
|
243
|
+
this.labelObserver.observe(this, { childList: true, subtree: true, characterData: true });
|
|
244
|
+
}
|
|
245
|
+
disconnectedCallback() {
|
|
246
|
+
super.disconnectedCallback();
|
|
247
|
+
this.labelObserver?.disconnect();
|
|
248
|
+
this.labelObserver = undefined;
|
|
139
249
|
}
|
|
140
250
|
willUpdate() {
|
|
141
251
|
// Seed `hasLabelSlot` from the light-DOM children synchronously before
|
|
@@ -148,28 +258,44 @@ export class LyraCheckbox extends LyraElement {
|
|
|
148
258
|
}
|
|
149
259
|
updateValidity() {
|
|
150
260
|
if (this.required && !this.checked) {
|
|
151
|
-
this.
|
|
261
|
+
this.validityController.setValidity({ valueMissing: true }, 'Please check this box if you want to continue.');
|
|
152
262
|
}
|
|
153
263
|
else {
|
|
154
|
-
this.
|
|
264
|
+
this.validityController.setValidity({});
|
|
155
265
|
}
|
|
266
|
+
this.reflectInvalid();
|
|
156
267
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
268
|
+
// Keeps `data-invalid` (styling hook) in lockstep with `aria-invalid`
|
|
269
|
+
// (rendered from the same expression in `render()`) any time validity
|
|
270
|
+
// could have changed, rather than waiting on Lit's async `updated()` --
|
|
271
|
+
// consistent with this component's already-synchronous
|
|
272
|
+
// `syncFormState()`/setter shape.
|
|
273
|
+
reflectInvalid() {
|
|
274
|
+
this.toggleAttribute('data-invalid', this.touched && !this.internals.validity.valid);
|
|
275
|
+
}
|
|
276
|
+
syncFormState() {
|
|
277
|
+
// A native checkbox submits its `value` content attribute (default
|
|
278
|
+
// "on") only while checked, and contributes nothing at all — not even
|
|
279
|
+
// an empty string — while unchecked.
|
|
280
|
+
const state = `${this.checked ? 'checked' : 'unchecked'}${this.indeterminate ? '/indeterminate' : ''}`;
|
|
281
|
+
this.internals.setFormValue(this.checked ? this.value : null, state);
|
|
282
|
+
this.updateValidity();
|
|
167
283
|
}
|
|
168
284
|
formResetCallback() {
|
|
169
285
|
this.checked = this._defaultChecked;
|
|
170
286
|
}
|
|
287
|
+
formStateRestoreCallback(state, _mode) {
|
|
288
|
+
const oldChecked = this._checked;
|
|
289
|
+
const oldIndeterminate = this._indeterminate;
|
|
290
|
+
this._checked = state === 'checked' || state === 'checked/indeterminate';
|
|
291
|
+
this._indeterminate = state === 'checked/indeterminate' || state === 'unchecked/indeterminate';
|
|
292
|
+
this.syncFormState();
|
|
293
|
+
this.requestUpdate('checked', oldChecked);
|
|
294
|
+
this.requestUpdate('indeterminate', oldIndeterminate);
|
|
295
|
+
}
|
|
171
296
|
formDisabledCallback(disabled) {
|
|
172
|
-
this.
|
|
297
|
+
this._fieldsetDisabled = disabled;
|
|
298
|
+
this.requestUpdate();
|
|
173
299
|
}
|
|
174
300
|
checkValidity() {
|
|
175
301
|
return this.internals.checkValidity();
|
|
@@ -178,25 +304,37 @@ export class LyraCheckbox extends LyraElement {
|
|
|
178
304
|
return this.internals.reportValidity();
|
|
179
305
|
}
|
|
180
306
|
toggle() {
|
|
181
|
-
if (this.
|
|
307
|
+
if (this.effectiveDisabled)
|
|
182
308
|
return;
|
|
183
309
|
this.checked = !this.checked;
|
|
184
310
|
this.indeterminate = false;
|
|
185
311
|
this.emit('lyra-change', { checked: this.checked });
|
|
186
312
|
}
|
|
313
|
+
// Shared by `onSlotChange` (the "set of distributed nodes changed" case)
|
|
314
|
+
// and `labelObserver` (the "an already-slotted node mutated in place"
|
|
315
|
+
// case) so both paths agree on what counts as real label content.
|
|
316
|
+
recomputeHasLabelSlot() {
|
|
317
|
+
const slot = this.renderRoot.querySelector('slot');
|
|
318
|
+
if (!slot)
|
|
319
|
+
return;
|
|
320
|
+
const nodes = slot.assignedNodes({ flatten: true });
|
|
321
|
+
this.hasLabelSlot = nodes.some((n) => (n.textContent ?? '').trim().length > 0);
|
|
322
|
+
}
|
|
187
323
|
render() {
|
|
188
324
|
const mixed = this.indeterminate;
|
|
189
325
|
return html `
|
|
190
326
|
<span
|
|
191
327
|
part="base"
|
|
192
328
|
role="checkbox"
|
|
193
|
-
tabindex=${this.
|
|
329
|
+
tabindex=${this.effectiveDisabled ? '-1' : '0'}
|
|
194
330
|
aria-checked=${mixed ? 'mixed' : this.checked ? 'true' : 'false'}
|
|
195
331
|
aria-required=${this.required ? 'true' : nothing}
|
|
196
|
-
aria-
|
|
332
|
+
aria-invalid=${this.touched && !this.internals.validity.valid ? 'true' : 'false'}
|
|
333
|
+
aria-disabled=${this.effectiveDisabled ? 'true' : nothing}
|
|
197
334
|
aria-label=${this.getAttribute('aria-label') || nothing}
|
|
198
335
|
@click=${this.onClick}
|
|
199
336
|
@keydown=${this.onKeyDown}
|
|
337
|
+
@blur=${this.onBlur}
|
|
200
338
|
>
|
|
201
339
|
<span part="box"> ${mixed ? indeterminateGlyph() : this.checked ? checkmarkGlyph() : nothing} </span>
|
|
202
340
|
<span part="label" ?hidden=${!this.hasLabelSlot}>
|
|
@@ -206,25 +344,10 @@ export class LyraCheckbox extends LyraElement {
|
|
|
206
344
|
`;
|
|
207
345
|
}
|
|
208
346
|
}
|
|
209
|
-
__decorate([
|
|
210
|
-
property({ type: Boolean, reflect: true })
|
|
211
|
-
], LyraCheckbox.prototype, "checked", void 0);
|
|
212
|
-
__decorate([
|
|
213
|
-
property({ type: Boolean, reflect: true })
|
|
214
|
-
], LyraCheckbox.prototype, "indeterminate", void 0);
|
|
215
|
-
__decorate([
|
|
216
|
-
property({ type: Boolean, reflect: true })
|
|
217
|
-
], LyraCheckbox.prototype, "disabled", void 0);
|
|
218
|
-
__decorate([
|
|
219
|
-
property({ type: Boolean, reflect: true })
|
|
220
|
-
], LyraCheckbox.prototype, "required", void 0);
|
|
221
|
-
__decorate([
|
|
222
|
-
property()
|
|
223
|
-
], LyraCheckbox.prototype, "name", void 0);
|
|
224
|
-
__decorate([
|
|
225
|
-
property()
|
|
226
|
-
], LyraCheckbox.prototype, "value", void 0);
|
|
227
347
|
__decorate([
|
|
228
348
|
state()
|
|
229
349
|
], LyraCheckbox.prototype, "hasLabelSlot", void 0);
|
|
350
|
+
__decorate([
|
|
351
|
+
state()
|
|
352
|
+
], LyraCheckbox.prototype, "touched", void 0);
|
|
230
353
|
defineElement('checkbox', LyraCheckbox);
|
|
@@ -14,7 +14,7 @@ export const styles = css `
|
|
|
14
14
|
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
15
15
|
outline-offset: var(--lyra-focus-ring-offset);
|
|
16
16
|
}
|
|
17
|
-
:host(
|
|
17
|
+
:host(:disabled) [part='base'] {
|
|
18
18
|
cursor: not-allowed;
|
|
19
19
|
opacity: var(--lyra-opacity-disabled);
|
|
20
20
|
}
|
|
@@ -40,7 +40,7 @@ export const styles = css `
|
|
|
40
40
|
background-color var(--lyra-transition-fast),
|
|
41
41
|
border-color var(--lyra-transition-fast);
|
|
42
42
|
}
|
|
43
|
-
:host(:not(
|
|
43
|
+
:host(:not(:disabled)) [part='base']:hover [part='box'] {
|
|
44
44
|
border-color: var(--lyra-color-brand);
|
|
45
45
|
}
|
|
46
46
|
:host([checked]) [part='box'],
|
|
@@ -48,6 +48,13 @@ export const styles = css `
|
|
|
48
48
|
background: var(--lyra-color-brand);
|
|
49
49
|
border-color: var(--lyra-color-brand);
|
|
50
50
|
}
|
|
51
|
+
/* Gives a required-but-unmet checkbox a persistent visible affordance --
|
|
52
|
+
matching lyra-combobox/lyra-select's data-invalid styling hook --
|
|
53
|
+
beyond the transient native validation-bubble popup, which only shows
|
|
54
|
+
momentarily around reportValidity()/form submission. */
|
|
55
|
+
:host([data-invalid]) [part='box'] {
|
|
56
|
+
border-color: var(--lyra-color-danger);
|
|
57
|
+
}
|
|
51
58
|
|
|
52
59
|
[part='checkmark'] {
|
|
53
60
|
display: block;
|
|
@@ -72,10 +72,16 @@ export class LyraChipGroup extends LyraElement {
|
|
|
72
72
|
firstUpdated() {
|
|
73
73
|
// Fallback reconciliation for slot-forwarding / engines that don't fire
|
|
74
74
|
// `slotchange` for content present at parse time — same idiom as
|
|
75
|
-
// `<lyra-source-list>`'s identical `firstUpdated`.
|
|
75
|
+
// `<lyra-source-list>`'s identical `firstUpdated`. This can't move to
|
|
76
|
+
// `willUpdate` (the `<slot>` doesn't exist in the shadow DOM until after
|
|
77
|
+
// the first render), so when it actually corrects `childCount` (the
|
|
78
|
+
// slot-forwarding case, where `this.children.length` under-counts) it
|
|
79
|
+
// unavoidably schedules a second update pass — `updated()` (below) always
|
|
80
|
+
// runs right after this and already recomputes visibility from this same
|
|
81
|
+
// corrected count, so there's nothing left for an explicit call here to
|
|
82
|
+
// do.
|
|
76
83
|
const slot = this.shadowRoot.querySelector('slot');
|
|
77
84
|
this.childCount = slot.assignedElements({ flatten: true }).length;
|
|
78
|
-
this.syncChildVisibility();
|
|
79
85
|
}
|
|
80
86
|
updated() {
|
|
81
87
|
this.syncChildVisibility();
|
|
@@ -72,10 +72,17 @@ export class LyraChip extends LyraElement {
|
|
|
72
72
|
}
|
|
73
73
|
// Only the default slot's own content counts toward the remove button's
|
|
74
74
|
// accessible name — text incidentally living inside the (decorative)
|
|
75
|
-
// `icon` slot shouldn't leak into "Remove {text}".
|
|
75
|
+
// `icon` slot shouldn't leak into "Remove {text}". Restricting to Text and
|
|
76
|
+
// Element nodes also excludes Comment nodes: when a consumer interpolates
|
|
77
|
+
// the label via a lit-html expression (`html\`<lyra-chip>${label}</lyra-chip>\``,
|
|
78
|
+
// the ordinary way a data-driven label gets bound) rather than a static
|
|
79
|
+
// string, lit-html inserts a marker Comment node alongside the Text node in
|
|
80
|
+
// the light DOM. That comment's own (non-empty) data is internal
|
|
81
|
+
// bookkeeping, not label content, so it must never reach `textContent`.
|
|
76
82
|
get labelText() {
|
|
77
83
|
return Array.from(this.childNodes)
|
|
78
|
-
.filter((n) =>
|
|
84
|
+
.filter((n) => (n.nodeType === Node.TEXT_NODE || n instanceof Element) &&
|
|
85
|
+
!(n instanceof Element && n.getAttribute('slot') === 'icon'))
|
|
79
86
|
.map((n) => n.textContent ?? '')
|
|
80
87
|
.join('')
|
|
81
88
|
.trim();
|
|
@@ -29,6 +29,17 @@ const STATUS_LABEL = {
|
|
|
29
29
|
// keyboard blur — those are intentional dismissals, not transient pointer
|
|
30
30
|
// travel, so they close immediately.
|
|
31
31
|
const HIDE_DELAY_MS = 200;
|
|
32
|
+
// The default slot's preview content is often plain text (see the Statuses
|
|
33
|
+
// story: "No source has confirmed this yet.") with no wrapping element at
|
|
34
|
+
// all, so an Element-only check (e.g. Array.from(children)/assignedElements)
|
|
35
|
+
// never counts it. Mirrors result-field.ts's hasRealContent: a node counts as
|
|
36
|
+
// real preview content if it's an element not assigned to some other named
|
|
37
|
+
// slot, or non-whitespace text.
|
|
38
|
+
function isRealPreviewNode(n) {
|
|
39
|
+
return n.nodeType === Node.ELEMENT_NODE
|
|
40
|
+
? !n.hasAttribute('slot')
|
|
41
|
+
: (n.textContent ?? '').trim().length > 0;
|
|
42
|
+
}
|
|
32
43
|
/**
|
|
33
44
|
* `<lyra-citation-badge>` — an inline `[n]` citation marker with a hover/
|
|
34
45
|
* focus preview popover and confidence/verification-status coloring. Used
|
|
@@ -113,7 +124,7 @@ export class LyraCitationBadge extends LyraElement {
|
|
|
113
124
|
this.hovering = false;
|
|
114
125
|
this.focused = false;
|
|
115
126
|
this.onSlotChange = (e) => {
|
|
116
|
-
this.hasPreviewSlot = e.target.
|
|
127
|
+
this.hasPreviewSlot = e.target.assignedNodes({ flatten: true }).some(isRealPreviewNode);
|
|
117
128
|
// The slot can be emptied out from under an already-open popover (e.g. a
|
|
118
129
|
// consumer clearing preview content asynchronously) — nothing left to
|
|
119
130
|
// show, so don't leave an empty panel floating open.
|
|
@@ -183,7 +194,7 @@ export class LyraCitationBadge extends LyraElement {
|
|
|
183
194
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
184
195
|
willUpdate() {
|
|
185
196
|
if (!this.hasUpdated) {
|
|
186
|
-
this.hasPreviewSlot = Array.from(this.
|
|
197
|
+
this.hasPreviewSlot = Array.from(this.childNodes).some(isRealPreviewNode);
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
updated(changed) {
|
|
@@ -214,10 +225,17 @@ export class LyraCitationBadge extends LyraElement {
|
|
|
214
225
|
// method names on every HTMLElement subclass, so reusing them here would
|
|
215
226
|
// be a same-name-different-signature override error.
|
|
216
227
|
showPreview() {
|
|
217
|
-
if (!this.hasPreviewSlot
|
|
228
|
+
if (!this.hasPreviewSlot)
|
|
218
229
|
return;
|
|
230
|
+
// Cancel any pending hide unconditionally -- including when the popover
|
|
231
|
+
// is already open -- so hover/focus returning within the grace period
|
|
232
|
+
// (pointerenter -> pointerleave -> pointerenter before HIDE_DELAY_MS)
|
|
233
|
+
// actually cancels the scheduled hide instead of leaving it armed to
|
|
234
|
+
// fire later regardless of the now-restored hover/focus state.
|
|
219
235
|
clearTimeout(this.hideTimer);
|
|
220
236
|
this.hideTimer = undefined;
|
|
237
|
+
if (this.popoverOpen)
|
|
238
|
+
return;
|
|
221
239
|
this.popoverOpen = true;
|
|
222
240
|
}
|
|
223
241
|
scheduleHidePreview() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
import { type ShikiLanguageInput } from './code-loader.js';
|
|
3
4
|
import '../skeleton/skeleton.js';
|
|
4
5
|
/**
|
|
5
6
|
* `<lyra-code-block>` — fenced code display with optional lazy syntax
|
|
@@ -21,11 +22,35 @@ import '../skeleton/skeleton.js';
|
|
|
21
22
|
* is already a perfectly readable placeholder for it, so a second
|
|
22
23
|
* loading-chrome state would add complexity for little practical benefit.
|
|
23
24
|
*
|
|
25
|
+
* `languages` is an additive, opt-in escape hatch from that default path for
|
|
26
|
+
* a consumer whose language set is fixed and known ahead of time: a map of
|
|
27
|
+
* language id to an already-imported shiki grammar module (e.g. `import bash
|
|
28
|
+
* from 'shiki/langs/bash.mjs'`). When `language` matches a key in `languages`,
|
|
29
|
+
* this component seeds a fine-grained `createHighlighterCore()` highlighter
|
|
30
|
+
* with *only* the pre-supplied grammars (see `code-loader.ts`'s
|
|
31
|
+
* `loadShikiHighlighterCore()`) instead of waiting on `loadShikiHighlighter()`
|
|
32
|
+
* and its dynamic per-language `loadLanguage()` import. The payoff isn't
|
|
33
|
+
* runtime cost — the default dynamic-import path is already well-optimized
|
|
34
|
+
* for that — it's *build output*: shiki's main entry point bundles a dynamic
|
|
35
|
+
* `import()` per bundled language (~200 of them) because a bundler can't
|
|
36
|
+
* statically narrow which of those a `loadLanguage(lang: string)` call might
|
|
37
|
+
* request at runtime, so it conservatively emits a build-output chunk for
|
|
38
|
+
* every one of them. `shiki/core`'s fine-grained API has no such table — a
|
|
39
|
+
* bundler only ever sees the exact grammar modules `languages` itself
|
|
40
|
+
* `import`s, so a consumer who pins its full language set this way trades a
|
|
41
|
+
* hand-maintained list for a build output scoped to just those languages
|
|
42
|
+
* instead of shiki's entire bundled set. A language requested but absent
|
|
43
|
+
* from `languages` still falls back to the ordinary dynamic-import path
|
|
44
|
+
* unchanged, so this is a partial opt-in, not a replacement for it.
|
|
45
|
+
*
|
|
24
46
|
* @customElement lyra-code-block
|
|
25
47
|
* @event lyra-copy - The copy button was activated. `detail: { text }` is
|
|
26
48
|
* always the raw `code` value (never the highlighted HTML), and always
|
|
27
49
|
* fires regardless of whether the actual OS clipboard write succeeded —
|
|
28
50
|
* same convention as `<lyra-json-viewer>`'s own copy button.
|
|
51
|
+
* @event lyra-toggle - The collapse/expand header button was activated.
|
|
52
|
+
* `detail: { collapsed }` — same event name and shape convention as
|
|
53
|
+
* `<lyra-thinking-panel>`'s own `lyra-toggle`.
|
|
29
54
|
* @csspart base - The outer container.
|
|
30
55
|
* @csspart header - The row above the code (filename/language/copy/toggle),
|
|
31
56
|
* present whenever there's anything to put in it.
|
|
@@ -63,6 +88,18 @@ export declare class LyraCodeBlock extends LyraElement {
|
|
|
63
88
|
/** A CSS length (e.g. `"20rem"`); once set, the code scrolls internally
|
|
64
89
|
* past this height instead of growing the page. */
|
|
65
90
|
maxHeight: string;
|
|
91
|
+
/** A map of language id to an already-imported shiki grammar module's
|
|
92
|
+
* default export (e.g. `{ bash: bashGrammar }` where `bashGrammar` came
|
|
93
|
+
* from a module-scope `import bash from 'shiki/langs/bash.mjs'`). When
|
|
94
|
+
* `language` matches a key here, highlighting for it is seeded from
|
|
95
|
+
* exactly this pre-supplied grammar via a fine-grained
|
|
96
|
+
* `createHighlighterCore()` highlighter, bypassing the default
|
|
97
|
+
* `loadShikiHighlighter()` singleton and its dynamic per-language
|
|
98
|
+
* `loadLanguage()` import entirely for that language — see the class doc
|
|
99
|
+
* above for the build-output rationale. A `language` value absent from
|
|
100
|
+
* this map (or left unset, or when `languages` itself is unset) falls
|
|
101
|
+
* back to that default dynamic-import path unchanged. */
|
|
102
|
+
languages?: Record<string, ShikiLanguageInput>;
|
|
66
103
|
private highlightedHtml;
|
|
67
104
|
private shikiReady;
|
|
68
105
|
private justCopied;
|
|
@@ -72,6 +109,7 @@ export declare class LyraCodeBlock extends LyraElement {
|
|
|
72
109
|
private readonly bodyId;
|
|
73
110
|
connectedCallback(): void;
|
|
74
111
|
disconnectedCallback(): void;
|
|
112
|
+
private preSuppliedGrammar;
|
|
75
113
|
protected willUpdate(changed: PropertyValues): void;
|
|
76
114
|
protected updated(): void;
|
|
77
115
|
private syncHighlight;
|