@astryxdesign/core 0.5.2-canary.c9c8564 → 0.5.2-canary.e03511b
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/BottomSheet/BottomSheet.d.ts +3 -1
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +4 -3
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +2 -2
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetEdgeTint.js +7 -10
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +1 -1
- package/dist/Button/Button.d.ts +2 -1
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +11 -4
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +2 -2
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +34 -17
- package/dist/ContextMenu/ContextMenu.d.ts +14 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +149 -26
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts +24 -5
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +340 -26
- package/dist/DropdownMenu/DropdownMenuContext.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +43 -14
- package/dist/DropdownMenu/MenuBottomSheet.d.ts +20 -0
- package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -0
- package/dist/DropdownMenu/MenuBottomSheet.js +36 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +10 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +111 -0
- package/dist/DropdownMenu/index.d.ts +2 -1
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/menuWidth.d.ts +14 -0
- package/dist/DropdownMenu/menuWidth.d.ts.map +1 -0
- package/dist/DropdownMenu/menuWidth.js +35 -0
- package/dist/DropdownMenu/useMenuOverflow.d.ts +10 -0
- package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -0
- package/dist/DropdownMenu/useMenuOverflow.js +60 -0
- package/dist/MoreMenu/MoreMenu.d.ts +8 -2
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/MoreMenu/MoreMenu.js +2 -0
- package/dist/MultiSelector/MultiSelector.d.ts +11 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +97 -68
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts.map +1 -1
- package/dist/Popover/Popover.d.ts +10 -6
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +141 -16
- package/dist/Popover/usePopover.d.ts +4 -0
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +52 -5
- package/dist/Selector/Selector.d.ts +10 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +106 -80
- package/dist/Selector/SelectorBottomSheet.d.ts +21 -0
- package/dist/Selector/SelectorBottomSheet.d.ts.map +1 -0
- package/dist/Selector/SelectorBottomSheet.js +83 -0
- package/dist/Selector/index.d.ts +1 -1
- package/dist/Selector/index.d.ts.map +1 -1
- package/dist/Selector/selectorPresentation.stylex.d.ts +16 -0
- package/dist/Selector/selectorPresentation.stylex.d.ts.map +1 -0
- package/dist/Selector/selectorPresentation.stylex.js +21 -0
- package/dist/Selector/useSelectorPresentation.d.ts +32 -0
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -0
- package/dist/Selector/useSelectorPresentation.js +90 -0
- package/dist/Toast/useToastGesture.d.ts.map +1 -1
- package/dist/Toast/useToastGesture.js +46 -9
- package/dist/astryx.css +19 -1
- package/dist/hooks/useAdaptivePresentation.d.ts +5 -0
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -0
- package/dist/hooks/useAdaptivePresentation.js +19 -0
- package/dist/hooks/useFocusReturnVisibility.d.ts +7 -0
- package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -0
- package/dist/hooks/useFocusReturnVisibility.js +35 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +12 -0
- package/locales/en.json +20 -0
- package/locales/pseudo.json +15 -0
- package/package.json +2 -2
- package/src/BottomSheet/BottomSheet.doc.mjs +37 -0
- package/src/BottomSheet/BottomSheet.spec.md +177 -0
- package/src/BottomSheet/BottomSheet.test.tsx +29 -0
- package/src/BottomSheet/BottomSheet.tsx +7 -4
- package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +4 -6
- package/src/BottomSheet/BottomSheetEdgeTint.tsx +7 -10
- package/src/BottomSheet/BottomSheetSwitcher.tsx +1 -2
- package/src/Button/Button.doc.mjs +56 -0
- package/src/Button/Button.test.tsx +10 -0
- package/src/Button/Button.tsx +13 -5
- package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
- package/src/Carousel/Carousel.test.tsx +83 -0
- package/src/Carousel/Carousel.tsx +8 -2
- package/src/Chat/ChatToolCalls.test.tsx +44 -0
- package/src/Chat/ChatToolCalls.tsx +36 -15
- package/src/CheckboxList/CheckboxList.doc.mjs +172 -31
- package/src/CheckboxList/CheckboxList.spec.md +214 -0
- package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
- package/src/CommandPalette/CommandPalette.spec.md +223 -0
- package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
- package/src/ComplexSelector/ComplexSelector.spec.md +189 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +61 -1
- package/src/ContextMenu/ContextMenu.spec.md +206 -0
- package/src/ContextMenu/ContextMenu.test.tsx +131 -1
- package/src/ContextMenu/ContextMenu.tsx +199 -32
- package/src/ContextMenu/index.ts +1 -0
- package/src/Divider/Divider.doc.mjs +24 -0
- package/src/Divider/Divider.spec.md +150 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +305 -40
- package/src/DropdownMenu/DropdownMenu.spec.md +245 -0
- package/src/DropdownMenu/DropdownMenu.test.tsx +518 -7
- package/src/DropdownMenu/DropdownMenu.tsx +459 -28
- package/src/DropdownMenu/DropdownMenuContext.tsx +1 -1
- package/src/DropdownMenu/DropdownMenuItem.tsx +2 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +4 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +124 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +72 -17
- package/src/DropdownMenu/MenuBottomSheet.tsx +46 -0
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +141 -0
- package/src/DropdownMenu/index.ts +2 -0
- package/src/DropdownMenu/menuWidth.ts +51 -0
- package/src/DropdownMenu/useMenuOverflow.ts +77 -0
- package/src/FieldStatus/FieldStatus.doc.mjs +21 -0
- package/src/FieldStatus/FieldStatus.spec.md +212 -0
- package/src/Grid/Grid.doc.mjs +19 -0
- package/src/Grid/Grid.spec.md +161 -0
- package/src/Icon/Icon.doc.mjs +196 -48
- package/src/Icon/Icon.spec.md +191 -0
- package/src/IconButton/IconButton.doc.mjs +38 -0
- package/src/Kbd/Kbd.doc.mjs +18 -0
- package/src/Kbd/Kbd.spec.md +141 -0
- package/src/Layout/Layout.doc.mjs +32 -0
- package/src/Layout/Layout.spec.md +199 -0
- package/src/Lightbox/Lightbox.doc.mjs +149 -33
- package/src/Lightbox/Lightbox.spec.md +197 -0
- package/src/Markdown/Markdown.doc.mjs +60 -0
- package/src/Markdown/Markdown.spec.md +200 -0
- package/src/MobileNav/MobileNav.doc.mjs +140 -32
- package/src/MobileNav/MobileNav.spec.md +208 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +59 -0
- package/src/MoreMenu/MoreMenu.spec.md +221 -0
- package/src/MoreMenu/MoreMenu.test.tsx +47 -0
- package/src/MoreMenu/MoreMenu.tsx +13 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +128 -0
- package/src/MultiSelector/MultiSelector.spec.md +266 -0
- package/src/MultiSelector/MultiSelector.test.tsx +127 -0
- package/src/MultiSelector/MultiSelector.tsx +121 -73
- package/src/MultiSelector/index.ts +1 -0
- package/src/NavIcon/NavIcon.doc.mjs +17 -0
- package/src/NavIcon/NavIcon.spec.md +133 -0
- package/src/NavMenu/NavHeadingMenu.spec.md +205 -0
- package/src/NavMenu/NavMenu.doc.mjs +37 -0
- package/src/Outline/Outline.doc.mjs +35 -0
- package/src/Outline/Outline.spec.md +161 -0
- package/src/OverflowList/OverflowList.doc.mjs +24 -0
- package/src/OverflowList/OverflowList.spec.md +156 -0
- package/src/Pagination/Pagination.doc.mjs +74 -0
- package/src/Pagination/Pagination.spec.md +225 -0
- package/src/Popover/Popover.doc.mjs +11 -11
- package/src/Popover/Popover.test.tsx +397 -2
- package/src/Popover/Popover.tsx +228 -21
- package/src/Popover/usePopover.tsx +92 -15
- package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
- package/src/ProgressBar/ProgressBar.spec.md +260 -0
- package/src/Resizable/Resizable.doc.mjs +59 -16
- package/src/Resizable/Resizable.spec.md +194 -0
- package/src/Section/Section.doc.mjs +17 -0
- package/src/Section/Section.spec.md +138 -0
- package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
- package/src/SegmentedControl/SegmentedControl.spec.md +151 -0
- package/src/Selector/Selector.doc.mjs +12 -0
- package/src/Selector/Selector.spec.md +202 -0
- package/src/Selector/Selector.test.tsx +135 -0
- package/src/Selector/Selector.tsx +141 -82
- package/src/Selector/SelectorBottomSheet.tsx +97 -0
- package/src/Selector/index.ts +1 -0
- package/src/Selector/selectorPresentation.stylex.ts +20 -0
- package/src/Selector/useSelectorPresentation.ts +147 -0
- package/src/Skeleton/Skeleton.doc.mjs +12 -0
- package/src/Skeleton/Skeleton.spec.md +126 -0
- package/src/Slider/Slider.doc.mjs +184 -30
- package/src/Slider/Slider.spec.md +223 -0
- package/src/Stack/Stack.doc.mjs +22 -0
- package/src/Stack/Stack.spec.md +154 -0
- package/src/StatusDot/StatusDot.doc.mjs +17 -0
- package/src/StatusDot/StatusDot.spec.md +137 -0
- package/src/Switch/Switch.doc.mjs +40 -0
- package/src/Switch/Switch.spec.md +174 -0
- package/src/Table/Table.doc.mjs +102 -24
- package/src/Table/Table.spec.md +283 -0
- package/src/Text/Text.doc.mjs +190 -43
- package/src/Text/Text.spec.md +205 -0
- package/src/TextArea/TextArea.doc.mjs +255 -45
- package/src/TextArea/TextArea.spec.md +204 -0
- package/src/Toast/ToastViewport.test.tsx +118 -4
- package/src/Toast/useToastGesture.ts +61 -8
- package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
- package/src/Toolbar/Toolbar.doc.mjs +19 -0
- package/src/Toolbar/Toolbar.spec.md +173 -0
- package/src/Tooltip/Tooltip.doc.mjs +17 -0
- package/src/Tooltip/Tooltip.spec.md +141 -0
- package/src/TreeList/TreeList.doc.mjs +58 -0
- package/src/TreeList/TreeList.spec.md +220 -0
- package/src/Typeahead/Typeahead.doc.mjs +83 -1
- package/src/Typeahead/Typeahead.spec.md +250 -0
- package/src/hooks/useAdaptivePresentation.ts +35 -0
- package/src/hooks/useFocusReturnVisibility.ts +45 -0
- package/src/hooks/useFocusTrap.test.tsx +40 -0
- package/src/hooks/useFocusTrap.ts +13 -0
- package/src/theme/themingTargets.test.ts +91 -25
|
@@ -850,4 +850,87 @@ describe('Carousel', () => {
|
|
|
850
850
|
expect(scroller).not.toHaveAttribute('data-padding');
|
|
851
851
|
});
|
|
852
852
|
});
|
|
853
|
+
|
|
854
|
+
describe('edge fade', () => {
|
|
855
|
+
function getScroller() {
|
|
856
|
+
const region = screen.getByRole('region');
|
|
857
|
+
return region.firstElementChild as HTMLElement;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function makeOverflowing(el: HTMLElement, scrollLeft: number) {
|
|
861
|
+
Object.defineProperty(el, 'scrollWidth', {
|
|
862
|
+
value: 500,
|
|
863
|
+
configurable: true,
|
|
864
|
+
});
|
|
865
|
+
Object.defineProperty(el, 'clientWidth', {
|
|
866
|
+
value: 200,
|
|
867
|
+
configurable: true,
|
|
868
|
+
});
|
|
869
|
+
Object.defineProperty(el, 'scrollLeft', {
|
|
870
|
+
value: scrollLeft,
|
|
871
|
+
writable: true,
|
|
872
|
+
configurable: true,
|
|
873
|
+
});
|
|
874
|
+
fireEvent.scroll(el);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
function injectedCss(): string {
|
|
878
|
+
let out = '';
|
|
879
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
880
|
+
try {
|
|
881
|
+
for (const rule of Array.from(sheet.cssRules)) {
|
|
882
|
+
out += rule.cssText + '\n';
|
|
883
|
+
}
|
|
884
|
+
} catch {
|
|
885
|
+
// Ignore cross-origin sheets.
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
return out;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
it('fades the physical left edge when only the start overflows (LTR)', () => {
|
|
892
|
+
render(
|
|
893
|
+
<Carousel aria-label="Fade">
|
|
894
|
+
<div>Item 1</div>
|
|
895
|
+
<div>Item 2</div>
|
|
896
|
+
</Carousel>,
|
|
897
|
+
);
|
|
898
|
+
const scroller = getScroller();
|
|
899
|
+
makeOverflowing(scroller, 300);
|
|
900
|
+
expect(getComputedStyle(scroller).maskImage).toContain(
|
|
901
|
+
'linear-gradient(to right',
|
|
902
|
+
);
|
|
903
|
+
});
|
|
904
|
+
|
|
905
|
+
it('fades the physical right edge when only the end overflows (LTR)', () => {
|
|
906
|
+
render(
|
|
907
|
+
<Carousel aria-label="Fade">
|
|
908
|
+
<div>Item 1</div>
|
|
909
|
+
<div>Item 2</div>
|
|
910
|
+
</Carousel>,
|
|
911
|
+
);
|
|
912
|
+
const scroller = getScroller();
|
|
913
|
+
makeOverflowing(scroller, 0);
|
|
914
|
+
expect(getComputedStyle(scroller).maskImage).toContain(
|
|
915
|
+
'linear-gradient(to left',
|
|
916
|
+
);
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
it('mirrors both single-edge fade gradients under RTL', () => {
|
|
920
|
+
render(
|
|
921
|
+
<Carousel aria-label="Fade">
|
|
922
|
+
<div>Item 1</div>
|
|
923
|
+
<div>Item 2</div>
|
|
924
|
+
</Carousel>,
|
|
925
|
+
);
|
|
926
|
+
const css = injectedCss();
|
|
927
|
+
expect(css).toMatch(
|
|
928
|
+
/:is\(\[dir="rtl"\][^)]*\)[^{]*\{\s*mask-image:\s*linear-gradient\(to left/,
|
|
929
|
+
);
|
|
930
|
+
expect(css).toMatch(
|
|
931
|
+
/:is\(\[dir="rtl"\][^)]*\)[^{]*\{\s*mask-image:\s*linear-gradient\(to right/,
|
|
932
|
+
);
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
|
|
853
936
|
});
|
|
@@ -178,10 +178,16 @@ const styles = stylex.create({
|
|
|
178
178
|
maskImage: 'none',
|
|
179
179
|
},
|
|
180
180
|
fadeStart: {
|
|
181
|
-
maskImage:
|
|
181
|
+
maskImage: {
|
|
182
|
+
default: `linear-gradient(to right, transparent 0%, rgba(0,0,0,0.3) 2px, black ${spacingVars['--spacing-1']})`,
|
|
183
|
+
':is([dir="rtl"] *)': `linear-gradient(to left, transparent 0%, rgba(0,0,0,0.3) 2px, black ${spacingVars['--spacing-1']})`,
|
|
184
|
+
},
|
|
182
185
|
},
|
|
183
186
|
fadeEnd: {
|
|
184
|
-
maskImage:
|
|
187
|
+
maskImage: {
|
|
188
|
+
default: `linear-gradient(to left, transparent 0%, rgba(0,0,0,0.3) 2px, black ${spacingVars['--spacing-1']})`,
|
|
189
|
+
':is([dir="rtl"] *)': `linear-gradient(to right, transparent 0%, rgba(0,0,0,0.3) 2px, black ${spacingVars['--spacing-1']})`,
|
|
190
|
+
},
|
|
185
191
|
},
|
|
186
192
|
fadeBoth: {
|
|
187
193
|
maskImage: `linear-gradient(to right, transparent 0%, rgba(0,0,0,0.3) 2px, black ${spacingVars['--spacing-1']}, black calc(100% - ${spacingVars['--spacing-1']}), rgba(0,0,0,0.3) calc(100% - 2px), transparent 100%)`,
|
|
@@ -46,6 +46,50 @@ describe('ChatToolCalls', () => {
|
|
|
46
46
|
expect(screen.queryByText('1.2s')).not.toBeInTheDocument();
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
it.each([
|
|
50
|
+
['pending', 'Pending'],
|
|
51
|
+
['running', 'Running'],
|
|
52
|
+
['complete', 'Complete'],
|
|
53
|
+
['error', 'Failed'],
|
|
54
|
+
] as const)(
|
|
55
|
+
'names the %s status for assistive technology',
|
|
56
|
+
(status, label) => {
|
|
57
|
+
render(<ChatToolCalls calls={[{name: 'bash', status}]} />);
|
|
58
|
+
expect(screen.getByText(label)).toBeInTheDocument();
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
it('includes the status in an expandable row accessible name', () => {
|
|
63
|
+
render(
|
|
64
|
+
<ChatToolCalls
|
|
65
|
+
calls={[
|
|
66
|
+
{
|
|
67
|
+
name: 'readFile',
|
|
68
|
+
status: 'running',
|
|
69
|
+
resultDetail: <div>file contents</div>,
|
|
70
|
+
},
|
|
71
|
+
]}
|
|
72
|
+
/>,
|
|
73
|
+
);
|
|
74
|
+
expect(
|
|
75
|
+
screen.getByRole('button', {name: /Running.*readFile/}),
|
|
76
|
+
).toBeInTheDocument();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('includes the latest status in a collapsed group accessible name', () => {
|
|
80
|
+
render(
|
|
81
|
+
<ChatToolCalls
|
|
82
|
+
calls={[
|
|
83
|
+
{name: 'searchCode', status: 'complete'},
|
|
84
|
+
{name: 'editFile', status: 'running'},
|
|
85
|
+
]}
|
|
86
|
+
/>,
|
|
87
|
+
);
|
|
88
|
+
expect(
|
|
89
|
+
screen.getByRole('button', {name: /Running.*editFile/}),
|
|
90
|
+
).toBeInTheDocument();
|
|
91
|
+
});
|
|
92
|
+
|
|
49
93
|
it('defaults to collapsed', () => {
|
|
50
94
|
render(
|
|
51
95
|
<ChatToolCalls
|
|
@@ -365,6 +365,26 @@ const STATUS_STYLES: Record<
|
|
|
365
365
|
error: styles.colorError,
|
|
366
366
|
};
|
|
367
367
|
|
|
368
|
+
function getStatusAnnouncement(
|
|
369
|
+
t: ReturnType<typeof useTranslator>,
|
|
370
|
+
status: ChatToolCallStatus,
|
|
371
|
+
errorMessage?: string,
|
|
372
|
+
): string {
|
|
373
|
+
if (status === 'error' && errorMessage != null) {
|
|
374
|
+
return t('@astryx.chatToolCalls.error', {message: errorMessage});
|
|
375
|
+
}
|
|
376
|
+
switch (status) {
|
|
377
|
+
case 'pending':
|
|
378
|
+
return t('@astryx.chatToolCalls.status.pending');
|
|
379
|
+
case 'running':
|
|
380
|
+
return t('@astryx.chatToolCalls.status.running');
|
|
381
|
+
case 'complete':
|
|
382
|
+
return t('@astryx.chatToolCalls.status.complete');
|
|
383
|
+
case 'error':
|
|
384
|
+
return t('@astryx.chatToolCalls.status.error');
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
368
388
|
function getToolCallKey(call: ChatToolCallItem): string {
|
|
369
389
|
return getKey(call.key, () =>
|
|
370
390
|
[
|
|
@@ -390,6 +410,11 @@ function CallRow({call}: {call: ChatToolCallItem}) {
|
|
|
390
410
|
const hasDetail = call.resultDetail != null;
|
|
391
411
|
const [isDetailOpen, setIsDetailOpen] = useState(false);
|
|
392
412
|
const detailId = useId();
|
|
413
|
+
const statusAnnouncement = getStatusAnnouncement(
|
|
414
|
+
t,
|
|
415
|
+
status,
|
|
416
|
+
call.errorMessage,
|
|
417
|
+
);
|
|
393
418
|
|
|
394
419
|
const toggleDetail = hasDetail
|
|
395
420
|
? () => setIsDetailOpen(prev => !prev)
|
|
@@ -417,9 +442,9 @@ function CallRow({call}: {call: ChatToolCallItem}) {
|
|
|
417
442
|
title={status === 'error' ? call.errorMessage : undefined}
|
|
418
443
|
{...stylex.props(styles.statusIcon, STATUS_STYLES[status])}>
|
|
419
444
|
{status === 'running' ? (
|
|
420
|
-
<Spinner size="sm" shade="subtle" />
|
|
445
|
+
<Spinner size="sm" shade="subtle" aria-hidden="true" />
|
|
421
446
|
) : status === 'pending' ? (
|
|
422
|
-
<Spinner size="sm" shade="subtle" />
|
|
447
|
+
<Spinner size="sm" shade="subtle" aria-hidden="true" />
|
|
423
448
|
) : (
|
|
424
449
|
<>
|
|
425
450
|
<span {...stylex.props(styles.statusIconCircle)} />
|
|
@@ -432,17 +457,7 @@ function CallRow({call}: {call: ChatToolCallItem}) {
|
|
|
432
457
|
</span>
|
|
433
458
|
</>
|
|
434
459
|
)}
|
|
435
|
-
{
|
|
436
|
-
// The title attribute above is hover-only; expose the error detail
|
|
437
|
-
// as real text so it reaches screen readers, keyboard, and touch
|
|
438
|
-
// users. Rendering it inside the row also folds it into the
|
|
439
|
-
// accessible name of expandable (role="button") rows.
|
|
440
|
-
<VisuallyHidden>
|
|
441
|
-
{t('@astryx.chatToolCalls.error', {
|
|
442
|
-
message: call.errorMessage ?? '',
|
|
443
|
-
})}
|
|
444
|
-
</VisuallyHidden>
|
|
445
|
-
)}
|
|
460
|
+
<VisuallyHidden>{statusAnnouncement}</VisuallyHidden>
|
|
446
461
|
</span>
|
|
447
462
|
<span {...stylex.props(styles.callName)}>{call.name}</span>
|
|
448
463
|
{call.node != null && (
|
|
@@ -581,6 +596,11 @@ export function ChatToolCalls(props: ChatToolCallsProps) {
|
|
|
581
596
|
// Multiple calls: latest call at surface with chevron to expand all
|
|
582
597
|
const latestCall = calls[calls.length - 1];
|
|
583
598
|
const latestStatus = latestCall.status ?? 'complete';
|
|
599
|
+
const latestStatusAnnouncement = getStatusAnnouncement(
|
|
600
|
+
t,
|
|
601
|
+
latestStatus,
|
|
602
|
+
latestCall.errorMessage,
|
|
603
|
+
);
|
|
584
604
|
|
|
585
605
|
return (
|
|
586
606
|
<div
|
|
@@ -620,9 +640,9 @@ export function ChatToolCalls(props: ChatToolCallsProps) {
|
|
|
620
640
|
<span
|
|
621
641
|
{...stylex.props(styles.statusIcon, STATUS_STYLES[latestStatus])}>
|
|
622
642
|
{latestStatus === 'running' ? (
|
|
623
|
-
<Spinner size="sm" shade="subtle" />
|
|
643
|
+
<Spinner size="sm" shade="subtle" aria-hidden="true" />
|
|
624
644
|
) : latestStatus === 'pending' ? (
|
|
625
|
-
<Spinner size="sm" shade="subtle" />
|
|
645
|
+
<Spinner size="sm" shade="subtle" aria-hidden="true" />
|
|
626
646
|
) : (
|
|
627
647
|
<>
|
|
628
648
|
<span {...stylex.props(styles.statusIconCircle)} />
|
|
@@ -635,6 +655,7 @@ export function ChatToolCalls(props: ChatToolCallsProps) {
|
|
|
635
655
|
</span>
|
|
636
656
|
</>
|
|
637
657
|
)}
|
|
658
|
+
<VisuallyHidden>{latestStatusAnnouncement}</VisuallyHidden>
|
|
638
659
|
</span>
|
|
639
660
|
<span {...stylex.props(styles.callName)}>{latestCall.name}</span>
|
|
640
661
|
{latestCall.target != null && (
|
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
|
|
4
|
+
const anatomy = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Group',
|
|
7
|
+
required: true,
|
|
8
|
+
description: 'Container for the labeled checkbox group.',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: 'Group label',
|
|
12
|
+
required: true,
|
|
13
|
+
description: 'Text identifying what the checkbox options represent.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Description',
|
|
17
|
+
required: false,
|
|
18
|
+
description: 'Helper text below the group label.',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'Options list',
|
|
22
|
+
required: true,
|
|
23
|
+
description: 'List containing the available checkbox options.',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'Option row',
|
|
27
|
+
required: true,
|
|
28
|
+
description: 'Selectable row containing one option.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'Checkbox',
|
|
32
|
+
required: true,
|
|
33
|
+
description: 'Selection indicator for an option.',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Option label',
|
|
37
|
+
required: true,
|
|
38
|
+
description: 'Primary content identifying an option.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'Option description',
|
|
42
|
+
required: false,
|
|
43
|
+
description: 'Secondary text below an option label.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'End content',
|
|
47
|
+
required: false,
|
|
48
|
+
description: 'Caller-provided content at the end of an option row.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'Spinner',
|
|
52
|
+
required: false,
|
|
53
|
+
description: 'Loading indicator shown inside the pending checkbox.',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'Status message',
|
|
57
|
+
required: false,
|
|
58
|
+
description: 'Error, warning, or success message below the group.',
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
|
|
3
62
|
/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
|
|
4
63
|
|
|
5
64
|
export const docs = {
|
|
@@ -8,13 +67,22 @@ export const docs = {
|
|
|
8
67
|
group: 'Checkbox',
|
|
9
68
|
category: 'Form Controls',
|
|
10
69
|
isHiddenFromOverview: true,
|
|
11
|
-
keywords: [
|
|
12
|
-
|
|
70
|
+
keywords: [
|
|
71
|
+
'checkboxlist',
|
|
72
|
+
'checkbox',
|
|
73
|
+
'checkboxgroup',
|
|
74
|
+
'multichoice',
|
|
75
|
+
'multiselect',
|
|
76
|
+
'checklist',
|
|
77
|
+
],
|
|
78
|
+
description:
|
|
79
|
+
'Checkbox group container with field integration for label, description, and status.',
|
|
13
80
|
props: [
|
|
14
81
|
{
|
|
15
82
|
name: 'label',
|
|
16
83
|
type: 'string',
|
|
17
|
-
description:
|
|
84
|
+
description:
|
|
85
|
+
'Label text for the checkbox group (always rendered for accessibility).',
|
|
18
86
|
required: true,
|
|
19
87
|
},
|
|
20
88
|
{
|
|
@@ -97,41 +165,89 @@ export const docs = {
|
|
|
97
165
|
{
|
|
98
166
|
name: 'xstyle',
|
|
99
167
|
type: 'StyleXStyles',
|
|
100
|
-
description:
|
|
168
|
+
description:
|
|
169
|
+
'StyleX styles for layout customization. Must be a stylex.create() value.',
|
|
101
170
|
},
|
|
102
171
|
],
|
|
103
|
-
components: [
|
|
104
|
-
{name: 'CheckboxListItem'},
|
|
105
|
-
],
|
|
172
|
+
components: [{name: 'CheckboxListItem'}],
|
|
106
173
|
usage: {
|
|
107
|
-
|
|
174
|
+
anatomy,
|
|
175
|
+
description:
|
|
176
|
+
'CheckboxList shows a small group of checkboxes so users can turn several options on or off at once. Place it in settings pages, filter panels, or forms where every choice should be visible without scrolling. For a single standalone checkbox (like "I agree to the terms"), use CheckboxInput instead. If only one option can be picked, use RadioList. If the list is long enough to need searching or scrolling, use MultiSelector instead.',
|
|
108
177
|
bestPractices: [
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{
|
|
178
|
+
{
|
|
179
|
+
guidance: true,
|
|
180
|
+
description:
|
|
181
|
+
'Keep the list short: three to seven options is the sweet spot. Beyond that, switch to MultiSelector which adds search and scrolling.',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
guidance: true,
|
|
185
|
+
description:
|
|
186
|
+
'Turn on dividers (hasDividers) when items have helper text underneath; without them the labels and descriptions blur together.',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
guidance: true,
|
|
190
|
+
description:
|
|
191
|
+
'Write a group label that says what the choices represent: "Export formats" tells users more than "Options".',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
guidance: false,
|
|
195
|
+
description:
|
|
196
|
+
'Show a CheckboxList when the user can only pick one thing; that is what RadioList is for.',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
guidance: false,
|
|
200
|
+
description:
|
|
201
|
+
'Put buttons or links inside the trailing slot (endContent); the whole row is already tappable, so a nested button creates two competing click targets.',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
guidance: false,
|
|
205
|
+
description:
|
|
206
|
+
'Wrap a disabled CheckboxList in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
|
|
207
|
+
},
|
|
115
208
|
],
|
|
116
209
|
},
|
|
117
210
|
theming: {
|
|
118
|
-
targets: [
|
|
119
|
-
{className: 'astryx-checkbox-list'},
|
|
120
|
-
],
|
|
211
|
+
targets: [{className: 'astryx-checkbox-list'}],
|
|
121
212
|
},
|
|
122
213
|
};
|
|
123
214
|
|
|
124
215
|
/** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
|
|
125
216
|
export const docsZh = {
|
|
126
217
|
usage: {
|
|
127
|
-
description:
|
|
218
|
+
description:
|
|
219
|
+
'CheckboxList shows a small group of checkboxes so users can turn several options on or off at once. Place it in settings pages, filter panels, or forms where every choice should be visible without scrolling. For a single standalone checkbox (like "I agree to the terms"), use CheckboxInput instead. If only one option can be picked, use RadioList. If the list is long enough to need searching or scrolling, use MultiSelector instead.',
|
|
128
220
|
bestPractices: [
|
|
129
|
-
{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
{
|
|
221
|
+
{
|
|
222
|
+
guidance: true,
|
|
223
|
+
description:
|
|
224
|
+
'Keep the list short: three to seven options is the sweet spot. Beyond that, switch to MultiSelector which adds search and scrolling.',
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
guidance: true,
|
|
228
|
+
description:
|
|
229
|
+
'Turn on dividers (hasDividers) when items have helper text underneath; without them the labels and descriptions blur together.',
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
guidance: true,
|
|
233
|
+
description:
|
|
234
|
+
'Write a group label that says what the choices represent: "Export formats" tells users more than "Options".',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
guidance: false,
|
|
238
|
+
description:
|
|
239
|
+
'Show a CheckboxList when the user can only pick one thing; that is what RadioList is for.',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
guidance: false,
|
|
243
|
+
description:
|
|
244
|
+
'Put buttons or links inside the trailing slot (endContent); the whole row is already tappable, so a nested button creates two competing click targets.',
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
guidance: false,
|
|
248
|
+
description:
|
|
249
|
+
'Wrap a disabled CheckboxList in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
|
|
250
|
+
},
|
|
135
251
|
],
|
|
136
252
|
},
|
|
137
253
|
};
|
|
@@ -141,14 +257,39 @@ export const docsDense = {
|
|
|
141
257
|
description:
|
|
142
258
|
'Checkbox group component for multi-value selection. Collection mode (parent state) + standalone mode (per-item state).',
|
|
143
259
|
usage: {
|
|
144
|
-
description:
|
|
260
|
+
description:
|
|
261
|
+
'CheckboxList shows a small group of checkboxes so users can turn several options on or off at once. Place it in settings pages, filter panels, or forms where every choice should be visible without scrolling. For a single standalone checkbox (like "I agree to the terms"), use CheckboxInput instead. If only one option can be picked, use RadioList. If the list is long enough to need searching or scrolling, use MultiSelector instead.',
|
|
145
262
|
bestPractices: [
|
|
146
|
-
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{
|
|
263
|
+
{
|
|
264
|
+
guidance: true,
|
|
265
|
+
description:
|
|
266
|
+
'Keep the list short: three to seven options is the sweet spot. Beyond that, switch to MultiSelector which adds search and scrolling.',
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
guidance: true,
|
|
270
|
+
description:
|
|
271
|
+
'Turn on dividers (hasDividers) when items have helper text underneath; without them the labels and descriptions blur together.',
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
guidance: true,
|
|
275
|
+
description:
|
|
276
|
+
'Write a group label that says what the choices represent: "Export formats" tells users more than "Options".',
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
guidance: false,
|
|
280
|
+
description:
|
|
281
|
+
'Show a CheckboxList when the user can only pick one thing; that is what RadioList is for.',
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
guidance: false,
|
|
285
|
+
description:
|
|
286
|
+
'Put buttons or links inside the trailing slot (endContent); the whole row is already tappable, so a nested button creates two competing click targets.',
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
guidance: false,
|
|
290
|
+
description:
|
|
291
|
+
'Wrap a disabled CheckboxList in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
|
|
292
|
+
},
|
|
152
293
|
],
|
|
153
294
|
},
|
|
154
295
|
};
|