@aceshooting/lyra-ui 1.0.0 → 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.
Files changed (148) hide show
  1. package/README.md +8 -9
  2. package/custom-elements.json +10463 -4519
  3. package/dist/components/chart/chart.d.ts +46 -1
  4. package/dist/components/chart/chart.js +148 -10
  5. package/dist/components/chart/chart.stories.d.ts +32 -0
  6. package/dist/components/chart/chart.stories.js +141 -0
  7. package/dist/components/chart/chart.styles.js +16 -0
  8. package/dist/components/chart/histogram.d.ts +2 -0
  9. package/dist/components/chart/histogram.js +18 -2
  10. package/dist/components/chart/line-chart.stories.d.ts +17 -0
  11. package/dist/components/chart/line-chart.stories.js +75 -0
  12. package/dist/components/chart/lite-chart.d.ts +74 -0
  13. package/dist/components/chart/lite-chart.js +384 -0
  14. package/dist/components/chart/lite-chart.stories.d.ts +12 -0
  15. package/dist/components/chart/lite-chart.stories.js +98 -0
  16. package/dist/components/chart/lite-chart.styles.d.ts +1 -0
  17. package/dist/components/chart/lite-chart.styles.js +83 -0
  18. package/dist/components/combobox/combobox.d.ts +9 -0
  19. package/dist/components/combobox/combobox.js +75 -12
  20. package/dist/components/combobox/combobox.stories.d.ts +18 -0
  21. package/dist/components/combobox/combobox.stories.js +75 -0
  22. package/dist/components/date-picker/calendar-core.js +13 -2
  23. package/dist/components/date-picker/date-input.d.ts +9 -1
  24. package/dist/components/date-picker/date-input.js +55 -7
  25. package/dist/components/date-picker/date-input.stories.d.ts +5 -0
  26. package/dist/components/date-picker/date-input.stories.js +36 -0
  27. package/dist/components/date-picker/date-picker.d.ts +11 -3
  28. package/dist/components/date-picker/date-picker.js +87 -37
  29. package/dist/components/date-picker/date-picker.stories.d.ts +4 -0
  30. package/dist/components/date-picker/date-picker.stories.js +12 -0
  31. package/dist/components/date-picker/date-picker.styles.js +1 -1
  32. package/dist/components/empty/empty.d.ts +12 -1
  33. package/dist/components/empty/empty.js +20 -3
  34. package/dist/components/empty/empty.stories.d.ts +2 -0
  35. package/dist/components/empty/empty.stories.js +20 -0
  36. package/dist/components/empty/empty.styles.js +11 -0
  37. package/dist/components/export-button/csv.js +6 -2
  38. package/dist/components/export-button/export-button.d.ts +15 -1
  39. package/dist/components/export-button/export-button.js +89 -12
  40. package/dist/components/export-button/export-button.stories.d.ts +1 -0
  41. package/dist/components/export-button/export-button.stories.js +5 -0
  42. package/dist/components/export-button/export-button.styles.js +11 -3
  43. package/dist/components/file-input/accept.d.ts +8 -2
  44. package/dist/components/file-input/accept.js +9 -3
  45. package/dist/components/file-input/file-input.d.ts +5 -2
  46. package/dist/components/file-input/file-input.js +23 -8
  47. package/dist/components/file-input/file-input.stories.d.ts +2 -0
  48. package/dist/components/file-input/file-input.stories.js +9 -0
  49. package/dist/components/flag/flag.d.ts +48 -3
  50. package/dist/components/flag/flag.js +65 -29
  51. package/dist/components/flag/flag.styles.js +1 -1
  52. package/dist/components/flag/language-map.d.ts +11 -0
  53. package/dist/components/flag/language-map.js +12 -1
  54. package/dist/components/gauge/gauge.d.ts +2 -0
  55. package/dist/components/gauge/gauge.js +19 -5
  56. package/dist/components/gauge/gauge.stories.d.ts +2 -0
  57. package/dist/components/gauge/gauge.stories.js +6 -0
  58. package/dist/components/graph/graph-loader.d.ts +28 -0
  59. package/dist/components/graph/graph-loader.js +44 -0
  60. package/dist/components/graph/graph.d.ts +41 -15
  61. package/dist/components/graph/graph.js +146 -71
  62. package/dist/components/graph/graph.stories.d.ts +3 -0
  63. package/dist/components/graph/graph.stories.js +38 -0
  64. package/dist/components/graph/graph.styles.js +6 -1
  65. package/dist/components/heatmap/calendar-grid.d.ts +7 -0
  66. package/dist/components/heatmap/calendar-grid.js +27 -10
  67. package/dist/components/heatmap/heatmap.d.ts +137 -12
  68. package/dist/components/heatmap/heatmap.js +427 -27
  69. package/dist/components/heatmap/heatmap.stories.d.ts +17 -0
  70. package/dist/components/heatmap/heatmap.stories.js +130 -0
  71. package/dist/components/heatmap/heatmap.styles.js +60 -2
  72. package/dist/components/map/map.d.ts +17 -1
  73. package/dist/components/map/map.js +68 -21
  74. package/dist/components/map/map.stories.d.ts +10 -0
  75. package/dist/components/map/map.stories.js +107 -12
  76. package/dist/components/map/map.styles.js +2 -2
  77. package/dist/components/playback/playback.d.ts +6 -2
  78. package/dist/components/playback/playback.js +36 -12
  79. package/dist/components/playback/playback.stories.d.ts +2 -0
  80. package/dist/components/playback/playback.stories.js +6 -0
  81. package/dist/components/playback/playback.styles.js +10 -2
  82. package/dist/components/select/select.d.ts +122 -0
  83. package/dist/components/select/select.js +516 -0
  84. package/dist/components/select/select.stories.d.ts +19 -0
  85. package/dist/components/select/select.stories.js +75 -0
  86. package/dist/components/select/select.styles.d.ts +1 -0
  87. package/dist/components/select/select.styles.js +188 -0
  88. package/dist/components/skeleton/skeleton.js +4 -7
  89. package/dist/components/sparkline/sparkline.d.ts +1 -1
  90. package/dist/components/sparkline/sparkline.js +40 -13
  91. package/dist/components/sparkline/sparkline.stories.d.ts +4 -0
  92. package/dist/components/sparkline/sparkline.stories.js +22 -0
  93. package/dist/components/split/split.d.ts +24 -3
  94. package/dist/components/split/split.js +155 -31
  95. package/dist/components/split/split.stories.d.ts +2 -0
  96. package/dist/components/split/split.stories.js +20 -0
  97. package/dist/components/stat/stat.d.ts +27 -1
  98. package/dist/components/stat/stat.js +56 -3
  99. package/dist/components/stat/stat.stories.d.ts +3 -0
  100. package/dist/components/stat/stat.stories.js +49 -1
  101. package/dist/components/stat/stat.styles.js +44 -0
  102. package/dist/components/table/table.d.ts +64 -2
  103. package/dist/components/table/table.js +213 -17
  104. package/dist/components/table/table.stories.d.ts +6 -0
  105. package/dist/components/table/table.stories.js +45 -0
  106. package/dist/components/table/table.styles.js +51 -4
  107. package/dist/components/time-range/time-range.d.ts +34 -5
  108. package/dist/components/time-range/time-range.js +217 -36
  109. package/dist/components/time-range/time-range.stories.d.ts +2 -0
  110. package/dist/components/time-range/time-range.stories.js +13 -0
  111. package/dist/components/time-range/time-range.styles.js +44 -2
  112. package/dist/components/toast/toast-item.d.ts +14 -2
  113. package/dist/components/toast/toast-item.js +134 -17
  114. package/dist/components/toast/toast-item.styles.js +28 -2
  115. package/dist/components/toast/toast.stories.d.ts +3 -0
  116. package/dist/components/toast/toast.stories.js +41 -1
  117. package/dist/components/toast/toast.styles.js +11 -11
  118. package/dist/components/toast/toaster.d.ts +1 -1
  119. package/dist/components/toast/toaster.js +13 -6
  120. package/dist/components/tree/tree-node.d.ts +13 -7
  121. package/dist/components/tree/tree-node.js +24 -10
  122. package/dist/components/tree/tree.d.ts +64 -15
  123. package/dist/components/tree/tree.js +113 -22
  124. package/dist/components/tree/tree.stories.d.ts +4 -0
  125. package/dist/components/tree/tree.stories.js +31 -1
  126. package/dist/components/tree/update-cascade.d.ts +13 -0
  127. package/dist/components/tree/update-cascade.js +13 -0
  128. package/dist/components/widget/widget.d.ts +15 -1
  129. package/dist/components/widget/widget.js +140 -5
  130. package/dist/components/widget/widget.stories.d.ts +1 -0
  131. package/dist/components/widget/widget.stories.js +10 -0
  132. package/dist/components/widget/widget.styles.js +11 -1
  133. package/dist/components/word-cloud/word-cloud-layout.d.ts +63 -0
  134. package/dist/components/word-cloud/word-cloud-layout.js +145 -0
  135. package/dist/components/word-cloud/word-cloud.d.ts +65 -0
  136. package/dist/components/word-cloud/word-cloud.js +255 -0
  137. package/dist/components/word-cloud/word-cloud.stories.d.ts +10 -0
  138. package/dist/components/word-cloud/word-cloud.stories.js +55 -0
  139. package/dist/components/word-cloud/word-cloud.styles.d.ts +1 -0
  140. package/dist/components/word-cloud/word-cloud.styles.js +54 -0
  141. package/dist/internal/a11y.js +2 -1
  142. package/dist/internal/rtl.d.ts +7 -0
  143. package/dist/internal/rtl.js +9 -0
  144. package/dist/lyra.d.ts +9 -1
  145. package/dist/lyra.js +6 -0
  146. package/llms-full.txt +892 -276
  147. package/llms.txt +12 -9
  148. 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
