@astryxdesign/core 0.7.1-canary.fe8cad0 → 0.7.1

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 (93) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/dist/Chat/ChatComposerInput.d.ts +9 -0
  3. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  4. package/dist/Chat/ChatComposerInput.js +5 -0
  5. package/dist/Chat/ChatMessage.d.ts +11 -0
  6. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  7. package/dist/Chat/ChatMessage.js +18 -9
  8. package/dist/Chat/useTriggerMenu.d.ts +9 -2
  9. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  10. package/dist/Chat/useTriggerMenu.js +222 -50
  11. package/dist/CommandPalette/CommandPalette.d.ts +6 -4
  12. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  13. package/dist/CommandPalette/CommandPalette.js +38 -20
  14. package/dist/CommandPalette/CommandPaletteEmpty.d.ts +4 -3
  15. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  16. package/dist/CommandPalette/CommandPaletteEmpty.js +4 -3
  17. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  18. package/dist/CommandPalette/CommandPaletteInput.js +11 -5
  19. package/dist/CommandPalette/CommandPaletteList.d.ts +4 -2
  20. package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
  21. package/dist/CommandPalette/CommandPaletteList.js +9 -4
  22. package/dist/ContextMenu/ContextMenu.d.ts +3 -3
  23. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  24. package/dist/ContextMenu/ContextMenu.js +62 -48
  25. package/dist/Divider/Divider.d.ts +1 -0
  26. package/dist/Divider/Divider.d.ts.map +1 -1
  27. package/dist/Divider/Divider.js +5 -4
  28. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +7 -5
  29. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  30. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +12 -5
  31. package/dist/Layer/useLayerDismissal.d.ts +9 -9
  32. package/dist/Layer/useLayerDismissal.js +9 -9
  33. package/dist/Markdown/Markdown.d.ts.map +1 -1
  34. package/dist/Markdown/Markdown.js +6 -1
  35. package/dist/astryx.css +2 -0
  36. package/dist/reset.a11y.chromium.spec.js +6 -1
  37. package/dist/utils/plainDate.d.ts.map +1 -1
  38. package/dist/utils/plainDate.js +14 -5
  39. package/locales/en.json +1 -1
  40. package/package.json +4 -4
  41. package/src/AlertDialog/AlertDialog.spec.md +1 -1
  42. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  43. package/src/Chat/ChatComposerInput.spec.md +64 -61
  44. package/src/Chat/ChatComposerInput.test.tsx +202 -1
  45. package/src/Chat/ChatComposerInput.tsx +13 -0
  46. package/src/Chat/ChatMessage.doc.mjs +31 -16
  47. package/src/Chat/ChatMessage.spec.md +265 -0
  48. package/src/Chat/ChatMessage.test.tsx +246 -0
  49. package/src/Chat/ChatMessage.tsx +30 -7
  50. package/src/Chat/ChatSystemMessage.spec.md +36 -37
  51. package/src/Chat/ChatSystemMessage.test.tsx +4 -4
  52. package/src/Chat/useTriggerMenu.test.tsx +994 -0
  53. package/src/Chat/useTriggerMenu.tsx +278 -46
  54. package/src/CommandPalette/CommandPalette.doc.mjs +31 -1
  55. package/src/CommandPalette/CommandPalette.spec.md +95 -46
  56. package/src/CommandPalette/CommandPalette.test.tsx +241 -2
  57. package/src/CommandPalette/CommandPalette.tsx +44 -20
  58. package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -3
  59. package/src/CommandPalette/CommandPaletteInput.spec.md +7 -4
  60. package/src/CommandPalette/CommandPaletteInput.test.tsx +63 -2
  61. package/src/CommandPalette/CommandPaletteInput.tsx +15 -5
  62. package/src/CommandPalette/CommandPaletteItem.test.tsx +7 -0
  63. package/src/CommandPalette/CommandPaletteList.doc.mjs +3 -3
  64. package/src/CommandPalette/CommandPaletteList.spec.md +41 -36
  65. package/src/CommandPalette/CommandPaletteList.test.tsx +67 -0
  66. package/src/CommandPalette/CommandPaletteList.tsx +9 -4
  67. package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +599 -0
  68. package/src/ContextMenu/ContextMenu.doc.mjs +6 -0
  69. package/src/ContextMenu/ContextMenu.spec.md +51 -53
  70. package/src/ContextMenu/ContextMenu.test.tsx +132 -1
  71. package/src/ContextMenu/ContextMenu.tsx +78 -48
  72. package/src/Divider/Divider.doc.mjs +5 -3
  73. package/src/Divider/Divider.spec.md +140 -54
  74. package/src/Divider/Divider.test.tsx +15 -0
  75. package/src/Divider/Divider.tsx +6 -4
  76. package/src/DropdownMenu/DropdownMenu.spec.md +34 -17
  77. package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +38 -2
  78. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +32 -18
  79. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +146 -1
  80. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +136 -0
  81. package/src/DropdownMenu/__tests__/MenuButton.a11y.known-failures.ts +12 -0
  82. package/src/DropdownMenu/__tests__/MenuButton.a11y.renders.tsx +67 -0
  83. package/src/DropdownMenu/__tests__/MenuButton.a11y.states.ts +141 -0
  84. package/src/DropdownMenu/__tests__/MenuButton.a11y.test.tsx +138 -0
  85. package/src/Layer/useLayerDismissal.ts +9 -9
  86. package/src/Markdown/Markdown.doc.mjs +1 -1
  87. package/src/Markdown/Markdown.spec.md +15 -7
  88. package/src/Markdown/Markdown.tsx +4 -0
  89. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +5 -0
  90. package/src/reset.a11y.chromium.spec.ts +9 -1
  91. package/src/reset.css +4 -1
  92. package/src/utils/plainDate.test.ts +99 -0
  93. package/src/utils/plainDate.ts +23 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,121 @@
