@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
@@ -71,16 +71,12 @@ function defaultFormatTimestamp(date, now = new Date()) {
71
71
  * identically-shaped choice. `lyra-select` therefore carries no detail
72
72
  * payload at all.
73
73
  *
74
- * `role="option"` (not `"button"`) on `[part="option"]`, since this is meant
75
- * to live inside a `role="listbox"` history list (that future list
76
- * component supplies the listbox/group ancestor `role="option"` requires)
77
- * rather than stand in for a single push-button action. Used truly
78
- * standalone -- with no listbox/group ancestor -- it's still fully
79
- * operable, just technically missing that ARIA parent context; wrap it in a
80
- * `role="listbox"` (or `role="group"`) container to satisfy that when
81
- * accessibility-auditing a standalone usage.
74
+ * `role="button"` on `[part="option"]` so the item has valid semantics both
75
+ * standalone and when placed in a larger history-list layout. A conversation
76
+ * row activates one current session; it is not itself a listbox option and
77
+ * therefore does not require a particular owner role.
82
78
  *
83
- * `role="option"` (like native `<option>`/`role="button"`) forbids focusable
79
+ * `role="button"` forbids focusable
84
80
  * descendants -- verified against axe-core's `nested-interactive` rule,
85
81
  * which flags it. That's why the rename button and the `actions` slot are
86
82
  * rendered as DOM *siblings* of `[part="option"]` (both inside
@@ -88,10 +84,9 @@ function defaultFormatTimestamp(date, now = new Date()) {
88
84
  * contains plain text/`<time>` content. The in-place rename `<input>` is the
89
85
  * same problem one level deeper -- it replaces the title *inside*
90
86
  * `[part="option"]` while renaming -- so `[part="option"]` sheds its
91
- * `role`/`tabindex`/`aria-selected`/`aria-label` entirely for the duration
92
- * of an edit. This isn't just an ARIA-compliance workaround: a row mid-edit
93
- * genuinely isn't a selectable listbox choice at that moment, it's a text
94
- * field, so suspending the option semantics is also the more accurate
87
+ * `role`/`tabindex`/`aria-current`/`aria-label` entirely for the duration
88
+ * of an edit. A row mid-edit is a text field, so suspending the button
89
+ * semantics is also the more accurate
95
90
  * description of what's on screen.
96
91
  *
97
92
  * Inline rename is a dedicated pencil/edit icon button (not a double-click
@@ -117,7 +112,7 @@ function defaultFormatTimestamp(date, now = new Date()) {
117
112
  * when the trimmed draft is empty or unchanged from the original `title`
118
113
  * (that's treated as an implicit cancel).
119
114
  * @csspart base - The outer row wrapper (plain, no ARIA role) laying out `[part="option"]`, the rename button, and `actions`.
120
- * @csspart option - The selectable region (`role="option"`, removed while renaming -- see the class doc). Wraps `content` and `timestamp`.
115
+ * @csspart option - The selectable region (`role="button"`, removed while renaming -- see the class doc). Wraps `content` and `timestamp`.
121
116
  * @csspart content - Wrapper around the title and excerpt.
122
117
  * @csspart title - The title text, shown while not renaming.
123
118
  * @csspart title-input - The in-place rename `<input>`, shown only while renaming.
@@ -137,7 +132,9 @@ export class LyraConversationItem extends LyraElement {
137
132
  * brand-quiet background treatment. */
138
133
  this.active = false;
139
134
  /** Whether inline-rename is available at all. When `false`, the rename
140
- * button never renders and the row can never enter its editing state. */
135
+ * button never renders and the row can never enter its editing state. If
136
+ * flipped to `false` while a rename is already open, the in-progress edit
137
+ * is cancelled (discarded, like Escape) rather than left committable. */
141
138
  this.editable = true;
142
139
  this.renaming = false;
143
140
  this.draftTitle = '';
@@ -200,10 +197,17 @@ export class LyraConversationItem extends LyraElement {
200
197
  };
201
198
  }
202
199
  static { this.styles = [LyraElement.styles, styles]; }
203
- willUpdate() {
200
+ willUpdate(changed) {
204
201
  if (!this.hasUpdated) {
205
202
  this.hasActionsSlot = Array.from(this.children).some((el) => el.getAttribute('slot') === 'actions');
206
203
  }
204
+ // `editable` documents that flipping it false can never leave a rename
205
+ // committable -- without this, toggling it mid-edit would strand the
206
+ // input mounted (and still submittable via Enter/blur) since nothing
207
+ // else observes `editable` while `renaming` is already true.
208
+ if (changed.has('editable') && !this.editable && this.renaming) {
209
+ this.cancelRename();
210
+ }
207
211
  }
208
212
  updated(changed) {
209
213
  if (changed.has('renaming') && this.renaming) {
@@ -245,13 +249,18 @@ export class LyraConversationItem extends LyraElement {
245
249
  const formatter = this.formatTimestamp ?? defaultFormatTimestamp;
246
250
  const displayTitle = this.title || 'Untitled conversation';
247
251
  const showRenameButton = this.editable && !this.renaming;
252
+ // Shared between the rename button and the input it opens: the input is
253
+ // where focus actually lands, so it needs the same row-specific
254
+ // accessible name (not a generic one) to disambiguate which row a
255
+ // screen-reader user is editing.
256
+ const renameLabel = `Rename ${displayTitle}`;
248
257
  return html `
249
258
  <div part="base">
250
259
  <div
251
260
  part="option"
252
- role=${this.renaming ? nothing : 'option'}
261
+ role=${this.renaming ? nothing : 'button'}
253
262
  tabindex=${this.renaming ? nothing : '0'}
254
- aria-selected=${this.renaming ? nothing : this.active ? 'true' : 'false'}
263
+ aria-current=${this.renaming || !this.active ? nothing : 'true'}
255
264
  aria-label=${this.renaming ? nothing : this.getAttribute('aria-label') || displayTitle}
256
265
  @click=${this.onOptionClick}
257
266
  @keydown=${this.onOptionKeyDown}
@@ -262,7 +271,7 @@ export class LyraConversationItem extends LyraElement {
262
271
  part="title-input"
263
272
  type="text"
264
273
  .value=${this.draftTitle}
265
- aria-label="Rename conversation"
274
+ aria-label=${renameLabel}
266
275
  @input=${this.onTitleInputChange}
267
276
  @keydown=${this.onTitleInputKeyDown}
268
277
  @blur=${this.onTitleInputBlur}
@@ -276,7 +285,7 @@ export class LyraConversationItem extends LyraElement {
276
285
  ? html `<button
277
286
  part="rename-button"
278
287
  type="button"
279
- aria-label=${`Rename ${displayTitle}`}
288
+ aria-label=${renameLabel}
280
289
  @click=${this.onRenameButtonClick}
281
290
  >
282
291
  ${pencilIcon()}
@@ -1,4 +1,18 @@
1
1
  export type WeekdayFormat = 'narrow' | 'short' | 'long';
2
+ export type CalendarMode = 'single' | 'range';
3
+ /** Normalize an untyped calendar count to the supported one- or two-month range. */
4
+ export declare function normalizeCalendarMonths(value: unknown): 1 | 2;
5
+ /** Normalize an untyped weekday format before passing it to `Intl.DateTimeFormat`. */
6
+ export declare function normalizeWeekdayFormat(value: unknown): WeekdayFormat;
7
+ /** Normalize an untyped picker mode to the single-date default. */
8
+ export declare function normalizeCalendarMode(value: unknown): CalendarMode;
9
+ /**
10
+ * Construct a date formatter while treating a malformed runtime locale as
11
+ * the platform default. Attribute values and JavaScript property writes are
12
+ * not constrained by TypeScript's declarations, so they must not be allowed
13
+ * to turn a calendar render into a `RangeError`.
14
+ */
15
+ export declare function dateTimeFormat(locale: unknown, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat;
2
16
  /** Parse `YYYY-MM-DD` into a local Date, or null if invalid. */
3
17
  export declare function parseISO(s: string): Date | null;
4
18
  /** Format a Date as local `YYYY-MM-DD`. */
@@ -6,6 +20,16 @@ export declare function formatISO(d: Date): string;
6
20
  export declare function isSameDay(a: Date, b: Date): boolean;
7
21
  /** First day of the month `n` months from `d`. */
8
22
  export declare function addMonths(d: Date, n: number): Date;
23
+ /**
24
+ * `d` shifted by `n` months, keeping the same day-of-month unless the target
25
+ * month is shorter, in which case the day is clamped to that month's last
26
+ * day. Plain `new Date(year, month + n, d.getDate())` construction instead
27
+ * overflows a too-large day-of-month into the *following* month (e.g. Jan 31
28
+ * + 1 month rolls into March, skipping February entirely) because the Date
29
+ * constructor normalizes out-of-range day components rather than clamping
30
+ * them.
31
+ */
32
+ export declare function addMonthsClampingDay(d: Date, n: number): Date;
9
33
  export declare function clampDate(d: Date, min: Date | null, max: Date | null): Date;
10
34
  /**
11
35
  * A 6×7 grid of Dates covering the given month, week-aligned to `firstDayOfWeek`
@@ -1,3 +1,32 @@
1
+ /** Normalize an untyped calendar count to the supported one- or two-month range. */
2
+ export function normalizeCalendarMonths(value) {
3
+ const numeric = typeof value === 'number' ? value : Number(value);
4
+ if (!Number.isFinite(numeric))
5
+ return 1;
6
+ return Math.min(2, Math.max(1, Math.trunc(numeric)));
7
+ }
8
+ /** Normalize an untyped weekday format before passing it to `Intl.DateTimeFormat`. */
9
+ export function normalizeWeekdayFormat(value) {
10
+ return value === 'narrow' || value === 'long' ? value : 'short';
11
+ }
12
+ /** Normalize an untyped picker mode to the single-date default. */
13
+ export function normalizeCalendarMode(value) {
14
+ return value === 'range' ? 'range' : 'single';
15
+ }
16
+ /**
17
+ * Construct a date formatter while treating a malformed runtime locale as
18
+ * the platform default. Attribute values and JavaScript property writes are
19
+ * not constrained by TypeScript's declarations, so they must not be allowed
20
+ * to turn a calendar render into a `RangeError`.
21
+ */
22
+ export function dateTimeFormat(locale, options) {
23
+ try {
24
+ return new Intl.DateTimeFormat(typeof locale === 'string' && locale ? locale : undefined, options);
25
+ }
26
+ catch {
27
+ return new Intl.DateTimeFormat(undefined, options);
28
+ }
29
+ }
1
30
  /** Parse `YYYY-MM-DD` into a local Date, or null if invalid. */
2
31
  export function parseISO(s) {
3
32
  if (!s)
@@ -32,6 +61,20 @@ export function isSameDay(a, b) {
32
61
  export function addMonths(d, n) {
33
62
  return new Date(d.getFullYear(), d.getMonth() + n, 1);
34
63
  }
64
+ /**
65
+ * `d` shifted by `n` months, keeping the same day-of-month unless the target
66
+ * month is shorter, in which case the day is clamped to that month's last
67
+ * day. Plain `new Date(year, month + n, d.getDate())` construction instead
68
+ * overflows a too-large day-of-month into the *following* month (e.g. Jan 31
69
+ * + 1 month rolls into March, skipping February entirely) because the Date
70
+ * constructor normalizes out-of-range day components rather than clamping
71
+ * them.
72
+ */
73
+ export function addMonthsClampingDay(d, n) {
74
+ const targetMonth = d.getMonth() + n;
75
+ const lastDayOfTargetMonth = new Date(d.getFullYear(), targetMonth + 1, 0).getDate();
76
+ return new Date(d.getFullYear(), targetMonth, Math.min(d.getDate(), lastDayOfTargetMonth));
77
+ }
35
78
  export function clampDate(d, min, max) {
36
79
  if (min && d < min)
37
80
  return min;
@@ -60,18 +103,22 @@ export function monthMatrix(year, month, firstDayOfWeek = 0) {
60
103
  }
61
104
  /** Localized weekday header labels, ordered from `firstDayOfWeek`. */
62
105
  export function weekdayLabels(firstDayOfWeek = 0, format = 'short', locale) {
63
- const fmt = new Intl.DateTimeFormat(locale || undefined, { weekday: format });
106
+ const numericFirstDay = Number(firstDayOfWeek);
107
+ const start = Number.isFinite(numericFirstDay)
108
+ ? ((Math.trunc(numericFirstDay) % 7) + 7) % 7
109
+ : 0;
110
+ const fmt = dateTimeFormat(locale, { weekday: normalizeWeekdayFormat(format) });
64
111
  const labels = [];
65
112
  // 2021-08-01 is a Sunday, so index i maps cleanly to a weekday.
66
113
  for (let i = 0; i < 7; i++) {
67
- const day = (firstDayOfWeek + i) % 7;
114
+ const day = (start + i) % 7;
68
115
  labels.push(fmt.format(new Date(2021, 7, 1 + day)));
69
116
  }
70
117
  return labels;
71
118
  }
72
119
  /** Localized "Month YYYY" title. */
73
120
  export function monthTitle(year, month, locale) {
74
- return new Intl.DateTimeFormat(locale || undefined, { month: 'long', year: 'numeric' }).format(new Date(year, month, 1));
121
+ return dateTimeFormat(locale, { month: 'long', year: 'numeric' }).format(new Date(year, month, 1));
75
122
  }
76
123
  const FDOW = { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 };
77
124
  /** Locale-derived first day of week (0=Sunday … 6=Saturday), or null if unsupported. */
@@ -97,5 +144,5 @@ export function resolveFirstDayOfWeek(value, locale) {
97
144
  const derived = locale ? localeFirstDayOfWeek(locale) : null;
98
145
  return derived ?? 0;
99
146
  }
100
- return FDOW[value.toLowerCase()] ?? 0;
147
+ return typeof value === 'string' ? (FDOW[value.toLowerCase()] ?? 0) : 0;
101
148
  }
@@ -16,43 +16,109 @@ declare const LyraDateInput_base: typeof LyraElement & (new (...args: any[]) =>
16
16
  * @event change - Fired on committed date transitions.
17
17
  * @event lyra-show / lyra-hide - Calendar popover lifecycle.
18
18
  * @event lyra-clear - The clear button was used.
19
- * @csspart form-control, form-control-label, input-wrapper, input, clear-button, expand-button, expand-icon, popup, date-picker, hint, error
19
+ * @csspart form-control - The outer form-control wrapper.
20
+ * @csspart form-control-label - The label wrapper.
21
+ * @csspart input-wrapper - The input and button wrapper.
22
+ * @csspart input - The text input.
23
+ * @csspart clear-button - The clear control.
24
+ * @csspart expand-button - The calendar popup toggle.
25
+ * @csspart expand-icon - The calendar icon.
26
+ * @csspart popup - The positioned calendar popup.
27
+ * @csspart date-picker - The nested date picker.
28
+ * @csspart hint - The hint message.
29
+ * @csspart error - The validation message.
20
30
  * @slot label - Custom label content.
21
31
  * @slot error - Custom error content.
22
32
  * @slot hint - Custom hint content.
23
33
  */
24
34
  export declare class LyraDateInput extends LyraDateInput_base {
25
35
  static styles: import("lit").CSSResultGroup[];
26
- mode: 'single' | 'range';
27
- min: string;
28
- max: string;
29
- readonly: boolean;
36
+ static properties: {
37
+ mode: {
38
+ noAccessor: boolean;
39
+ };
40
+ min: {
41
+ noAccessor: boolean;
42
+ };
43
+ max: {
44
+ noAccessor: boolean;
45
+ };
46
+ readonly: {
47
+ type: BooleanConstructor;
48
+ reflect: boolean;
49
+ noAccessor: boolean;
50
+ };
51
+ disablePast: {
52
+ type: BooleanConstructor;
53
+ attribute: string;
54
+ noAccessor: boolean;
55
+ };
56
+ disableFuture: {
57
+ type: BooleanConstructor;
58
+ attribute: string;
59
+ noAccessor: boolean;
60
+ };
61
+ };
30
62
  open: boolean;
31
63
  withClear: boolean;
32
64
  label: string;
33
65
  hint: string;
34
66
  errorText: string;
35
67
  placeholder: string;
68
+ private accessibleLabel;
36
69
  locale: string;
37
70
  months: 1 | 2;
38
71
  firstDayOfWeek: string;
39
72
  weekdayFormat: WeekdayFormat;
40
- disablePast: boolean;
41
- disableFuture: boolean;
42
73
  withOutsideDays: boolean;
74
+ /** Accessible label for the clear button. Override for a non-English `locale`. */
75
+ clearLabel: string;
76
+ /** Accessible label for the calendar-toggle button. Override for a non-English `locale`. */
77
+ openLabel: string;
78
+ /** Accessible name for the calendar popover dialog. Override for a non-English `locale`. */
79
+ dialogLabel: string;
43
80
  private cleanupFn?;
81
+ private popupTrigger?;
82
+ private restorePopupFocusOnClose;
44
83
  private inputId;
45
84
  private popupId;
46
85
  private touched;
86
+ constructor();
47
87
  private hasHintSlot;
48
88
  private hasErrorSlot;
49
89
  private hasLabelSlot;
90
+ private _mode;
91
+ private _min;
92
+ private _max;
93
+ private _readonly;
94
+ private _disablePast;
95
+ private _disableFuture;
96
+ private typedBadInput;
97
+ get mode(): 'single' | 'range';
98
+ set mode(next: 'single' | 'range');
99
+ get min(): string;
100
+ set min(next: string);
101
+ get max(): string;
102
+ set max(next: string);
103
+ get readonly(): boolean;
104
+ set readonly(next: boolean);
105
+ get disablePast(): boolean;
106
+ set disablePast(next: boolean);
107
+ get disableFuture(): boolean;
108
+ set disableFuture(next: boolean);
109
+ get value(): string;
110
+ set value(next: string);
111
+ private setTypedBadInput;
112
+ private parseStrictISO;
113
+ private normalizeCommittedValue;
114
+ private valueDates;
115
+ protected updateValidity(): void;
50
116
  private get displayText();
51
- protected willUpdate(): void;
117
+ protected willUpdate(changed: PropertyValues): void;
52
118
  /** Open the calendar popover. */
53
119
  show(): void;
54
120
  /** Close the calendar popover. */
55
- hide(): void;
121
+ hide(restoreFocus?: boolean): void;
56
122
  private onDocPointer;
57
123
  /** Clear the value. */
58
124
  clear(): void;
@@ -82,10 +148,11 @@ export declare class LyraDateInput extends LyraDateInput_base {
82
148
  * from-before-to order, matching what the date-picker's own UI-driven
83
149
  * `commit()` already does for a UI-picked range. */
84
150
  private parseRangeText;
85
- private isWithinBounds;
86
151
  private onInputKey;
87
152
  private onFormControlKey;
88
153
  private onInputBlur;
154
+ formStateRestoreCallback(state: string | File | FormData | null, _mode?: 'restore' | 'autocomplete'): void;
155
+ formResetCallback(): void;
89
156
  private onHintSlotChange;
90
157
  private onErrorSlotChange;
91
158
  private onLabelSlotChange;