@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.
Files changed (224) hide show
  1. package/README.md +87 -14
  2. package/custom-elements.json +11555 -5539
  3. package/dist/components/app-rail/app-rail-item.d.ts +30 -0
  4. package/dist/components/app-rail/app-rail-item.js +68 -0
  5. package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
  6. package/dist/components/app-rail/app-rail-item.styles.js +65 -0
  7. package/dist/components/app-rail/app-rail.d.ts +21 -24
  8. package/dist/components/app-rail/app-rail.js +68 -132
  9. package/dist/components/app-rail/app-rail.styles.js +5 -2
  10. package/dist/components/attachment-chip/attachment-chip.d.ts +38 -11
  11. package/dist/components/attachment-chip/attachment-chip.js +73 -29
  12. package/dist/components/attachment-trigger/attachment-trigger.d.ts +13 -0
  13. package/dist/components/attachment-trigger/attachment-trigger.js +13 -1
  14. package/dist/components/attachment-trigger/attachment-trigger.styles.js +28 -6
  15. package/dist/components/chart/bar-chart.js +2 -18
  16. package/dist/components/chart/box-plot.d.ts +25 -1
  17. package/dist/components/chart/box-plot.js +136 -6
  18. package/dist/components/chart/box-plot.styles.js +13 -0
  19. package/dist/components/chart/bubble-chart.js +2 -18
  20. package/dist/components/chart/chart.d.ts +54 -10
  21. package/dist/components/chart/chart.js +182 -39
  22. package/dist/components/chart/doughnut-chart.js +2 -18
  23. package/dist/components/chart/histogram-bin.d.ts +5 -2
  24. package/dist/components/chart/histogram-bin.js +12 -4
  25. package/dist/components/chart/histogram.js +8 -16
  26. package/dist/components/chart/line-chart.js +2 -18
  27. package/dist/components/chart/lite-chart.d.ts +80 -3
  28. package/dist/components/chart/lite-chart.js +250 -53
  29. package/dist/components/chart/pie-chart.js +2 -18
  30. package/dist/components/chart/polar-area-chart.js +2 -18
  31. package/dist/components/chart/radar-chart.js +2 -18
  32. package/dist/components/chart/scatter-chart.js +2 -18
  33. package/dist/components/chat-composer/chat-composer.d.ts +42 -1
  34. package/dist/components/chat-composer/chat-composer.js +84 -3
  35. package/dist/components/chat-composer/chat-composer.styles.js +11 -1
  36. package/dist/components/chat-message/chat-message.d.ts +32 -4
  37. package/dist/components/chat-message/chat-message.js +57 -17
  38. package/dist/components/checkbox/checkbox.d.ts +66 -8
  39. package/dist/components/checkbox/checkbox.js +173 -50
  40. package/dist/components/checkbox/checkbox.styles.js +9 -2
  41. package/dist/components/chip/chip-group.js +8 -2
  42. package/dist/components/chip/chip.js +9 -2
  43. package/dist/components/citation-badge/citation-badge.js +21 -3
  44. package/dist/components/code-block/code-block.d.ts +38 -0
  45. package/dist/components/code-block/code-block.js +72 -7
  46. package/dist/components/code-block/code-loader.d.ts +44 -1
  47. package/dist/components/code-block/code-loader.js +63 -0
  48. package/dist/components/combobox/combobox.d.ts +46 -5
  49. package/dist/components/combobox/combobox.js +175 -35
  50. package/dist/components/combobox/combobox.styles.js +3 -3
  51. package/dist/components/context-meter/context-meter.js +17 -8
  52. package/dist/components/context-meter/context-meter.styles.js +0 -6
  53. package/dist/components/conversation-item/conversation-item.d.ts +13 -16
  54. package/dist/components/conversation-item/conversation-item.js +29 -20
  55. package/dist/components/date-picker/calendar-core.d.ts +24 -0
  56. package/dist/components/date-picker/calendar-core.js +51 -4
  57. package/dist/components/date-picker/date-input.d.ts +77 -10
  58. package/dist/components/date-picker/date-input.js +278 -73
  59. package/dist/components/date-picker/date-picker.d.ts +28 -4
  60. package/dist/components/date-picker/date-picker.js +95 -37
  61. package/dist/components/dialog/confirm.js +3 -6
  62. package/dist/components/dialog/dialog.d.ts +75 -31
  63. package/dist/components/dialog/dialog.js +147 -131
  64. package/dist/components/dialog/dialog.styles.js +46 -2
  65. package/dist/components/dock-panel/dock-panel.d.ts +8 -0
  66. package/dist/components/dock-panel/dock-panel.js +15 -1
  67. package/dist/components/dock-panel/dock-panel.styles.js +15 -1
  68. package/dist/components/document-preview/document-preview.d.ts +15 -7
  69. package/dist/components/document-preview/document-preview.js +29 -13
  70. package/dist/components/empty/empty.d.ts +1 -2
  71. package/dist/components/empty/empty.js +18 -12
  72. package/dist/components/empty/empty.styles.js +0 -3
  73. package/dist/components/export-button/export-button.d.ts +12 -0
  74. package/dist/components/export-button/export-button.js +33 -5
  75. package/dist/components/export-button/export-button.styles.js +5 -1
  76. package/dist/components/file-input/accept.js +2 -0
  77. package/dist/components/file-input/file-input.d.ts +10 -1
  78. package/dist/components/file-input/file-input.js +36 -5
  79. package/dist/components/flag/flag.d.ts +1 -1
  80. package/dist/components/flag/flag.js +15 -1
  81. package/dist/components/flag/flag.styles.js +1 -1
  82. package/dist/components/flag/language-map.d.ts +4 -1
  83. package/dist/components/flag/language-map.js +6 -3
  84. package/dist/components/gauge/gauge.d.ts +10 -1
  85. package/dist/components/gauge/gauge.js +28 -9
  86. package/dist/components/generation-status/generation-status.d.ts +13 -5
  87. package/dist/components/generation-status/generation-status.js +59 -5
  88. package/dist/components/graph/graph.d.ts +37 -3
  89. package/dist/components/graph/graph.js +132 -20
  90. package/dist/components/heatmap/calendar-grid.d.ts +15 -6
  91. package/dist/components/heatmap/calendar-grid.js +17 -6
  92. package/dist/components/heatmap/heatmap-scale.d.ts +5 -1
  93. package/dist/components/heatmap/heatmap-scale.js +8 -2
  94. package/dist/components/heatmap/heatmap.d.ts +166 -25
  95. package/dist/components/heatmap/heatmap.js +372 -89
  96. package/dist/components/json-viewer/json-viewer.d.ts +22 -5
  97. package/dist/components/json-viewer/json-viewer.js +115 -37
  98. package/dist/components/json-viewer/json-viewer.styles.js +2 -1
  99. package/dist/components/kbd/kbd.js +24 -7
  100. package/dist/components/live-region/live-region.d.ts +10 -1
  101. package/dist/components/live-region/live-region.js +42 -6
  102. package/dist/components/map/map.d.ts +24 -1
  103. package/dist/components/map/map.js +89 -24
  104. package/dist/components/markdown/markdown-loader.d.ts +24 -0
  105. package/dist/components/markdown/markdown-loader.js +35 -1
  106. package/dist/components/markdown/markdown.d.ts +46 -8
  107. package/dist/components/markdown/markdown.js +136 -31
  108. package/dist/components/markdown/markdown.styles.js +7 -1
  109. package/dist/components/media-card/media-card.d.ts +25 -17
  110. package/dist/components/media-card/media-card.js +43 -65
  111. package/dist/components/mention-popover/mention-popover.d.ts +4 -1
  112. package/dist/components/mention-popover/mention-popover.js +23 -5
  113. package/dist/components/menu/menu-item.d.ts +32 -3
  114. package/dist/components/menu/menu-item.js +94 -7
  115. package/dist/components/menu/menu-item.styles.js +8 -0
  116. package/dist/components/menu/menu.d.ts +25 -1
  117. package/dist/components/menu/menu.js +99 -3
  118. package/dist/components/menu/menu.styles.js +3 -2
  119. package/dist/components/model-select/model-select.d.ts +48 -3
  120. package/dist/components/model-select/model-select.js +120 -22
  121. package/dist/components/model-select/model-select.styles.js +17 -3
  122. package/dist/components/model-settings-panel/model-settings-panel.d.ts +25 -1
  123. package/dist/components/model-settings-panel/model-settings-panel.js +65 -1
  124. package/dist/components/playback/playback.d.ts +6 -2
  125. package/dist/components/playback/playback.js +72 -29
  126. package/dist/components/playback/playback.styles.js +6 -1
  127. package/dist/components/responsive-panel/responsive-panel.d.ts +29 -16
  128. package/dist/components/responsive-panel/responsive-panel.js +130 -132
  129. package/dist/components/responsive-panel/responsive-panel.styles.js +1 -1
  130. package/dist/components/result-card/result-card.d.ts +8 -2
  131. package/dist/components/result-card/result-card.js +9 -3
  132. package/dist/components/result-card/result-card.styles.js +0 -1
  133. package/dist/components/select/select.d.ts +59 -20
  134. package/dist/components/select/select.js +125 -43
  135. package/dist/components/skeleton/skeleton.d.ts +3 -0
  136. package/dist/components/skeleton/skeleton.js +7 -1
  137. package/dist/components/skeleton/skeleton.styles.js +5 -4
  138. package/dist/components/slider/slider.d.ts +57 -5
  139. package/dist/components/slider/slider.js +195 -80
  140. package/dist/components/source-card/source-card.d.ts +17 -5
  141. package/dist/components/source-card/source-card.js +55 -8
  142. package/dist/components/source-card/source-card.styles.js +1 -1
  143. package/dist/components/source-list/source-list.js +9 -1
  144. package/dist/components/sparkline/sparkline.js +34 -10
  145. package/dist/components/split/split.d.ts +141 -14
  146. package/dist/components/split/split.js +357 -52
  147. package/dist/components/split/split.styles.js +18 -1
  148. package/dist/components/stat/stat.d.ts +10 -4
  149. package/dist/components/stat/stat.js +46 -11
  150. package/dist/components/stream-status/stream-status.d.ts +27 -11
  151. package/dist/components/stream-status/stream-status.js +95 -13
  152. package/dist/components/streaming-text/streaming-text.d.ts +9 -3
  153. package/dist/components/streaming-text/streaming-text.js +25 -10
  154. package/dist/components/streaming-text/streaming-text.styles.js +3 -2
  155. package/dist/components/switch/switch.d.ts +52 -7
  156. package/dist/components/switch/switch.js +111 -40
  157. package/dist/components/switch/switch.styles.js +1 -1
  158. package/dist/components/table/table.d.ts +18 -3
  159. package/dist/components/table/table.js +88 -20
  160. package/dist/components/tabs/tabs.d.ts +23 -0
  161. package/dist/components/tabs/tabs.js +76 -12
  162. package/dist/components/tabs/tabs.styles.js +11 -0
  163. package/dist/components/thinking-panel/thinking-panel.d.ts +3 -1
  164. package/dist/components/thinking-panel/thinking-panel.js +34 -9
  165. package/dist/components/thinking-panel/thinking-panel.styles.js +6 -0
  166. package/dist/components/time-range/time-range.d.ts +59 -2
  167. package/dist/components/time-range/time-range.js +163 -67
  168. package/dist/components/toast/toast-item.d.ts +12 -3
  169. package/dist/components/toast/toast-item.js +90 -53
  170. package/dist/components/toast/toast-item.styles.js +59 -28
  171. package/dist/components/toast/toast.js +17 -5
  172. package/dist/components/toast/toaster.js +10 -1
  173. package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +11 -10
  174. package/dist/components/tool-approval-dialog/tool-approval-dialog.js +50 -124
  175. package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +1 -1
  176. package/dist/components/tool-call-chip/tool-call-chip.d.ts +18 -2
  177. package/dist/components/tool-call-chip/tool-call-chip.js +86 -25
  178. package/dist/components/tool-param-form/tool-param-form.d.ts +89 -28
  179. package/dist/components/tool-param-form/tool-param-form.js +350 -106
  180. package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +27 -7
  181. package/dist/components/tool-result-dialog/tool-result-dialog.js +80 -115
  182. package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +1 -1
  183. package/dist/components/tool-result-view/registry.d.ts +0 -8
  184. package/dist/components/tool-result-view/registry.js +7 -2
  185. package/dist/components/tool-result-view/tool-result-view.d.ts +6 -3
  186. package/dist/components/tool-result-view/tool-result-view.js +18 -4
  187. package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +11 -11
  188. package/dist/components/tool-select-dialog/tool-select-dialog.js +44 -133
  189. package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +13 -4
  190. package/dist/components/tree/tree-node.d.ts +4 -1
  191. package/dist/components/tree/tree-node.js +4 -1
  192. package/dist/components/tree/tree.d.ts +17 -8
  193. package/dist/components/tree/tree.js +21 -20
  194. package/dist/components/typing-indicator/typing-indicator.d.ts +12 -2
  195. package/dist/components/typing-indicator/typing-indicator.js +16 -4
  196. package/dist/components/typing-indicator/typing-indicator.styles.js +2 -2
  197. package/dist/components/virtual-list/virtual-list.d.ts +56 -19
  198. package/dist/components/virtual-list/virtual-list.js +184 -38
  199. package/dist/components/virtual-list/virtual-list.styles.js +12 -0
  200. package/dist/components/widget/widget.d.ts +5 -4
  201. package/dist/components/widget/widget.js +54 -120
  202. package/dist/components/widget/widget.styles.js +8 -2
  203. package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
  204. package/dist/components/word-cloud/word-cloud-layout.js +20 -6
  205. package/dist/components/word-cloud/word-cloud.d.ts +22 -2
  206. package/dist/components/word-cloud/word-cloud.js +45 -6
  207. package/dist/components/word-cloud/word-cloud.styles.js +13 -1
  208. package/dist/internal/anchored-validity.d.ts +1 -0
  209. package/dist/internal/anchored-validity.js +86 -0
  210. package/dist/internal/form-associated.d.ts +7 -0
  211. package/dist/internal/form-associated.js +43 -4
  212. package/dist/internal/numbers.d.ts +12 -0
  213. package/dist/internal/numbers.js +26 -0
  214. package/dist/internal/overlay-manager.d.ts +51 -0
  215. package/dist/internal/overlay-manager.js +523 -0
  216. package/dist/internal/positioner.js +27 -3
  217. package/dist/internal/safe-url.d.ts +12 -0
  218. package/dist/internal/safe-url.js +41 -0
  219. package/dist/internal/tokens.styles.js +17 -11
  220. package/dist/lyra.d.ts +5 -2
  221. package/dist/lyra.js +3 -1
  222. package/llms-full.txt +970 -426
  223. package/llms.txt +5 -4
  224. package/package.json +19 -2