- base.style.setProperty('--lyra-skeleton-w', this.width);
33
+ this.style.setProperty('--lyra-skeleton-w', this.width);
37
34
  }
38
35
  else {
39
- base.style.removeProperty('--lyra-skeleton-w');
36
+ this.style.removeProperty('--lyra-skeleton-w');
40
37
  }
41
38
  if (this.height) {
42
- base.style.setProperty('--lyra-skeleton-h', this.height);
39
+ this.style.setProperty('--lyra-skeleton-h', this.height);
43
40
  }
44
41
  else {
45
- base.style.removeProperty('--lyra-skeleton-h');
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
- const lo = this.min ?? Math.min(...v);
34
- const hi = this.max ?? Math.max(...v);
35
- const span = hi - lo || 1;
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
- const d = pts.map(([x, y], i) => `${i ? 'L' : 'M'}${x},${y}`).join(' ');
53
- const shape = this.type === 'bar'
54
- ? pts.map(([x, y]) => svg `<rect part="bar" x="${x - 2}" y="${y}" width="4" height="${VIEW - y}"></rect>`)
55
- : svg `<path part="line" d="${d}"></path>`;
56
- return html `<svg viewBox="0 0 ${VIEW} ${VIEW}" preserveAspectRatio="none">
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
- ${shape}
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 dragIndex;
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;