@astryxdesign/core 0.1.4-canary.37c19d3 → 0.1.4-canary.39ffd21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +1 -8
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +11 -31
- package/dist/Calendar/styles.d.ts +2 -2
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +2 -2
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +0 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +1 -8
- package/dist/CheckboxInput/CheckboxInput.d.ts +1 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +1 -3
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +3 -26
- package/dist/CodeBlock/CodeBlock.d.ts +1 -10
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +5 -23
- package/dist/Collapsible/Collapsible.d.ts +3 -9
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +13 -101
- package/dist/Collapsible/CollapsibleGroup.d.ts +7 -39
- package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroup.js +9 -70
- package/dist/Collapsible/CollapsibleGroupContext.d.ts +0 -31
- package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
- package/dist/Collapsible/CollapsibleGroupContext.js +3 -33
- package/dist/Collapsible/index.d.ts +0 -1
- package/dist/Collapsible/index.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +0 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +0 -2
- package/dist/Grid/Grid.d.ts +3 -4
- package/dist/Grid/Grid.d.ts.map +1 -1
- package/dist/Grid/Grid.js +9 -26
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +1 -5
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +2 -26
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +16 -32
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +36 -87
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +21 -39
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +1 -2
- package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
- package/dist/Resizable/ResizeHandle.js +2 -10
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +2 -6
- package/dist/TabList/TabMenu.d.ts.map +1 -1
- package/dist/TabList/TabMenu.js +7 -34
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +2 -12
- package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
- package/dist/Table/plugins/columnResize/useTableColumnResize.js +2 -5
- package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
- package/dist/Table/plugins/pagination/paginateData.js +1 -5
- package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelectionState.js +1 -11
- package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
- package/dist/Table/plugins/sortable/useTableSortableState.js +4 -8
- package/dist/Thumbnail/Thumbnail.d.ts +2 -3
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +0 -1
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +1 -6
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +3 -11
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +0 -12
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +2 -5
- package/dist/astryx.css +0 -7
- package/dist/astryx.umd.js +48 -48
- package/dist/astryx.umd.js.map +4 -4
- package/dist/hooks/focusableSelector.d.ts +1 -1
- package/dist/hooks/focusableSelector.d.ts.map +1 -1
- package/dist/hooks/focusableSelector.js +1 -1
- package/dist/hooks/useFocusTrap.d.ts +0 -3
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +1 -38
- package/dist/theme/defineTheme.d.ts +1 -1
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/expandColorScale.d.ts.map +1 -1
- package/dist/theme/expandColorScale.js +3 -10
- package/dist/theme/hct.d.ts +15 -0
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +9 -9
- package/dist/theme/tokens.d.ts +2 -10
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +4 -220
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -2
- package/dist/utils/timeParser.d.ts.map +1 -1
- package/dist/utils/timeParser.js +5 -8
- package/package.json +1 -1
- package/src/Avatar/Avatar.doc.mjs +0 -11
- package/src/Banner/Banner.doc.mjs +0 -8
- package/src/Banner/Banner.test.tsx +0 -38
- package/src/Banner/Banner.tsx +1 -8
- package/src/Calendar/Calendar.doc.mjs +1 -1
- package/src/Calendar/Calendar.test.tsx +4 -112
- package/src/Calendar/Calendar.tsx +5 -26
- package/src/Calendar/styles.ts +2 -12
- package/src/Carousel/Carousel.doc.mjs +12 -12
- package/src/Carousel/Carousel.test.tsx +0 -13
- package/src/Carousel/Carousel.tsx +0 -1
- package/src/Chat/Chat.doc.mjs +1 -1
- package/src/Chat/ChatToolCalls.test.tsx +0 -55
- package/src/Chat/ChatToolCalls.tsx +12 -10
- package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -3
- package/src/CheckboxInput/CheckboxInput.test.tsx +4 -71
- package/src/CheckboxInput/CheckboxInput.tsx +0 -2
- package/src/Citation/Citation.doc.mjs +0 -5
- package/src/ClickableCard/ClickableCard.tsx +2 -45
- package/src/CodeBlock/CodeBlock.doc.mjs +2 -7
- package/src/CodeBlock/CodeBlock.test.tsx +3 -87
- package/src/CodeBlock/CodeBlock.tsx +3 -43
- package/src/Collapsible/Collapsible.doc.mjs +4 -8
- package/src/Collapsible/Collapsible.tsx +10 -86
- package/src/Collapsible/CollapsibleGroup.doc.mjs +3 -27
- package/src/Collapsible/CollapsibleGroup.test.tsx +0 -288
- package/src/Collapsible/CollapsibleGroup.tsx +9 -107
- package/src/Collapsible/CollapsibleGroupContext.tsx +2 -42
- package/src/Collapsible/index.ts +0 -4
- package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +0 -5
- package/src/CommandPalette/CommandPaletteGroup.doc.mjs +0 -10
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +0 -6
- package/src/CommandPalette/CommandPaletteItem.doc.mjs +0 -6
- package/src/CommandPalette/CommandPaletteList.doc.mjs +0 -9
- package/src/ContextMenu/ContextMenu.doc.mjs +0 -15
- package/src/ContextMenu/ContextMenu.test.tsx +0 -15
- package/src/ContextMenu/ContextMenu.tsx +0 -2
- package/src/ContextMenu/ContextMenuItem.doc.mjs +0 -6
- package/src/DateTimeInput/DateTimeInput.test.tsx +0 -70
- package/src/DateTimeInput/DateTimeInput.tsx +0 -2
- package/src/Dialog/DialogHeader.doc.mjs +0 -45
- package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
- package/src/Field/FieldLabel.test.tsx +2 -2
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +3 -0
- package/src/Grid/Grid.test.tsx +18 -43
- package/src/Grid/Grid.tsx +9 -26
- package/src/Icon/Icon.test.tsx +29 -41
- package/src/Icon/Icon.tsx +2 -6
- package/src/Layout/LayoutContent.doc.mjs +0 -12
- package/src/Layout/LayoutPanel.doc.mjs +0 -40
- package/src/Lightbox/Lightbox.doc.mjs +0 -5
- package/src/Lightbox/Lightbox.test.tsx +2 -123
- package/src/Lightbox/Lightbox.tsx +1 -29
- package/src/NavMenu/NavMenu.doc.mjs +0 -15
- package/src/NumberInput/NumberInput.test.tsx +3 -48
- package/src/NumberInput/NumberInput.tsx +15 -32
- package/src/Overlay/Overlay.doc.mjs +0 -6
- package/src/Pagination/Pagination.test.tsx +0 -143
- package/src/Pagination/Pagination.tsx +23 -75
- package/src/Popover/Popover.test.tsx +0 -65
- package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
- package/src/PowerSearch/PowerSearch.test.tsx +1 -109
- package/src/PowerSearch/PowerSearch.tsx +16 -37
- package/src/ProgressBar/ProgressBar.test.tsx +0 -10
- package/src/ProgressBar/ProgressBar.tsx +1 -2
- package/src/Resizable/ResizeHandle.tsx +2 -10
- package/src/SegmentedControl/SegmentedControl.doc.mjs +1 -1
- package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
- package/src/SideNav/SideNav.doc.mjs +1 -7
- package/src/SideNav/SideNav.test.tsx +0 -20
- package/src/SideNav/SideNav.tsx +2 -6
- package/src/TabList/TabList.test.tsx +1 -185
- package/src/TabList/TabMenu.tsx +9 -45
- package/src/Table/BaseTable.tsx +1 -11
- package/src/Table/Table.test.tsx +0 -51
- package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +0 -13
- package/src/Table/plugins/columnResize/useTableColumnResize.tsx +1 -3
- package/src/Table/plugins/pagination/paginateData.ts +1 -5
- package/src/Table/plugins/pagination/useTablePagination.test.tsx +0 -13
- package/src/Table/plugins/selection/useTableSelectionState.test.tsx +0 -23
- package/src/Table/plugins/selection/useTableSelectionState.tsx +6 -11
- package/src/Table/plugins/sortable/useTableSortableState.test.tsx +1 -35
- package/src/Table/plugins/sortable/useTableSortableState.tsx +4 -8
- package/src/TextArea/TextArea.test.tsx +3 -3
- package/src/TextInput/TextInput.test.tsx +3 -3
- package/src/Thumbnail/Thumbnail.test.tsx +2 -36
- package/src/Thumbnail/Thumbnail.tsx +2 -4
- package/src/TimeInput/TimeInput.test.tsx +0 -37
- package/src/TimeInput/TimeInput.tsx +1 -11
- package/src/Timestamp/Timestamp.doc.mjs +1 -1
- package/src/Toast/Toast.tsx +3 -11
- package/src/Toast/ToastViewport.test.tsx +0 -64
- package/src/Toast/ToastViewport.tsx +0 -12
- package/src/ToggleButton/ToggleButton.doc.mjs +0 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
- package/src/TopNav/TopNav.doc.mjs +1 -1
- package/src/TreeList/TreeList.doc.mjs +2 -2
- package/src/Typeahead/BaseTypeahead.doc.mjs +0 -19
- package/src/Typeahead/BaseTypeahead.tsx +2 -5
- package/src/Typeahead/Typeahead.doc.mjs +1 -1
- package/src/Typeahead/Typeahead.test.tsx +1 -45
- package/src/hooks/focusableSelector.ts +1 -1
- package/src/hooks/useFocusTrap.doc.mjs +2 -4
- package/src/hooks/useFocusTrap.test.tsx +1 -149
- package/src/hooks/useFocusTrap.ts +1 -50
- package/src/theme/SyntaxTheme.doc.mjs +4 -4
- package/src/theme/defineTheme.ts +13 -4
- package/src/theme/derivedVarRegistry.test.ts +2 -2
- package/src/theme/expandColorScale.test.ts +0 -29
- package/src/theme/expandColorScale.ts +6 -11
- package/src/theme/hct.ts +17 -9
- package/src/theme/tokens.test.ts +9 -182
- package/src/theme/tokens.ts +4 -239
- package/src/theme/useTheme.test.tsx +0 -20
- package/src/utils/index.ts +0 -3
- package/src/utils/timeParser.test.ts +0 -13
- package/src/utils/timeParser.ts +5 -8
- package/dist/utils/color.d.ts +0 -42
- package/dist/utils/color.d.ts.map +0 -1
- package/dist/utils/color.js +0 -150
- package/src/Resizable/ResizeHandle.test.tsx +0 -180
- package/src/__tests__/TestIcon.tsx +0 -26
- package/src/docPropReferences.test.ts +0 -178
- package/src/utils/color.test.ts +0 -133
- package/src/utils/color.ts +0 -148
|
@@ -270,44 +270,6 @@ describe('Banner', () => {
|
|
|
270
270
|
expect(expandIndex).toBeLessThan(dismissIndex);
|
|
271
271
|
});
|
|
272
272
|
|
|
273
|
-
it('links the expand toggle to its content region via aria-controls', () => {
|
|
274
|
-
render(
|
|
275
|
-
<Banner status="info" title="Controls Test" defaultIsExpanded>
|
|
276
|
-
<div data-testid="region-content">Region content</div>
|
|
277
|
-
</Banner>,
|
|
278
|
-
);
|
|
279
|
-
|
|
280
|
-
const toggle = screen.getByRole('button', {name: 'Collapse'});
|
|
281
|
-
const controlsId = toggle.getAttribute('aria-controls');
|
|
282
|
-
// aria-controls must be present and point at the real content region.
|
|
283
|
-
expect(controlsId).toBeTruthy();
|
|
284
|
-
const region = document.getElementById(controlsId as string);
|
|
285
|
-
expect(region).not.toBeNull();
|
|
286
|
-
expect(region).toContainElement(screen.getByTestId('region-content'));
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
it('sets aria-controls only while the content region is mounted', async () => {
|
|
290
|
-
const user = userEvent.setup();
|
|
291
|
-
render(
|
|
292
|
-
<Banner status="info" title="Controls Toggle">
|
|
293
|
-
<div data-testid="region-content">Region content</div>
|
|
294
|
-
</Banner>,
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
// Collapsed: the region is unmounted, so no dangling aria-controls target.
|
|
298
|
-
const collapsedToggle = screen.getByRole('button', {name: 'Expand'});
|
|
299
|
-
expect(collapsedToggle).not.toHaveAttribute('aria-controls');
|
|
300
|
-
|
|
301
|
-
// Expanded: aria-controls resolves to the mounted region with the children.
|
|
302
|
-
await user.click(collapsedToggle);
|
|
303
|
-
const expandedToggle = screen.getByRole('button', {name: 'Collapse'});
|
|
304
|
-
const controlsId = expandedToggle.getAttribute('aria-controls');
|
|
305
|
-
expect(controlsId).toBeTruthy();
|
|
306
|
-
const region = document.getElementById(controlsId as string);
|
|
307
|
-
expect(region).not.toBeNull();
|
|
308
|
-
expect(region).toContainElement(screen.getByTestId('region-content'));
|
|
309
|
-
});
|
|
310
|
-
|
|
311
273
|
it('does not render content area when no children', () => {
|
|
312
274
|
const {container} = render(<Banner status="info" title="No Children" />);
|
|
313
275
|
const root = container.firstElementChild;
|
package/src/Banner/Banner.tsx
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* - /packages/cli/templates/blocks/components/Banner/ (showcase blocks)
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
|
-
import {
|
|
34
|
+
import {useState, type ReactNode} from 'react';
|
|
35
35
|
import * as stylex from '@stylexjs/stylex';
|
|
36
36
|
import type {BaseProps} from '../BaseProps';
|
|
37
37
|
import {Button} from '../Button';
|
|
@@ -387,11 +387,6 @@ export function Banner({
|
|
|
387
387
|
}: BannerProps) {
|
|
388
388
|
const [isDismissed, setIsDismissed] = useState(false);
|
|
389
389
|
const [isExpanded, setIsExpanded] = useState(defaultIsExpanded);
|
|
390
|
-
// Links the expand/collapse toggle to the content region it shows/hides so
|
|
391
|
-
// assistive tech can move from the button to its controlled content
|
|
392
|
-
// (disclosure pattern). The region is conditionally rendered, so aria-controls
|
|
393
|
-
// below is set only while it's mounted to avoid a dangling reference.
|
|
394
|
-
const contentId = useId();
|
|
395
390
|
const defaultIconName = defaultIconNames[status];
|
|
396
391
|
const role = statusRole[status];
|
|
397
392
|
const iconColor = statusIconColor[status];
|
|
@@ -482,7 +477,6 @@ export function Banner({
|
|
|
482
477
|
}
|
|
483
478
|
onClick={handleToggleExpand}
|
|
484
479
|
aria-expanded={isExpanded}
|
|
485
|
-
aria-controls={showContent ? contentId : undefined}
|
|
486
480
|
isIconOnly
|
|
487
481
|
/>
|
|
488
482
|
)}
|
|
@@ -503,7 +497,6 @@ export function Banner({
|
|
|
503
497
|
{/* Content area: collapsible card background — theme target ('banner-content') */}
|
|
504
498
|
{showContent && (
|
|
505
499
|
<div
|
|
506
|
-
id={contentId}
|
|
507
500
|
{...mergeProps(
|
|
508
501
|
themeProps('banner-content', {container, status}),
|
|
509
502
|
stylex.props(styles.contentArea, isCard && styles.contentAreaCard),
|
|
@@ -19,7 +19,7 @@ export const docs = {
|
|
|
19
19
|
{guidance: false, description: 'Disable large blocks of dates without context. The user should understand why dates are unavailable.'},
|
|
20
20
|
],
|
|
21
21
|
anatomy: [
|
|
22
|
-
{name: 'Month header', required: true, description: 'The month name and year with navigation arrows to move between months.
|
|
22
|
+
{name: 'Month header', required: true, description: 'The month name and year with navigation arrows to move between months.'},
|
|
23
23
|
{name: 'Day grid', required: true, description: 'A 7-column grid of days with column headers for the day names.'},
|
|
24
24
|
{name: 'Selected day', required: false, description: 'The currently selected date, highlighted. In range mode, the start and end dates plus the days between them.'},
|
|
25
25
|
{name: 'Today marker', required: false, description: 'A subtle indicator on the current date for orientation.'},
|
|
@@ -12,10 +12,8 @@
|
|
|
12
12
|
import {describe, it, expect, vi} from 'vitest';
|
|
13
13
|
import {act, render, screen, within} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
|
-
import * as stylex from '@stylexjs/stylex';
|
|
16
15
|
import {Calendar} from './Calendar';
|
|
17
16
|
import type {CalendarHandle} from './Calendar';
|
|
18
|
-
import {calendarStyles} from './styles';
|
|
19
17
|
|
|
20
18
|
/**
|
|
21
19
|
* Helper to find a day button by its day number.
|
|
@@ -73,24 +71,6 @@ describe('Calendar', () => {
|
|
|
73
71
|
expect(screen.getByText(expectedLabel)).toBeInTheDocument();
|
|
74
72
|
});
|
|
75
73
|
|
|
76
|
-
it("marks today's cell with aria-current='date'", () => {
|
|
77
|
-
render(<Calendar />);
|
|
78
|
-
|
|
79
|
-
const now = new Date();
|
|
80
|
-
const iso = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
|
81
|
-
|
|
82
|
-
const todayCell = document.querySelector(`button[data-date="${iso}"]`);
|
|
83
|
-
expect(todayCell).not.toBeNull();
|
|
84
|
-
expect(todayCell).toHaveAttribute('aria-current', 'date');
|
|
85
|
-
|
|
86
|
-
// Only today's cell is marked current.
|
|
87
|
-
const others = Array.from(
|
|
88
|
-
document.querySelectorAll('button[data-date]'),
|
|
89
|
-
).filter(el => el.getAttribute('data-date') !== iso);
|
|
90
|
-
expect(others.length).toBeGreaterThan(0);
|
|
91
|
-
others.forEach(el => expect(el).not.toHaveAttribute('aria-current'));
|
|
92
|
-
});
|
|
93
|
-
|
|
94
74
|
it('displays day names', () => {
|
|
95
75
|
render(<Calendar />);
|
|
96
76
|
|
|
@@ -117,11 +97,7 @@ describe('Calendar', () => {
|
|
|
117
97
|
render(<Calendar value="2026-01-15" focusDate="2026-01-01" />);
|
|
118
98
|
|
|
119
99
|
const day15 = getDayButton(15);
|
|
120
|
-
|
|
121
|
-
// (a plain button role does not permit aria-selected).
|
|
122
|
-
const gridcell15 = day15.closest('[role="gridcell"]');
|
|
123
|
-
expect(gridcell15).toHaveAttribute('aria-selected', 'true');
|
|
124
|
-
expect(day15).not.toHaveAttribute('aria-selected');
|
|
100
|
+
expect(day15).toHaveAttribute('aria-selected', 'true');
|
|
125
101
|
});
|
|
126
102
|
|
|
127
103
|
it('calls onChange when date is selected', async () => {
|
|
@@ -239,33 +215,6 @@ describe('Calendar', () => {
|
|
|
239
215
|
expect(screen.getByText(/February 2026.*March 2026/)).toBeInTheDocument();
|
|
240
216
|
});
|
|
241
217
|
|
|
242
|
-
it('clamps out-of-range numberOfMonths to a single month', () => {
|
|
243
|
-
// 1000 would otherwise try to render 1000 month grids and lock the page up.
|
|
244
|
-
render(
|
|
245
|
-
<Calendar
|
|
246
|
-
numberOfMonths={1000 as unknown as 1 | 2}
|
|
247
|
-
focusDate="2026-01-01"
|
|
248
|
-
/>,
|
|
249
|
-
);
|
|
250
|
-
|
|
251
|
-
// Only the focused month renders — no second month, no range separator.
|
|
252
|
-
expect(screen.getByText('January 2026')).toBeInTheDocument();
|
|
253
|
-
expect(screen.queryByText(/February 2026/)).not.toBeInTheDocument();
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it('clamps numberOfMonths={0} to a single month', () => {
|
|
257
|
-
render(
|
|
258
|
-
<Calendar
|
|
259
|
-
numberOfMonths={0 as unknown as 1 | 2}
|
|
260
|
-
focusDate="2026-01-01"
|
|
261
|
-
/>,
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
// 0 previously rendered no months at all; now falls back to one.
|
|
265
|
-
expect(screen.getByText('January 2026')).toBeInTheDocument();
|
|
266
|
-
expect(screen.getAllByRole('gridcell').length).toBeGreaterThan(0);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
218
|
// ─── Display Options ─────────────────────────────────────────
|
|
270
219
|
|
|
271
220
|
it('shows week numbers when hasWeekNumbers is true', () => {
|
|
@@ -361,22 +310,9 @@ describe('Calendar', () => {
|
|
|
361
310
|
const day12 = getDayButton(12);
|
|
362
311
|
const day15 = getDayButton(15);
|
|
363
312
|
|
|
364
|
-
|
|
365
|
-
expect(
|
|
366
|
-
|
|
367
|
-
'true',
|
|
368
|
-
);
|
|
369
|
-
expect(day12.closest('[role="gridcell"]')).toHaveAttribute(
|
|
370
|
-
'aria-selected',
|
|
371
|
-
'true',
|
|
372
|
-
);
|
|
373
|
-
expect(day15.closest('[role="gridcell"]')).toHaveAttribute(
|
|
374
|
-
'aria-selected',
|
|
375
|
-
'true',
|
|
376
|
-
);
|
|
377
|
-
expect(day10).not.toHaveAttribute('aria-selected');
|
|
378
|
-
expect(day12).not.toHaveAttribute('aria-selected');
|
|
379
|
-
expect(day15).not.toHaveAttribute('aria-selected');
|
|
313
|
+
expect(day10).toHaveAttribute('aria-selected', 'true');
|
|
314
|
+
expect(day12).toHaveAttribute('aria-selected', 'true');
|
|
315
|
+
expect(day15).toHaveAttribute('aria-selected', 'true');
|
|
380
316
|
});
|
|
381
317
|
|
|
382
318
|
it('caps the range highlight next to a disabled mid-range day (#2715)', () => {
|
|
@@ -739,48 +675,4 @@ describe('Calendar', () => {
|
|
|
739
675
|
}
|
|
740
676
|
}
|
|
741
677
|
});
|
|
742
|
-
|
|
743
|
-
// ─── RTL (#3388) ─────────────────────────────────────────────
|
|
744
|
-
|
|
745
|
-
describe('RTL month navigation', () => {
|
|
746
|
-
// jsdom does not apply compiled StyleX CSS, so the scaleX(-1) mirror
|
|
747
|
-
// itself is only observable in a browser (see the dir="rtl" Storybook
|
|
748
|
-
// story). These tests pin the structure the fix depends on: both nav
|
|
749
|
-
// chevrons render inside the navIcon wrapper that carries the
|
|
750
|
-
// ':is([dir="rtl"] *)' conditional transform.
|
|
751
|
-
it('wraps both nav chevrons in the RTL-mirroring navIcon wrapper', () => {
|
|
752
|
-
render(<Calendar focusDate="2026-01-01" />);
|
|
753
|
-
|
|
754
|
-
const {className: navIconClass} = stylex.props(calendarStyles.navIcon);
|
|
755
|
-
expect(navIconClass).toBeTruthy();
|
|
756
|
-
|
|
757
|
-
for (const name of ['Previous month', 'Next month']) {
|
|
758
|
-
const button = screen.getByRole('button', {name});
|
|
759
|
-
const wrappers = Array.from(button.querySelectorAll('span')).filter(
|
|
760
|
-
span => span.className === navIconClass,
|
|
761
|
-
);
|
|
762
|
-
expect(wrappers.length).toBe(1);
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
|
|
766
|
-
it('keeps navigation semantics unchanged under dir="rtl"', async () => {
|
|
767
|
-
const user = userEvent.setup();
|
|
768
|
-
|
|
769
|
-
render(
|
|
770
|
-
<div dir="rtl">
|
|
771
|
-
<Calendar focusDate="2026-02-01" />
|
|
772
|
-
</div>,
|
|
773
|
-
);
|
|
774
|
-
|
|
775
|
-
expect(screen.getByText('February 2026')).toBeInTheDocument();
|
|
776
|
-
|
|
777
|
-
// DOM order and handlers must not change in RTL: flexbox already
|
|
778
|
-
// places "Previous month" at the visual right; only the glyph mirrors.
|
|
779
|
-
await user.click(screen.getByRole('button', {name: 'Previous month'}));
|
|
780
|
-
expect(screen.getByText('January 2026')).toBeInTheDocument();
|
|
781
|
-
|
|
782
|
-
await user.click(screen.getByRole('button', {name: 'Next month'}));
|
|
783
|
-
expect(screen.getByText('February 2026')).toBeInTheDocument();
|
|
784
|
-
});
|
|
785
|
-
});
|
|
786
678
|
});
|
|
@@ -203,7 +203,7 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
203
203
|
value,
|
|
204
204
|
defaultValue,
|
|
205
205
|
onChange,
|
|
206
|
-
numberOfMonths
|
|
206
|
+
numberOfMonths = 1,
|
|
207
207
|
min,
|
|
208
208
|
max,
|
|
209
209
|
dateConstraints,
|
|
@@ -223,11 +223,6 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
223
223
|
// DayOfWeek so all downstream date math keeps working with an index.
|
|
224
224
|
const weekStartsOn = normalizeDayOfWeek(weekStartsOnProp);
|
|
225
225
|
|
|
226
|
-
// `numberOfMonths` is typed `1 | 2`; defensively clamp anything else that
|
|
227
|
-
// slips through at runtime to 1 so `Array.from({length})` can't render an
|
|
228
|
-
// absurd number of month grids (e.g. `numberOfMonths={1000}`).
|
|
229
|
-
const numberOfMonths = numberOfMonthsProp === 2 ? 2 : 1;
|
|
230
|
-
|
|
231
226
|
// Today's date (memoized)
|
|
232
227
|
const today = useMemo(() => plainDateToday(), []);
|
|
233
228
|
|
|
@@ -431,14 +426,7 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
431
426
|
<Button
|
|
432
427
|
label="Previous month"
|
|
433
428
|
variant="ghost"
|
|
434
|
-
icon={
|
|
435
|
-
// Wrapper span (not Icon props): Icon's string mode clobbers
|
|
436
|
-
// caller classNames, so the RTL mirror must live on its own
|
|
437
|
-
// element.
|
|
438
|
-
<span {...stylex.props(calendarStyles.navIcon)}>
|
|
439
|
-
<Icon icon="chevronLeft" size="sm" color="inherit" />
|
|
440
|
-
</span>
|
|
441
|
-
}
|
|
429
|
+
icon={<Icon icon="chevronLeft" size="sm" color="inherit" />}
|
|
442
430
|
onClick={() => navigateMonth(-1)}
|
|
443
431
|
isDisabled={!canNavigatePrevious}
|
|
444
432
|
isIconOnly
|
|
@@ -451,11 +439,7 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
451
439
|
<Button
|
|
452
440
|
label="Next month"
|
|
453
441
|
variant="ghost"
|
|
454
|
-
icon={
|
|
455
|
-
<span {...stylex.props(calendarStyles.navIcon)}>
|
|
456
|
-
<Icon icon="chevronRight" size="sm" color="inherit" />
|
|
457
|
-
</span>
|
|
458
|
-
}
|
|
442
|
+
icon={<Icon icon="chevronRight" size="sm" color="inherit" />}
|
|
459
443
|
onClick={() => navigateMonth(1)}
|
|
460
444
|
isDisabled={!canNavigateNext}
|
|
461
445
|
isIconOnly
|
|
@@ -928,10 +912,7 @@ function DayCell({
|
|
|
928
912
|
});
|
|
929
913
|
|
|
930
914
|
return (
|
|
931
|
-
<div
|
|
932
|
-
role="gridcell"
|
|
933
|
-
aria-selected={state.isSelected || state.isInRange || undefined}
|
|
934
|
-
{...stylex.props(dayCellStyles.cell)}>
|
|
915
|
+
<div role="gridcell" {...stylex.props(dayCellStyles.cell)}>
|
|
935
916
|
{/* Range background */}
|
|
936
917
|
{state.isInRange && (
|
|
937
918
|
<div
|
|
@@ -971,10 +952,8 @@ function DayCell({
|
|
|
971
952
|
type="button"
|
|
972
953
|
data-date={day.iso}
|
|
973
954
|
aria-label={plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY)}
|
|
955
|
+
aria-selected={state.isSelected || state.isInRange || undefined}
|
|
974
956
|
aria-disabled={state.effectivelyDisabled || undefined}
|
|
975
|
-
// Mark today's cell programmatically (APG date-picker pattern), not just
|
|
976
|
-
// visually, so screen-reader users can identify the current date.
|
|
977
|
-
aria-current={state.isToday ? 'date' : undefined}
|
|
978
957
|
disabled={isDisabled}
|
|
979
958
|
// Initial roving tab-stop seed; useGridFocus owns it after mount.
|
|
980
959
|
tabIndex={isTabbableDay ? 0 : -1}
|
package/src/Calendar/styles.ts
CHANGED
|
@@ -64,19 +64,9 @@ export const calendarStyles = stylex.create({
|
|
|
64
64
|
whiteSpace: 'nowrap',
|
|
65
65
|
borderWidth: 0,
|
|
66
66
|
},
|
|
67
|
-
/**
|
|
68
|
-
* Wrapper for the month nav chevrons. In RTL the flex header already
|
|
69
|
-
* swaps the buttons' visual sides; the glyphs must mirror with them so
|
|
70
|
-
* "Previous month" points outward (visually right) instead of inward.
|
|
71
|
-
* Keyed on the dir attribute (dir="rtl"), same as MobileNav's drawer
|
|
72
|
-
* transform — bare CSS `direction: rtl` alone won't trigger it.
|
|
73
|
-
*/
|
|
74
67
|
navIcon: {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
default: null,
|
|
78
|
-
':is([dir="rtl"] *)': 'scaleX(-1)',
|
|
79
|
-
},
|
|
68
|
+
width: spacingVars['--spacing-4'],
|
|
69
|
+
height: spacingVars['--spacing-4'],
|
|
80
70
|
},
|
|
81
71
|
});
|
|
82
72
|
|
|
@@ -20,15 +20,15 @@ export const docs = {
|
|
|
20
20
|
],
|
|
21
21
|
anatomy: [
|
|
22
22
|
{name: 'Scroll container', required: true, description: 'The horizontal overflow area that holds all items.'},
|
|
23
|
-
{name: 'Items', required: true, description: 'The children rendered in a row
|
|
23
|
+
{name: 'Items', required: true, description: 'The children rendered in a row. Each item is animated with a scroll-driven scale effect.'},
|
|
24
24
|
{name: 'Fade edges', required: false, description: 'Gradient fades on the left and right edges that indicate more content is available. Enabled by default, disable with hasEdgeFade={false}.'},
|
|
25
|
-
{name: 'Navigation buttons', required: false, description: 'Prev/next buttons that appear
|
|
25
|
+
{name: 'Navigation buttons', required: false, description: 'Prev/next buttons that appear on hover. Enabled by default, disable with hasButtons={false}.'},
|
|
26
26
|
],
|
|
27
27
|
},
|
|
28
28
|
props: [
|
|
29
29
|
{name: 'children', type: 'ReactNode', description: 'Carousel items rendered in a horizontal scroll container.', required: true},
|
|
30
30
|
{name: 'gap', type: "0 | 0.5 | 1 | 1.5 | 2 | 3 | 4", description: 'Gap between items using the spacing token scale.', default: '1'},
|
|
31
|
-
{name: 'hasButtons', type: 'boolean', description: 'Show prev/next navigation buttons
|
|
31
|
+
{name: 'hasButtons', type: 'boolean', description: 'Show prev/next navigation buttons on hover (desktop only).', default: 'true'},
|
|
32
32
|
{name: 'hasEdgeFade', type: 'boolean', description: 'Show a gradient edge-fade mask when content overflows, signalling that more items exist off-screen.', default: 'true'},
|
|
33
33
|
{name: 'hasSnap', type: 'boolean', description: 'Enable scroll-snap so each child snaps to the start edge.', default: 'false'},
|
|
34
34
|
{name: 'padding', type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10', description: 'Inline padding inside the scroll container, with matching scroll-padding so snap points align to the content edge.'},
|
|
@@ -59,20 +59,20 @@ export const docs = {
|
|
|
59
59
|
export const docsZh = {
|
|
60
60
|
usage: {
|
|
61
61
|
description:
|
|
62
|
-
'Carousel
|
|
62
|
+
'Carousel scrolls a row of items horizontally when they overflow the available width. Use it for card grids, image galleries, product lists, or any set of items that should be browsable without taking up the full page.',
|
|
63
63
|
bestPractices: [
|
|
64
|
-
{guidance: true, description: '
|
|
65
|
-
{guidance: true, description: '
|
|
66
|
-
{guidance: true, description: '
|
|
67
|
-
{guidance: false, description: '
|
|
68
|
-
{guidance: false, description: '
|
|
69
|
-
{guidance: false, description: '
|
|
64
|
+
{guidance: true, description: 'Enable scroll-snap when each item should land precisely at the start edge, like a gallery or product list.'},
|
|
65
|
+
{guidance: true, description: 'Always provide an aria-label that describes what the carousel contains, like "Featured products" or "Team members".'},
|
|
66
|
+
{guidance: true, description: 'Use a consistent gap and item width so the carousel looks intentional, not like content overflowing by accident.'},
|
|
67
|
+
{guidance: false, description: 'Use a carousel for content every user must see. Not everyone scrolls horizontally, so put critical content above the fold.'},
|
|
68
|
+
{guidance: false, description: 'Auto-advance items. Let the user scroll at their own pace.'},
|
|
69
|
+
{guidance: false, description: 'Nest carousels. A carousel inside a carousel is confusing and breaks keyboard navigation.'},
|
|
70
70
|
],
|
|
71
71
|
},
|
|
72
72
|
propDescriptions: {
|
|
73
73
|
children: '在水平滚动容器中渲染的轮播项目。',
|
|
74
74
|
gap: '使用间距令牌比例的项目间距。',
|
|
75
|
-
hasButtons: '
|
|
75
|
+
hasButtons: '悬停时显示上一个/下一个导航按钮(仅桌面端)。',
|
|
76
76
|
hasEdgeFade: '内容溢出时显示渐变边缘遮罩,提示屏幕外还有更多项目。',
|
|
77
77
|
hasSnap: '启用滚动吸附,使每个子元素吸附到起始边缘。',
|
|
78
78
|
padding: '滚动容器内的内联内边距,并设置匹配的 scroll-padding,使吸附点与内容边缘对齐。',
|
|
@@ -98,7 +98,7 @@ export const docsDense = {
|
|
|
98
98
|
propDescriptions: {
|
|
99
99
|
children: 'carousel items in horizontal scroll',
|
|
100
100
|
gap: 'item spacing via spacing token scale',
|
|
101
|
-
hasButtons: 'prev/next buttons
|
|
101
|
+
hasButtons: 'prev/next buttons on hover (desktop)',
|
|
102
102
|
hasEdgeFade: 'gradient edge-fade mask on overflow',
|
|
103
103
|
hasSnap: 'scroll-snap; children snap to start edge',
|
|
104
104
|
padding: 'inline padding; scroll-padding keeps snap points on content edge',
|
|
@@ -38,19 +38,6 @@ describe('Carousel', () => {
|
|
|
38
38
|
expect(region).toHaveAttribute('aria-roledescription', 'carousel');
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
it('makes the scroll container keyboard-focusable', () => {
|
|
42
|
-
render(
|
|
43
|
-
<Carousel aria-label="Photos">
|
|
44
|
-
<div>Item</div>
|
|
45
|
-
</Carousel>,
|
|
46
|
-
);
|
|
47
|
-
// The inner scroll container overflows, so it must be reachable by
|
|
48
|
-
// keyboard (axe: scrollable-region-focusable).
|
|
49
|
-
const region = screen.getByRole('region', {name: 'Photos'});
|
|
50
|
-
const scroller = region.firstElementChild;
|
|
51
|
-
expect(scroller).toHaveAttribute('tabindex', '0');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
41
|
it('applies data-testid', () => {
|
|
55
42
|
render(
|
|
56
43
|
<Carousel data-testid="my-carousel">
|
package/src/Chat/Chat.doc.mjs
CHANGED
|
@@ -17,7 +17,7 @@ export const docs = {
|
|
|
17
17
|
{className: 'astryx-chat-composer', visualProps: ['density']},
|
|
18
18
|
{className: 'astryx-chat-composer-input'},
|
|
19
19
|
{className: 'astryx-chat-composer-drawer', visualProps: ['collapsed']},
|
|
20
|
-
{className: 'astryx-chat-message', visualProps: ['sender'
|
|
20
|
+
{className: 'astryx-chat-message', visualProps: ['sender']},
|
|
21
21
|
{
|
|
22
22
|
className: 'astryx-chat-message-bubble',
|
|
23
23
|
visualProps: ['sender', 'variant', 'density'],
|
|
@@ -97,59 +97,4 @@ describe('ChatToolCalls', () => {
|
|
|
97
97
|
);
|
|
98
98
|
expect(screen.getByText('git status')).toBeInTheDocument();
|
|
99
99
|
});
|
|
100
|
-
|
|
101
|
-
it('exposes no aria-expanded on a call row without resultDetail', () => {
|
|
102
|
-
const {container} = render(
|
|
103
|
-
<ChatToolCalls calls={[{name: 'bash', status: 'complete'}]} />,
|
|
104
|
-
);
|
|
105
|
-
expect(container.querySelector('[aria-expanded]')).toBeNull();
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('wires disclosure semantics on an expandable call row', () => {
|
|
109
|
-
render(
|
|
110
|
-
<ChatToolCalls
|
|
111
|
-
calls={[
|
|
112
|
-
{
|
|
113
|
-
name: 'readFile',
|
|
114
|
-
status: 'complete',
|
|
115
|
-
resultDetail: <div>file contents here</div>,
|
|
116
|
-
},
|
|
117
|
-
]}
|
|
118
|
-
/>,
|
|
119
|
-
);
|
|
120
|
-
const row = screen.getByRole('button');
|
|
121
|
-
expect(row).toHaveAttribute('aria-expanded', 'false');
|
|
122
|
-
// Detail panel is conditionally mounted, so no aria-controls while closed.
|
|
123
|
-
expect(row).not.toHaveAttribute('aria-controls');
|
|
124
|
-
expect(screen.queryByText('file contents here')).not.toBeInTheDocument();
|
|
125
|
-
|
|
126
|
-
fireEvent.click(row);
|
|
127
|
-
|
|
128
|
-
expect(row).toHaveAttribute('aria-expanded', 'true');
|
|
129
|
-
const detailId = row.getAttribute('aria-controls');
|
|
130
|
-
expect(detailId).toBeTruthy();
|
|
131
|
-
const panel = document.getElementById(detailId as string);
|
|
132
|
-
expect(panel).not.toBeNull();
|
|
133
|
-
expect(panel).toHaveTextContent('file contents here');
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('points the group header aria-controls at the content region', () => {
|
|
137
|
-
render(
|
|
138
|
-
<ChatToolCalls
|
|
139
|
-
defaultIsExpanded={true}
|
|
140
|
-
calls={[
|
|
141
|
-
{name: 'searchCode', status: 'complete'},
|
|
142
|
-
{name: 'readFile', status: 'complete'},
|
|
143
|
-
]}
|
|
144
|
-
/>,
|
|
145
|
-
);
|
|
146
|
-
const header = screen.getByRole('button');
|
|
147
|
-
expect(header).toHaveAttribute('aria-expanded', 'true');
|
|
148
|
-
const regionId = header.getAttribute('aria-controls');
|
|
149
|
-
expect(regionId).toBeTruthy();
|
|
150
|
-
const region = document.getElementById(regionId as string);
|
|
151
|
-
expect(region).not.toBeNull();
|
|
152
|
-
expect(region).toHaveTextContent('searchCode');
|
|
153
|
-
expect(region).toHaveTextContent('readFile');
|
|
154
|
-
});
|
|
155
100
|
});
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* for builders to wire up.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import React, {useState, useCallback,
|
|
21
|
+
import React, {useState, useCallback, type ReactNode} from 'react';
|
|
22
22
|
import type {BaseProps} from '../BaseProps';
|
|
23
23
|
import * as stylex from '@stylexjs/stylex';
|
|
24
24
|
import {
|
|
@@ -41,7 +41,11 @@ import {themeProps} from '../utils/themeProps';
|
|
|
41
41
|
// Types
|
|
42
42
|
// =============================================================================
|
|
43
43
|
|
|
44
|
-
export type ChatToolCallStatus =
|
|
44
|
+
export type ChatToolCallStatus =
|
|
45
|
+
| 'pending'
|
|
46
|
+
| 'running'
|
|
47
|
+
| 'complete'
|
|
48
|
+
| 'error';
|
|
45
49
|
|
|
46
50
|
export interface ChatToolCallItem {
|
|
47
51
|
/** Tool/function name. */
|
|
@@ -352,7 +356,6 @@ function CallRow({call}: {call: ChatToolCallItem}) {
|
|
|
352
356
|
const status = call.status ?? 'complete';
|
|
353
357
|
const hasDetail = call.resultDetail != null;
|
|
354
358
|
const [isDetailOpen, setIsDetailOpen] = useState(false);
|
|
355
|
-
const detailId = useId();
|
|
356
359
|
|
|
357
360
|
const toggleDetail = hasDetail
|
|
358
361
|
? () => setIsDetailOpen(prev => !prev)
|
|
@@ -362,8 +365,6 @@ function CallRow({call}: {call: ChatToolCallItem}) {
|
|
|
362
365
|
<div
|
|
363
366
|
role={hasDetail ? 'button' : undefined}
|
|
364
367
|
tabIndex={hasDetail ? 0 : undefined}
|
|
365
|
-
aria-expanded={hasDetail ? isDetailOpen : undefined}
|
|
366
|
-
aria-controls={hasDetail && isDetailOpen ? detailId : undefined}
|
|
367
368
|
onClick={toggleDetail}
|
|
368
369
|
onKeyDown={
|
|
369
370
|
hasDetail
|
|
@@ -398,7 +399,11 @@ function CallRow({call}: {call: ChatToolCallItem}) {
|
|
|
398
399
|
</span>
|
|
399
400
|
<span {...stylex.props(styles.callName)}>{call.name}</span>
|
|
400
401
|
{call.node != null && (
|
|
401
|
-
<Badge
|
|
402
|
+
<Badge
|
|
403
|
+
label={call.node}
|
|
404
|
+
variant="neutral"
|
|
405
|
+
xstyle={styles.nodePill}
|
|
406
|
+
/>
|
|
402
407
|
)}
|
|
403
408
|
{call.target != null && (
|
|
404
409
|
<span {...stylex.props(styles.callLabel)}>{call.target}</span>
|
|
@@ -443,7 +448,7 @@ function CallRow({call}: {call: ChatToolCallItem}) {
|
|
|
443
448
|
<div>
|
|
444
449
|
{row}
|
|
445
450
|
{isDetailOpen && (
|
|
446
|
-
<div
|
|
451
|
+
<div {...stylex.props(styles.callDetailContent)}>
|
|
447
452
|
{call.resultDetail}
|
|
448
453
|
</div>
|
|
449
454
|
)}
|
|
@@ -492,7 +497,6 @@ export function ChatToolCalls(props: ChatToolCallsProps) {
|
|
|
492
497
|
|
|
493
498
|
const autoDefault = defaultIsExpanded ?? false;
|
|
494
499
|
const [internalExpanded, setInternalExpanded] = useState(autoDefault);
|
|
495
|
-
const contentId = useId();
|
|
496
500
|
const isControlled = controlledExpanded !== undefined;
|
|
497
501
|
const isExpanded = isControlled ? controlledExpanded : internalExpanded;
|
|
498
502
|
|
|
@@ -544,7 +548,6 @@ export function ChatToolCalls(props: ChatToolCallsProps) {
|
|
|
544
548
|
role="button"
|
|
545
549
|
tabIndex={0}
|
|
546
550
|
aria-expanded={isExpanded}
|
|
547
|
-
aria-controls={contentId}
|
|
548
551
|
onClick={toggle}
|
|
549
552
|
onKeyDown={e => {
|
|
550
553
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
@@ -610,7 +613,6 @@ export function ChatToolCalls(props: ChatToolCallsProps) {
|
|
|
610
613
|
|
|
611
614
|
{/* Expanded: all calls with full metadata */}
|
|
612
615
|
<div
|
|
613
|
-
id={contentId}
|
|
614
616
|
{...stylex.props(
|
|
615
617
|
styles.groupContent,
|
|
616
618
|
isExpanded && styles.groupContentExpanded,
|
|
@@ -125,7 +125,7 @@ export const docs = {
|
|
|
125
125
|
theming: {
|
|
126
126
|
targets: [
|
|
127
127
|
{className: 'astryx-checkbox-input', visualProps: ['size']},
|
|
128
|
-
{className: 'astryx-checkbox'
|
|
128
|
+
{className: 'astryx-checkbox'},
|
|
129
129
|
],
|
|
130
130
|
},
|
|
131
131
|
usage: {
|
|
@@ -178,7 +178,7 @@ export const docsZh = {
|
|
|
178
178
|
{name: 'isLoading', type: 'boolean', description: '复选框是否处于加载状态。显示旋转器并阻止交互。', default: 'false'},
|
|
179
179
|
{name: 'isDisabled', type: 'boolean', description: '复选框是否禁用。', default: 'false'},
|
|
180
180
|
{name: 'htmlName', type: 'string', description: '底层复选框输入的 HTML name 属性,用于表单提交(勾选时提交 "on")。'},
|
|
181
|
-
{name: 'disabledMessage', type: 'string', description: 'Explains why the checkbox is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the checkbox focusable via aria-disabled (toggling stays blocked). Use this instead of wrapping a disabled CheckboxInput in Tooltip
|
|
181
|
+
{name: 'disabledMessage', type: 'string', description: 'Explains why the checkbox is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the checkbox focusable via aria-disabled (toggling stays blocked). Use this instead of wrapping a disabled CheckboxInput in Tooltip — disabled controls swallow the hover events an external Tooltip needs.'},
|
|
182
182
|
{name: 'isReadOnly', type: 'boolean', description: '复选框是否为只读。以完整不透明度显示当前状态但阻止交互。与 isDisabled 不同,只读复选框不会变暗。', default: 'false'},
|
|
183
183
|
{name: 'isOptional', type: 'boolean', description: '字段是否可选。与 isRequired 互斥。', default: 'false'},
|
|
184
184
|
{name: 'isRequired', type: 'boolean', description: '复选框是否必填。与 isOptional 互斥。', default: 'false'},
|
|
@@ -200,7 +200,7 @@ export const docsZh = {
|
|
|
200
200
|
'size',
|
|
201
201
|
],
|
|
202
202
|
},
|
|
203
|
-
{className: 'astryx-checkbox'
|
|
203
|
+
{className: 'astryx-checkbox'},
|
|
204
204
|
],
|
|
205
205
|
},
|
|
206
206
|
};
|