Skip to content

Commit

Permalink
feat: Enable non-scrollable modal content (#572)
Browse files Browse the repository at this point in the history
  • Loading branch information
dogmar authored Feb 14, 2024
1 parent e45314b commit d96bd8b
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 141 deletions.
9 changes: 3 additions & 6 deletions src/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,12 @@ const hueToFill = {
lightest: 3,
} as const satisfies Record<CardHue, CardFillLevel>

const fillToNeutralSelectedBgC: Record<
FillLevel,
keyof DefaultTheme['colors']
> = {
const fillToNeutralSelectedBgC = {
0: 'fill-one-selected',
1: 'fill-one-selected',
2: 'fill-two-selected',
3: 'fill-three-selected',
}
} as const satisfies Record<FillLevel, keyof DefaultTheme['colors']>

export function useDecideFillLevel({
hue,
Expand Down Expand Up @@ -207,7 +204,7 @@ const CardSC = styled(Div)<{
})}`,
borderRadius: theme.borderRadiuses[cornerSize],
backgroundColor: selected
? fillToNeutralSelectedBgC[fillLevel]
? theme.colors[fillToNeutralSelectedBgC[fillLevel]]
: getBgColor({ theme, fillLevel, severity }),
'&:focus, &:focus-visible': {
outline: 'none',
Expand Down
22 changes: 4 additions & 18 deletions src/components/HonorableModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
} from 'react'
import { createPortal } from 'react-dom'
import { Transition } from 'react-transition-group'
import PropTypes from 'prop-types'

import { Div, useTheme } from 'honorable'
import useRootStyles from 'honorable/dist/hooks/useRootStyles.js'
Expand All @@ -29,29 +28,17 @@ import filterUndefinedValues from 'honorable/dist/utils/filterUndefinedValues.js

export const modalParts = ['Backdrop'] as const

export const modalPropTypes = {
open: PropTypes.bool,
onClose: PropTypes.func,
fade: PropTypes.bool,
transitionDuration: PropTypes.number,
disableEscapeKey: PropTypes.bool,
portal: PropTypes.bool,
}

export type ModalBaseProps = {
open?: boolean
onClose?: (event: MouseEvent | KeyboardEvent) => void
onClose?: (event?: MouseEvent | KeyboardEvent) => void
fade?: boolean
transitionDuration?: number
disableEscapeKey?: boolean
portal?: boolean
}

export type ModalProps = ComponentProps<
ModalBaseProps,
'div',
(typeof modalParts)[number]
>
export type ModalProps = ModalBaseProps &
ComponentProps<ModalBaseProps, 'div', (typeof modalParts)[number]>

function ModalRef(props: ModalProps, ref: Ref<any>) {
const {
Expand Down Expand Up @@ -225,7 +212,7 @@ function ModalRef(props: ModalProps, ref: Ref<any>) {
ref={ref}
backgroundColor="background"
overflowY="auto"
margin={32}
margin="xlarge"
{...rootStyles}
{...filterUndefinedValues(otherProps)}
/>
Expand All @@ -238,6 +225,5 @@ function ModalRef(props: ModalProps, ref: Ref<any>) {
const BaseModal = forwardRef(ModalRef)

BaseModal.displayName = 'Modal'
BaseModal.propTypes = modalPropTypes

export const HonorableModal = memo(BaseModal)
104 changes: 65 additions & 39 deletions src/components/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { type ReactNode, type Ref, forwardRef, useEffect } from 'react'
import { Flex, H1, type ModalProps } from 'honorable'
import PropTypes from 'prop-types'

import styled, { type StyledComponentPropsWithRef } from 'styled-components'
Expand All @@ -8,7 +7,7 @@ import { type ColorKey, type SeverityExt } from '../types'

import useLockedBody from '../hooks/useLockedBody'

import { HonorableModal } from './HonorableModal'
import { HonorableModal, type ModalProps } from './HonorableModal'

import CheckRoundedIcon from './icons/CheckRoundedIcon'
import type createIcon from './icons/createIcon'
Expand Down Expand Up @@ -37,6 +36,7 @@ type ModalPropsType = Omit<ModalProps, 'size'> & {
lockBody?: boolean
asForm?: boolean
formProps?: StyledComponentPropsWithRef<'form'>
scrollable?: boolean
[x: string]: unknown
}

Expand Down Expand Up @@ -73,17 +73,32 @@ const sizeToWidth = {
large: 608,
} as const satisfies Record<ModalSize, number>

const ModalSC = styled.div((_) => ({
const ModalSC = styled.div<{ $scrollable: boolean }>(({ $scrollable }) => ({
position: 'relative',
...($scrollable
? {}
: {
display: 'flex',
flexDirection: 'column',
height: '100%',
}),
}))

const ModalContentSC = styled.div<{ $hasActions: boolean }>(
({ theme, $hasActions }) => ({
margin: theme.spacing.large,
marginBottom: $hasActions ? 0 : theme.spacing.large,
...theme.partials.text.body1,
})
)
const ModalContentSC = styled.div<{
$scrollable: boolean
$hasActions: boolean
}>(({ theme, $scrollable, $hasActions }) => ({
margin: theme.spacing.large,
marginBottom: $hasActions ? 0 : theme.spacing.large,
...theme.partials.text.body1,
...($scrollable
? {}
: {
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
}),
}))

const ModalActionsSC = styled.div((_) => ({
display: 'flex',
Expand All @@ -92,6 +107,34 @@ const ModalActionsSC = styled.div((_) => ({
bottom: '0',
}))

const gradientHeight = 12
const ModalActionsGradientSC = styled.div(({ theme }) => ({
display: 'flex',
background: `linear-gradient(180deg, transparent 0%, ${theme.colors['fill-one']} 100%);`,
height: gradientHeight,
}))
const ModalActionsContentSC = styled.div(({ theme }) => ({
display: 'flex',
padding: theme.spacing.large,
paddingTop: theme.spacing.large - gradientHeight,
alignItems: 'center',
justifyContent: 'flex-end',
backgroundColor: theme.colors['fill-one'],
}))

const ModalHeaderWrapSC = styled.div(({ theme }) => ({
alignItems: 'center',
justifyContent: 'start',
marginBottom: theme.spacing.large,
gap: theme.spacing.xsmall,
}))

const ModalHeaderSC = styled.h1(({ theme }) => ({
margin: 0,
...theme.partials.text.overline,
color: theme.colors['text-xlight'],
}))

function ModalRef(
{
children,
Expand All @@ -105,6 +148,7 @@ function ModalRef(
lockBody = true,
asForm = false,
formProps = {},
scrollable = true,
...props
}: ModalPropsType,
ref: Ref<any>
Expand All @@ -123,55 +167,37 @@ function ModalRef(
open={open}
onClose={onClose}
ref={ref}
fontSize={16}
color="text"
width={sizeToWidth[size]}
maxWidth={sizeToWidth[size]}
scrollable={scrollable}
{...props}
>
<ModalSC
as={asForm ? 'form' : undefined}
$scrollable={scrollable}
{...(asForm ? formProps : {})}
>
<ModalContentSC $hasActions={!!actions}>
<ModalContentSC
$scrollable={scrollable}
$hasActions={!!actions}
>
{!!header && (
<Flex
ref={ref}
align="center"
justify="start"
marginBottom="large"
gap="xsmall"
>
<ModalHeaderWrapSC ref={ref}>
{HeaderIcon && (
<HeaderIcon
marginTop={-2} // optically center icon
color={iconColorKey}
/>
)}
<H1
overline
color="text-xlight"
>
{header}
</H1>
</Flex>
<ModalHeaderSC>{header}</ModalHeaderSC>
</ModalHeaderWrapSC>
)}
{children}
</ModalContentSC>
{!!actions && (
<ModalActionsSC>
<Flex
background="linear-gradient(180deg, transparent 0%, fill-one 100%);"
height={16}
/>
<Flex
padding="large"
align="center"
justify="flex-end"
backgroundColor="fill-one"
>
{actions}
</Flex>
<ModalActionsGradientSC />
<ModalActionsContentSC>{actions}</ModalActionsContentSC>
</ModalActionsSC>
)}
</ModalSC>
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export { default as Highlight } from './components/Highlight'
export type { IconFrameProps } from './components/IconFrame'
export { default as IconFrame } from './components/IconFrame'
export { default as Input } from './components/Input'
export { default as Input2 } from './components/Input2'
export { default as Markdown } from './components/Markdown'
export type { PageCardProps } from './components/PageCard'
export { default as PageCard } from './components/PageCard'
Expand Down Expand Up @@ -71,6 +72,7 @@ export { default as Sidebar } from './components/Sidebar'
export { default as SidebarSection } from './components/SidebarSection'
export { default as SidebarItem } from './components/SidebarItem'
export { default as Modal } from './components/Modal'
export { HonorableModal } from './components/HonorableModal'
export type {
ChecklistProps,
ChecklistStateProps,
Expand Down
Loading

0 comments on commit d96bd8b

Please sign in to comment.