@aceshooting/lyra-ui 2.9.0 → 2.11.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 +3 -1
- package/custom-elements.json +1302 -56
- package/dist/components/button/button.class.d.ts +57 -0
- package/dist/components/button/button.class.d.ts.map +1 -0
- package/dist/components/button/button.class.js +108 -0
- package/dist/components/button/button.class.js.map +1 -0
- package/dist/components/button/button.d.ts +2 -0
- package/dist/components/button/button.d.ts.map +1 -0
- package/dist/components/button/button.js +5 -0
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/button/button.styles.d.ts +2 -0
- package/dist/components/button/button.styles.d.ts.map +1 -0
- package/dist/components/button/button.styles.js +121 -0
- package/dist/components/button/button.styles.js.map +1 -0
- package/dist/components/heatmap/heatmap.class.d.ts +29 -0
- package/dist/components/heatmap/heatmap.class.d.ts.map +1 -1
- package/dist/components/heatmap/heatmap.class.js +97 -5
- package/dist/components/heatmap/heatmap.class.js.map +1 -1
- package/dist/components/heatmap/heatmap.styles.d.ts.map +1 -1
- package/dist/components/heatmap/heatmap.styles.js +6 -0
- package/dist/components/heatmap/heatmap.styles.js.map +1 -1
- package/dist/components/input/input.class.d.ts +113 -0
- package/dist/components/input/input.class.d.ts.map +1 -0
- package/dist/components/input/input.class.js +275 -0
- package/dist/components/input/input.class.js.map +1 -0
- package/dist/components/input/input.d.ts +2 -0
- package/dist/components/input/input.d.ts.map +1 -0
- package/dist/components/input/input.js +5 -0
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/input/input.styles.d.ts +2 -0
- package/dist/components/input/input.styles.d.ts.map +1 -0
- package/dist/components/input/input.styles.js +111 -0
- package/dist/components/input/input.styles.js.map +1 -0
- package/dist/components/tool-result-view/tool-result-view.class.d.ts +13 -5
- package/dist/components/tool-result-view/tool-result-view.class.d.ts.map +1 -1
- package/dist/components/tool-result-view/tool-result-view.class.js +26 -7
- package/dist/components/tool-result-view/tool-result-view.class.js.map +1 -1
- package/dist/components/tool-result-view/tool-result-view.styles.d.ts.map +1 -1
- package/dist/components/tool-result-view/tool-result-view.styles.js +11 -0
- package/dist/components/tool-result-view/tool-result-view.styles.js.map +1 -1
- package/dist/internal/icons.d.ts +6 -0
- package/dist/internal/icons.d.ts.map +1 -1
- package/dist/internal/icons.js +20 -0
- package/dist/internal/icons.js.map +1 -1
- package/dist/internal/localization.d.ts +1 -1
- package/dist/internal/localization.d.ts.map +1 -1
- package/dist/internal/localization.js +5 -0
- package/dist/internal/localization.js.map +1 -1
- package/dist/internal/root-registration-allowlist.d.ts +1 -1
- package/dist/internal/root-registration-allowlist.d.ts.map +1 -1
- package/dist/internal/root-registration-allowlist.js +2 -0
- package/dist/internal/root-registration-allowlist.js.map +1 -1
- package/dist/lyra.d.ts +7 -0
- package/dist/lyra.d.ts.map +1 -1
- package/dist/lyra.js +4 -0
- package/dist/lyra.js.map +1 -1
- package/llms-full.txt +141 -9
- package/llms.txt +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
export type ButtonVariant = 'neutral' | 'brand' | 'success' | 'warning' | 'danger';
|
|
4
|
+
export type ButtonAppearance = 'filled' | 'outlined' | 'plain';
|
|
5
|
+
export type ButtonSize = 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
6
|
+
export type ButtonType = 'button' | 'submit' | 'reset';
|
|
7
|
+
/**
|
|
8
|
+
* `<lyra-button>` — a generic action-button primitive, the `lyra-*` equivalent of a plain
|
|
9
|
+
* `wa-button`. Renders an internal native `<button part="base">` (never a real `<wa-button>` —
|
|
10
|
+
* this library has no runtime dependency on Web Awesome, matching `<lyra-copy-button>`/
|
|
11
|
+
* `<lyra-export-button>`'s own clean-room, API-mirroring approach). `type="submit"`/`type="reset"`
|
|
12
|
+
* are handled by this component itself via the host's own `closest('form')` — a shadow-internal
|
|
13
|
+
* native `<button type="submit">` does not participate in an ancestor light-DOM form's submission
|
|
14
|
+
* on its own, since form-submitter semantics don't cross the shadow boundary.
|
|
15
|
+
*
|
|
16
|
+
* A host `aria-label` is forwarded to the internal button as a literal string (for an icon-only
|
|
17
|
+
* button with no visible label); external `aria-labelledby`/`aria-describedby` idrefs are not
|
|
18
|
+
* copied across the shadow boundary.
|
|
19
|
+
*
|
|
20
|
+
* @customElement lyra-button
|
|
21
|
+
* @slot - Default slot: the button's label content.
|
|
22
|
+
* @slot start - Leading icon/content, rendered before the label.
|
|
23
|
+
* @slot end - Trailing icon/content, rendered after the label.
|
|
24
|
+
* @csspart base - The internal native `<button>`.
|
|
25
|
+
* @csspart label - The default-slot label wrapper.
|
|
26
|
+
* @csspart start - The `start` slot wrapper.
|
|
27
|
+
* @csspart end - The `end` slot wrapper.
|
|
28
|
+
* @csspart spinner - The loading spinner, present only while `loading` is `true`.
|
|
29
|
+
*/
|
|
30
|
+
export declare class LyraButton extends LyraElement {
|
|
31
|
+
static styles: import("lit").CSSResultGroup[];
|
|
32
|
+
/** Tone vocabulary shared with `<lyra-chip>`/`<lyra-avatar>`'s own `tone` property, named
|
|
33
|
+
* `variant` here (not `tone`) to mirror `wa-button`'s own attribute name for a mechanical
|
|
34
|
+
* migration off a plain `wa-button`. */
|
|
35
|
+
variant: ButtonVariant;
|
|
36
|
+
appearance: ButtonAppearance;
|
|
37
|
+
size: ButtonSize;
|
|
38
|
+
/** Forwarded to this component's own submit/reset handling — see the class doc comment above
|
|
39
|
+
* for why this component (not the shadow-internal `<button>`) owns that behavior. */
|
|
40
|
+
type: ButtonType;
|
|
41
|
+
/** Shows an internal spinner in place of interaction affordance and disables the button, without
|
|
42
|
+
* clearing `disabled` — a consumer's own `disabled` state and a transient `loading` state are
|
|
43
|
+
* independent (mirrors `<lyra-export-button>`'s own `loading`/`disabled` pair). */
|
|
44
|
+
loading: boolean;
|
|
45
|
+
disabled: boolean;
|
|
46
|
+
private buttonEl?;
|
|
47
|
+
focus(options?: FocusOptions): void;
|
|
48
|
+
blur(): void;
|
|
49
|
+
private onClick;
|
|
50
|
+
render(): TemplateResult;
|
|
51
|
+
}
|
|
52
|
+
declare global {
|
|
53
|
+
interface HTMLElementTagNameMap {
|
|
54
|
+
'lyra-button': LyraButton;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=button.class.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.class.d.ts","sourceRoot":"","sources":["../../../src/components/button/button.class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAI7D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AACnF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAC/D,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;AACvD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,UAAW,SAAQ,WAAW;IACzC,MAAM,CAAC,MAAM,iCAAgC;IAE7C;;6CAEyC;IACZ,OAAO,EAAE,aAAa,CAAa;IACnC,UAAU,EAAE,gBAAgB,CAAY;IACxC,IAAI,EAAE,UAAU,CAAO;IACpD;0FACsF;IAC1E,IAAI,EAAE,UAAU,CAAY;IACxC;;wFAEoF;IACxC,OAAO,UAAS;IAChB,QAAQ,UAAS;IAE5C,OAAO,CAAC,QAAQ,CAAC,CAAoB;IAE7C,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAE3C;IAEQ,IAAI,IAAI,IAAI,CAEpB;IAED,OAAO,CAAC,OAAO,CAMb;IAEF,MAAM,IAAI,cAAc,CAiBvB;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, nothing } from 'lit';
|
|
8
|
+
import { property, query } from 'lit/decorators.js';
|
|
9
|
+
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
|
+
import { spinnerIcon } from '../../internal/icons.js';
|
|
11
|
+
import { styles } from './button.styles.js';
|
|
12
|
+
/**
|
|
13
|
+
* `<lyra-button>` — a generic action-button primitive, the `lyra-*` equivalent of a plain
|
|
14
|
+
* `wa-button`. Renders an internal native `<button part="base">` (never a real `<wa-button>` —
|
|
15
|
+
* this library has no runtime dependency on Web Awesome, matching `<lyra-copy-button>`/
|
|
16
|
+
* `<lyra-export-button>`'s own clean-room, API-mirroring approach). `type="submit"`/`type="reset"`
|
|
17
|
+
* are handled by this component itself via the host's own `closest('form')` — a shadow-internal
|
|
18
|
+
* native `<button type="submit">` does not participate in an ancestor light-DOM form's submission
|
|
19
|
+
* on its own, since form-submitter semantics don't cross the shadow boundary.
|
|
20
|
+
*
|
|
21
|
+
* A host `aria-label` is forwarded to the internal button as a literal string (for an icon-only
|
|
22
|
+
* button with no visible label); external `aria-labelledby`/`aria-describedby` idrefs are not
|
|
23
|
+
* copied across the shadow boundary.
|
|
24
|
+
*
|
|
25
|
+
* @customElement lyra-button
|
|
26
|
+
* @slot - Default slot: the button's label content.
|
|
27
|
+
* @slot start - Leading icon/content, rendered before the label.
|
|
28
|
+
* @slot end - Trailing icon/content, rendered after the label.
|
|
29
|
+
* @csspart base - The internal native `<button>`.
|
|
30
|
+
* @csspart label - The default-slot label wrapper.
|
|
31
|
+
* @csspart start - The `start` slot wrapper.
|
|
32
|
+
* @csspart end - The `end` slot wrapper.
|
|
33
|
+
* @csspart spinner - The loading spinner, present only while `loading` is `true`.
|
|
34
|
+
*/
|
|
35
|
+
export class LyraButton extends LyraElement {
|
|
36
|
+
constructor() {
|
|
37
|
+
super(...arguments);
|
|
38
|
+
/** Tone vocabulary shared with `<lyra-chip>`/`<lyra-avatar>`'s own `tone` property, named
|
|
39
|
+
* `variant` here (not `tone`) to mirror `wa-button`'s own attribute name for a mechanical
|
|
40
|
+
* migration off a plain `wa-button`. */
|
|
41
|
+
this.variant = 'neutral';
|
|
42
|
+
this.appearance = 'filled';
|
|
43
|
+
this.size = 'm';
|
|
44
|
+
/** Forwarded to this component's own submit/reset handling — see the class doc comment above
|
|
45
|
+
* for why this component (not the shadow-internal `<button>`) owns that behavior. */
|
|
46
|
+
this.type = 'button';
|
|
47
|
+
/** Shows an internal spinner in place of interaction affordance and disables the button, without
|
|
48
|
+
* clearing `disabled` — a consumer's own `disabled` state and a transient `loading` state are
|
|
49
|
+
* independent (mirrors `<lyra-export-button>`'s own `loading`/`disabled` pair). */
|
|
50
|
+
this.loading = false;
|
|
51
|
+
this.disabled = false;
|
|
52
|
+
this.onClick = () => {
|
|
53
|
+
if (this.type === 'submit') {
|
|
54
|
+
this.closest('form')?.requestSubmit();
|
|
55
|
+
}
|
|
56
|
+
else if (this.type === 'reset') {
|
|
57
|
+
this.closest('form')?.reset();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
static { this.styles = [LyraElement.styles, styles]; }
|
|
62
|
+
focus(options) {
|
|
63
|
+
this.buttonEl?.focus(options);
|
|
64
|
+
}
|
|
65
|
+
blur() {
|
|
66
|
+
this.buttonEl?.blur();
|
|
67
|
+
}
|
|
68
|
+
render() {
|
|
69
|
+
const ariaLabel = this.getAttribute('aria-label');
|
|
70
|
+
return html `
|
|
71
|
+
<button
|
|
72
|
+
part="base"
|
|
73
|
+
type="button"
|
|
74
|
+
aria-label=${ariaLabel || nothing}
|
|
75
|
+
aria-busy=${this.loading ? 'true' : 'false'}
|
|
76
|
+
?disabled=${this.disabled || this.loading}
|
|
77
|
+
@click=${this.onClick}
|
|
78
|
+
>
|
|
79
|
+
<span part="start"><slot name="start"></slot></span>
|
|
80
|
+
<span part="label"><slot></slot></span>
|
|
81
|
+
<span part="end"><slot name="end"></slot></span>
|
|
82
|
+
${this.loading ? html `<span part="spinner" aria-hidden="true">${spinnerIcon()}</span>` : ''}
|
|
83
|
+
</button>
|
|
84
|
+
`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
__decorate([
|
|
88
|
+
property({ reflect: true })
|
|
89
|
+
], LyraButton.prototype, "variant", void 0);
|
|
90
|
+
__decorate([
|
|
91
|
+
property({ reflect: true })
|
|
92
|
+
], LyraButton.prototype, "appearance", void 0);
|
|
93
|
+
__decorate([
|
|
94
|
+
property({ reflect: true })
|
|
95
|
+
], LyraButton.prototype, "size", void 0);
|
|
96
|
+
__decorate([
|
|
97
|
+
property()
|
|
98
|
+
], LyraButton.prototype, "type", void 0);
|
|
99
|
+
__decorate([
|
|
100
|
+
property({ type: Boolean, reflect: true })
|
|
101
|
+
], LyraButton.prototype, "loading", void 0);
|
|
102
|
+
__decorate([
|
|
103
|
+
property({ type: Boolean, reflect: true })
|
|
104
|
+
], LyraButton.prototype, "disabled", void 0);
|
|
105
|
+
__decorate([
|
|
106
|
+
query('button')
|
|
107
|
+
], LyraButton.prototype, "buttonEl", void 0);
|
|
108
|
+
//# sourceMappingURL=button.class.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.class.js","sourceRoot":"","sources":["../../../src/components/button/button.class.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAuB,MAAM,KAAK,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAO5C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,UAAW,SAAQ,WAAW;IAA3C;;QAGE;;iDAEyC;QACZ,YAAO,GAAkB,SAAS,CAAC;QACnC,eAAU,GAAqB,QAAQ,CAAC;QACxC,SAAI,GAAe,GAAG,CAAC;QACpD;8FACsF;QAC1E,SAAI,GAAe,QAAQ,CAAC;QACxC;;4FAEoF;QACxC,YAAO,GAAG,KAAK,CAAC;QAChB,aAAQ,GAAG,KAAK,CAAC;QAYrD,YAAO,GAAG,GAAS,EAAE;YAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;YACxC,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;YAChC,CAAC;QACH,CAAC,CAAC;IAoBJ,CAAC;aArDQ,WAAM,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,AAA/B,CAAgC;IAmBpC,KAAK,CAAC,OAAsB;QACnC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAEQ,IAAI;QACX,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IAUD,MAAM;QACJ,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAClD,OAAO,IAAI,CAAA;;;;qBAIM,SAAS,IAAI,OAAO;oBACrB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;oBAC/B,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO;iBAChC,IAAI,CAAC,OAAO;;;;;UAKnB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,2CAA2C,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE;;KAE9F,CAAC;IACJ,CAAC;CACF;AAhD8B;IAA5B,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CAAoC;AACnC;IAA5B,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;8CAAyC;AACxC;IAA5B,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;wCAAwB;AAGxC;IAAX,QAAQ,EAAE;wCAA6B;AAII;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;2CAAiB;AAChB;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;4CAAkB;AAEpC;IAAxB,KAAK,CAAC,QAAQ,CAAC;4CAAsC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/button/button.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../src/components/button/button.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.styles.d.ts","sourceRoot":"","sources":["../../../src/components/button/button.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,yBAsHlB,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: inline-block;
|
|
5
|
+
--lyra-button-accent: var(--lyra-color-text);
|
|
6
|
+
--lyra-button-fill: var(--lyra-color-surface);
|
|
7
|
+
--lyra-button-on-fill: var(--lyra-color-text);
|
|
8
|
+
--lyra-button-border: var(--lyra-color-border);
|
|
9
|
+
}
|
|
10
|
+
:host([variant='brand']) {
|
|
11
|
+
--lyra-button-accent: var(--lyra-color-brand);
|
|
12
|
+
--lyra-button-fill: var(--lyra-color-brand);
|
|
13
|
+
--lyra-button-on-fill: var(--lyra-color-on-brand);
|
|
14
|
+
--lyra-button-border: var(--lyra-color-brand);
|
|
15
|
+
}
|
|
16
|
+
:host([variant='success']) {
|
|
17
|
+
--lyra-button-accent: var(--lyra-color-success);
|
|
18
|
+
--lyra-button-fill: var(--lyra-color-success);
|
|
19
|
+
--lyra-button-on-fill: var(--lyra-color-on-success);
|
|
20
|
+
--lyra-button-border: var(--lyra-color-success);
|
|
21
|
+
}
|
|
22
|
+
:host([variant='warning']) {
|
|
23
|
+
--lyra-button-accent: var(--lyra-color-warning);
|
|
24
|
+
--lyra-button-fill: var(--lyra-color-warning);
|
|
25
|
+
--lyra-button-on-fill: var(--lyra-color-on-warning);
|
|
26
|
+
--lyra-button-border: var(--lyra-color-warning);
|
|
27
|
+
}
|
|
28
|
+
:host([variant='danger']) {
|
|
29
|
+
--lyra-button-accent: var(--lyra-color-danger);
|
|
30
|
+
--lyra-button-fill: var(--lyra-color-danger);
|
|
31
|
+
--lyra-button-on-fill: var(--lyra-color-on-danger);
|
|
32
|
+
--lyra-button-border: var(--lyra-color-danger);
|
|
33
|
+
}
|
|
34
|
+
[part='base'] {
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
gap: var(--lyra-space-2xs);
|
|
39
|
+
border-radius: var(--lyra-radius);
|
|
40
|
+
border: var(--lyra-border-width-thin) solid var(--lyra-button-border);
|
|
41
|
+
font: inherit;
|
|
42
|
+
font-weight: var(--lyra-font-weight-semibold);
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
}
|
|
45
|
+
:host([appearance='filled']) [part='base'] {
|
|
46
|
+
background: var(--lyra-button-fill);
|
|
47
|
+
color: var(--lyra-button-on-fill);
|
|
48
|
+
}
|
|
49
|
+
:host([appearance='outlined']) [part='base'] {
|
|
50
|
+
background: transparent;
|
|
51
|
+
color: var(--lyra-button-accent);
|
|
52
|
+
}
|
|
53
|
+
:host([appearance='plain']) [part='base'] {
|
|
54
|
+
background: transparent;
|
|
55
|
+
color: var(--lyra-button-accent);
|
|
56
|
+
border-color: transparent;
|
|
57
|
+
}
|
|
58
|
+
[part='base']:disabled {
|
|
59
|
+
opacity: var(--lyra-opacity-disabled);
|
|
60
|
+
cursor: not-allowed;
|
|
61
|
+
}
|
|
62
|
+
[part='base']:focus-visible {
|
|
63
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
64
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
65
|
+
}
|
|
66
|
+
[part='start']:empty,
|
|
67
|
+
[part='end']:empty {
|
|
68
|
+
display: none;
|
|
69
|
+
}
|
|
70
|
+
[part='start'],
|
|
71
|
+
[part='end'] {
|
|
72
|
+
display: inline-flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
}
|
|
75
|
+
:host([size='xs']) [part='base'] {
|
|
76
|
+
padding-inline: var(--lyra-space-xs);
|
|
77
|
+
padding-block: var(--lyra-space-2xs);
|
|
78
|
+
font-size: var(--lyra-font-size-xs);
|
|
79
|
+
min-block-size: var(--lyra-size-1-5rem);
|
|
80
|
+
}
|
|
81
|
+
:host([size='s']) [part='base'] {
|
|
82
|
+
padding-inline: var(--lyra-space-s);
|
|
83
|
+
padding-block: var(--lyra-space-2xs);
|
|
84
|
+
font-size: var(--lyra-font-size-sm);
|
|
85
|
+
min-block-size: var(--lyra-size-1-75rem);
|
|
86
|
+
}
|
|
87
|
+
:host([size='m']) [part='base'] {
|
|
88
|
+
padding-inline: var(--lyra-space-m);
|
|
89
|
+
padding-block: var(--lyra-space-xs);
|
|
90
|
+
font-size: var(--lyra-font-size-md-sm);
|
|
91
|
+
min-block-size: var(--lyra-size-2rem);
|
|
92
|
+
}
|
|
93
|
+
:host([size='l']) [part='base'] {
|
|
94
|
+
padding-inline: var(--lyra-space-l);
|
|
95
|
+
padding-block: var(--lyra-space-s);
|
|
96
|
+
font-size: var(--lyra-font-size-md);
|
|
97
|
+
min-block-size: var(--lyra-size-2-5rem);
|
|
98
|
+
}
|
|
99
|
+
:host([size='xl']) [part='base'] {
|
|
100
|
+
padding-inline: var(--lyra-space-2xl);
|
|
101
|
+
padding-block: var(--lyra-space-m);
|
|
102
|
+
font-size: var(--lyra-font-size-lg);
|
|
103
|
+
min-block-size: var(--lyra-size-3rem);
|
|
104
|
+
}
|
|
105
|
+
[part='spinner'] {
|
|
106
|
+
display: inline-flex;
|
|
107
|
+
animation: lyra-button-spin 1s linear infinite;
|
|
108
|
+
}
|
|
109
|
+
@keyframes lyra-button-spin {
|
|
110
|
+
to {
|
|
111
|
+
transform: rotate(360deg);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
@media (prefers-reduced-motion: reduce) {
|
|
115
|
+
[part='spinner'] {
|
|
116
|
+
animation-duration: 0.001ms;
|
|
117
|
+
animation-iteration-count: 1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
//# sourceMappingURL=button.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.styles.js","sourceRoot":"","sources":["../../../src/components/button/button.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsHxB,CAAC"}
|
|
@@ -31,6 +31,14 @@ export interface HeatmapAnnotation {
|
|
|
31
31
|
date?: string;
|
|
32
32
|
label?: string;
|
|
33
33
|
}
|
|
34
|
+
/** A single cell to mark as persistently selected -- `row`/`col` in matrix mode, `date` in
|
|
35
|
+
* calendar mode (whichever pair matches the active `mode`; the other field is ignored),
|
|
36
|
+
* mirroring `HeatmapAnnotation`'s own row/col/date shape. */
|
|
37
|
+
export interface HeatmapSelectedCell {
|
|
38
|
+
row?: number;
|
|
39
|
+
col?: number;
|
|
40
|
+
date?: string;
|
|
41
|
+
}
|
|
34
42
|
/**
|
|
35
43
|
* Parses a strict `#rgb`/`#rgba`/`#rrggbb`/`#rrggbbaa` hex string into an
|
|
36
44
|
* `[r, g, b, a]` quadruple (`a` in `[0, 1]`, defaulting to `1` for the
|
|
@@ -204,6 +212,16 @@ export declare class LyraHeatmap extends LyraElement<LyraHeatmapEventMap> {
|
|
|
204
212
|
set bucketCount(value: number);
|
|
205
213
|
/** Cells to ring-highlight — `row`/`col` in matrix mode, `date` in calendar mode. See `HeatmapAnnotation`. */
|
|
206
214
|
annotations: HeatmapAnnotation[];
|
|
215
|
+
/**
|
|
216
|
+
* The single cell to mark as persistently selected -- `row`/`col` in matrix mode, `date` in
|
|
217
|
+
* calendar mode. Purely a controlled, consumer-owned visual/accessibility marker, mirroring
|
|
218
|
+
* `<lyra-lite-chart>`'s `selectedIndex` -- this component never mutates it itself; a consumer
|
|
219
|
+
* wires it up from `lyra-cell-click` (or any other source) to build a toggle-select
|
|
220
|
+
* interaction. Unset (the default, `null`) draws no selection ring, adds no selected-cell text
|
|
221
|
+
* to the host's `aria-label`, and adds no "(selected)" suffix to the live-region announcement,
|
|
222
|
+
* reproducing today's exact output.
|
|
223
|
+
*/
|
|
224
|
+
selectedCell: HeatmapSelectedCell | null;
|
|
207
225
|
/** Formats the per-cell tooltip and keyboard live-region text — receives the cell position
|
|
208
226
|
* (`MatrixCellPos` in matrix mode, `CalendarCellPos` in calendar mode) and its value. Falls back to
|
|
209
227
|
* the built-in English "Row X, Col Y: value" / "Mon DD: value" template when unset. */
|
|
@@ -319,6 +337,9 @@ export declare class LyraHeatmap extends LyraElement<LyraHeatmapEventMap> {
|
|
|
319
337
|
private queueThemeRefresh;
|
|
320
338
|
private watchTheme;
|
|
321
339
|
protected willUpdate(changed: PropertyValues): void;
|
|
340
|
+
/** The localized "Selected: <cell>." description appended to the host `aria-label`, or `''` when
|
|
341
|
+
* `selectedCell` is unset or doesn't resolve to a real cell in the current grid. */
|
|
342
|
+
private selectedCellDescription;
|
|
322
343
|
/**
|
|
323
344
|
* The real (non-no-data) value range across `values` (or `days` in
|
|
324
345
|
* calendar mode), or `null` if there is none. Only called from
|
|
@@ -344,6 +365,14 @@ export declare class LyraHeatmap extends LyraElement<LyraHeatmapEventMap> {
|
|
|
344
365
|
private focusRingColor;
|
|
345
366
|
/** Reads the customizable canvas-drawn annotation-ring stroke color off the host's computed style. */
|
|
346
367
|
private annotationColor;
|
|
368
|
+
/** Reads the customizable canvas-drawn selected-cell-ring stroke color off the host's computed style. */
|
|
369
|
+
private selectedColor;
|
|
370
|
+
/** Whether `selectedCell` refers to the given grid position, in whichever mode is active --
|
|
371
|
+
* `row`/`col` equality in matrix mode, resolved-date equality in calendar mode (looking the
|
|
372
|
+
* position's actual date up via `calendarCellAt()`, the same way the annotation ring resolves
|
|
373
|
+
* `ann.date` against `cells`). Shared by the live-region announcement, which needs to know
|
|
374
|
+
* whether the just-announced cell *is* the selection. */
|
|
375
|
+
private isSelectedPos;
|
|
347
376
|
private draw;
|
|
348
377
|
private scheduleDraw;
|
|
349
378
|
private colorRamp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heatmap.class.d.ts","sourceRoot":"","sources":["../../../src/components/heatmap/heatmap.class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAI7D,OAAO,EAAsE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAoB1H;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"heatmap.class.d.ts","sourceRoot":"","sources":["../../../src/components/heatmap/heatmap.class.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,6 +41,7 @@ export const MAX_BUCKET_COUNT = 256;
|
|
|
41
41
|
const RING_LINE_WIDTH = 2;
|
|
42
42
|
const FALLBACK_FOCUS_RING_COLOR = '#0969da';
|
|
43
43
|
const FALLBACK_ANNOTATION_COLOR = '#cf222e';
|
|
44
|
+
const FALLBACK_SELECTED_COLOR = '#1a7f37';
|
|
44
45
|
const ARROW_KEYS = new Set(['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']);
|
|
45
46
|
const MS_PER_DAY = 86_400_000;
|
|
46
47
|
const HEX_RE = /^([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
|
|
@@ -278,6 +279,16 @@ export class LyraHeatmap extends LyraElement {
|
|
|
278
279
|
this._bucketCount = DEFAULT_BUCKET_COUNT;
|
|
279
280
|
/** Cells to ring-highlight — `row`/`col` in matrix mode, `date` in calendar mode. See `HeatmapAnnotation`. */
|
|
280
281
|
this.annotations = [];
|
|
282
|
+
/**
|
|
283
|
+
* The single cell to mark as persistently selected -- `row`/`col` in matrix mode, `date` in
|
|
284
|
+
* calendar mode. Purely a controlled, consumer-owned visual/accessibility marker, mirroring
|
|
285
|
+
* `<lyra-lite-chart>`'s `selectedIndex` -- this component never mutates it itself; a consumer
|
|
286
|
+
* wires it up from `lyra-cell-click` (or any other source) to build a toggle-select
|
|
287
|
+
* interaction. Unset (the default, `null`) draws no selection ring, adds no selected-cell text
|
|
288
|
+
* to the host's `aria-label`, and adds no "(selected)" suffix to the live-region announcement,
|
|
289
|
+
* reproducing today's exact output.
|
|
290
|
+
*/
|
|
291
|
+
this.selectedCell = null;
|
|
281
292
|
this.themeRefreshQueued = false;
|
|
282
293
|
/** The current value range, refreshed once per update cycle by `willUpdate()`. See `computeValueRange()`. */
|
|
283
294
|
this.cachedValueRange = null;
|
|
@@ -510,24 +521,54 @@ export class LyraHeatmap extends LyraElement {
|
|
|
510
521
|
if (!this.authorSuppliedRole)
|
|
511
522
|
this.setAttribute('role', 'group');
|
|
512
523
|
if (!this.authorSuppliedAriaLabel) {
|
|
524
|
+
let label;
|
|
513
525
|
if (this.mode === 'calendar') {
|
|
514
|
-
|
|
526
|
+
label = this.localize('heatmapCalendarLabel', undefined, {
|
|
515
527
|
days: this.days.length,
|
|
516
528
|
label: this.valueLabel,
|
|
517
529
|
range,
|
|
518
|
-
})
|
|
530
|
+
});
|
|
519
531
|
}
|
|
520
532
|
else {
|
|
521
533
|
const rows = this.rowLabels.length;
|
|
522
534
|
const cols = this.colLabels.length;
|
|
523
|
-
|
|
535
|
+
label = this.localize('heatmapMatrixLabel', undefined, {
|
|
524
536
|
rows,
|
|
525
537
|
cols,
|
|
526
538
|
label: this.valueLabel,
|
|
527
539
|
range,
|
|
528
|
-
})
|
|
540
|
+
});
|
|
529
541
|
}
|
|
542
|
+
// A persistent selection description, appended to the host's own accessible name -- *not*
|
|
543
|
+
// an `aria-describedby` idref pointing into this element's shadow root, since an idref like
|
|
544
|
+
// that can't resolve across the shadow boundary. Reusing the plain aria-label string here
|
|
545
|
+
// keeps it discoverable any time a screen reader user queries this element's accessible
|
|
546
|
+
// name, regardless of which cell (if any) currently has keyboard focus.
|
|
547
|
+
const selectedText = this.selectedCellDescription();
|
|
548
|
+
this.setAttribute('aria-label', selectedText ? `${label} ${selectedText}` : label);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
/** The localized "Selected: <cell>." description appended to the host `aria-label`, or `''` when
|
|
552
|
+
* `selectedCell` is unset or doesn't resolve to a real cell in the current grid. */
|
|
553
|
+
selectedCellDescription() {
|
|
554
|
+
if (!this.selectedCell)
|
|
555
|
+
return '';
|
|
556
|
+
if (this.mode === 'calendar') {
|
|
557
|
+
if (this.selectedCell.date == null)
|
|
558
|
+
return '';
|
|
559
|
+
const match = this.cachedCalendarGrid.cells.find((c) => c.date === this.selectedCell.date);
|
|
560
|
+
if (!match)
|
|
561
|
+
return '';
|
|
562
|
+
return this.localize('heatmapSelectedCellLabel', undefined, {
|
|
563
|
+
cell: this.calendarCellText({ week: match.week, weekday: match.weekday }),
|
|
564
|
+
});
|
|
530
565
|
}
|
|
566
|
+
const { row, col } = this.selectedCell;
|
|
567
|
+
if (row == null || col == null)
|
|
568
|
+
return '';
|
|
569
|
+
if (row < 0 || row >= this.rowLabels.length || col < 0 || col >= this.colLabels.length)
|
|
570
|
+
return '';
|
|
571
|
+
return this.localize('heatmapSelectedCellLabel', undefined, { cell: this.matrixCellText({ row, col }) });
|
|
531
572
|
}
|
|
532
573
|
/**
|
|
533
574
|
* The real (non-no-data) value range across `values` (or `days` in
|
|
@@ -561,6 +602,7 @@ export class LyraHeatmap extends LyraElement {
|
|
|
561
602
|
'focusedCell',
|
|
562
603
|
'colorSteps',
|
|
563
604
|
'cellColor',
|
|
605
|
+
'selectedCell',
|
|
564
606
|
].some((name) => changed.has(name))) {
|
|
565
607
|
this.draw();
|
|
566
608
|
}
|
|
@@ -596,6 +638,25 @@ export class LyraHeatmap extends LyraElement {
|
|
|
596
638
|
annotationColor() {
|
|
597
639
|
return (getComputedStyle(this).getPropertyValue('--lyra-heatmap-annotation-color').trim() || FALLBACK_ANNOTATION_COLOR);
|
|
598
640
|
}
|
|
641
|
+
/** Reads the customizable canvas-drawn selected-cell-ring stroke color off the host's computed style. */
|
|
642
|
+
selectedColor() {
|
|
643
|
+
return getComputedStyle(this).getPropertyValue('--lyra-heatmap-selected-color').trim() || FALLBACK_SELECTED_COLOR;
|
|
644
|
+
}
|
|
645
|
+
/** Whether `selectedCell` refers to the given grid position, in whichever mode is active --
|
|
646
|
+
* `row`/`col` equality in matrix mode, resolved-date equality in calendar mode (looking the
|
|
647
|
+
* position's actual date up via `calendarCellAt()`, the same way the annotation ring resolves
|
|
648
|
+
* `ann.date` against `cells`). Shared by the live-region announcement, which needs to know
|
|
649
|
+
* whether the just-announced cell *is* the selection. */
|
|
650
|
+
isSelectedPos(pos) {
|
|
651
|
+
if (!this.selectedCell)
|
|
652
|
+
return false;
|
|
653
|
+
if ('week' in pos) {
|
|
654
|
+
if (this.selectedCell.date == null)
|
|
655
|
+
return false;
|
|
656
|
+
return this.calendarCellAt(pos).date === this.selectedCell.date;
|
|
657
|
+
}
|
|
658
|
+
return this.selectedCell.row === pos.row && this.selectedCell.col === pos.col;
|
|
659
|
+
}
|
|
599
660
|
draw() {
|
|
600
661
|
if (this.mode === 'calendar')
|
|
601
662
|
this.drawCalendar();
|
|
@@ -824,6 +885,20 @@ export class LyraHeatmap extends LyraElement {
|
|
|
824
885
|
ctx.strokeRect(x + 0.5, y + 0.5, cellSize - 1, cellSize - 1);
|
|
825
886
|
}
|
|
826
887
|
}
|
|
888
|
+
// Persistent "selected" ring, drawn after the annotation ring and before the keyboard focus
|
|
889
|
+
// ring so focus visually layers on top of a selection when both target the same cell.
|
|
890
|
+
// Independent of focusedCell -- unlike the transient focus cursor, this persists across focus
|
|
891
|
+
// moves and hover, driven entirely by the controlled `selectedCell` property.
|
|
892
|
+
if (this.selectedCell?.date != null) {
|
|
893
|
+
const match = cells.find((c) => c.date === this.selectedCell.date);
|
|
894
|
+
if (match) {
|
|
895
|
+
ctx.lineWidth = RING_LINE_WIDTH;
|
|
896
|
+
ctx.strokeStyle = this.selectedColor();
|
|
897
|
+
const x = this.columnXFor(match.week);
|
|
898
|
+
const y = this.rowYFor(match.weekday);
|
|
899
|
+
ctx.strokeRect(x + 0.5, y + 0.5, cellSize - 1, cellSize - 1);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
827
902
|
// Keyboard focus ring, redrawn on top of the fill pass (and any
|
|
828
903
|
// annotation rings) on every draw.
|
|
829
904
|
if (this.focusedCell && 'week' in this.focusedCell) {
|
|
@@ -942,6 +1017,19 @@ export class LyraHeatmap extends LyraElement {
|
|
|
942
1017
|
ctx.strokeRect(x + 1, y + 1, cellSize - 3, cellSize - 3);
|
|
943
1018
|
}
|
|
944
1019
|
}
|
|
1020
|
+
// Persistent "selected" ring, drawn after the annotation ring and before the keyboard focus
|
|
1021
|
+
// ring so focus visually layers on top of a selection when both target the same cell.
|
|
1022
|
+
// Independent of focusedCell -- see drawCalendar()'s twin of this block.
|
|
1023
|
+
if (this.selectedCell?.row != null && this.selectedCell.col != null) {
|
|
1024
|
+
const { row, col } = this.selectedCell;
|
|
1025
|
+
if (row >= 0 && row < rows && col >= 0 && col < cols) {
|
|
1026
|
+
ctx.lineWidth = RING_LINE_WIDTH;
|
|
1027
|
+
ctx.strokeStyle = this.selectedColor();
|
|
1028
|
+
const x = PAD_LEFT + col * cellSize;
|
|
1029
|
+
const y = PAD_TOP + row * cellSize;
|
|
1030
|
+
ctx.strokeRect(x + 1, y + 1, cellSize - 3, cellSize - 3);
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
945
1033
|
// Keyboard focus ring, redrawn on top of the fill pass (and any
|
|
946
1034
|
// annotation rings) on every draw — canvas has no persistent DOM focus
|
|
947
1035
|
// affordance of its own for an individual cell, only a `:focus-visible`
|
|
@@ -1130,7 +1218,8 @@ export class LyraHeatmap extends LyraElement {
|
|
|
1130
1218
|
}
|
|
1131
1219
|
/** Refreshes the visually-hidden live-region text for a newly-focused cell. */
|
|
1132
1220
|
announce(pos) {
|
|
1133
|
-
|
|
1221
|
+
const text = this.resolveCellText(pos);
|
|
1222
|
+
this.liveText = this.isSelectedPos(pos) ? `${text}${this.localize('heatmapCellSelectedSuffix')}` : text;
|
|
1134
1223
|
}
|
|
1135
1224
|
emitCellClick(pos) {
|
|
1136
1225
|
if ('week' in pos) {
|
|
@@ -1331,6 +1420,9 @@ __decorate([
|
|
|
1331
1420
|
__decorate([
|
|
1332
1421
|
property({ attribute: false })
|
|
1333
1422
|
], LyraHeatmap.prototype, "annotations", void 0);
|
|
1423
|
+
__decorate([
|
|
1424
|
+
property({ attribute: false })
|
|
1425
|
+
], LyraHeatmap.prototype, "selectedCell", void 0);
|
|
1334
1426
|
__decorate([
|
|
1335
1427
|
property({ attribute: false })
|
|
1336
1428
|
], LyraHeatmap.prototype, "cellText", void 0);
|