Skip to content

Commit

Permalink
Fix buttons in S2 dialogs stuck in hover state (adobe#6916)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Lu <[email protected]>
  • Loading branch information
devongovett and LFDanLu authored Aug 20, 2024
1 parent d27e833 commit 72b8098
Showing 1 changed file with 105 additions and 104 deletions.
209 changes: 105 additions & 104 deletions packages/@react-spectrum/s2/src/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/

import {PopoverProps as AriaPopoverProps, composeRenderProps, Provider, Dialog as RACDialog, DialogProps as RACDialogProps} from 'react-aria-components';
import {PopoverProps as AriaPopoverProps, composeRenderProps, OverlayTriggerStateContext, Provider, Dialog as RACDialog, DialogProps as RACDialogProps} from 'react-aria-components';
import {ButtonGroupContext} from './ButtonGroup';
import {CloseButton} from './CloseButton';
import {ContentContext, FooterContext, HeaderContext, HeadingContext, ImageContext} from './Content';
Expand Down Expand Up @@ -187,125 +187,126 @@ function DialogInner(props: DialogProps & DialogContextValue & {dialogRef: RefOb
ref={props.dialogRef}
style={props.UNSAFE_style}
className={(props.UNSAFE_className || '') + dialogInner}>
{composeRenderProps(props.children, (children, {close}) =>
// Render the children multiple times inside the wrappers we need to implement the layout.
// Each instance hides certain children so that they are all rendered in the correct locations.
(<>
{/* Hero image */}
<Provider
values={[
[ImageContext, {className: image}],
[HeadingContext, {isHidden: true}],
[HeaderContext, {isHidden: true}],
[ContentContext, {isHidden: true}],
[FooterContext, {isHidden: true}],
[ButtonGroupContext, {isHidden: true}]
]}>
{children}
</Provider>
{/* Top header: heading, header, dismiss button, and button group (in fullscreen dialogs). */}
{composeRenderProps(props.children, (children, {close}) => (
// Render the children multiple times inside the wrappers we need to implement the layout.
// Each instance hides certain children so that they are all rendered in the correct locations.
// Reset OverlayTriggerStateContext so the buttons inside the dialog don't retain their hover state.
<OverlayTriggerStateContext.Provider value={null}>
{/* Hero image */}
<Provider
values={[
[ImageContext, {className: image}],
[HeadingContext, {isHidden: true}],
[HeaderContext, {isHidden: true}],
[ContentContext, {isHidden: true}],
[FooterContext, {isHidden: true}],
[ButtonGroupContext, {isHidden: true}]
]}>
{children}
</Provider>
{/* Top header: heading, header, dismiss button, and button group (in fullscreen dialogs). */}
<div
className={style({
// Wrapper that creates the margin for the dismiss button.
display: 'flex',
alignItems: 'start',
columnGap: 12,
marginStart: {
default: 32
},
marginEnd: {
default: 32,
isDismissable: 12
},
marginTop: {
default: 12 // margin to dismiss button
}
})({isDismissable: props.isDismissable, type: props.type})}>
<div
className={style({
// Wrapper that creates the margin for the dismiss button.
// Wrapper for heading, header, and button group.
// This swaps orientation from horizontal to vertical at small screen sizes.
display: 'flex',
alignItems: 'start',
columnGap: 12,
marginStart: {
default: 32
},
marginEnd: {
default: 32,
isDismissable: 12
},
flexGrow: 1,
marginTop: {
default: 12 // margin to dismiss button
}
})({isDismissable: props.isDismissable, type: props.type})}>
<div
className={style({
// Wrapper for heading, header, and button group.
// This swaps orientation from horizontal to vertical at small screen sizes.
display: 'flex',
flexGrow: 1,
marginTop: {
default: 20, // 32 - 12 (handled above)
':empty': 0
},
marginBottom: {
default: 16,
':empty': 0
},
columnGap: 24,
rowGap: 8,
flexDirection: {
default: 'column',
sm: 'row'
},
alignItems: {
default: 'start',
sm: 'center'
}
})}>
<Provider
values={[
[ImageContext, {hidden: true}],
[HeadingContext, {styles: heading}],
[HeaderContext, {styles: header}],
[ContentContext, {isHidden: true}],
[FooterContext, {isHidden: true}],
[ButtonGroupContext, {isHidden: buttonGroupPlacement !== 'top'}]
]}>
{children}
</Provider>
</div>
{props.isDismissable &&
<CloseButton aria-label={stringFormatter.format('dialog.dismiss')} onPress={close} styles={style({marginBottom: 12})} />
}
</div>
{/* Main content */}
<Provider
values={[
[ImageContext, {hidden: true}],
[HeadingContext, {isHidden: true}],
[HeaderContext, {isHidden: true}],
[ContentContext, {styles: content({type: props.type})}],
[FooterContext, {isHidden: true}],
[ButtonGroupContext, {isHidden: true}]
]}>
{children}
</Provider>
{/* Footer and button group */}
<div
className={style({
display: 'flex',
paddingX: {
default: 32
},
paddingBottom: {
default: 32
default: 20, // 32 - 12 (handled above)
':empty': 0
},
paddingTop: {
default: 32,
marginBottom: {
default: 16,
':empty': 0
},
gap: 24,
alignItems: 'center',
flexWrap: 'wrap'
columnGap: 24,
rowGap: 8,
flexDirection: {
default: 'column',
sm: 'row'
},
alignItems: {
default: 'start',
sm: 'center'
}
})}>
<Provider
values={[
[ImageContext, {hidden: true}],
[HeadingContext, {isHidden: true}],
[HeaderContext, {isHidden: true}],
[HeadingContext, {styles: heading}],
[HeaderContext, {styles: header}],
[ContentContext, {isHidden: true}],
[FooterContext, {styles: footer}],
[ButtonGroupContext, {isHidden: buttonGroupPlacement !== 'bottom', styles: buttonGroup, align: 'end'}]
[FooterContext, {isHidden: true}],
[ButtonGroupContext, {isHidden: buttonGroupPlacement !== 'top'}]
]}>
{children}
</Provider>
</div>
</>)
)}
{props.isDismissable &&
<CloseButton aria-label={stringFormatter.format('dialog.dismiss')} onPress={close} styles={style({marginBottom: 12})} />
}
</div>
{/* Main content */}
<Provider
values={[
[ImageContext, {hidden: true}],
[HeadingContext, {isHidden: true}],
[HeaderContext, {isHidden: true}],
[ContentContext, {styles: content({type: props.type})}],
[FooterContext, {isHidden: true}],
[ButtonGroupContext, {isHidden: true}]
]}>
{children}
</Provider>
{/* Footer and button group */}
<div
className={style({
display: 'flex',
paddingX: {
default: 32
},
paddingBottom: {
default: 32
},
paddingTop: {
default: 32,
':empty': 0
},
gap: 24,
alignItems: 'center',
flexWrap: 'wrap'
})}>
<Provider
values={[
[ImageContext, {hidden: true}],
[HeadingContext, {isHidden: true}],
[HeaderContext, {isHidden: true}],
[ContentContext, {isHidden: true}],
[FooterContext, {styles: footer}],
[ButtonGroupContext, {isHidden: buttonGroupPlacement !== 'bottom', styles: buttonGroup, align: 'end'}]
]}>
{children}
</Provider>
</div>
</OverlayTriggerStateContext.Provider>
))}
</RACDialog>
);
}

0 comments on commit 72b8098

Please sign in to comment.