diff --git a/packages/react/src/Dialog/Dialog.module.css b/packages/react/src/Dialog/Dialog.module.css index 343be7320da..2b6f3431505 100644 --- a/packages/react/src/Dialog/Dialog.module.css +++ b/packages/react/src/Dialog/Dialog.module.css @@ -38,6 +38,14 @@ } } +/* Used to determine whether there should be a border between the body and footer */ +@keyframes detect-scroll { + from, + to { + --can-scroll: 1; + } +} + .Backdrop { position: fixed; top: 0; @@ -212,6 +220,28 @@ flex-grow: 1; } +/* +Add a border between the body and footer if: +- the dialog has a footer +- the dialog has a body that can scroll +- the browser supports the `animation-timeline` property and its `scroll()` function +*/ +.Dialog:has(.Footer) { + --can-scroll: 0; + + .DialogOverflowWrapper { + animation: detect-scroll; + animation-timeline: scroll(self); + + /* If the browser does not support the `animation-timeline` property, always show a border */ + border-bottom: var(--borderWidth-default) solid var(--borderColor-default); + + @supports (animation-timeline: scroll(self)) { + border-bottom: calc(1px * var(--can-scroll)) solid var(--borderColor-default); + } + } +} + .Header { z-index: 1; padding: var(--base-size-8); @@ -246,8 +276,6 @@ flex-flow: wrap; justify-content: flex-end; padding: var(--base-size-16); - /* stylelint-disable-next-line primer/box-shadow */ - box-shadow: 0 -1px 0 var(--borderColor-default); gap: var(--base-size-8); flex-shrink: 0; diff --git a/packages/react/src/Dialog/Dialog.tsx b/packages/react/src/Dialog/Dialog.tsx index 118ffd22432..9a26fb9771e 100644 --- a/packages/react/src/Dialog/Dialog.tsx +++ b/packages/react/src/Dialog/Dialog.tsx @@ -370,6 +370,35 @@ const StyledDialog = toggleStyledComponent( } } + /* Used to determine whether there should be a border between the body and footer */ + @keyframes detect-scroll { + from, + to { + --can-scroll: 1; + } + } + + /* + Add a border between the body and footer if: + - the dialog has a footer + - the dialog has a body that can scroll + - the browser supports the animation-timeline property and its scroll() function + */ + &:has([data-component='Dialog.Footer']) { + --can-scroll: 0; + [data-component='Dialog.Body'] { + animation: detect-scroll; + animation-timeline: scroll(self); + + /* If the browser does not support the animation-timeline property, always show a border */ + border-bottom: var(--borderWidth-default) solid var(--borderColor-default); + + @supports (animation-timeline: scroll(self)) { + border-bottom: calc(1px * var(--can-scroll)) solid var(--borderColor-default); + } + } + } + ${sx}; `, ) @@ -527,7 +556,13 @@ const _Dialog = React.forwardRef {header} - + {body} {footer} @@ -623,7 +658,6 @@ const StyledFooter = toggleStyledComponent( CSS_MODULES_FEATURE_FLAG, 'div', styled.div` - box-shadow: 0 -1px 0 ${get('colors.border.default')}; padding: ${get('space.3')}; display: flex; flex-flow: wrap; @@ -644,7 +678,16 @@ type StyledFooterProps = React.ComponentProps<'div'> & SxProp const Footer = React.forwardRef(function Footer({className, ...rest}, forwardRef) { const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) - return + return ( + + ) }) Footer.displayName = 'Dialog.Footer'