@aceshooting/lyra-ui 1.0.1 → 1.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 +8 -9
- package/custom-elements.json +12479 -6535
- package/dist/components/chart/chart.d.ts +46 -1
- package/dist/components/chart/chart.js +148 -10
- package/dist/components/chart/chart.stories.d.ts +32 -0
- package/dist/components/chart/chart.stories.js +141 -0
- package/dist/components/chart/chart.styles.js +16 -0
- package/dist/components/chart/histogram.d.ts +2 -0
- package/dist/components/chart/histogram.js +18 -2
- package/dist/components/chart/line-chart.stories.d.ts +17 -0
- package/dist/components/chart/line-chart.stories.js +75 -0
- package/dist/components/chart/lite-chart.d.ts +74 -0
- package/dist/components/chart/lite-chart.js +384 -0
- package/dist/components/chart/lite-chart.stories.d.ts +12 -0
- package/dist/components/chart/lite-chart.stories.js +98 -0
- package/dist/components/chart/lite-chart.styles.d.ts +1 -0
- package/dist/components/chart/lite-chart.styles.js +83 -0
- package/dist/components/combobox/combobox.d.ts +9 -0
- package/dist/components/combobox/combobox.js +75 -12
- package/dist/components/combobox/combobox.stories.d.ts +18 -0
- package/dist/components/combobox/combobox.stories.js +75 -0
- package/dist/components/date-picker/calendar-core.js +13 -2
- package/dist/components/date-picker/date-input.d.ts +9 -1
- package/dist/components/date-picker/date-input.js +55 -7
- package/dist/components/date-picker/date-input.stories.d.ts +5 -0
- package/dist/components/date-picker/date-input.stories.js +36 -0
- package/dist/components/date-picker/date-picker.d.ts +11 -3
- package/dist/components/date-picker/date-picker.js +87 -37
- package/dist/components/date-picker/date-picker.stories.d.ts +4 -0
- package/dist/components/date-picker/date-picker.stories.js +12 -0
- package/dist/components/date-picker/date-picker.styles.js +1 -1
- package/dist/components/empty/empty.d.ts +12 -1
- package/dist/components/empty/empty.js +20 -3
- package/dist/components/empty/empty.stories.d.ts +2 -0
- package/dist/components/empty/empty.stories.js +20 -0
- package/dist/components/empty/empty.styles.js +11 -0
- package/dist/components/export-button/csv.js +6 -2
- package/dist/components/export-button/export-button.d.ts +15 -1
- package/dist/components/export-button/export-button.js +89 -12
- package/dist/components/export-button/export-button.stories.d.ts +1 -0
- package/dist/components/export-button/export-button.stories.js +5 -0
- package/dist/components/export-button/export-button.styles.js +11 -3
- package/dist/components/file-input/accept.d.ts +8 -2
- package/dist/components/file-input/accept.js +9 -3
- package/dist/components/file-input/file-input.d.ts +5 -2
- package/dist/components/file-input/file-input.js +23 -8
- package/dist/components/file-input/file-input.stories.d.ts +2 -0
- package/dist/components/file-input/file-input.stories.js +9 -0
- package/dist/components/flag/flag.d.ts +48 -3
- package/dist/components/flag/flag.js +65 -29
- package/dist/components/flag/flag.styles.js +1 -1
- package/dist/components/flag/language-map.d.ts +11 -0
- package/dist/components/flag/language-map.js +12 -1
- package/dist/components/gauge/gauge.d.ts +2 -0
- package/dist/components/gauge/gauge.js +19 -5
- package/dist/components/gauge/gauge.stories.d.ts +2 -0
- package/dist/components/gauge/gauge.stories.js +6 -0
- package/dist/components/graph/graph-loader.d.ts +28 -0
- package/dist/components/graph/graph-loader.js +44 -0
- package/dist/components/graph/graph.d.ts +41 -15
- package/dist/components/graph/graph.js +146 -71
- package/dist/components/graph/graph.stories.d.ts +3 -0
- package/dist/components/graph/graph.stories.js +38 -0
- package/dist/components/graph/graph.styles.js +6 -1
- package/dist/components/heatmap/calendar-grid.d.ts +7 -0
- package/dist/components/heatmap/calendar-grid.js +27 -10
- package/dist/components/heatmap/heatmap.d.ts +137 -12
- package/dist/components/heatmap/heatmap.js +427 -27
- package/dist/components/heatmap/heatmap.stories.d.ts +17 -0
- package/dist/components/heatmap/heatmap.stories.js +130 -0
- package/dist/components/heatmap/heatmap.styles.js +60 -2
- package/dist/components/map/map.d.ts +17 -1
- package/dist/components/map/map.js +68 -21
- package/dist/components/map/map.stories.d.ts +10 -0
- package/dist/components/map/map.stories.js +107 -12
- package/dist/components/map/map.styles.js +2 -2
- package/dist/components/playback/playback.d.ts +6 -2
- package/dist/components/playback/playback.js +36 -12
- package/dist/components/playback/playback.stories.d.ts +2 -0
- package/dist/components/playback/playback.stories.js +6 -0
- package/dist/components/playback/playback.styles.js +10 -2
- package/dist/components/select/select.d.ts +122 -0
- package/dist/components/select/select.js +516 -0
- package/dist/components/select/select.stories.d.ts +19 -0
- package/dist/components/select/select.stories.js +75 -0
- package/dist/components/select/select.styles.d.ts +1 -0
- package/dist/components/select/select.styles.js +188 -0
- package/dist/components/skeleton/skeleton.js +4 -7
- package/dist/components/sparkline/sparkline.d.ts +1 -1
- package/dist/components/sparkline/sparkline.js +40 -13
- package/dist/components/sparkline/sparkline.stories.d.ts +4 -0
- package/dist/components/sparkline/sparkline.stories.js +22 -0
- package/dist/components/split/split.d.ts +24 -3
- package/dist/components/split/split.js +155 -31
- package/dist/components/split/split.stories.d.ts +2 -0
- package/dist/components/split/split.stories.js +20 -0
- package/dist/components/stat/stat.d.ts +27 -1
- package/dist/components/stat/stat.js +56 -3
- package/dist/components/stat/stat.stories.d.ts +3 -0
- package/dist/components/stat/stat.stories.js +49 -1
- package/dist/components/stat/stat.styles.js +44 -0
- package/dist/components/table/table.d.ts +64 -2
- package/dist/components/table/table.js +213 -17
- package/dist/components/table/table.stories.d.ts +6 -0
- package/dist/components/table/table.stories.js +45 -0
- package/dist/components/table/table.styles.js +51 -4
- package/dist/components/time-range/time-range.d.ts +34 -5
- package/dist/components/time-range/time-range.js +217 -36
- package/dist/components/time-range/time-range.stories.d.ts +2 -0
- package/dist/components/time-range/time-range.stories.js +13 -0
- package/dist/components/time-range/time-range.styles.js +44 -2
- package/dist/components/toast/toast-item.d.ts +14 -2
- package/dist/components/toast/toast-item.js +134 -17
- package/dist/components/toast/toast-item.styles.js +28 -2
- package/dist/components/toast/toast.stories.d.ts +3 -0
- package/dist/components/toast/toast.stories.js +41 -1
- package/dist/components/toast/toast.styles.js +11 -11
- package/dist/components/toast/toaster.d.ts +1 -1
- package/dist/components/toast/toaster.js +13 -6
- package/dist/components/tree/tree-node.d.ts +13 -7
- package/dist/components/tree/tree-node.js +24 -10
- package/dist/components/tree/tree.d.ts +64 -15
- package/dist/components/tree/tree.js +113 -22
- package/dist/components/tree/tree.stories.d.ts +4 -0
- package/dist/components/tree/tree.stories.js +31 -1
- package/dist/components/tree/update-cascade.d.ts +13 -0
- package/dist/components/tree/update-cascade.js +13 -0
- package/dist/components/widget/widget.d.ts +15 -1
- package/dist/components/widget/widget.js +140 -5
- package/dist/components/widget/widget.stories.d.ts +1 -0
- package/dist/components/widget/widget.stories.js +10 -0
- package/dist/components/widget/widget.styles.js +11 -1
- package/dist/components/word-cloud/word-cloud-layout.d.ts +63 -0
- package/dist/components/word-cloud/word-cloud-layout.js +145 -0
- package/dist/components/word-cloud/word-cloud.d.ts +65 -0
- package/dist/components/word-cloud/word-cloud.js +255 -0
- package/dist/components/word-cloud/word-cloud.stories.d.ts +10 -0
- package/dist/components/word-cloud/word-cloud.stories.js +55 -0
- package/dist/components/word-cloud/word-cloud.styles.d.ts +1 -0
- package/dist/components/word-cloud/word-cloud.styles.js +54 -0
- package/dist/internal/a11y.js +2 -1
- package/dist/internal/rtl.d.ts +7 -0
- package/dist/internal/rtl.js +9 -0
- package/dist/lyra.d.ts +9 -1
- package/dist/lyra.js +6 -0
- package/llms-full.txt +892 -276
- package/llms.txt +12 -9
- package/package.json +6 -4
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
[part='form-control-label'] {
|
|
7
|
+
display: block;
|
|
8
|
+
margin-block-end: var(--lyra-space-xs);
|
|
9
|
+
font-size: 0.875rem;
|
|
10
|
+
font-weight: 600;
|
|
11
|
+
}
|
|
12
|
+
/* :empty never matches here -- the part always contains a literal slot
|
|
13
|
+
child element regardless of assigned/text content -- so real emptiness
|
|
14
|
+
is tracked in JS (hasLabelSlot) and reflected via the hidden attribute
|
|
15
|
+
instead (same fix as [part='hint']/[part='error'] below, and as
|
|
16
|
+
lyra-combobox). Without this, the required-asterisk ::after below
|
|
17
|
+
(which attaches to this box) renders a stray ' *' with nothing before
|
|
18
|
+
it whenever label is unset. */
|
|
19
|
+
[part='form-control-label'][hidden] {
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
:host([required]) [part='form-control-label']::after {
|
|
23
|
+
content: ' *';
|
|
24
|
+
color: var(--lyra-color-danger);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
[part='trigger'] {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
justify-content: space-between;
|
|
31
|
+
gap: var(--lyra-space-xs);
|
|
32
|
+
inline-size: 100%;
|
|
33
|
+
min-block-size: 2.5rem;
|
|
34
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s);
|
|
35
|
+
border: 1px solid var(--lyra-color-border);
|
|
36
|
+
border-radius: var(--lyra-radius);
|
|
37
|
+
background: var(--lyra-color-surface);
|
|
38
|
+
color: inherit;
|
|
39
|
+
font: inherit;
|
|
40
|
+
text-align: start;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
}
|
|
43
|
+
[part='trigger']:focus-visible {
|
|
44
|
+
outline: var(--lyra-focus-ring-width) solid var(--lyra-focus-ring-color);
|
|
45
|
+
outline-offset: var(--lyra-focus-ring-offset);
|
|
46
|
+
}
|
|
47
|
+
:host([open]) [part='trigger'] {
|
|
48
|
+
border-color: var(--lyra-color-brand);
|
|
49
|
+
}
|
|
50
|
+
:host([disabled]) [part='trigger'] {
|
|
51
|
+
/* Shared library-wide disabled-state token -- see lyra-combobox. */
|
|
52
|
+
opacity: var(--lyra-opacity-disabled);
|
|
53
|
+
cursor: not-allowed;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.trigger-label {
|
|
57
|
+
flex: 1 1 auto;
|
|
58
|
+
min-inline-size: 0;
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
text-overflow: ellipsis;
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
}
|
|
63
|
+
/* Placeholder text (no value selected yet) renders quieter, matching a
|
|
64
|
+
native <select>'s empty-option / combobox's placeholder styling. */
|
|
65
|
+
.trigger-label[data-placeholder] {
|
|
66
|
+
color: var(--lyra-color-text-quiet);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[part='expand-icon'] {
|
|
70
|
+
flex: 0 0 auto;
|
|
71
|
+
display: inline-flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
justify-content: center;
|
|
74
|
+
color: var(--lyra-color-text-quiet);
|
|
75
|
+
/* Same real-touch-target reasoning as lyra-combobox's expand-icon. */
|
|
76
|
+
min-inline-size: min(var(--lyra-icon-button-size), 1.75rem);
|
|
77
|
+
min-block-size: min(var(--lyra-icon-button-size), 1.75rem);
|
|
78
|
+
line-height: 1;
|
|
79
|
+
}
|
|
80
|
+
[part='expand-icon'] svg {
|
|
81
|
+
transform: rotate(90deg);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
[part='listbox'] {
|
|
85
|
+
position: fixed;
|
|
86
|
+
z-index: 900;
|
|
87
|
+
box-sizing: border-box;
|
|
88
|
+
max-block-size: 18rem;
|
|
89
|
+
overflow-y: auto;
|
|
90
|
+
inline-size: max-content;
|
|
91
|
+
min-inline-size: 12rem;
|
|
92
|
+
max-inline-size: min(92vw, 28rem);
|
|
93
|
+
padding: var(--lyra-space-xs);
|
|
94
|
+
background: var(--lyra-color-surface);
|
|
95
|
+
border: 1px solid var(--lyra-color-border);
|
|
96
|
+
border-radius: var(--lyra-radius);
|
|
97
|
+
box-shadow: var(--lyra-shadow);
|
|
98
|
+
/* Closed state: invisible + slightly raised. visibility (not
|
|
99
|
+
display:none) so opacity/transform can actually transition; hit-testing
|
|
100
|
+
and a11y exposure stay off since this part is already position:fixed. */
|
|
101
|
+
visibility: hidden;
|
|
102
|
+
opacity: 0;
|
|
103
|
+
transform: translateY(-0.25rem);
|
|
104
|
+
transition:
|
|
105
|
+
opacity var(--lyra-transition-fast),
|
|
106
|
+
transform var(--lyra-transition-fast),
|
|
107
|
+
visibility var(--lyra-transition-fast);
|
|
108
|
+
}
|
|
109
|
+
:host([open]) [part='listbox'] {
|
|
110
|
+
visibility: visible;
|
|
111
|
+
opacity: 1;
|
|
112
|
+
transform: translateY(0);
|
|
113
|
+
}
|
|
114
|
+
@media (prefers-reduced-motion: reduce) {
|
|
115
|
+
[part='listbox'] {
|
|
116
|
+
transition: none !important;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
[part='option'] {
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-direction: column;
|
|
123
|
+
align-items: start;
|
|
124
|
+
inline-size: 100%;
|
|
125
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s);
|
|
126
|
+
border: 1px solid transparent;
|
|
127
|
+
border-radius: var(--lyra-radius);
|
|
128
|
+
background: none;
|
|
129
|
+
color: inherit;
|
|
130
|
+
font: inherit;
|
|
131
|
+
text-align: start;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
}
|
|
134
|
+
[part='option']:hover,
|
|
135
|
+
[part='option'][data-active] {
|
|
136
|
+
background: var(--lyra-color-brand-quiet);
|
|
137
|
+
}
|
|
138
|
+
[part='option'][aria-selected='true'] {
|
|
139
|
+
border-color: var(--lyra-color-brand);
|
|
140
|
+
color: var(--lyra-color-brand);
|
|
141
|
+
font-weight: 600;
|
|
142
|
+
}
|
|
143
|
+
[part='option'][aria-disabled='true'] {
|
|
144
|
+
opacity: var(--lyra-opacity-disabled);
|
|
145
|
+
cursor: not-allowed;
|
|
146
|
+
}
|
|
147
|
+
[part='option-dot'] {
|
|
148
|
+
inline-size: 0.5rem;
|
|
149
|
+
block-size: 0.5rem;
|
|
150
|
+
border-radius: 50%;
|
|
151
|
+
flex: 0 0 auto;
|
|
152
|
+
}
|
|
153
|
+
[part='option-label'] {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-direction: column;
|
|
156
|
+
min-inline-size: 0;
|
|
157
|
+
}
|
|
158
|
+
[part='option-sub'] {
|
|
159
|
+
font-size: 0.75rem;
|
|
160
|
+
color: var(--lyra-color-text-quiet);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.group-label {
|
|
164
|
+
padding: var(--lyra-space-xs) var(--lyra-space-s) 0;
|
|
165
|
+
font-size: 0.6875rem;
|
|
166
|
+
font-weight: 700;
|
|
167
|
+
text-transform: uppercase;
|
|
168
|
+
letter-spacing: 0.04em;
|
|
169
|
+
color: var(--lyra-color-text-quiet);
|
|
170
|
+
}
|
|
171
|
+
[part='hint'] {
|
|
172
|
+
margin-block-start: var(--lyra-space-xs);
|
|
173
|
+
font-size: 0.8125rem;
|
|
174
|
+
color: var(--lyra-color-text-quiet);
|
|
175
|
+
}
|
|
176
|
+
/* :empty never matches here either -- same fix as lyra-combobox's hint/error. */
|
|
177
|
+
[part='hint'][hidden] {
|
|
178
|
+
display: none;
|
|
179
|
+
}
|
|
180
|
+
[part='error'] {
|
|
181
|
+
margin-block-start: var(--lyra-space-xs);
|
|
182
|
+
font-size: 0.8125rem;
|
|
183
|
+
color: var(--lyra-color-danger);
|
|
184
|
+
}
|
|
185
|
+
[part='error'][hidden] {
|
|
186
|
+
display: none;
|
|
187
|
+
}
|
|
188
|
+
`;
|
|
@@ -29,20 +29,17 @@ export class LyraSkeleton extends LyraElement {
|
|
|
29
29
|
}
|
|
30
30
|
updated(changed) {
|
|
31
31
|
if (changed.has('width') || changed.has('height')) {
|
|
32
|
-
const base = this.renderRoot.querySelector('[part="base"]');
|
|
33
|
-
if (!base)
|
|
34
|
-
return;
|
|
35
32
|
if (this.width) {
|
|
36
|
-
|
|
33
|
+
this.style.setProperty('--lyra-skeleton-w', this.width);
|
|
37
34
|
}
|
|
38
35
|
else {
|
|
39
|
-
|
|
36
|
+
this.style.removeProperty('--lyra-skeleton-w');
|
|
40
37
|
}
|
|
41
38
|
if (this.height) {
|
|
42
|
-
|
|
39
|
+
this.style.setProperty('--lyra-skeleton-h', this.height);
|
|
43
40
|
}
|
|
44
41
|
else {
|
|
45
|
-
|
|
42
|
+
this.style.removeProperty('--lyra-skeleton-h');
|
|
46
43
|
}
|
|
47
44
|
}
|
|
48
45
|
}
|
|
@@ -5,7 +5,7 @@ import { LyraElement } from '../../internal/lyra-element.js';
|
|
|
5
5
|
* Mirrors the Web Awesome `<wa-sparkline>` API under the `lyra-` prefix.
|
|
6
6
|
*
|
|
7
7
|
* @customElement lyra-sparkline
|
|
8
|
-
* @csspart line - The line path (type="line").
|
|
8
|
+
* @csspart line - The stroked line path (type="line" and type="area").
|
|
9
9
|
* @csspart area - The filled area under the line (type="area").
|
|
10
10
|
* @csspart bar - Each bar rectangle (type="bar").
|
|
11
11
|
*/
|
|
@@ -10,12 +10,21 @@ import { LyraElement } from '../../internal/lyra-element.js';
|
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
11
|
import { styles } from './sparkline.styles.js';
|
|
12
12
|
const VIEW = 100;
|
|
13
|
+
// A <rect> per bar doesn't collapse into one path the way line/area do, so an
|
|
14
|
+
// unbounded `values` array turns directly into that many shadow-DOM nodes.
|
|
15
|
+
// Capping it keeps worst-case DOM size bounded without affecting any
|
|
16
|
+
// realistically-sized bar chart.
|
|
17
|
+
const MAX_BARS = 500;
|
|
18
|
+
function decimate(arr, max) {
|
|
19
|
+
const step = arr.length / max;
|
|
20
|
+
return Array.from({ length: max }, (_, i) => arr[Math.floor(i * step)]);
|
|
21
|
+
}
|
|
13
22
|
/**
|
|
14
23
|
* `<lyra-sparkline>` — a zero-dependency inline SVG trend chart.
|
|
15
24
|
* Mirrors the Web Awesome `<wa-sparkline>` API under the `lyra-` prefix.
|
|
16
25
|
*
|
|
17
26
|
* @customElement lyra-sparkline
|
|
18
|
-
* @csspart line - The line path (type="line").
|
|
27
|
+
* @csspart line - The stroked line path (type="line" and type="area").
|
|
19
28
|
* @csspart area - The filled area under the line (type="area").
|
|
20
29
|
* @csspart bar - Each bar rectangle (type="bar").
|
|
21
30
|
*/
|
|
@@ -30,12 +39,20 @@ export class LyraSparkline extends LyraElement {
|
|
|
30
39
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
31
40
|
points() {
|
|
32
41
|
const v = this.values;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
42
|
+
let autoLo = v[0];
|
|
43
|
+
let autoHi = v[0];
|
|
44
|
+
for (const n of v) {
|
|
45
|
+
if (n < autoLo)
|
|
46
|
+
autoLo = n;
|
|
47
|
+
if (n > autoHi)
|
|
48
|
+
autoHi = n;
|
|
49
|
+
}
|
|
50
|
+
const lo = this.min ?? autoLo;
|
|
51
|
+
const hi = this.max ?? autoHi;
|
|
52
|
+
const span = hi - lo;
|
|
36
53
|
return v.map((n, i) => {
|
|
37
54
|
const x = v.length > 1 ? (i / (v.length - 1)) * VIEW : VIEW / 2;
|
|
38
|
-
const y = VIEW - ((n - lo) / span) * VIEW;
|
|
55
|
+
const y = span === 0 ? VIEW / 2 : VIEW - ((n - lo) / span) * VIEW;
|
|
39
56
|
return [x, y];
|
|
40
57
|
});
|
|
41
58
|
}
|
|
@@ -46,16 +63,26 @@ export class LyraSparkline extends LyraElement {
|
|
|
46
63
|
}
|
|
47
64
|
render() {
|
|
48
65
|
const v = this.values;
|
|
49
|
-
if (!v.length)
|
|
50
|
-
return html `<svg viewBox="0 0 ${VIEW} ${VIEW}"></svg>`;
|
|
66
|
+
if (!v.length) {
|
|
67
|
+
return html `<svg viewBox="0 0 ${VIEW} ${VIEW}" aria-hidden="true"></svg>`;
|
|
68
|
+
}
|
|
51
69
|
const pts = this.points();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
if (this.type === 'bar') {
|
|
71
|
+
const barPts = pts.length > MAX_BARS ? decimate(pts, MAX_BARS) : pts;
|
|
72
|
+
const bars = barPts.map(([x, y]) => {
|
|
73
|
+
const barY = Math.min(y, VIEW);
|
|
74
|
+
return svg `<rect part="bar" x="${x - 2}" y="${barY}" width="4" height="${VIEW - barY}"></rect>`;
|
|
75
|
+
});
|
|
76
|
+
return html `<svg viewBox="0 0 ${VIEW} ${VIEW}" preserveAspectRatio="none" aria-hidden="true">
|
|
77
|
+
${bars}
|
|
78
|
+
</svg>`;
|
|
79
|
+
}
|
|
80
|
+
const d = pts.length > 1
|
|
81
|
+
? pts.map(([x, y], i) => `${i ? 'L' : 'M'}${x},${y}`).join(' ')
|
|
82
|
+
: `M${pts[0][0]},${pts[0][1]} L${pts[0][0]},${pts[0][1]}`;
|
|
83
|
+
return html `<svg viewBox="0 0 ${VIEW} ${VIEW}" preserveAspectRatio="none" aria-hidden="true">
|
|
57
84
|
${this.type === 'area' ? svg `<path part="area" d="${d} L${VIEW},${VIEW} L0,${VIEW} Z"></path>` : ''}
|
|
58
|
-
${
|
|
85
|
+
<path part="line" d="${d}"></path>
|
|
59
86
|
</svg>`;
|
|
60
87
|
}
|
|
61
88
|
}
|
|
@@ -5,3 +5,7 @@ type Story = StoryObj;
|
|
|
5
5
|
export declare const Line: Story;
|
|
6
6
|
export declare const Area: Story;
|
|
7
7
|
export declare const Bar: Story;
|
|
8
|
+
export declare const ExplicitRange: Story;
|
|
9
|
+
export declare const NoData: Story;
|
|
10
|
+
export declare const FlatData: Story;
|
|
11
|
+
export declare const SingleValue: Story;
|
|
@@ -15,3 +15,25 @@ export const Area = {
|
|
|
15
15
|
export const Bar = {
|
|
16
16
|
render: () => html `<lyra-sparkline type="bar" .values=${DATA}></lyra-sparkline>`,
|
|
17
17
|
};
|
|
18
|
+
export const ExplicitRange = {
|
|
19
|
+
render: () => html `
|
|
20
|
+
<lyra-sparkline type="bar" .values=${[20, 40, 30]} min="0" max="100"></lyra-sparkline>
|
|
21
|
+
<lyra-sparkline type="bar" .values=${[70, 90, 80]} min="0" max="100"></lyra-sparkline>
|
|
22
|
+
`,
|
|
23
|
+
};
|
|
24
|
+
export const NoData = {
|
|
25
|
+
render: () => html `<lyra-sparkline></lyra-sparkline>`,
|
|
26
|
+
};
|
|
27
|
+
export const FlatData = {
|
|
28
|
+
render: () => html `
|
|
29
|
+
<lyra-sparkline type="line" .values=${[5, 5, 5, 5]}></lyra-sparkline>
|
|
30
|
+
<lyra-sparkline type="area" .values=${[5, 5, 5, 5]}></lyra-sparkline>
|
|
31
|
+
<lyra-sparkline type="bar" .values=${[5, 5, 5, 5]}></lyra-sparkline>
|
|
32
|
+
`,
|
|
33
|
+
};
|
|
34
|
+
export const SingleValue = {
|
|
35
|
+
render: () => html `
|
|
36
|
+
<lyra-sparkline type="line" .values=${[5]}></lyra-sparkline>
|
|
37
|
+
<lyra-sparkline type="bar" .values=${[5]}></lyra-sparkline>
|
|
38
|
+
`,
|
|
39
|
+
};
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
2
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
3
|
+
/** A fixed-pixel-range constraint for one panel; index-aligned with `sizes`/
|
|
4
|
+
* `panelConstraints`. Either bound may be omitted to leave that side
|
|
5
|
+
* unconstrained (falls back to the component's percent-based `min`). */
|
|
6
|
+
export interface PanelConstraint {
|
|
7
|
+
minPx?: number;
|
|
8
|
+
maxPx?: number;
|
|
9
|
+
}
|
|
3
10
|
/**
|
|
4
11
|
* `<lyra-split>` — resizable panels for dashboard layouts. Direct light-DOM
|
|
5
12
|
* children are the panels; a divider is auto-inserted between each pair.
|
|
@@ -7,6 +14,7 @@ import { LyraElement } from '../../internal/lyra-element.js';
|
|
|
7
14
|
* @customElement lyra-split
|
|
8
15
|
* @event lyra-resize - `detail: { sizes }`, fired on every drag step/release
|
|
9
16
|
* and every keyboard step.
|
|
17
|
+
* @slot - Panels to arrange side by side (or stacked, when `orientation="vertical"`); each direct child becomes one resizable panel.
|
|
10
18
|
* @csspart base, divider
|
|
11
19
|
*/
|
|
12
20
|
export declare class LyraSplit extends LyraElement {
|
|
@@ -15,10 +23,14 @@ export declare class LyraSplit extends LyraElement {
|
|
|
15
23
|
min: number;
|
|
16
24
|
orientation: 'horizontal' | 'vertical';
|
|
17
25
|
storageKey?: string;
|
|
26
|
+
/** Optional fixed-pixel min/max per panel, index-aligned with `sizes`. A
|
|
27
|
+
* `null`/missing entry leaves that panel purely percent-based (the
|
|
28
|
+
* existing `min`-only behavior). `sizes`, the `lyra-resize` payload, and
|
|
29
|
+
* localStorage persistence stay percent-based regardless — only the
|
|
30
|
+
* effective clamp bounds change for a constrained panel. */
|
|
31
|
+
panelConstraints: (PanelConstraint | null)[];
|
|
18
32
|
private panelCount;
|
|
19
|
-
private
|
|
20
|
-
private dragStartPos;
|
|
21
|
-
private dragStartSizes;
|
|
33
|
+
private drags;
|
|
22
34
|
connectedCallback(): void;
|
|
23
35
|
disconnectedCallback(): void;
|
|
24
36
|
private get storageFullKey();
|
|
@@ -26,6 +38,15 @@ export declare class LyraSplit extends LyraElement {
|
|
|
26
38
|
private persist;
|
|
27
39
|
private ensureSizes;
|
|
28
40
|
private onSlotChange;
|
|
41
|
+
/** The container extent (px) along the resize axis, read live so a
|
|
42
|
+
* container resize between calls is always picked up — same live read
|
|
43
|
+
* `onPointerMove` already does via `drag.base.clientWidth/clientHeight`. */
|
|
44
|
+
private getContainerSize;
|
|
45
|
+
/** Resolves panel `index`'s effective percent min/max for this clamp pass:
|
|
46
|
+
* a `panelConstraints` entry's px bound converted against the live
|
|
47
|
+
* `containerSize`, or the component's plain percent `min` (no upper
|
|
48
|
+
* bound) when the panel carries no constraint for that side. */
|
|
49
|
+
private percentBounds;
|
|
29
50
|
private clampPair;
|
|
30
51
|
private applyDelta;
|
|
31
52
|
private onPointerDown;
|