From 5d709bf5c49bbd5a6776899ee4cd3c6f565fd4fc Mon Sep 17 00:00:00 2001 From: lisa Date: Tue, 26 Nov 2024 10:28:56 +0100 Subject: [PATCH] fix: spacing and custom header --- .../Drawer/__stories__/Footer.stories.tsx | 28 ++- ....stories.tsx => FunctionProps.stories.tsx} | 24 +- .../Drawer/__stories__/Playground.stories.tsx | 1 - .../Drawer/__stories__/Size.stories.tsx | 4 +- .../Drawer/__stories__/Template.stories.tsx | 2 +- .../Drawer/__stories__/index.stories.tsx | 2 +- .../__snapshots__/index.test.tsx.snap | 227 ++++++++++++------ .../Drawer/__tests__/index.test.tsx | 76 ++++-- packages/ui/src/components/Drawer/index.tsx | 135 +++++++---- 9 files changed, 356 insertions(+), 143 deletions(-) rename packages/ui/src/components/Drawer/__stories__/{FunctionChildren.stories.tsx => FunctionProps.stories.tsx} (58%) diff --git a/packages/ui/src/components/Drawer/__stories__/Footer.stories.tsx b/packages/ui/src/components/Drawer/__stories__/Footer.stories.tsx index 49a522f64e..c8df674168 100644 --- a/packages/ui/src/components/Drawer/__stories__/Footer.stories.tsx +++ b/packages/ui/src/components/Drawer/__stories__/Footer.stories.tsx @@ -1,5 +1,6 @@ import { Button } from '../../Button' import { Stack } from '../../Stack' +import { Text } from '../../Text' import { DefaultDisclosure, Template } from './Template.stories' export const Footer = Template.bind({}) @@ -17,8 +18,29 @@ const FooterComponent = () => ( Footer.args = { disclosure: DefaultDisclosure, footer: , - title: 'With a footer', + header: 'With a footer', size: 'small', - children: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce iaculis non lectus sed sagittis. Etiam luctus velit ac semper accumsan. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin ut nulla lacus. Nullam auctor dolor at euismod luctus. Suspendisse potenti. Ut vulputate pellentesque pharetra. Suspendisse eleifend ac urna eget pellentesque. Nulla facilisi. Morbi id neque eget mauris sodales tristique sit amet ut lacus. Nullam fringilla finibus massa, vel molestie sapien suscipit et. Aliquam blandit lectus sapien, nec venenatis risus vestibulum a. Nullam scelerisque leo at pharetra vestibulum. Quisque eget turpis eu tellus imperdiet ultricies. Aliquam cursus mattis vulputate. Etiam vulputate nunc vel eros luctus finibus. Vivamus efficitur dolor eu sem elementum condimentum. Suspendisse potenti. Ut vulputate pellentesque pharetra. Suspendisse eleifend ac urna eget pellentesque. Nulla facilisi. Morbi id neque eget mauris sodales tristique sit amet ut lacus. Nullam fringilla finibus massa, vel molestie sapien suscipit et. Aliquam blandit lectus sapien, nec venenatis risus vestibulum a. Nullam scelerisque leo at pharetra vestibulum. Quisque eget turpis eu tellus imperdiet ultricies. Aliquam cursus mattis vulputate. Etiam vulputate nunc vel eros luctus finibus. Vivamus efficitur dolor eu sem elementum condimentum.', + children: ( + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce iaculis non + lectus sed sagittis. Etiam luctus velit ac semper accumsan. Orci varius + natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. + Proin ut nulla lacus. Nullam auctor dolor at euismod luctus. Suspendisse + potenti. Ut vulputate pellentesque pharetra. Suspendisse eleifend ac urna + eget pellentesque. Nulla facilisi. Morbi id neque eget mauris sodales + tristique sit amet ut lacus. Nullam fringilla finibus massa, vel molestie + sapien suscipit et. Aliquam blandit lectus sapien, nec venenatis risus + vestibulum a. Nullam scelerisque leo at pharetra vestibulum. Quisque eget + turpis eu tellus imperdiet ultricies. Aliquam cursus mattis vulputate. + Etiam vulputate nunc vel eros luctus finibus. Vivamus efficitur dolor eu + sem elementum condimentum. Suspendisse potenti. Ut vulputate pellentesque + pharetra. Suspendisse eleifend ac urna eget pellentesque. Nulla facilisi. + Morbi id neque eget mauris sodales tristique sit amet ut lacus. Nullam + fringilla finibus massa, vel molestie sapien suscipit et. Aliquam blandit + lectus sapien, nec venenatis risus vestibulum a. Nullam scelerisque leo at + pharetra vestibulum. Quisque eget turpis eu tellus imperdiet ultricies. + Aliquam cursus mattis vulputate. Etiam vulputate nunc vel eros luctus + finibus. Vivamus efficitur dolor eu sem elementum condimentum. + + ), } diff --git a/packages/ui/src/components/Drawer/__stories__/FunctionChildren.stories.tsx b/packages/ui/src/components/Drawer/__stories__/FunctionProps.stories.tsx similarity index 58% rename from packages/ui/src/components/Drawer/__stories__/FunctionChildren.stories.tsx rename to packages/ui/src/components/Drawer/__stories__/FunctionProps.stories.tsx index 52c914a868..a1f6a09752 100644 --- a/packages/ui/src/components/Drawer/__stories__/FunctionChildren.stories.tsx +++ b/packages/ui/src/components/Drawer/__stories__/FunctionProps.stories.tsx @@ -3,12 +3,12 @@ import { Drawer } from '..' import { Button } from '../../Button' import { Stack } from '../../Stack' -export const FunctionChildren: StoryFn = props => ( +export const FunctionProps: StoryFn = props => ( Function children} - title="Function children" + header="Function children" footer="Footer" > {({ close }) => ( @@ -21,7 +21,7 @@ export const FunctionChildren: StoryFn = props => ( Function footer} - title="Function footer" + header="Function footer" footer={({ close }) => ( } + header={({ close }) => ( + + )} + footer="footer" + > + children + ) -FunctionChildren.parameters = { +FunctionProps.parameters = { docs: { description: { story: - '`disclosure`, `footer` and `children` can all be functions that can get the Drawer state', + '`disclosure`, `footer`, `header` and `children` can all be functions that can get the Drawer state', }, }, } diff --git a/packages/ui/src/components/Drawer/__stories__/Playground.stories.tsx b/packages/ui/src/components/Drawer/__stories__/Playground.stories.tsx index 4e25f5601a..2baba4baf7 100644 --- a/packages/ui/src/components/Drawer/__stories__/Playground.stories.tsx +++ b/packages/ui/src/components/Drawer/__stories__/Playground.stories.tsx @@ -4,5 +4,4 @@ export const Playground = Template.bind({}) Playground.args = { disclosure: DefaultDisclosure, - title: 'Title', } diff --git a/packages/ui/src/components/Drawer/__stories__/Size.stories.tsx b/packages/ui/src/components/Drawer/__stories__/Size.stories.tsx index 47574d2828..e39f8bdcd1 100644 --- a/packages/ui/src/components/Drawer/__stories__/Size.stories.tsx +++ b/packages/ui/src/components/Drawer/__stories__/Size.stories.tsx @@ -10,9 +10,9 @@ export const Size: StoryFn = props => ( {...props} size={width as keyof typeof SIZES} disclosure={} - title={width} + header={width} > -
Content of the {width} drawer
+
Content of the {width} drawer
))} diff --git a/packages/ui/src/components/Drawer/__stories__/Template.stories.tsx b/packages/ui/src/components/Drawer/__stories__/Template.stories.tsx index 7dd8d5dbf4..e298202bd8 100644 --- a/packages/ui/src/components/Drawer/__stories__/Template.stories.tsx +++ b/packages/ui/src/components/Drawer/__stories__/Template.stories.tsx @@ -7,5 +7,5 @@ export const DefaultDisclosure = export const Template: StoryFn = args => Template.args = { - title: 'Drawer', + header: 'Drawer', } diff --git a/packages/ui/src/components/Drawer/__stories__/index.stories.tsx b/packages/ui/src/components/Drawer/__stories__/index.stories.tsx index dfd4569741..472d9e181e 100644 --- a/packages/ui/src/components/Drawer/__stories__/index.stories.tsx +++ b/packages/ui/src/components/Drawer/__stories__/index.stories.tsx @@ -9,4 +9,4 @@ export default { export { Playground } from './Playground.stories' export { Size } from './Size.stories' export { Footer } from './Footer.stories' -export { FunctionChildren } from './FunctionChildren.stories' +export { FunctionProps } from './FunctionProps.stories' diff --git a/packages/ui/src/components/Drawer/__tests__/__snapshots__/index.test.tsx.snap b/packages/ui/src/components/Drawer/__tests__/__snapshots__/index.test.tsx.snap index 9d9d4e26da..dd1153b7f4 100644 --- a/packages/ui/src/components/Drawer/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/ui/src/components/Drawer/__tests__/__snapshots__/index.test.tsx.snap @@ -1,5 +1,21 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`Drawer > custom header 1`] = ` + +
+ +
+
+`; + exports[`Drawer > function footer 1`] = `
function footer 1`] = ` `; +exports[`Drawer > function header 1`] = ` + +
+ +
+
+`; + exports[`Drawer > renders custom size=large 1`] = `
renders with disclosure and onClose 1`] = ` @keyframes animation-1 { from { - -webkit-transform: translateX(300px); - -moz-transform: translateX(300px); - -ms-transform: translateX(300px); - transform: translateX(300px); + -webkit-transform: translateX(22rem); + -moz-transform: translateX(22rem); + -ms-transform: translateX(22rem); + transform: translateX(22rem); } to { @@ -183,10 +215,10 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` @keyframes animation-1 { from { - -webkit-transform: translateX(300px); - -moz-transform: translateX(300px); - -ms-transform: translateX(300px); - transform: translateX(300px); + -webkit-transform: translateX(22rem); + -moz-transform: translateX(22rem); + -ms-transform: translateX(22rem); + transform: translateX(22rem); } to { @@ -199,10 +231,10 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` @keyframes animation-2 { from { - -webkit-transform: translateX(500px); - -moz-transform: translateX(500px); - -ms-transform: translateX(500px); - transform: translateX(500px); + -webkit-transform: translateX(48rem); + -moz-transform: translateX(48rem); + -ms-transform: translateX(48rem); + transform: translateX(48rem); } to { @@ -215,10 +247,10 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` @keyframes animation-2 { from { - -webkit-transform: translateX(500px); - -moz-transform: translateX(500px); - -ms-transform: translateX(500px); - transform: translateX(500px); + -webkit-transform: translateX(48rem); + -moz-transform: translateX(48rem); + -ms-transform: translateX(48rem); + transform: translateX(48rem); } to { @@ -231,10 +263,10 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` @keyframes animation-3 { from { - -webkit-transform: translateX(1000px); - -moz-transform: translateX(1000px); - -ms-transform: translateX(1000px); - transform: translateX(1000px); + -webkit-transform: translateX(70rem); + -moz-transform: translateX(70rem); + -ms-transform: translateX(70rem); + transform: translateX(70rem); } to { @@ -247,10 +279,10 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` @keyframes animation-3 { from { - -webkit-transform: translateX(1000px); - -moz-transform: translateX(1000px); - -ms-transform: translateX(1000px); - transform: translateX(1000px); + -webkit-transform: translateX(70rem); + -moz-transform: translateX(70rem); + -ms-transform: translateX(70rem); + transform: translateX(70rem); } to { @@ -340,7 +372,7 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` margin-right: 0; height: 100%; border-radius: 0; - padding: 1rem; + padding: 0; } .emotion-3[data-size="large"] { @@ -417,21 +449,21 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` } .emotion-3[data-size="small"] { - width: 356px; + width: 22.25rem; -webkit-animation: animation-1 linear 150ms; animation: animation-1 linear 150ms; } .emotion-3[data-size="medium"] { - width: 783px; + width: 49rem; -webkit-animation: animation-2 linear 250ms; animation: animation-2 linear 250ms; } .emotion-3[data-size="large"] { - width: 1209px; - -webkit-animation: animation-3 linear 400ms; - animation: animation-3 linear 400ms; + width: 75.5rem; + -webkit-animation: animation-3 linear 300ms; + animation: animation-3 linear 300ms; } .emotion-3 { @@ -447,7 +479,7 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` margin-right: 0; height: 100%; border-radius: 0; - padding: 1rem; + padding: 0; } .emotion-3[data-size="large"] { @@ -524,21 +556,21 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` } .emotion-3[data-size="small"] { - width: 356px; + width: 22.25rem; -webkit-animation: animation-1 linear 150ms; animation: animation-1 linear 150ms; } .emotion-3[data-size="medium"] { - width: 783px; + width: 49rem; -webkit-animation: animation-2 linear 250ms; animation: animation-2 linear 250ms; } .emotion-3[data-size="large"] { - width: 1209px; - -webkit-animation: animation-3 linear 400ms; - animation: animation-3 linear 400ms; + width: 75.5rem; + -webkit-animation: animation-3 linear 300ms; + animation: animation-3 linear 300ms; } .emotion-5 { @@ -563,6 +595,7 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` -ms-flex-wrap: nowrap; flex-wrap: nowrap; height: 100%; + position: relative; } .emotion-5 { @@ -587,9 +620,10 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` -ms-flex-wrap: nowrap; flex-wrap: nowrap; height: 100%; + position: relative; } -.emotion-7 { +.emotion-8 { color: #3f4250; font-size: 1.3125rem; font-family: Space Grotesk,sans-serif; @@ -599,9 +633,11 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` text-transform: none; -webkit-text-decoration: none; text-decoration: none; + padding-inline: 1rem; + padding-top: 2rem; } -.emotion-7 { +.emotion-8 { color: #3f4250; font-size: 1.3125rem; font-family: Space Grotesk,sans-serif; @@ -611,9 +647,11 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` text-transform: none; -webkit-text-decoration: none; text-decoration: none; + padding-inline: 1rem; + padding-top: 2rem; } -.emotion-9 { +.emotion-10 { margin: 0; border: 0; width: auto; @@ -624,7 +662,7 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` background-color: #e9eaeb; } -.emotion-9 { +.emotion-10 { margin: 0; border: 0; width: auto; @@ -635,29 +673,81 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` background-color: #e9eaeb; } -.emotion-11 { - overflow-y: scroll; +.emotion-12 { + overflow-y: auto; height: 100%; + padding-inline: 1rem; } -.emotion-11 { - overflow-y: scroll; +.emotion-12 { + overflow-y: auto; height: 100%; + padding-inline: 1rem; +} + +.emotion-14 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0rem; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-align-items: normal; + -webkit-box-align: normal; + -ms-flex-align: normal; + align-items: normal; + -webkit-box-pack: normal; + -ms-flex-pack: normal; + -webkit-justify-content: normal; + justify-content: normal; + -webkit-box-flex-wrap: nowrap; + -webkit-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + padding: 1rem; + padding-top: 0; +} + +.emotion-14 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + gap: 0rem; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-align-items: normal; + -webkit-box-align: normal; + -ms-flex-align: normal; + align-items: normal; + -webkit-box-pack: normal; + -ms-flex-pack: normal; + -webkit-justify-content: normal; + justify-content: normal; + -webkit-box-flex-wrap: nowrap; + -webkit-flex-wrap: nowrap; + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + padding: 1rem; + padding-top: 0; } -.emotion-13 { +.emotion-16 { position: absolute; top: 1rem; right: 1rem; } -.emotion-13 { +.emotion-16 { position: absolute; top: 1rem; right: 1rem; } -.emotion-15 { +.emotion-18 { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; @@ -696,22 +786,22 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` color: #3f4250; } -.emotion-15:hover { +.emotion-18:hover { -webkit-text-decoration: none; text-decoration: none; } -.emotion-15:active { +.emotion-18:active { box-shadow: 0px 0px 0px 3px #151a2d5c; } -.emotion-15:hover, -.emotion-15:active { +.emotion-18:hover, +.emotion-18:active { background: #e9eaeb; color: #222638; } -.emotion-15 { +.emotion-18 { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; @@ -750,22 +840,22 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` color: #3f4250; } -.emotion-15:hover { +.emotion-18:hover { -webkit-text-decoration: none; text-decoration: none; } -.emotion-15:active { +.emotion-18:active { box-shadow: 0px 0px 0px 3px #151a2d5c; } -.emotion-15:hover, -.emotion-15:active { +.emotion-18:hover, +.emotion-18:active { background: #e9eaeb; color: #222638; } -.emotion-17 { +.emotion-20 { vertical-align: middle; fill: currentColor; height: 16px; @@ -774,12 +864,12 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` min-height: 16px; } -.emotion-17 .fillStroke { +.emotion-20 .fillStroke { stroke: currentColor; fill: none; } -.emotion-17 { +.emotion-20 { vertical-align: middle; fill: currentColor; height: 16px; @@ -788,7 +878,7 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` min-height: 16px; } -.emotion-17 .fillStroke { +.emotion-20 .fillStroke { stroke: currentColor; fill: none; } @@ -818,34 +908,37 @@ exports[`Drawer > renders with disclosure and onClose 1`] = ` class="emotion-5 emotion-6" >

- title + header

modal
+
} title="title"> + Test} header="header">
test
, )) test(`renders without disclosure`, () => shouldMatchEmotionSnapshotWithPortal( - +
test
, )) test(`renders with default Props and function children`, () => shouldMatchEmotionSnapshotWithPortal( - {() =>
test
}
, + {() =>
test
}
, )) test(`renders with default Props and function children open`, () => shouldMatchEmotionSnapshotWithPortal( - + {() =>
test
}
, )) test(`renders with open={true}`, () => shouldMatchEmotionSnapshotWithPortal( - +
test
, )) @@ -55,7 +55,7 @@ describe('Drawer', () => { test(`renders custom size=medium`, async () => { const { asFragment } = renderWithTheme( button} > @@ -70,7 +70,7 @@ describe('Drawer', () => { test(`renders custom size=large`, async () => { const { asFragment } = renderWithTheme( button} > @@ -86,7 +86,7 @@ describe('Drawer', () => { test(`renders custom size=small`, async () => { const { asFragment } = renderWithTheme( button} > @@ -101,7 +101,7 @@ describe('Drawer', () => { test(`renders with custom classNames`, () => shouldMatchEmotionSnapshotWithPortal( - +
test
, )) @@ -111,7 +111,7 @@ describe('Drawer', () => { Test} >
modal
@@ -124,7 +124,7 @@ describe('Drawer', () => { Open modal} data-testid="test" onClose={() => { @@ -151,7 +151,7 @@ describe('Drawer', () => { ( } footer={({ close }) => ( } footer={ } + header={

Custom header

} + > +
test
+
, + ) + }) + + test(`function header`, () => { + shouldMatchEmotionSnapshotWithPortal( + Open} + header={({ close }) => ( + + )} + > +
test
+
, + ) + }) }) diff --git a/packages/ui/src/components/Drawer/index.tsx b/packages/ui/src/components/Drawer/index.tsx index 2950c95c34..bd5489e34f 100644 --- a/packages/ui/src/components/Drawer/index.tsx +++ b/packages/ui/src/components/Drawer/index.tsx @@ -1,20 +1,22 @@ import { css, keyframes } from '@emotion/react' import styled from '@emotion/styled' -import { type ComponentProps } from 'react' +import type { ComponentProps } from 'react' import { Modal, type ModalProps } from '../Modal' +import type { ModalState } from '../Modal/types' import { Separator } from '../Separator' import { Stack } from '../Stack' import { Text } from '../Text' import './style.css' export const SIZES = { - small: 356, - medium: 783, - large: 1209, + // 1 rem = 16 px + small: 22.25, + medium: 49, + large: 75.5, } const slideIn = (translation: number) => keyframes` from { - transform: translateX(${translation}px); + transform: translateX(${translation}rem); } to { transform: translateX(0); @@ -22,40 +24,52 @@ const slideIn = (translation: number) => keyframes` ` const slideAnimation = (size: 'small' | 'medium' | 'large') => { - if (size === 'small') return css`animation: ${slideIn(300)} linear 150ms;` - if (size === 'medium') return css`animation: ${slideIn(500)} linear 250ms;` + if (size === 'small') return css`animation: ${slideIn(22)} linear 150ms;` + if (size === 'medium') return css`animation: ${slideIn(48)} linear 250ms;` - return css`animation: ${slideIn(1000)} linear 400ms;` + return css`animation: ${slideIn(70)} linear 300ms;` } const StyledModal = styled(Modal)` margin-right: 0; height: 100%; border-radius: 0; - padding: ${({ theme }) => theme.space[2]} ; + padding: 0; &[data-size="small"]{ - width: ${SIZES.small}px; + width: ${SIZES.small}rem; ${slideAnimation('small')} } &[data-size="medium"]{ - width: ${SIZES.medium}px; + width: ${SIZES.medium}rem; ${slideAnimation('medium')} } &[data-size="large"]{ - width: ${SIZES.large}px; + width: ${SIZES.large}rem; ${slideAnimation('large')} } ` const CustomStack = styled(Stack)` height: 100%; + position: relative; ` const ChildrenContainer = styled.div` - overflow-y: scroll; + overflow-y: auto; height: 100%; + padding-inline: ${({ theme }) => theme.space[2]}; +` + +const StyledText = styled(Text)` + padding-inline: ${({ theme }) => theme.space[2]}; + padding-top: ${({ theme }) => theme.space[4]}; +` + +const Footer = styled(Stack)` + padding: ${({ theme }) => theme.space[2]}; + padding-top: 0; ` type DrawerProps = Pick< @@ -71,20 +85,22 @@ type DrawerProps = Pick< | 'onClose' | 'open' | 'placement' + | 'isClosable' > & { - title: string + header?: ModalProps['children'] size?: keyof typeof SIZES /** * Fixed info at the bottom of the */ footer?: ModalProps['children'] + separator?: boolean } export const Drawer = ({ size = 'medium', onClose, open = false, - title, + header, footer, disclosure, children, @@ -94,38 +110,67 @@ export const Drawer = ({ hideOnClickOutside, hideOnEsc, id, -}: DrawerProps) => ( - - {modalProps => ( - - { + const computeHeader = (modalProps: ModalState) => { + if (typeof header === 'string') { + return ( + - {title} - - - - {typeof children === 'function' ? children(modalProps) : children} - - {typeof footer === 'function' ? footer(modalProps) : footer} - - )} - -) + {header} + + ) + } + if (typeof header === 'function') { + return ( + + {header(modalProps)} + + ) + } + + return header + } + + return ( + + {modalProps => ( + + {computeHeader(modalProps)} + {separator ? : null} + + {typeof children === 'function' ? children(modalProps) : children} + + + + )} + + ) +}