@@ -1,4 +1,4 @@
1
- import { type TemplateResult, type PropertyValues } from 'lit';
1
+ import { type TemplateResult } from 'lit';
2
2
  import { LyraElement } from '../../internal/lyra-element.js';
3
3
  export type AttachmentChipStatus = 'pending' | 'uploading' | 'error' | 'done';
4
4
  export interface AttachmentChipIdDetail {
@@ -25,9 +25,9 @@ export declare function formatFileSize(bytes: number): string;
25
25
  * (e.g. after a page reload, when no real `File` object exists any more).
26
26
  *
27
27
  * `file` always wins when both are present — see each accessor's own doc.
28
- * The image thumbnail for a real `File` is a lazily-created (only once the
29
- * thumbnail is actually about to render, not eagerly on assignment)
30
- * `URL.createObjectURL()` blob URL, revoked automatically once `file`
28
+ * The image thumbnail for a real `File` is a cached `URL.createObjectURL()`
29
+ * blob URL, created in the update lifecycle immediately before the thumbnail
30
+ * renders and revoked automatically once `file`
31
31
  * changes away from the object it was created for, and on disconnect — this
32
32
  * component never leaks a blob URL.
33
33
  *
@@ -43,6 +43,16 @@ export declare function formatFileSize(bytes: number): string;
43
43
  * consumer to invent one. When neither is available, a generated internal id
44
44
  * is used as a last resort so the event always has *some* id.
45
45
  *
46
+ * i18n/locale: every translatable word rendered by this component is
47
+ * override-able via a dedicated property — `removeLabel`/`retryLabel`
48
+ * (the verb prefixed to the remove/retry buttons' `aria-label`, keeping the
49
+ * `displayName` interpolation), and `uploadingLabel`/`uploadFailedLabel` (the
50
+ * verb/phrase used in the visible `status-text`, keeping the live percentage
51
+ * interpolation for `uploadingLabel`). All four default to today's exact
52
+ * hardcoded English text (`'Remove'`, `'Retry'`, `'Uploading'`, `'Upload
53
+ * failed'`), so leaving them unset changes nothing. These are plain
54
+ * properties, not slots — this component still exposes no slots.
55
+ *
46
56
  * @customElement lyra-attachment-chip
47
57
  * @event lyra-remove - The user activated the remove (×) button. `detail: { id }`. Only rendered while `removable`.
48
58
  * @event lyra-retry - The user activated the retry button. `detail: { id }`. Only rendered while `status="error"`.
@@ -51,7 +61,7 @@ export declare function formatFileSize(bytes: number): string;
51
61
  * @csspart meta - Wrapper around `name` and `size`.
52
62
  * @csspart name - The filename (ellipsis-truncated via CSS; the untruncated name is always available via the native `title` tooltip).
53
63
  * @csspart size - The human-readable formatted file size. Hidden when no size is known.
54
- * @csspart status-text - The visible text twin of the status accent color — carries the state in text, not just color. Empty/hidden for `pending`/`done`.
64
+ * @csspart status-text - The visible text twin of the status accent color — carries the state in text, not just color. Empty/hidden for `pending`/`done`. Gets `role="alert"` for `status="error"` only, so a screen-reader user not already focused on the chip still hears an upload failure; the ticking `'uploading'` readout deliberately stays out of the accessibility tree the same way `<lyra-generation-status>`'s per-second elapsed/token readout does — a live region re-announcing every progress tick would be noise, not information, while a one-shot failure is exactly the kind of infrequent, actionable transition a live region exists for.
55
65
  * @csspart progress - The numeric upload progress bar (`role="progressbar"`), shown only while `status="uploading"` and `progress` is a meaningful (>0) number.
56
66
  * @csspart progress-fill - The filled portion of `progress`.
57
67
  * @csspart spinner - The indeterminate upload spinner, shown instead of `progress` while `status="uploading"` and `progress` is unset/0.
@@ -83,6 +93,26 @@ export declare class LyraAttachmentChip extends LyraElement {
83
93
  progress: number;
84
94
  /** Shows the remove (×) button. */
85
95
  removable: boolean;
96
+ /** Verb used in the remove button's `aria-label`, interpolated as
97
+ * `` `${removeLabel} ${displayName}` `` -- override for i18n/locale.
98
+ * Defaults to `'Remove'`, reproducing today's exact `"Remove ${displayName}"`
99
+ * text byte-for-byte. */
100
+ removeLabel: string;
101
+ /** Verb used in the retry button's `aria-label`, interpolated as
102
+ * `` `${retryLabel} ${displayName}` `` -- override for i18n/locale.
103
+ * Defaults to `'Retry'`, reproducing today's exact `"Retry ${displayName}"`
104
+ * text byte-for-byte. */
105
+ retryLabel: string;
106
+ /** Verb used in the visible uploading status text -- rendered as
107
+ * `` `${uploadingLabel} ${percent}%` `` once progress is a meaningful
108
+ * number, else `` `${uploadingLabel}…` ``. Override for i18n/locale.
109
+ * Defaults to `'Uploading'`, reproducing today's exact `"Uploading N%"`/
110
+ * `"Uploading…"` text byte-for-byte. */
111
+ uploadingLabel: string;
112
+ /** Visible status text shown for `status="error"`. Override for
113
+ * i18n/locale. Defaults to `'Upload failed'`, reproducing today's exact
114
+ * text byte-for-byte. */
115
+ uploadFailedLabel: string;
86
116
  private objectUrl?;
87
117
  private objectUrlFile?;
88
118
  private readonly fallbackId;
@@ -93,14 +123,11 @@ export declare class LyraAttachmentChip extends LyraElement {
93
123
  private get hasNumericProgress();
94
124
  private get clampedProgress();
95
125
  /** Returns (creating or reusing as needed) the object URL for `file`'s
96
- * image thumbnail. Only ever called from `render()`, i.e. only once a
97
- * thumbnail is actually about to be painted -- never eagerly from a
98
- * `file`/`willUpdate`/`updated` property-change hook -- so a `file` that's
99
- * reassigned several times before the next paint never creates URLs that
100
- * are immediately thrown away unused. */
126
+ * image thumbnail. Called from the update lifecycle, never from `render()`,
127
+ * so rendering stays a pure projection of already-prepared state. */
101
128
  private ensureObjectUrl;
102
129
  private revokeObjectUrl;
103
- protected updated(changed: PropertyValues): void;
130
+ protected willUpdate(): void;
104
131
  disconnectedCallback(): void;
105
132
  private onRemoveClick;
106
133
  private onRetryClick;
@@ -5,7 +5,7 @@ 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, nothing, svg } from 'lit';
8
- import { property, state } from 'lit/decorators.js';
8
+ import { property } from 'lit/decorators.js';
9
9
  import { LyraElement } from '../../internal/lyra-element.js';
10
10
  import { defineElement } from '../../internal/prefix.js';
11
11
  import { nextId } from '../../internal/a11y.js';
@@ -78,12 +78,20 @@ export function formatFileSize(bytes) {
78
78
  return `${value.toFixed(1)} ${BYTE_UNITS[unitIndex]}`;
79
79
  }
80
80
  /** Visible (not just color-coded) text for every non-resting status --
81
- * `'pending'`/`'done'` render nothing here, they're resting states. */
82
- function statusText(status, progress) {
81
+ * `'pending'`/`'done'` render nothing here, they're resting states.
82
+ * `clampedProgress` (not the raw `progress`) is what gets displayed, so the
83
+ * percentage shown here can never drift from the progressbar's own
84
+ * `aria-valuenow`/fill-width, which reads from the same clamped value.
85
+ * `uploadingLabel`/`uploadFailedLabel` are the host's (possibly overridden)
86
+ * verb/phrase -- defaulting to `'Uploading'`/`'Upload failed'` reproduces
87
+ * today's exact hardcoded text byte-for-byte. */
88
+ function statusText(status, progress, clampedProgress, uploadingLabel, uploadFailedLabel) {
83
89
  if (status === 'error')
84
- return 'Upload failed';
90
+ return uploadFailedLabel;
85
91
  if (status === 'uploading') {
86
- return Number.isFinite(progress) && progress > 0 ? `Uploading ${Math.round(Math.min(100, progress))}%` : 'Uploading…';
92
+ return Number.isFinite(progress) && progress > 0
93
+ ? `${uploadingLabel} ${Math.round(clampedProgress)}%`
94
+ : `${uploadingLabel}…`;
87
95
  }
88
96
  return '';
89
97
  }
@@ -101,9 +109,9 @@ function statusText(status, progress) {
101
109
  * (e.g. after a page reload, when no real `File` object exists any more).
102
110
  *
103
111
  * `file` always wins when both are present — see each accessor's own doc.
104
- * The image thumbnail for a real `File` is a lazily-created (only once the
105
- * thumbnail is actually about to render, not eagerly on assignment)
106
- * `URL.createObjectURL()` blob URL, revoked automatically once `file`
112
+ * The image thumbnail for a real `File` is a cached `URL.createObjectURL()`
113
+ * blob URL, created in the update lifecycle immediately before the thumbnail
114
+ * renders and revoked automatically once `file`
107
115
  * changes away from the object it was created for, and on disconnect — this
108
116
  * component never leaks a blob URL.
109
117
  *
@@ -119,6 +127,16 @@ function statusText(status, progress) {
119
127
  * consumer to invent one. When neither is available, a generated internal id
120
128
  * is used as a last resort so the event always has *some* id.
121
129
  *
130
+ * i18n/locale: every translatable word rendered by this component is
131
+ * override-able via a dedicated property — `removeLabel`/`retryLabel`
132
+ * (the verb prefixed to the remove/retry buttons' `aria-label`, keeping the
133
+ * `displayName` interpolation), and `uploadingLabel`/`uploadFailedLabel` (the
134
+ * verb/phrase used in the visible `status-text`, keeping the live percentage
135
+ * interpolation for `uploadingLabel`). All four default to today's exact
136
+ * hardcoded English text (`'Remove'`, `'Retry'`, `'Uploading'`, `'Upload
137
+ * failed'`), so leaving them unset changes nothing. These are plain
138
+ * properties, not slots — this component still exposes no slots.
139
+ *
122
140
  * @customElement lyra-attachment-chip
123
141
  * @event lyra-remove - The user activated the remove (×) button. `detail: { id }`. Only rendered while `removable`.
124
142
  * @event lyra-retry - The user activated the retry button. `detail: { id }`. Only rendered while `status="error"`.
@@ -127,7 +145,7 @@ function statusText(status, progress) {
127
145
  * @csspart meta - Wrapper around `name` and `size`.
128
146
  * @csspart name - The filename (ellipsis-truncated via CSS; the untruncated name is always available via the native `title` tooltip).
129
147
  * @csspart size - The human-readable formatted file size. Hidden when no size is known.
130
- * @csspart status-text - The visible text twin of the status accent color — carries the state in text, not just color. Empty/hidden for `pending`/`done`.
148
+ * @csspart status-text - The visible text twin of the status accent color — carries the state in text, not just color. Empty/hidden for `pending`/`done`. Gets `role="alert"` for `status="error"` only, so a screen-reader user not already focused on the chip still hears an upload failure; the ticking `'uploading'` readout deliberately stays out of the accessibility tree the same way `<lyra-generation-status>`'s per-second elapsed/token readout does — a live region re-announcing every progress tick would be noise, not information, while a one-shot failure is exactly the kind of infrequent, actionable transition a live region exists for.
131
149
  * @csspart progress - The numeric upload progress bar (`role="progressbar"`), shown only while `status="uploading"` and `progress` is a meaningful (>0) number.
132
150
  * @csspart progress-fill - The filled portion of `progress`.
133
151
  * @csspart spinner - The indeterminate upload spinner, shown instead of `progress` while `status="uploading"` and `progress` is unset/0.
@@ -156,6 +174,26 @@ export class LyraAttachmentChip extends LyraElement {
156
174
  this.progress = 0;
157
175
  /** Shows the remove (×) button. */
158
176
  this.removable = true;
177
+ /** Verb used in the remove button's `aria-label`, interpolated as
178
+ * `` `${removeLabel} ${displayName}` `` -- override for i18n/locale.
179
+ * Defaults to `'Remove'`, reproducing today's exact `"Remove ${displayName}"`
180
+ * text byte-for-byte. */
181
+ this.removeLabel = 'Remove';
182
+ /** Verb used in the retry button's `aria-label`, interpolated as
183
+ * `` `${retryLabel} ${displayName}` `` -- override for i18n/locale.
184
+ * Defaults to `'Retry'`, reproducing today's exact `"Retry ${displayName}"`
185
+ * text byte-for-byte. */
186
+ this.retryLabel = 'Retry';
187
+ /** Verb used in the visible uploading status text -- rendered as
188
+ * `` `${uploadingLabel} ${percent}%` `` once progress is a meaningful
189
+ * number, else `` `${uploadingLabel}…` ``. Override for i18n/locale.
190
+ * Defaults to `'Uploading'`, reproducing today's exact `"Uploading N%"`/
191
+ * `"Uploading…"` text byte-for-byte. */
192
+ this.uploadingLabel = 'Uploading';
193
+ /** Visible status text shown for `status="error"`. Override for
194
+ * i18n/locale. Defaults to `'Upload failed'`, reproducing today's exact
195
+ * text byte-for-byte. */
196
+ this.uploadFailedLabel = 'Upload failed';
159
197
  // Last-resort id, generated once per instance -- see the class doc's
160
198
  // "Identifying which attachment..." section.
161
199
  this.fallbackId = nextId('attachment-chip');
@@ -190,11 +228,8 @@ export class LyraAttachmentChip extends LyraElement {
190
228
  return Math.min(100, Math.max(0, this.progress));
191
229
  }
192
230
  /** Returns (creating or reusing as needed) the object URL for `file`'s
193
- * image thumbnail. Only ever called from `render()`, i.e. only once a
194
- * thumbnail is actually about to be painted -- never eagerly from a
195
- * `file`/`willUpdate`/`updated` property-change hook -- so a `file` that's
196
- * reassigned several times before the next paint never creates URLs that
197
- * are immediately thrown away unused. */
231
+ * image thumbnail. Called from the update lifecycle, never from `render()`,
232
+ * so rendering stays a pure projection of already-prepared state. */
198
233
  ensureObjectUrl(file) {
199
234
  if (this.objectUrlFile === file && this.objectUrl)
200
235
  return this.objectUrl;
@@ -209,15 +244,15 @@ export class LyraAttachmentChip extends LyraElement {
209
244
  this.objectUrl = undefined;
210
245
  this.objectUrlFile = undefined;
211
246
  }
212
- updated(changed) {
213
- // `file` changed to a different object (including to `undefined`) since
214
- // the URL currently held was created -- it no longer represents anything
215
- // this chip still shows, so revoke it now rather than waiting for a
216
- // render that may never again call `ensureObjectUrl()` (e.g. the new
217
- // `file` isn't an image, or is unset).
218
- if (changed.has('file') && this.objectUrlFile && this.objectUrlFile !== this.file) {
247
+ willUpdate() {
248
+ // Prepare or revoke the non-reactive cache before render. This keeps URL
249
+ // allocation out of the render phase and also handles a file changing to
250
+ // a non-image or to undefined, where no thumbnail render would otherwise
251
+ // revisit the old cache entry.
252
+ if (this.file?.type.startsWith('image/'))
253
+ this.ensureObjectUrl(this.file);
254
+ else if (this.objectUrlFile)
219
255
  this.revokeObjectUrl();
220
- }
221
256
  }
222
257
  disconnectedCallback() {
223
258
  super.disconnectedCallback();
@@ -226,7 +261,7 @@ export class LyraAttachmentChip extends LyraElement {
226
261
  renderThumbnail() {
227
262
  if (this.file) {
228
263
  return this.effectiveMimeType.startsWith('image/')
229
- ? html `<img src=${this.ensureObjectUrl(this.file)} alt="" />`
264
+ ? html `<img src=${this.objectUrl ?? ''} alt="" />`
230
265
  : html `${fileGlyph()}`;
231
266
  }
232
267
  // No `file`: `thumbnail-src` is used whenever present, regardless of
@@ -242,7 +277,7 @@ export class LyraAttachmentChip extends LyraElement {
242
277
  // distinguish a genuinely empty file from a size that was simply never
243
278
  // supplied) -- hide the part entirely rather than show a literal "0 B".
244
279
  const sizeText = this.effectiveSize > 0 ? formatFileSize(this.effectiveSize) : '';
245
- const text = statusText(this.status, this.progress);
280
+ const text = statusText(this.status, this.progress, this.clampedProgress, this.uploadingLabel, this.uploadFailedLabel);
246
281
  const uploading = this.status === 'uploading';
247
282
  return html `
248
283
  <div part="base">
@@ -250,7 +285,7 @@ export class LyraAttachmentChip extends LyraElement {
250
285
  <span part="meta">
251
286
  <span part="name" title=${name || 'Untitled file'}>${displayName}</span>
252
287
  <span part="size" ?hidden=${!sizeText}>${sizeText || nothing}</span>
253
- <span part="status-text" ?hidden=${!text}>${text || nothing}</span>
288
+ <span part="status-text" role=${this.status === 'error' ? 'alert' : nothing} ?hidden=${!text}>${text || nothing}</span>
254
289
  </span>
255
290
  ${uploading
256
291
  ? this.hasNumericProgress
@@ -269,12 +304,12 @@ export class LyraAttachmentChip extends LyraElement {
269
304
  : html `<span part="spinner" role="status" aria-label=${`Uploading ${displayName}`}></span>`
270
305
  : nothing}
271
306
  ${this.status === 'error'
272
- ? html `<button part="retry-button" type="button" aria-label=${`Retry ${displayName}`} @click=${this.onRetryClick}>
307
+ ? html `<button part="retry-button" type="button" aria-label=${`${this.retryLabel} ${displayName}`} @click=${this.onRetryClick}>
273
308
  ${retryIcon()}
274
309
  </button>`
275
310
  : nothing}
276
311
  ${this.removable
277
- ? html `<button part="remove-button" type="button" aria-label=${`Remove ${displayName}`} @click=${this.onRemoveClick}>
312
+ ? html `<button part="remove-button" type="button" aria-label=${`${this.removeLabel} ${displayName}`} @click=${this.onRemoveClick}>
278
313
  ${closeIcon()}
279
314
  </button>`
280
315
  : nothing}
@@ -307,6 +342,15 @@ __decorate([
307
342
  property({ type: Boolean, reflect: true })
308
343
  ], LyraAttachmentChip.prototype, "removable", void 0);
309
344
  __decorate([
310
- state()
311
- ], LyraAttachmentChip.prototype, "objectUrl", void 0);
345
+ property({ attribute: 'remove-label' })
346
+ ], LyraAttachmentChip.prototype, "removeLabel", void 0);
347
+ __decorate([
348
+ property({ attribute: 'retry-label' })
349
+ ], LyraAttachmentChip.prototype, "retryLabel", void 0);
350
+ __decorate([
351
+ property({ attribute: 'uploading-label' })
352
+ ], LyraAttachmentChip.prototype, "uploadingLabel", void 0);
353
+ __decorate([
354
+ property({ attribute: 'upload-failed-label' })
355
+ ], LyraAttachmentChip.prototype, "uploadFailedLabel", void 0);
312
356
  defineElement('attachment-chip', LyraAttachmentChip);
@@ -50,6 +50,12 @@ export interface AttachmentPickDetail {
50
50
  * actual capture flow.
51
51
  * @csspart trigger - The single-capability icon button. Only rendered when `capabilities.length === 1`.
52
52
  * @csspart menu - The `<lyra-menu>` wrapper. Only rendered when `capabilities.length > 1`.
53
+ * @csspart menu-trigger - The multi-capability button slotted into `<lyra-menu>`'s own `trigger` slot. Only rendered when `capabilities.length > 1`.
54
+ * @csspart expand-icon - The disclosure chevron inside the multi-capability trigger button. Only rendered when `capabilities.length > 1`.
55
+ *
56
+ * `triggerLabel` lets a host override the single-capability trigger button's
57
+ * `aria-label` (i18n) — see that property's own doc for exactly what it
58
+ * does and doesn't affect.
53
59
  */
54
60
  export declare class LyraAttachmentTrigger extends LyraElement {
55
61
  static styles: import("lit").CSSResultGroup[];
@@ -60,6 +66,13 @@ export declare class LyraAttachmentTrigger extends LyraElement {
60
66
  * `'.pdf,.docx'`), forwarded to the hidden file input for the
61
67
  * `files`/`image` capabilities — see the class doc for how each uses it. */
62
68
  accept: string;
69
+ /** Overrides the single-capability trigger button's `aria-label`, which
70
+ * otherwise comes from `CAPABILITY_META[capability].triggerLabel` (e.g.
71
+ * `'Attach files'`). Set this to localize the accessible name; leave it
72
+ * unset to keep the built-in English default. Only affects the
73
+ * single-capability button ([part='trigger']) — the multi-capability
74
+ * menu's own trigger keeps its fixed `'Add attachment'` label regardless. */
75
+ triggerLabel?: string;
63
76
  /** Forwarded to the hidden file input's own `multiple` attribute. */
64
77
  multiple: boolean;
65
78
  disabled: boolean;
@@ -8,6 +8,7 @@ import { html, nothing, svg } from 'lit';
8
8
  import { property, query } from 'lit/decorators.js';
9
9
  import { LyraElement } from '../../internal/lyra-element.js';
10
10
  import { defineElement } from '../../internal/prefix.js';
11
+ import { chevronIcon } from '../../internal/icons.js';
11
12
  import { styles } from './attachment-trigger.styles.js';
12
13
  import '../menu/menu.js';
13
14
  import '../menu/menu-item.js';
@@ -104,6 +105,12 @@ const CAPABILITY_META = {
104
105
  * actual capture flow.
105
106
  * @csspart trigger - The single-capability icon button. Only rendered when `capabilities.length === 1`.
106
107
  * @csspart menu - The `<lyra-menu>` wrapper. Only rendered when `capabilities.length > 1`.
108
+ * @csspart menu-trigger - The multi-capability button slotted into `<lyra-menu>`'s own `trigger` slot. Only rendered when `capabilities.length > 1`.
109
+ * @csspart expand-icon - The disclosure chevron inside the multi-capability trigger button. Only rendered when `capabilities.length > 1`.
110
+ *
111
+ * `triggerLabel` lets a host override the single-capability trigger button's
112
+ * `aria-label` (i18n) — see that property's own doc for exactly what it
113
+ * does and doesn't affect.
107
114
  */
108
115
  export class LyraAttachmentTrigger extends LyraElement {
109
116
  constructor() {
@@ -198,7 +205,7 @@ export class LyraAttachmentTrigger extends LyraElement {
198
205
  part="trigger"
199
206
  class="trigger-button"
200
207
  type="button"
201
- aria-label=${meta.triggerLabel}
208
+ aria-label=${this.triggerLabel ?? meta.triggerLabel}
202
209
  ?disabled=${this.disabled}
203
210
  @click=${this.onTriggerClick}
204
211
  >
@@ -211,12 +218,14 @@ export class LyraAttachmentTrigger extends LyraElement {
211
218
  <lyra-menu part="menu" label="Add attachment" @lyra-menu-select=${this.onMenuSelect}>
212
219
  <button
213
220
  slot="trigger"
221
+ part="menu-trigger"
214
222
  class="trigger-button"
215
223
  type="button"
216
224
  aria-label="Add attachment"
217
225
  ?disabled=${this.disabled}
218
226
  >
219
227
  ${paperclipIcon()}
228
+ <span part="expand-icon" aria-hidden="true">${chevronIcon()}</span>
220
229
  </button>
221
230
  ${this.capabilities.map((capability) => {
222
231
  const meta = CAPABILITY_META[capability];
@@ -246,6 +255,9 @@ __decorate([
246
255
  __decorate([
247
256
  property()
248
257
  ], LyraAttachmentTrigger.prototype, "accept", void 0);
258
+ __decorate([
259
+ property({ attribute: 'trigger-label' })
260
+ ], LyraAttachmentTrigger.prototype, "triggerLabel", void 0);
249
261
  __decorate([
250
262
  property({ type: Boolean, reflect: true })
251
263
  ], LyraAttachmentTrigger.prototype, "multiple", void 0);
@@ -11,12 +11,13 @@ export const styles = css `
11
11
  }
12
12
 
13
13
  /* Shared visual treatment for both the single-capability button
14
- ([part='trigger']) and the multi-capability button slotted into
15
- lyra-menu's own trigger slot -- the latter can't itself carry
16
- part='trigger' (that name is reserved for the single-capability case,
17
- so a consumer's ::part(trigger) selector unambiguously targets exactly
18
- one button), so both buttons share this plain class instead of
19
- duplicating the same declaration block twice. */
14
+ ([part='trigger']) and the multi-capability button ([part='menu-trigger'])
15
+ slotted into lyra-menu's own trigger slot -- the latter can't reuse
16
+ part='trigger' itself (that name is reserved for the single-capability
17
+ case, so a consumer's ::part(trigger) selector unambiguously targets
18
+ exactly one button), so both buttons share this plain class for the
19
+ declarations that genuinely are identical, on top of each one's own
20
+ distinct part name. */
20
21
  .trigger-button {
21
22
  display: inline-flex;
22
23
  flex: 0 0 auto;
@@ -60,6 +61,27 @@ export const styles = css `
60
61
  display: block;
61
62
  }
62
63
 
64
+ /* [part='menu-trigger'] carries a second glyph (the paperclip plus this
65
+ disclosure chevron) alongside the single-capability [part='trigger']'s
66
+ one, so it alone needs a gap between them. */
67
+ [part='menu-trigger'] {
68
+ gap: var(--lyra-space-xs);
69
+ }
70
+
71
+ /* Disclosure cue for the multi-capability trigger, matching
72
+ lyra-combobox/lyra-select's own [part='expand-icon'] convention (same
73
+ chevronIcon() rotated to point down) -- but sized down from their
74
+ dedicated-touch-target treatment since here it's a second glyph inside
75
+ one already-compact icon button, not its own separate control. */
76
+ [part='expand-icon'] {
77
+ display: inline-flex;
78
+ flex: 0 0 auto;
79
+ font-size: 0.75em;
80
+ }
81
+ [part='expand-icon'] svg {
82
+ transform: rotate(90deg);
83
+ }
84
+
63
85
  @media (prefers-reduced-motion: reduce) {
64
86
  .trigger-button {
65
87
  transition: none !important;
@@ -1,4 +1,4 @@
1
- import { LyraChart } from './chart.js';
1
+ import { LyraChart, lockChartType } from './chart.js';
2
2
  import { defineElement } from '../../internal/prefix.js';
3
3
  /**
4
4
  * `<lyra-bar-chart>` — `<lyra-chart>` with `type` locked to `"bar"`.
@@ -7,21 +7,5 @@ import { defineElement } from '../../internal/prefix.js';
7
7
  */
8
8
  export class LyraBarChart extends LyraChart {
9
9
  }
10
- // `type` is locked read-only rather than a settable class field with just a
11
- // default value — `LyraChart` declares it as a plain (decorator-managed)
12
- // class field, and TypeScript forbids a subclass from re-declaring a base
13
- // field as a getter/setter pair via ordinary class syntax (TS2611) — so the
14
- // accessor pair is installed directly on the prototype instead, which is
15
- // runtime-equivalent (same shadowing semantics as a class-syntax override)
16
- // without tripping that check.
17
- Object.defineProperty(LyraBarChart.prototype, 'type', {
18
- configurable: true,
19
- enumerable: true,
20
- get() {
21
- return 'bar';
22
- },
23
- set(_v) {
24
- /* locked to 'bar'; direct writes are ignored */
25
- },
26
- });
10
+ lockChartType(LyraBarChart, 'bar');
27
11
  defineElement('bar-chart', LyraBarChart);
@@ -19,7 +19,11 @@ export interface BoxPlotSeries {
19
19
  * Awesome's chart set — useful for summarizing distributions.
20
20
  *
21
21
  * @customElement lyra-box-plot
22
- * @csspart base, canvas
22
+ * @csspart base - The chart wrapper.
23
+ * @csspart canvas - The box-plot canvas.
24
+ * @csspart description - The accessible box-plot summary.
25
+ * @csspart data-table - The optional generated or slotted data table.
26
+ * @slot data-table - An optional consumer-provided accessible table alternative.
23
27
  */
24
28
  export declare class LyraBoxPlot extends LyraElement {
25
29
  static styles: import("lit").CSSResultGroup[];
@@ -29,21 +33,41 @@ export declare class LyraBoxPlot extends LyraElement {
29
33
  height: string;
30
34
  yLabel: string;
31
35
  beginAtZero: boolean;
36
+ /** Accessible name applied to the canvas. Falls back to the box labels. */
37
+ accessibleLabel: string;
38
+ /** Accessible description for the canvas. When unset, a five-number summary is generated. */
39
+ accessibleDescription: string;
40
+ /** Makes the generated data table visible; it remains screen-reader available when false. */
41
+ showDataTable: boolean;
32
42
  /**
33
43
  * True until the lazy-loaded `chart.js` + `@sgratzl/chartjs-chart-boxplot`
34
44
  * peer dependencies have settled (success or failure) — mirrors
35
45
  * `LyraChart`'s `loading` state.
36
46
  */
37
47
  private loading;
48
+ private visible;
49
+ private intersectionObserver?;
38
50
  private canvasEl?;
39
51
  private chart?;
40
52
  private chartJsModule?;
53
+ private descriptionId;
41
54
  connectedCallback(): void;
42
55
  private onBoxPlotPluginLoaded;
43
56
  disconnectedCallback(): void;
44
57
  protected updated(changed: PropertyValues): void;
58
+ /**
59
+ * Resolves the `--lyra-chart-*` theme tokens (declared in
60
+ * `box-plot.styles.ts`, each layered over an existing semantic token) via
61
+ * `getComputedStyle`. Chart.js renders to canvas, not the DOM, so it can't
62
+ * consume CSS `var()` directly — same constraint `chart.ts`'s
63
+ * `themeColors()` documents — so this is called fresh from `buildConfig()`
64
+ * on every draw rather than cached.
65
+ */
66
+ private themeColors;
45
67
  private buildConfig;
46
68
  private draw;
69
+ private boxPlotDescription;
70
+ private renderDataTable;
47
71
  render(): TemplateResult;
48
72
  }
49
73
  declare global {