-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat: Add isExpanded renderProp to Button #9563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…he overlay is opened on mousedown
|
Build successful! 🎉 |
|
Build successful! 🎉 |
snowystinger
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we run chromatic against this?
|
Build successful! 🎉 |
|
https://www.chromatic.com/build?appId=5f0dd5ad2b5fc10022a2e320&number=1107, changes seem unrelated to my updates |
|
We should change lines like this (e.g. S2 ActionButton/Button) to use the isExpanded state instead: // Retain hover styles when an overlay is open.
isHovered: renderProps.isHovered || overlayTriggerState?.isOpen || false, |
|
Looks like the RAC starters should also be updated to use |
| } = props; | ||
| let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/s2'); | ||
|
|
||
| // For mouse interactions, pickers open on press start. When the popover underlay appears |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this code is in S2 MenuTrigger too, so we should move that into RAC too I guess. The RAC Menu examples don't have any press scaling anymore.
This reverts commit f0d9772.
|
Build successful! 🎉 |
## API Changes
react-aria-components/react-aria-components:ComboBox ComboBox <T extends {}> {
allowsCustomValue?: boolean
allowsEmptyCollection?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ChildrenOrFunction<ComboBoxRenderProps>
className?: ClassNameOrFunction<ComboBoxRenderProps> = 'react-aria-ComboBox'
defaultFilter?: (string, string) => boolean
defaultInputValue?: string
defaultItems?: Iterable<T>
defaultSelectedKey?: Key
disabledKeys?: Iterable<Key>
form?: string
formValue?: 'text' | 'key' = 'key'
id?: string
inputValue?: string
isDisabled?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
items?: Iterable<T>
menuTrigger?: MenuTriggerAction = 'input'
name?: string
onBlur?: (FocusEvent<HTMLInputElement>) => void
onFocusChange?: (boolean) => void
onInputChange?: (string) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean, MenuTriggerAction) => void
onSelectionChange?: (Key | null) => void
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, ComboBoxRenderProps>
selectedKey?: Key | null
shouldFocusWrap?: boolean
slot?: string | null
style?: StyleOrFunction<ComboBoxRenderProps>
validate?: (ComboBoxValidationValue) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
}/react-aria-components:DatePicker DatePicker <T extends DateValue> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoComplete?: string
autoFocus?: boolean
children?: ChildrenOrFunction<DatePickerRenderProps>
className?: ClassNameOrFunction<DatePickerRenderProps> = 'react-aria-DatePicker'
defaultOpen?: boolean
defaultValue?: DateValue | null
firstDayOfWeek?: 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
form?: string
granularity?: Granularity
hideTimeZone?: boolean = false
hourCycle?: number | number
id?: string
isDateUnavailable?: (DateValue) => boolean
isDisabled?: boolean
isInvalid?: boolean
isOpen?: boolean
isReadOnly?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
maxValue?: DateValue | null
minValue?: DateValue | null
name?: string
onBlur?: (FocusEvent<Target>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean) => void
pageBehavior?: PageBehavior = visible
placeholderValue?: DateValue | null
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, DatePickerRenderProps>
shouldCloseOnSelect?: boolean | () => boolean = true
shouldForceLeadingZeros?: boolean
slot?: string | null
style?: StyleOrFunction<DatePickerRenderProps>
validate?: (MappedDateValue<DateValue>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: DateValue | null
}/react-aria-components:DateRangePicker DateRangePicker <T extends DateValue> {
allowsNonContiguousRanges?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ChildrenOrFunction<DateRangePickerRenderProps>
className?: ClassNameOrFunction<DateRangePickerRenderProps> = 'react-aria-DateRangePicker'
defaultOpen?: boolean
defaultValue?: RangeValue<DateValue> | null
endName?: string
firstDayOfWeek?: 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
form?: string
granularity?: Granularity
hideTimeZone?: boolean = false
hourCycle?: number | number
id?: string
isDateUnavailable?: (DateValue) => boolean
isDisabled?: boolean
isInvalid?: boolean
isOpen?: boolean
isReadOnly?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
maxValue?: DateValue | null
minValue?: DateValue | null
onBlur?: (FocusEvent<Target>) => void
onChange?: (RangeValue<MappedDateValue<DateValue>> | null) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean) => void
pageBehavior?: PageBehavior = visible
placeholderValue?: DateValue | null
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, DateRangePickerRenderProps>
shouldCloseOnSelect?: boolean | () => boolean = true
shouldForceLeadingZeros?: boolean
slot?: string | null
startName?: string
style?: StyleOrFunction<DateRangePickerRenderProps>
validate?: (RangeValue<MappedDateValue<DateValue>>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: RangeValue<DateValue> | null
}/react-aria-components:DialogTrigger DialogTrigger {
children: ReactNode
defaultOpen?: boolean
isOpen?: boolean
- isTriggerUpWhenOpen?: boolean
onOpenChange?: (boolean) => void
}/react-aria-components:MenuTrigger MenuTrigger {
children: ReactNode
defaultOpen?: boolean
isOpen?: boolean
- isTriggerUpWhenOpen?: boolean
onOpenChange?: (boolean) => void
trigger?: MenuTriggerType = 'press'
}/react-aria-components:Select Select <M extends SelectionMode = 'single', T extends {} = {
}> {
allowsEmptyCollection?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoComplete?: string
autoFocus?: boolean
children?: ChildrenOrFunction<SelectRenderProps>
className?: ClassNameOrFunction<SelectRenderProps> = 'react-aria-Select'
defaultOpen?: boolean
defaultValue?: ValueType<SelectionMode>
disabledKeys?: Iterable<Key>
excludeFromTabOrder?: boolean
form?: string
id?: string
isDisabled?: boolean
isInvalid?: boolean
isOpen?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (ChangeValueType<SelectionMode>) => void
onFocus?: (FocusEvent<Target>) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean) => void
placeholder?: string = 'Select an item' (localized)
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SelectRenderProps>
selectionMode?: SelectionMode = 'single'
slot?: string | null
style?: StyleOrFunction<SelectRenderProps>
validate?: (ValidationType<SelectionMode>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: ValueType<SelectionMode>
}/react-aria-components:ButtonRenderProps ButtonRenderProps {
isDisabled: boolean
+ isExpanded?: boolean
isFocusVisible: boolean
isFocused: boolean
isHovered: boolean
isPending: boolean
}/react-aria-components:ComboBoxProps ComboBoxProps <T extends {}> {
allowsCustomValue?: boolean
allowsEmptyCollection?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ChildrenOrFunction<ComboBoxRenderProps>
className?: ClassNameOrFunction<ComboBoxRenderProps> = 'react-aria-ComboBox'
defaultFilter?: (string, string) => boolean
defaultInputValue?: string
defaultItems?: Iterable<T>
defaultSelectedKey?: Key
disabledKeys?: Iterable<Key>
form?: string
formValue?: 'text' | 'key' = 'key'
id?: string
inputValue?: string
isDisabled?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
items?: Iterable<T>
menuTrigger?: MenuTriggerAction = 'input'
name?: string
onBlur?: (FocusEvent<HTMLInputElement>) => void
onFocusChange?: (boolean) => void
onInputChange?: (string) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean, MenuTriggerAction) => void
onSelectionChange?: (Key | null) => void
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, ComboBoxRenderProps>
selectedKey?: Key | null
shouldFocusWrap?: boolean
slot?: string | null
style?: StyleOrFunction<ComboBoxRenderProps>
validate?: (ComboBoxValidationValue) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
}/react-aria-components:DatePickerProps DatePickerProps <T extends DateValue> {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoComplete?: string
autoFocus?: boolean
children?: ChildrenOrFunction<DatePickerRenderProps>
className?: ClassNameOrFunction<DatePickerRenderProps> = 'react-aria-DatePicker'
defaultOpen?: boolean
defaultValue?: DateValue | null
firstDayOfWeek?: 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
form?: string
granularity?: Granularity
hideTimeZone?: boolean = false
hourCycle?: number | number
id?: string
isDateUnavailable?: (DateValue) => boolean
isDisabled?: boolean
isInvalid?: boolean
isOpen?: boolean
isReadOnly?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
maxValue?: DateValue | null
minValue?: DateValue | null
name?: string
onBlur?: (FocusEvent<Target>) => void
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean) => void
pageBehavior?: PageBehavior = visible
placeholderValue?: DateValue | null
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, DatePickerRenderProps>
shouldCloseOnSelect?: boolean | () => boolean = true
shouldForceLeadingZeros?: boolean
slot?: string | null
style?: StyleOrFunction<DatePickerRenderProps>
validate?: (MappedDateValue<DateValue>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: DateValue | null
}/react-aria-components:DateRangePickerProps DateRangePickerProps <T extends DateValue> {
allowsNonContiguousRanges?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children?: ChildrenOrFunction<DateRangePickerRenderProps>
className?: ClassNameOrFunction<DateRangePickerRenderProps> = 'react-aria-DateRangePicker'
defaultOpen?: boolean
defaultValue?: RangeValue<DateValue> | null
endName?: string
firstDayOfWeek?: 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
form?: string
granularity?: Granularity
hideTimeZone?: boolean = false
hourCycle?: number | number
id?: string
isDateUnavailable?: (DateValue) => boolean
isDisabled?: boolean
isInvalid?: boolean
isOpen?: boolean
isReadOnly?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
maxValue?: DateValue | null
minValue?: DateValue | null
onBlur?: (FocusEvent<Target>) => void
onChange?: (RangeValue<MappedDateValue<DateValue>> | null) => void
onFocusChange?: (boolean) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean) => void
pageBehavior?: PageBehavior = visible
placeholderValue?: DateValue | null
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, DateRangePickerRenderProps>
shouldCloseOnSelect?: boolean | () => boolean = true
shouldForceLeadingZeros?: boolean
slot?: string | null
startName?: string
style?: StyleOrFunction<DateRangePickerRenderProps>
validate?: (RangeValue<MappedDateValue<DateValue>>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: RangeValue<DateValue> | null
}/react-aria-components:DialogTriggerProps DialogTriggerProps {
children: ReactNode
defaultOpen?: boolean
isOpen?: boolean
- isTriggerUpWhenOpen?: boolean
onOpenChange?: (boolean) => void
}/react-aria-components:MenuTriggerProps MenuTriggerProps {
children: ReactNode
defaultOpen?: boolean
isOpen?: boolean
- isTriggerUpWhenOpen?: boolean
onOpenChange?: (boolean) => void
trigger?: MenuTriggerType = 'press'
}/react-aria-components:SelectProps SelectProps <M extends SelectionMode = 'single', T extends {} = {
}> {
allowsEmptyCollection?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoComplete?: string
autoFocus?: boolean
children?: ChildrenOrFunction<SelectRenderProps>
className?: ClassNameOrFunction<SelectRenderProps> = 'react-aria-Select'
defaultOpen?: boolean
defaultValue?: ValueType<SelectionMode>
disabledKeys?: Iterable<Key>
excludeFromTabOrder?: boolean
form?: string
id?: string
isDisabled?: boolean
isInvalid?: boolean
isOpen?: boolean
isRequired?: boolean
- isTriggerUpWhenOpen?: boolean
name?: string
onBlur?: (FocusEvent<Target>) => void
onChange?: (ChangeValueType<SelectionMode>) => void
onFocus?: (FocusEvent<Target>) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onOpenChange?: (boolean) => void
placeholder?: string = 'Select an item' (localized)
render?: DOMRenderFunction<keyof React.JSX.IntrinsicElements, SelectRenderProps>
selectionMode?: SelectionMode = 'single'
slot?: string | null
style?: StyleOrFunction<SelectRenderProps>
validate?: (ValidationType<SelectionMode>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
value?: ValueType<SelectionMode>
}/react-aria-components:ToggleButtonRenderProps ToggleButtonRenderProps {
isDisabled: boolean
+ isExpanded?: boolean
isFocusVisible: boolean
isFocused: boolean
isHovered: boolean
isPressed: boolean
state: ToggleState
}@react-spectrum/s2/@react-spectrum/s2:DialogTrigger DialogTrigger {
-
+ children: ReactNode
+ defaultOpen?: boolean
+ isOpen?: boolean
+ onOpenChange?: (boolean) => void
}/@react-spectrum/s2:DialogTriggerProps DialogTriggerProps {
- D: undefined
+ children: ReactNode
+ defaultOpen?: boolean
+ isOpen?: boolean
+ onOpenChange?: (boolean) => void
} |
snowystinger
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can a ToggleButton be expanded? it's now in the types
|
@snowystinger oh good catch, I suppose not. I'll remove it for now and we can always readd it if people are using the toggle button for opening overlays |
|
|
||
| &[data-open], | ||
| &[data-pressed] { | ||
| &[data-expanded] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is right? This is changing the MenuItem styles, not the button. I think you need to change Button.css to add data-expanded that sets the background to match the pressed state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh whoops, should've checked my bulk change here, I'll fix
| min-width: 0; | ||
|
|
||
| &[data-pressed] { | ||
| &[data-expanded] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is right either. On touch the menu doesn't open until press up, so now it has press scaling when it didn't before.
You need to add a new selector for data-expanded that just adds the background color change so that persists while the popover is open.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yep, accidentally conflated the press scaling with the background color styles
|
changes needed to tailwind starter as well |
As a alternative for
isTriggerUpWhenOpenfrom #8971, we've decided to addisExpandedalongsideisPressedso that users can decide style their ComboBox/DatePicker/Menu etc trigger button states to be independent of the open state.✅ Pull Request Checklist:
📝 Test Instructions:
Tests should cover this, but you can sanity check ComboBox/DatePicker/etc and make sure the RAC button has the proper data attribute for expanded. Additionally, double check the equivalent S2 components (and Picker/TabsPicker) and make sure the press state doesn't get stuck when opening the dropdowns/menus.
🧢 Your Project:
RSP