Skip to content

Commit

Permalink
fix: modal regressions (#636)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsladerman authored Aug 21, 2024
1 parent 8592fab commit d55d588
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 52 deletions.
9 changes: 3 additions & 6 deletions src/components/IconFrame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ type IconFrameProps = {
type?: Type
selected?: boolean
background?: SemanticColorKey
}
} & Omit<ComponentProps<typeof IconFrameSC>, 'size'>

const IconFrameSC = styled(Flex)<{
$type: Type
Expand Down Expand Up @@ -148,10 +148,7 @@ const IconFrameSC = styled(Flex)<{
...($type === 'floating' ? { boxShadow: theme.boxShadows.slight } : {}),
}))

const IconFrame = forwardRef<
HTMLDivElement,
IconFrameProps & ComponentProps<typeof IconFrameSC>
>(
const IconFrame = forwardRef(
(
{
icon,
Expand All @@ -166,7 +163,7 @@ const IconFrame = forwardRef<
background,
as,
...props
},
}: IconFrameProps,
ref
) => {
icon = cloneElement(icon, { size: sizeToIconSize[size] })
Expand Down
34 changes: 27 additions & 7 deletions src/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import {
useEffect,
} from 'react'

import styled, { type StyledComponentPropsWithRef } from 'styled-components'
import styled, {
type StyledComponentPropsWithRef,
useTheme,
} from 'styled-components'

import { type ColorKey, type Nullable, type SeverityExt } from '../types'

Expand All @@ -28,7 +31,7 @@ export const SEVERITIES = [
'success',
'danger',
] as const satisfies Readonly<SeverityExt[]>
const SIZES = ['medium', 'large', 'custom'] as const
const SIZES = ['medium', 'large', 'custom', 'auto'] as const

type ModalSeverity = Extract<SeverityExt, (typeof SEVERITIES)[number]>

Expand All @@ -37,6 +40,7 @@ type ModalSize = (typeof SIZES)[number]
type ModalPropsType = ModalWrapperProps & {
onClose?: Nullable<() => void>
form?: boolean
scrollable?: boolean
size?: ModalSize
header?: ReactNode
actions?: ReactNode
Expand Down Expand Up @@ -68,24 +72,32 @@ const severityToIcon = {
const sizeToWidth = {
medium: 480,
large: 608,
auto: 'auto',
custom: undefined as undefined,
} as const satisfies Record<ModalSize, number | undefined>
} as const satisfies Partial<Record<ModalSize, number | string | undefined>>

const ModalSC = styled(Card)<{
$width: number
$maxWidth: number
}>(({ theme, $width, $maxWidth }) => ({
position: 'relative',
display: 'flex',
flexDirection: 'column',
height: '100%',
width: $width,
maxWidth: $maxWidth,
backgroundColor: theme.colors['fill-one'],
}))

const ModalContentSC = styled.div<{
$scrollable: boolean
$hasActions: boolean
}>(({ theme, $hasActions }) => ({
}>(({ theme, $scrollable, $hasActions }) => ({
position: 'relative',
zIndex: 0,
display: 'flex',
flexDirection: 'column',
overflow: $scrollable ? 'auto' : 'hidden',
margin: theme.spacing.large,
marginBottom: $hasActions ? 0 : theme.spacing.large,
...theme.partials.text.body1,
Expand Down Expand Up @@ -144,6 +156,7 @@ function ModalRef(
}: ModalPropsType,
ref: Ref<any>
) {
const theme = useTheme()
const HeaderIcon = severityToIcon[severity ?? 'default']
const iconColorKey = severityToIconColorKey[severity ?? 'default']

Expand All @@ -160,21 +173,28 @@ function ModalRef(
[onClose]
)

const maxWidth =
size === 'auto'
? `min(1000px, 100vw - ${theme.spacing.xlarge * 2}px)`
: sizeToWidth[size]

return (
<ModalWrapper
ref={ref}
open={open}
onOpenChange={triggerClose}
scrollable={scrollable}
{...props}
>
<ModalSC
forwardedAs={asForm ? 'form' : undefined}
$width={sizeToWidth[size]}
$maxWidth={sizeToWidth[size]}
$maxWidth={maxWidth}
{...(asForm ? formProps : {})}
>
<ModalContentSC $hasActions={!!actions}>
<ModalContentSC
$scrollable={scrollable}
$hasActions={!!actions}
>
{!!header && (
<ModalHeaderWrapSC ref={ref}>
{HeaderIcon && (
Expand Down
69 changes: 30 additions & 39 deletions src/components/ModalWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
// styling here mostly just for the overlay and animations
import * as Dialog from '@radix-ui/react-dialog'

import { type ComponentProps, type ReactNode, forwardRef } from 'react'
import { type ReactNode, forwardRef } from 'react'
import styled, { useTheme } from 'styled-components'

const ANIMATION_SPEED = '150ms'

export type ModalWrapperProps = {
open: boolean
onOpenChange?: (open: boolean) => void
scrollable?: boolean
children?: ReactNode
} & ComponentProps<'div'>
} & Dialog.DialogContentProps

function ModalWrapperRef(
{
open,
onOpenChange,
scrollable = true,
children,
...props
}: ModalWrapperProps,
{ open, onOpenChange, children, ...props }: ModalWrapperProps,
ref: any
) {
const theme = useTheme()
Expand All @@ -32,10 +25,9 @@ function ModalWrapperRef(
onOpenChange={onOpenChange}
>
<Dialog.Portal container={portalElement}>
<OverlaySC>
<OverlaySC onClick={(e) => e.stopPropagation()}>
<ContentSC
ref={ref}
$scrollable={scrollable}
{...props}
>
{children}
Expand All @@ -46,36 +38,35 @@ function ModalWrapperRef(
)
}

const ContentSC = styled(Dialog.Content)<{ $scrollable?: boolean }>(
({ $scrollable }) => ({
overflowY: $scrollable ? 'auto' : 'hidden',
maxHeight: '100%',
'@keyframes popIn': {
from: { transform: 'scale(0.8)' },
to: { transform: 'scale(1)' },
},
'@keyframes popOut': {
from: { transform: 'scale(1)' },
to: { transform: 'scale(0.9)' },
},
'&[data-state="open"]': {
animation: `popIn ${ANIMATION_SPEED} ease-out`,
},
'&[data-state="closed"]': {
animation: `popOut ${ANIMATION_SPEED} ease-out`,
},
})
)
const ContentSC = styled(Dialog.Content)({
display: 'flex',
flexDirection: 'column',
overflow: 'auto',
'@keyframes popIn': {
from: { transform: 'scale(0.8)' },
to: { transform: 'scale(1)' },
},
'@keyframes popOut': {
from: { transform: 'scale(1)' },
to: { transform: 'scale(0.9)' },
},
'&[data-state="open"]': {
animation: `popIn ${ANIMATION_SPEED} ease-out`,
},
'&[data-state="closed"]': {
animation: `popOut ${ANIMATION_SPEED} ease-out`,
},
})

const OverlaySC = styled(Dialog.Overlay)(({ theme }) => ({
background: theme.colors['modal-backdrop'],
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
position: 'fixed',
inset: 0,
background: theme.colors['modal-backdrop'],
padding: theme.spacing.xlarge,
top: 0,
left: 0,
right: 0,
bottom: 0,
display: 'grid',
placeItems: 'center',
zIndex: theme.zIndexes.modal,
'@keyframes fadeIn': {
from: { opacity: 0 },
Expand Down

0 comments on commit d55d588

Please sign in to comment.