From 70bcd1982b28a50420131240410916fd715e1578 Mon Sep 17 00:00:00 2001 From: Yihui Liao <44729383+yihuiliao@users.noreply.github.com> Date: Fri, 5 Dec 2025 15:01:33 -0800 Subject: [PATCH 1/4] docs: add rc badge to react aria autocomplete (#9289) --- packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx b/packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx index c3532067e88..c731bde7fe9 100644 --- a/packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Autocomplete.mdx @@ -6,6 +6,7 @@ import vanillaDocs from 'docs:vanilla-starter/CommandPalette'; import '../../tailwind/tailwind.css'; export const tags = ['combobox', 'typeahead', 'input']; +export const version = 'rc'; export const relatedPages = [{'title': 'useAutocomplete', 'url': 'https://react-spectrum.adobe.com/react-aria/useAutocomplete.html'}]; export const description = 'Allows users to search or filter a list of suggestions.'; From a49b4aa63034bbd3c2728b0a6d6c30d51e3d795e Mon Sep 17 00:00:00 2001 From: Robert Snow Date: Sat, 6 Dec 2025 10:21:26 +1100 Subject: [PATCH 2/4] fix: Toast tailwind example focus ring (#9262) --- starters/tailwind/src/Toast.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/starters/tailwind/src/Toast.tsx b/starters/tailwind/src/Toast.tsx index cdb66c26ea2..d27252bc396 100644 --- a/starters/tailwind/src/Toast.tsx +++ b/starters/tailwind/src/Toast.tsx @@ -40,7 +40,7 @@ export function MyToastRegion() { // The ToastRegion should be rendered at the root of your app. + className="fixed bottom-4 right-4 flex flex-col-reverse gap-2 rounded-lg outline-none focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2"> {({toast}) => ( @@ -52,7 +52,7 @@ export function MyToastRegion() { @@ -68,7 +68,7 @@ export function MyToast(props: ToastProps) { style={{viewTransitionName: props.toast.key} as CSSProperties} className={composeTailwindRenderProps( props.className, - "flex items-center gap-4 bg-blue-600 px-4 py-3 rounded-lg outline-none forced-colors:outline focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 [view-transition-class:toast] font-sans w-[230px]" + "flex items-center gap-4 bg-blue-600 px-4 py-3 rounded-lg outline-none forced-colors:outline focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 [view-transition-class:toast] font-sans w-[230px]" )} /> ); From a73ac9789a3ccf0e5c205ce7f015ebd399f03552 Mon Sep 17 00:00:00 2001 From: Daniel Lu Date: Fri, 5 Dec 2025 15:52:17 -0800 Subject: [PATCH 3/4] fix: various S2 bug fixes from docs testing (#9272) * remove allowsEmptycollection from our pickers since we dont support that behavior * fix focusing DateFields on mobile tap * fix SelectBoxGroup overflow when horizontal and only show checkbox in multiple selection * fix taggroup remove button * update link button to support genai and premium variants * clear the context at the collapse collection level instead * review comments * chromatic fix * make sure unavaliable dates are never marked as selected * fix test case * get rid of act --- .../calendar/src/useCalendarCell.ts | 6 +- .../s2/chromatic/Button.stories.tsx | 72 +++++++++++++++++-- .../s2/chromatic/LinkButton.stories.tsx | 16 +++++ .../s2/chromatic/SelectBoxGroup.stories.tsx | 56 ++++++++++++++- packages/@react-spectrum/s2/src/Button.tsx | 63 ++++++++++------ packages/@react-spectrum/s2/src/Field.tsx | 3 +- packages/@react-spectrum/s2/src/Picker.tsx | 2 +- .../@react-spectrum/s2/src/SelectBoxGroup.tsx | 31 +++++--- packages/@react-spectrum/s2/src/TagGroup.tsx | 9 ++- .../@react-spectrum/s2/test/TagGroup.test.tsx | 55 ++++++++++++++ .../s2/test/TextField.test.tsx | 32 +++++++++ packages/@react-types/select/src/index.d.ts | 2 +- .../test/RangeCalendar.test.tsx | 42 +++++++++++ 13 files changed, 344 insertions(+), 45 deletions(-) create mode 100644 packages/@react-spectrum/s2/test/TagGroup.test.tsx create mode 100644 packages/@react-spectrum/s2/test/TextField.test.tsx diff --git a/packages/@react-aria/calendar/src/useCalendarCell.ts b/packages/@react-aria/calendar/src/useCalendarCell.ts index aabeac2f9a5..1c415d0b3d8 100644 --- a/packages/@react-aria/calendar/src/useCalendarCell.ts +++ b/packages/@react-aria/calendar/src/useCalendarCell.ts @@ -101,7 +101,11 @@ export function useCalendarCell(props: AriaCalendarCellProps, state: CalendarSta ); if (isInvalid) { - isSelected = true; + // don't mark unavaliable + invalid dates in range calendars as selected, that case only comes up via allowsNoncontiguousRanges + // and thus those unavailable dates shouldn't be selected. For single select calendars, we mark unavailble + invalid days as selected for styling reasons + if (!('highlightedRange' in state) || !isUnavailable) { + isSelected = true; + } } // For performance, reuse the same date object as before if the new date prop is the same. diff --git a/packages/@react-spectrum/s2/chromatic/Button.stories.tsx b/packages/@react-spectrum/s2/chromatic/Button.stories.tsx index 2ad49d90c26..0149063d3fb 100644 --- a/packages/@react-spectrum/s2/chromatic/Button.stories.tsx +++ b/packages/@react-spectrum/s2/chromatic/Button.stories.tsx @@ -40,18 +40,34 @@ let states = [ let combinations = generatePowerset(states); -const Template = (args: ButtonProps): ReactNode => { - let {children, ...otherArgs} = args; +let premiumStates = [ + {isDisabled: true}, + {size: ['S', 'M', 'L', 'XL']} +]; + +let premiumCombinations = generatePowerset(premiumStates); + +let genaiStates = [ + {isDisabled: true}, + {size: ['S', 'M', 'L', 'XL']} +]; + +let genaiCombinations = generatePowerset(genaiStates); + +const Template = (args: ButtonProps & {combos?: any[]}): ReactNode => { + let {children, combos = combinations, variant, ...otherArgs} = args; return (
- {combinations.map(c => { + {combos.map(c => { let fullComboName = Object.keys(c).map(k => `${k}: ${c[k]}`).join(' '); let key = Object.keys(c).map(k => shortName(k, c[k])).join(' '); if (!key) { key = 'default'; } - let button = ; + let finalVariant = c.variant ?? variant; + let buttonProps = {...otherArgs, ...c, ...(finalVariant && {variant: finalVariant})}; + let button = ; if (c.staticColor != null) { return ( @@ -84,4 +100,52 @@ export const IconOnly: StoryObj = { } }; +export const Premium: StoryObj = { + render: (args) =>