1
1
  # @xds/core
2
2
 
3
+ # 0.7.1
4
+
5
+ #### New Features
6
+
7
+ - Chat: mention people and topics by multi-word names with opt-in `hasMultiWordQuery` on `ChatComposerTrigger` (#6128)
8
+ Set `hasMultiWordQuery: true` on a trigger whose suggestions contain spaces, and typing `@Jordan Le` keeps narrowing the menu instead of closing it at the first space. The query runs until a line break or about 64 characters, typed text is never changed unless a row is picked, and an unmatched multi-word phrase hides the menu unless the trigger sets `emptySearchText`. Triggers that don't opt in still end their query at a space.
9
+
10
+ For every trigger: while results for the current query are still loading, Enter sends the message as typed and never picks a row from an earlier query. Results that arrive after a send or after the editor clears are dropped, so the menu never reopens over an empty composer. Escape and the arrow keys pass through while the menu is hidden, and IME keystrokes never pick a row.
11
+
12
+ - `CodeBlock` gains `isDiff`, a diff layer over any `language`, and Markdown renders a ```diff fence as tinted diff rows instead of plain text. (#7389)
13
+ With `isDiff`, lines starting with `+` sit on a success-tinted row, `-` on an error-tinted row, `@@` hunk headers (and a `--- `/`+++ ` file-header pair directly before one) on a quiet muted row, and the rest of every line keeps the language's syntax highlighting. The glyph renders in its own column so the code's indentation lines up on every row and stays in the copied text. A changed row's margin reads the change: the tint runs under the line-number gutter too and spans the full scroll width of a long line, and the line number and the glyph take the row's marker colour, while the code keeps the syntax theme's colours. These are five new syntax-theme slots — `--color-syntax-added`, `--color-syntax-removed`, `--color-syntax-diff-header` (row paints, defaulting to `--color-success-muted` and `--color-error-muted` at 25% strength and to `--color-background-muted`; a defined syntax theme that leaves the header paint unset gets none, its header rows sitting on its own background in its punctuation colour) and `--color-syntax-added-marker`, `--color-syntax-removed-marker` (defaulting to `--color-text-green` and `--color-text-red` in the default syntax theme; a defined syntax theme that leaves them unset keeps its own line-number colour) — so existing and custom syntax themes need no change and may override them.
14
+
15
+ Markdown maps a ```diff-<lang> fence to the layer over `<lang>` (labelled `<lang> diff`) and a ```diff fence to the layer over plaintext (labelled `diff`), so a diff keeps its header, copy button, disclosure, and a viewport name that still says `diff`.
16
+
17
+ A ```diff fence that should stay plain text can use ```text. A custom `components.code` renderer is unchanged: it keeps receiving the fence's leading word characters in `language` (`diff` for both ```diff and ```diff-tsx, as today), so an existing `language === 'diff'` check still matches, and receives nothing new.
18
+
19
+ - Clearable inputs: the clear button's tooltip now reads just "Clear" (localized) instead of repeating the field's label, so a long label no longer turns into awkward tooltip copy such as "Clear Assigned engineering partner". The button's accessible name is unchanged and still names the field, such as "Clear Search". Applies to every input that renders the shared clear button, including `TextInput`, `NumberInput`, the date and time inputs, `FileInput`, `Selector`, `MultiSelector`, `Typeahead`, and `Tokenizer`. Override the new `@astryx.inputClearButton.tooltip` catalog key to change the wording. (#7476)
20
+ - `Markdown` fenced code blocks wrap long lines instead of scrolling them sideways. A reader on a narrow screen sees the whole line without a horizontal scroll, and where `Markdown` and RichText give a code block the same width, a long line takes the same number of lines in both. Only the appearance changes: the code's text, line numbers, syntax colours and what Copy returns are unchanged, and a code block whose lines no longer overflow also no longer takes the scroll region's Tab stop, as a code block that fits never has. To keep the old sideways-scrolling look, render code yourself through the `components.code` prop with a `CodeBlock` that leaves `isWrapped` off. (#7564)
21
+ - Selector, MultiSelector, and ComplexSelector gain a `secondary` variant: a borderless, neutral-filled trigger matching secondary buttons in navigation and toolbar compositions. Inside an `InputGroup`, a secondary Selector or MultiSelector keeps its fill and takes the group's row height and connected edges. Existing `input` (default) and `ghost` behavior is unchanged. (#7252)
22
+
23
+ #### Fixes
24
+
25
+ - `Typeahead`, `Tokenizer`, and `PowerSearch`: focusing an empty field with `hasEntriesOnFocus` after its search source changed now bootstraps entries from the new source. Previously the results cached from the old source were already invalidated but still blocked the bootstrap, so focusing or clicking into the field opened nothing until the user typed. Cached results that are still current are re-shown without a new bootstrap, as before. (#7157)
26
+ - `BottomSheet` returns focus without a focus ring after a pointer close (a tap in WebKit, or a pointer close of a sheet opened from the keyboard) and keeps the ring after a keyboard close, including on a `DropdownMenu` bottom-sheet trigger the caller renders (`renderTrigger`). The sheet now asks the browser not to treat that focus as keyboard focus, the way Dialog's focus moves do. (#7388)
27
+ - Keep DateInput's calendar selection empty after clearing the field. (#6935)
28
+ - `Calendar`: PageUp and PageDown move the focused day by a month — into the month the grid shows, on the same day of the month where it exists — instead of by a week; a page from a borrowed adjacent-month day lands on that day of the month now shown rather than on the month's first day. With two months, a page or an arrow crossing a month edge from the first month now lands on the correct day (the second grid no longer overrides the first grid's target). An arrow or page past `min`/`max` changes nothing, and a page into a month with no enabled day keeps focus in the grid. (#7467)
29
+ - `Calendar`: the arrow keys, Home and End no longer land on a borrowed adjacent-month day (shown dimmed, exposed as disabled, and inert to Enter, Space and clicks). An arrow crosses into that month and focuses the real day there, including across the two grids of a two-month view; Home and End stop at the first or last enabled day of the week in the month shown. A month with no enabled day holds no Tab stop. (#7511)
30
+ - `Calendar` with `hasWeekNumbers`: the blank cell above the week-number column is now a `columnheader` named with the locale's own word for the week field (from CLDR, visually hidden), so every cell in the header row has a grid role and assistive technology reads the weekday header row without a stray unnamed cell. (#7509)
31
+ - `ChatMessage` no longer leaves empty space for an avatar, name, or metadata that renders nothing. Booleans and empty strings create no slot, and any other slot content that renders nothing, such as an empty Fragment or a component that returns `null`, collapses its wrapper. A name that renders no text falls back to the translated sender label, while numeric values such as `0` still render. (#6597)
32
+ - `CodeBlock`'s code viewport is a keyboard Tab stop only while its content actually overflows, through the shared scroll capability: a short snippet no longer adds an unexplained stop to the page's Tab order, a wide or capped block still does, and a viewport that stops overflowing keeps focus where it is. Role and accessible name are unchanged. (#7424)
33
+ - `CommandPaletteInput` now exposes the semantics and name that its visible state promises. (#7321)
34
+ - A standalone field with no popup attributes was `role="combobox"` with `aria-expanded="true"` and `aria-autocomplete="list"`; it is now `role="searchbox"` with no popup state. Pass `role="combobox"`, or your popup's own ARIA attributes, to keep the old semantics. A field that already passes popup attributes (`aria-expanded`, `aria-controls`, `aria-owns`, `aria-haspopup`, and the like) stays a `combobox` and keeps them, and a field inside `CommandPalette` is unchanged.
35
+
36
+ - The field's default accessible name was its placeholder (`Search…`, or the caller's `placeholder`); it is now `Search commands`, translated. Pass `label` to keep a specific name, for example `label="Search…"` for the old default. A caller whose custom `placeholder` served as the name keeps working code and hears the generic name until it passes `label`.
37
+
38
+ - The CLI's async-search CommandPalette block names its field `Search files`.
39
+
40
+ - `endContent={true}` no longer renders an empty trailing slot, and `endContent={0}` renders inside the trailing slot instead of after it.
41
+ - A standalone `CommandPaletteItem` now keeps a caller-supplied id on its rendered option and ignores click callbacks while disabled, so labels and test hooks keep pointing at the option and a disabled command cannot run. (#7324)
42
+ - `CommandPalette` now keeps dismissal, text entry, result focus, and empty-state announcements aligned with what the reader sees. (#6950)
43
+ - While no selectable result exists, the results container no longer exposes an empty `listbox`, and the query field reports `aria-expanded="false"` with no `aria-controls` or `aria-activedescendant`. It was an expanded combobox controlling an empty listbox.
44
+
45
+ - Home and End move the caret in the query field, as in any text field; they used to jump to the first and last result. Page Up and Page Down still jump to the first and last result.
46
+
47
+ - A search with no results announces the empty message the palette renders (`No results` by default, or the caller's `emptySearchText`), once the search settles. It used to announce `No results for <query>`, whatever the palette showed. An override of the `@astryx.commandPalette.noResultsFor` catalog entry no longer has any effect; use `emptySearchText` to customize the message.
48
+ - `ContextMenu` paints in Safari when its trigger sits inside a scroll container. The menu is anchored to a box at the pointer, and that box was empty: WebKit counts an empty anchor box inside a scroller as clipped, so the default `position-visibility: anchors-visible` hid the open menu. The anchor is now 1px, kept inside the trigger, so the menu still hides while a scroller clips the pointer position and paints again when it scrolls back. A pointer-opened menu now starts 1px lower, below the pixel under the pointer. (#7369)
49
+ - `ContextMenu` now lets Escape dismiss the topmost nested overlay before the menu itself, and preserves consumer trigger handlers while adding its own, so an overlay opened from a menu stays usable and product event logic still runs. (#7167)
50
+ - The touch month scroller shared by `DateInput` and `DateTimeInput`: under RTL the horizontal arrows follow the reading direction (ArrowLeft moves to the next day, ArrowRight to the previous), and every keyboard move — arrows and Home/End — now lands on the real day in its own month pane rather than on the dimmed, disabled copy a neighbouring pane shows at its edge. Touch scrolling is unchanged. (#7466)
51
+ - `DateRangeInput`: activating the clear button with the keyboard now returns focus to the range trigger. Previously the button unmounted once the range was cleared and focus fell to `<body>`, so a keyboard user had to Tab back in from the top of the page. Pointer clears are unchanged. (#7507)
52
+ - `Dialog` now preserves consumer `onClick` handlers while retaining its controlled backdrop-dismissal behavior. (#7452)
53
+ - `DialogHeader` now keeps valid numeric zero content inside its `startContent` and `endContent` wrappers and theme targets. (#7454)
54
+ - `Divider` now keeps numeric zero labels inside the labelled separator and omits boolean or empty-string labels without leaving empty label spacing. (#7572)
55
+ - `DropdownMenuCheckboxItem` now preserves consumer click and pointer-move handlers while keeping its checked-state, disabled, hover-focus, and close-menu behavior. (#7573)
56
+ - A `DropdownMenu` with `header` or `footer` is now exposed as a modal dialog around its menu, as the APG Dialog pattern requires. The popover is a named `role="dialog"` with `aria-modal` and the `role="menu"` inside it; the trigger says `aria-haspopup="dialog"` and its `aria-controls` names the popover holding the dialog. Tab and Shift+Tab wrap through the header, the menu and the footer instead of closing the menu at either end. Escape still closes and returns focus to the trigger. A menu without either prop is unchanged. (#7515)
57
+ - A `DropdownMenu` whose trigger the caller renders (`renderTrigger`) returns focus to it without a focus ring after a pointer pick (a mouse click in Chromium, a click or a tap in WebKit), as the built-in trigger already did: the menu now asks the browser not to treat that focus as keyboard focus, the way Dialog's focus moves do. (#7382)
58
+ - `DropdownMenu` and `MoreMenu`: a disabled trigger no longer opens the menu. A disabled trigger with a tooltip stays focusable (`aria-disabled`), and Button swallowed only Enter and Space, so ArrowDown, ArrowUp, a press, or a click could still open the anchored menu; the anchored open path and the bottom-sheet trigger's click now check the trigger's availability first, for the default Button and for a natively or `aria-disabled` custom trigger. (#7475)
59
+ - `FormLayout`: below the 480px collapse, `direction="horizontal-labels"` controls now fill the column the way they do in a vertical `FormLayout`. Previously each control shrank to its content, so a `Selector` was only as wide as its current value. The two-column layout above 480px is unchanged. (#7501)
60
+ - Buttons used as InputGroup addons now share the group's outer shape, with square inner corners where they meet the adjacent input. (#7233)
61
+ Standalone buttons and buttons rendered inside an input keep their existing shape and behavior.
62
+ - Keep `useHoverCard()` trigger refs stable across unchanged rerenders. The hook returned a fresh `ref`/`interactionRef` on every render because its callbacks depended on the whole `layer` and `touch` objects, which are rebuilt each render — React detached and re-attached every trigger listener and rewrote the trigger's inline `anchor-name` on each rerender. Hooks now depend on the stable layer and touch members instead, mirroring the Tooltip fix in #5951. (#6472) (#6606)
63
+ - MobileNav: return focus to the element that opened the drawer when it closes. The drawer relied entirely on the browser's implicit `<dialog>` focus restore, which was reported failing in Safari 26.5.2: `document.activeElement` became `<body>` after close, stranding keyboard and screen-reader users at the top of the document. MobileNav now captures the opener before `showModal()` moves focus into the top layer and hands it back as soon as the native dialog has closed, matching what `Dialog` already does. The close is deferred until the slide-out has played, so the restore waits for it too; until then the rest of the document is inert and an earlier `focus()` would be silently dropped. The restore also covers the AppShell path, where the drawer is torn down by an `<Activity>` switching to `mode="hidden"` rather than by the close branch re-running. No API change. Focus is left untouched when there was no real opener (`activeElement` was `<body>`), when the opener has since left the DOM, or when the drawer is reopened before its pending close runs. (#3343) (#4410)
64
+ - `MultiSelector`: activating the clear button with the keyboard now returns focus to the trigger, as `hasClear` documents. Previously the button unmounted once the selection was empty and focus fell to `<body>`, so a keyboard user had to Tab back in from the top of the page. Pointer clears are unchanged. (#7506)
65
+ - `NumberInput`: the screen-reader "Invalid number" alert now goes through the i18n translator, so an `InternationalizationProvider` locale or override can replace it. Adds `@astryx.numberInput.invalidNumber` to the `en` catalog. Locales without a translation yet still fall back to English. (#7482)
66
+ - `astryx.css`, `reset.css`, and every other package stylesheet (`richtext.css`, `lab.css`, `charts.css`) now open with `@layer reset, astryx-base, astryx-theme;`, the same line theme stylesheets carry. The Astryx layer order holds whichever Astryx stylesheet loads first: loading `reset.css` after `astryx.css` no longer lets the reset override component styles, and theme overrides keep winning. Setups that already declare the order on their own first line are unchanged. (#7585)
67
+ - `plainDateToInstant` now resolves skipped and repeated wall times the way Temporal's default `"compatible"` disambiguation does. (#7081)
68
+ - A skipped wall time moves forward by the length of the gap. In a zone that springs forward from a negative offset at local midnight, such as America/Santiago on September 6, 2026 or America/Havana on March 8, 2026, the start of that day came back as 11:00 PM the day before, so a week or day range landed on the wrong date; it is now the day's first instant (1:00 AM).
69
+
70
+ - A repeated wall time resolves to its earlier occurrence in every zone. In zones with a positive offset, such as Europe/Berlin on October 25, 2026, it resolved to the later one.
71
+ - `Calendar`: dates in years 1-99 now show their own year instead of 1900-1999. A value of `0001-01-15` was captioned "January 1901" with 1901's weekday layout and day labels, while `onChange` still emitted the year-1 ISO date. The shared date helpers behind the caption, day grid, week numbers, day counts, and timezone instants now keep years 1-99 as given. One limitation remains: in a timezone west of UTC, the instant for January 1 of year 1 still comes out a year early, because its timezone offset is read from a 1 BC wall clock without the era. (#7465)
72
+ - `PowerSearch`: pressing Enter on a focused button in the filter editor now activates that button. Enter on Cancel closes the editor without applying the draft, and Enter on Delete removes the filter; before, both applied the draft instead. Enter in a text or number value field still applies the filter; Enter on the date picker's calendar button now opens the calendar. (#7500)
73
+ - `CommandPaletteList` now preserves a caller-supplied id when used standalone, while a managed `CommandPalette` still assigns the ARIA id its search field controls. External labels and test hooks stay attached without breaking the palette's combobox relationship. (#6988)
74
+ - `reset.css` no longer hides `hidden="until-found"` content with `display: none`. The browser's own rendering, `content-visibility: hidden`, now applies, so find in page and text fragment links can find the content and reveal it, as the HTML Standard specifies. Plain `hidden` elements are still `display: none`, and a browser without until-found support still hides the content with its own `[hidden]` rule. (#7520)
75
+ - `ResizeHandle`: on a collapsed pane, the arrow that grows it opens it one step above its minimum, or at its `collapsedSize` when that is larger (a single step below the collapse threshold used to leave it collapsed); the arrow that shrinks it stays a no-op. Enter and double-click still restore the previous size. (#7512)
76
+ - `ResizeHandle`: Enter and double-click on a collapsed pane restore it to the size it had before it collapsed, not to its minimum, and reopen it even when `minSize` is below `collapsedSize`. The handle uses `useResizable`'s own collapse and expand transitions; `ResizableProps` is unchanged, and a hand-built props object keeps the previous resize-to-minimum behavior. (#7479)
77
+ - `ResizeHandle`: with snap points set, an arrow key moves the pane to the adjacent snap point in its direction (Shift moves two), a point beyond the bounds counting as that bound — a 10px step used to snap straight back to the point it started on. With snap points, a shrink arrow at the lowest point no longer collapses a collapsible pane; Enter, double-click and dragging still do. (#7514)
78
+ - `ResizeHandle`: a separator whose region sets no `maxSize` now reports an `aria-valuemax` — a measured extent standing in for the missing maximum (the window's extent on the region's axis, or the container's content box while a percentage bound observes it), never below the current size or, while collapsed, the minimum. Pixel-only regions inside a container still report no maximum (measuring one would add an observer). `ResizableProps` is unchanged; End still moves only to a configured maximum. (#7481)
79
+ - `useScrollOverflow` (the strip of `TabList`, the scroller of `Carousel`) measures a resize, and its container at registration, only while the container is rendered. Inside a `display: none` ancestor or a `content-visibility: hidden` subtree the hook keeps its last state instead of reading layout, since a layout read there made the browser render the whole hidden subtree for the answer; the resize observation that comes with the reveal measures again, one frame after the reveal paints. A scroll is measured hidden or not, so a container script scrolled while hidden (a selected tab's reveal) is right at a reveal that brings no resize. Before, a hidden container reported no overflow. (#7518)
80
+ - A `secondary` Selector, MultiSelector, or ComplexSelector now matches the theme's secondary Button: under butter, chocolate, gothic, stone, and y2k it takes that Button's border, fill, text color, and hover instead of the default borderless neutral fill, so a toolbar mixing secondary buttons and selectors reads as one set of controls. Disabled and read-only triggers keep a still fill on hover, as a disabled Button does, and a Selector or MultiSelector inside an InputGroup keeps the group's neutral fill and edges. The default theme is unchanged, the selector docs now say `secondary` follows the theme's secondary Button, and themes added with the CLI get the same parity. (#7548)
81
+ - `Selector`: activating the clear button with the keyboard now returns focus to the trigger, as `hasClear` documents. Previously the button unmounted once the value was cleared and focus fell to `<body>`, so a keyboard user had to Tab back in from the top of the page. Pointer clears are unchanged. (#7455)
82
+ - `SideNav`: the resize handle now names the navigation pane it resizes with `aria-controls` (the nav gets a generated id when the consumer gives none), as the APG window splitter pattern requires, so assistive technology can relate the separator to the pane. (#7473)
83
+ - `Slider`: End now reaches `max` even when the step grid does not land on it (for `max={100}` with `step={3}`, End stopped at 99). Arrow and Page key results still snap to the nearest step and then clamp. (#7484)
84
+ - `Slider`: on a horizontal track under RTL the arrow keys now follow the mirrored track — ArrowLeft increases the value and ArrowRight decreases it, matching where the thumb moves on screen. ArrowUp/ArrowDown, PageUp/PageDown, Home/End, and vertical sliders are unchanged. (#7461)
85
+ - Stop Tokenizer's `hasCreate` "Create X" entry from offering a label that is already tokenized under a different id. The duplicate check compared the typed text against selected ids, but real selections usually carry an opaque id (`u1` under the label "Alice"), and the search results could not catch the match because they are pre-filtered to remove already-selected items — so typing an existing token's label offered "Create", which committed a second, duplicate token with a new id. The check now also compares against selected labels (case-insensitive), in both the Create entry and the stale-entry commit guard. (#6367)
86
+ - Keep Toolbar keyboard navigation and roving tab stops outside nested popover menus, without disabling toolbar navigation inside an outer popover. (#7446)
87
+ - `TreeList`: each row is now named by its label alone and described by its description (`aria-labelledby`/`aria-describedby` on the `treeitem`), so screen readers no longer read the chevron toggle's label or the description as part of a row's name, and link and action rows are named as rows, not only through their inner control. Typeahead matches the label rather than the row's whole text. (#7472)
88
+
89
+ #### Documentation
90
+
91
+ - `AlertDialog`'s anatomy lists the dialog surface — the modal panel that holds the title, description, and buttons — and `Calendar`'s anatomy lists the calendar root and the day button, so every part that carries a theming target (`alert-dialog`, `calendar`, `calendar-day`) is named in the component docs. (#7464)
92
+ - List `DateInput`'s `containerClassName`, `containerStyle`, `controlClassName`, and `controlStyle` props in its API reference, alongside `containerXstyle` and `controlXstyle`. (#7372)
93
+ - Grid's `columns` docs now lead with the shape that reflows: a numeric `columns` is exactly N columns at every width and never reflows, and `columns={{minWidth, max}}` is the form for columns that must survive a phone. The `astryx docs layout/responsive` topic gains a "Columns that reflow" section with a reflowing stat row beside a fixed week row. No behavior changes. (#7340)
94
+
95
+ #### Other Changes
96
+
97
+ - The core build now fails when StyleX rejects a declaration such as a `border`, `background`, or `all` shorthand, instead of silently dropping it from the shipped CSS. The emitted `dist/` is unchanged. No API change. (#6830)
98
+
99
+ #### Contributors
100
+
101
+ Thanks to everyone who contributed to this release:
102
+
103
+ - @AKnassa
104
+ - @athz
105
+ - @barm
106
+ - @cixzhang
107
+ - @ernestt
108
+ - @Geervan
109
+ - @harjothkhara
110
+ - @imdreamrunner
111
+ - @korkt-kim
112
+ - @kyu-rong
113
+ - @ManoharPaturi
114
+ - @rubyycheung
115
+ - @vjeux
116
+
117
+ ---
118
+
3
119
  # 0.7.0
4
120
 
5
121
  #### Breaking Changes
@@ -116,6 +116,15 @@ export type ChatComposerTrigger = {
116
116
  loadingText?: string;
117
117
  /** Accessible label for the menu. @default 'Suggestions' */
118
118
  menuLabel?: string;
119
+ /**
120
+ * Whether the query continues past spaces, for suggestions whose names have
121
+ * spaces (e.g. "@María José García", "@Design Review: Q4"). The query then
122
+ * runs until a line break or about 64 characters, and when nothing matches
123
+ * the menu hides unless `emptySearchText` is set. When false, the query ends
124
+ * at the first space.
125
+ * @default false
126
+ */
127
+ hasMultiWordQuery?: boolean;
119
128
  };
120
129
  export interface ChatComposerInputProps extends Omit<BaseProps<HTMLDivElement>, 'onChange' | 'onPaste' | 'onSubmit'> {
121
130
  /** Ref forwarded to the root element. */
@@ -1 +1 @@
1
- {"version":3,"file":"ChatComposerInput.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatComposerInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChatComposerInput.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatComposerInput.tsx"],"names":[],"mappings":"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"}
@@ -437,6 +437,11 @@ export function ChatComposerInput(props) {
437
437
  historyIndexRef.current = -1;
438
438
  currentDraftRef.current = '';
439
439
  }
440
+
441
+ // Submitting ends any trigger query, including one dismissed with
442
+ // Escape: no menu stays open, and no dismissal carries into the next
443
+ // message.
444
+ triggerMenu.reset();
440
445
  onSubmit?.(text);
441
446
  editableRef.current.textContent = '';
442
447
  setIsEmpty(true);
@@ -12,6 +12,7 @@
12
12
  * SYNC: When modified, update these files to stay in sync:
13
13
  * - /packages/core/src/Chat/index.ts (exports)
14
14
  * - /apps/storybook/stories/Chat.stories.tsx
15
+ * - /apps/storybook/stories/ChatMessage.stories.tsx
15
16
  * - /packages/cli/assets/templates/blocks/components/ChatMessage/ (block examples)
16
17
  */
17
18
  import { type ReactNode } from 'react';
@@ -28,9 +29,17 @@ export interface ChatMessageProps extends BaseProps<HTMLElement> {
28
29
  * should span the full message column.
29
30
  */
30
31
  children: ReactNode;
32
+ /**
33
+ * Avatar content rendered beside a non-system message.
34
+ * `null`, booleans, and empty strings create no slot; any other content that
35
+ * renders nothing collapses its slot.
36
+ */
31
37
  avatar?: ReactNode;
32
38
  /**
33
39
  * Sender name rendered above the message body.
40
+ * `null`, booleans, and empty strings create no slot, and the message is
41
+ * labelled by the translated sender fallback; any other content that renders
42
+ * nothing collapses its slot and falls back to the same label.
34
43
  * Use when the first child is raw content (not a bubble).
35
44
  * If the first child is a ChatMessageBubble, put the name on the
36
45
  * bubble's `name` prop instead — it aligns with the bubble's padding.
@@ -38,6 +47,8 @@ export interface ChatMessageProps extends BaseProps<HTMLElement> {
38
47
  name?: ReactNode;
39
48
  /**
40
49
  * Metadata rendered below the message body.
50
+ * `null`, booleans, and empty strings create no slot; any other content that
51
+ * renders nothing collapses its slot.
41
52
  * Use when the last child is raw content (not a bubble).
42
53
  * If the last child is a ChatMessageBubble, put metadata on the
43
54
  * bubble's `metadata` prop instead — it aligns with the bubble's padding.
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAQrD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAoFD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA2FlB;yBAxGe,WAAW"}
1
+ {"version":3,"file":"ChatMessage.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessage.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAQrD,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC9D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AA4FD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,+BA+FlB;yBA5Ge,WAAW"}
@@ -16,6 +16,7 @@
16
16
  * SYNC: When modified, update these files to stay in sync:
17
17
  * - /packages/core/src/Chat/index.ts (exports)
18
18
  * - /apps/storybook/stories/Chat.stories.tsx
19
+ * - /apps/storybook/stories/ChatMessage.stories.tsx
19
20
  * - /packages/cli/assets/templates/blocks/components/ChatMessage/ (block examples)
20
21
  */
21
22
  import { useMemo, useId } from 'react';
@@ -23,7 +24,7 @@ import * as stylex from '@stylexjs/stylex';
23
24
  import "../theme/tokens.stylex.js";
24
25
  import { colorVars, spacingVars, typeScaleVars, fontWeightVars } from "../theme/tokens.stylex.js";
25
26
  import { ChatMessageContext, useChatListContext } from "./ChatContext.js";
26
- import { mergeProps } from "../utils/index.js";
27
+ import { isRenderable, mergeProps } from "../utils/index.js";
27
28
  import { themeProps } from "../utils/themeProps.js";
28
29
  import { useTranslator } from "../i18n/index.js";
29
30
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -155,18 +156,23 @@ export function ChatMessage({
155
156
  const columnAlignment = sender === 'system' ? styles.contentColumnSystem : sender === 'user' ? styles.contentColumnUser : styles.contentColumnAssistant;
156
157
  const childrenAlignment = sender === 'system' ? styles.childrenSystem : sender === 'user' ? styles.childrenUser : styles.childrenAssistant;
157
158
  const isSystem = sender === 'system';
158
- const hasAvatar = avatar != null && !isSystem;
159
- const hasName = name != null && !isSystem;
159
+ const hasAvatar = !isSystem && isRenderable(avatar);
160
+ const hasName = !isSystem && isRenderable(name);
161
+ const hasMetadata = !isSystem && isRenderable(metadata);
160
162
  const nameId = useId();
161
163
  return /*#__PURE__*/_jsx(ChatMessageContext, {
162
164
  value: contextValue,
163
165
  children: /*#__PURE__*/_jsxs("article", {
164
166
  ...rest,
165
167
  ref: ref,
166
- "data-testid": testId,
167
- "aria-label": !hasName ? t('@astryx.chatMessage.messageFrom', {
168
+ "data-testid": testId
169
+ // The visible name labels the article. When it renders no text, the
170
+ // label reference resolves to nothing and the accessible name falls
171
+ // back to aria-label (accessible name computation 1.2, step 2B).
172
+ ,
173
+ "aria-label": t('@astryx.chatMessage.messageFrom', {
168
174
  sender
169
- }) : undefined,
175
+ }),
170
176
  "aria-labelledby": hasName ? nameId : undefined,
171
177
  ...mergeProps(themeProps('chat-message', {
172
178
  sender,
@@ -174,7 +180,7 @@ export function ChatMessage({
174
180
  }), stylex.props(styles.root, rootAlignment, hasAvatar && rootGap, xstyle), className, styleProp),
175
181
  children: [hasAvatar && /*#__PURE__*/_jsx("div", {
176
182
  ...{
177
- className: "x2lah0s x5du68j"
183
+ className: "xjl7jj x2lah0s x5du68j"
178
184
  },
179
185
  children: avatar
180
186
  }), /*#__PURE__*/_jsxs("div", {
@@ -182,13 +188,16 @@ export function ChatMessage({
182
188
  children: [hasName && /*#__PURE__*/_jsx("div", {
183
189
  id: nameId,
184
190
  ...{
185
- className: "x141an7d x2mo6ok xv1l7n4 x1ltkj2j x14cgwvg"
191
+ className: "xjl7jj x141an7d x2mo6ok xv1l7n4 x1ltkj2j x14cgwvg"
186
192
  },
187
193
  children: name
188
194
  }), /*#__PURE__*/_jsx("div", {
189
195
  ...stylex.props(styles.childrenWrap, childrenAlignment, childrenGap),
190
196
  children: children
191
- }), metadata != null && !isSystem && /*#__PURE__*/_jsx("div", {
197
+ }), hasMetadata && /*#__PURE__*/_jsx("div", {
198
+ ...{
199
+ className: "xjl7jj"
200
+ },
192
201
  children: metadata
193
202
  })]
194
203
  })]
@@ -6,7 +6,9 @@
6
6
  *
7
7
  * Detects trigger characters (@ / etc.) typed inside a contentEditable,
8
8
  * opens a popover at the cursor position with filtered items, handles
9
- * keyboard navigation, and inserts tokens or text on selection.
9
+ * keyboard navigation, and inserts tokens or text on selection. Triggers
10
+ * opt into multi-word queries with hasMultiWordQuery; results apply only
11
+ * while their query is current (component:ChatComposerInput FR10–FR16).
10
12
  *
11
13
  * Reuses SearchSource from Typeahead for async/sync search with
12
14
  * cancel() support and debounce.
@@ -25,6 +27,11 @@ export interface TriggerMenuState {
25
27
  items: SearchableItem[];
26
28
  highlightedIndex: number;
27
29
  isLoading: boolean;
30
+ /**
31
+ * The last settled results were an unmatched multi-word query, so the menu
32
+ * is closed. It stays closed while a newer search for the same query runs.
33
+ */
34
+ isHidden: boolean;
28
35
  }
29
36
  export interface UseTriggerMenuOptions {
30
37
  triggers?: ChatComposerTrigger[];
@@ -42,7 +49,7 @@ export interface UseTriggerMenuReturn {
42
49
  state: TriggerMenuState;
43
50
  /** Call on every input event to check for trigger activation */
44
51
  handleInput: () => void;
45
- /** Call on keydown \u2014 returns true if the event was consumed */
52
+ /** Call on keydown — returns true if the event was consumed */
46
53
  handleKeyDown: (e: React.KeyboardEvent) => boolean;
47
54
  /** Render the trigger menu popover */
48
55
  renderMenu: () => ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"useTriggerMenu.d.ts","sourceRoot":"","sources":["../../src/Chat/useTriggerMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAYf,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAGvD,OAAO,KAAK,EAAC,mBAAmB,EAAE,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AAMhF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACpD,aAAa,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,gBAAgB,CAAC;IACxB,gEAAgE;IAChE,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,oEAAoE;IACpE,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,OAAO,CAAC;IACnD,sCAAsC;IACtC,UAAU,EAAE,MAAM,SAAS,CAAC;IAC5B,mCAAmC;IACnC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;;;OAKG;IACH,SAAS,EAAE;QACT,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;QAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,eAAe,CAAC,EAAE,SAAS,CAAC;KAC7B,CAAC;CACH;AA+JD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CA0dtB"}
1
+ {"version":3,"file":"useTriggerMenu.d.ts","sourceRoot":"","sources":["../../src/Chat/useTriggerMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAYf,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAGvD,OAAO,KAAK,EAAC,mBAAmB,EAAE,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AAMhF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACpD,aAAa,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,gBAAgB,CAAC;IACxB,gEAAgE;IAChE,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,+DAA+D;IAC/D,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,OAAO,CAAC;IACnD,sCAAsC;IACtC,UAAU,EAAE,MAAM,SAAS,CAAC;IAC5B,mCAAmC;IACnC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;;;OAKG;IACH,SAAS,EAAE;QACT,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;QAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,eAAe,CAAC,EAAE,SAAS,CAAC;KAC7B,CAAC;CACH;AAoOD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAsnBtB"}