Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/violet-moose-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@channel.io/bezier-react": minor
---

Re-implement `ConfirmModal` component

BREAKING CHANGES:

- `onConfirm` prop of `ConfirmModal` has been removed.
Original file line number Diff line number Diff line change
@@ -1,196 +1,111 @@
/* eslint-disable no-restricted-imports */
/* External dependencies */
import React from 'react'
import React, { useState, useEffect } from 'react'
import base from 'paths.macro'
import { Story, Meta } from '@storybook/react'

/* Internal dependencies */
import { getTitle } from 'Utils/storyUtils'
import {
ModalContent,
ModalAction,
ModalActionProps,
ModalContentProps,
} from '../LegacyModal'
import { ModalTitleSize } from '../LegacyModal/Modal.types'
import type { ConfirmModalProps } from './ConfirmModal.types'
import ConfirmModal from './ConfirmModal'

export default {
title: getTitle(base),
component: ConfirmModal,
argTypes: {
titleSize: {
control: {
type: 'radio',
options: [
...Object.values(ModalTitleSize),
],
},
},
},
} as Meta

interface ModalStorybookProps extends
Omit<ConfirmModalProps, 'title'>,
ModalContentProps,
ModalActionProps { }

const DEFAULT_OPTIONAL_MODAL_PROPS: Partial<ModalStorybookProps> = {
show: false,
autoFocus: true,
showCloseIcon: false,
padded: true,
backdropClassName: '',
targetElement: undefined,
zIndex: 1e7,
}

const ModalStorybook = ({
import { Button, ButtonColorVariant, ButtonStyleVariant } from 'Components/Button'
import { ButtonGroup } from 'Components/ButtonGroup'
import { ConfirmModal } from './ConfirmModal'
import { ConfirmModalContent } from './ConfirmModalContent'
import { ConfirmModalHeader } from './ConfirmModalHeader'
import { ConfirmModalBody } from './ConfirmModalBody'
import { ConfirmModalFooter } from './ConfirmModalFooter'
import { ConfirmModalTrigger, ConfirmModalClose } from './ConfirmModalHelpers'
import { ConfirmModalProps, ConfirmModalContentProps, ConfirmModalHeaderProps } from './ConfirmModal.types'

type ConfirmModalCompositionProps = ConfirmModalProps & ConfirmModalContentProps & ConfirmModalHeaderProps

function ConfirmModalComposition({
show: showProp = false,
width,
height,
title,
titleSize,
subTitle,
description,
showCloseIcon,
leftContent,
rightContent,
show,
children,
...rests
}: ModalStorybookProps) => {
const [isShow, setShow] = React.useState(show)

React.useEffect(function watchShowToChange() {
setShow(show)
}, [show])
}: ConfirmModalCompositionProps) {
const [show, setShow] = useState(false)

const onHide = React.useCallback(() => {
setShow(false)
}, [])

const handleShowAsToggle = React.useCallback(() => {
setShow(!isShow)
}, [isShow])

const onConfirm = React.useCallback((e: React.MouseEvent | React.KeyboardEvent) => {
e.stopPropagation()
onHide()
}, [onHide])
useEffect(function watchShowToChange() {
setShow(showProp)
}, [showProp])

return (
<>
<button
type="button"
onClick={handleShowAsToggle}
>
{ isShow ? 'Hide' : 'Show' }
</button>
<ConfirmModal
{...rests}
show={isShow}
onHide={onHide}
onConfirm={onConfirm}
<ConfirmModal
show={show}
onShow={() => setShow(true)}
onHide={() => setShow(false)}
>
<ConfirmModalTrigger>
<Button text="Open Modal" />
</ConfirmModalTrigger>

<ConfirmModalContent
width={width}
height={height}
>
<ModalContent
<ConfirmModalHeader
title={title}
titleSize={titleSize}
subTitle={subTitle}
description={description}
showCloseIcon={showCloseIcon}
>
{ children }
</ModalContent>
<ModalAction
leftContent={leftContent}
/>

<ConfirmModalFooter
rightContent={(
<button
type="button"
onClick={onConfirm}
>
onConfirm
</button>
<ButtonGroup>
<ConfirmModalClose>
<Button
colorVariant={ButtonColorVariant.MonochromeLight}
styleVariant={ButtonStyleVariant.Secondary}
text="Cancel"
/>
</ConfirmModalClose>
<ConfirmModalClose>
<Button
colorVariant={ButtonColorVariant.Red}
styleVariant={ButtonStyleVariant.Primary}
text="Yes, delete account"
/>
</ConfirmModalClose>
</ButtonGroup>
)}
/>
</ConfirmModal>
</>
</ConfirmModalContent>
</ConfirmModal>
)
}

const PrimaryTemplate: Story<ModalStorybookProps> = (props) => (
<ModalStorybook {...props} />
)

export const Primary = PrimaryTemplate.bind({})
Primary.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
title: 'Title',
description: 'Description',
leftContent: 'Left content',
rightContent: 'Right content',
}

export const WithChildren = PrimaryTemplate.bind({})
WithChildren.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
title: 'Title',
subTitle: 'Sub Title',
description: 'Description',
leftContent: 'Left content',
rightContent: 'Right content',
children: (
<div style={{ width: '100%', height: '50px', backgroundColor: 'rgba(94, 86, 240, 0.1)' }} />
),
}

export const WithSubTitle = PrimaryTemplate.bind({})
WithSubTitle.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
title: 'Title',
subTitle: 'Sub Title',
description: 'Description',
leftContent: 'Left content',
rightContent: 'Right content',
}

export const LongTitle = PrimaryTemplate.bind({})
LongTitle.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
title: Array.from(Array(500)).map(() => 'Title ').join(''),
description: 'Description',
leftContent: 'Left content',
rightContent: 'Right content',
}

export const LongDescription = PrimaryTemplate.bind({})
LongDescription.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
title: 'Title',
description: Array.from(Array(500)).map(() => 'Description ').join(''),
leftContent: 'Left content',
rightContent: 'Right content',
}

export const LongTitleAndDescription = PrimaryTemplate.bind({})
LongTitleAndDescription.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
title: Array.from(Array(500)).map(() => 'Title ').join(''),
description: Array.from(Array(500)).map(() => 'Description ').join(''),
leftContent: 'Left content',
rightContent: 'Right content',
}
export default {
title: getTitle(base),
component: ConfirmModalComposition,
subcomponents: {
ConfirmModal,
ConfirmModalContent,
ConfirmModalHeader,
ConfirmModalBody,
ConfirmModalFooter,
ConfirmModalTrigger,
ConfirmModalClose,
},
argTypes: {
width: {
control: {
type: 'text',
},
},
height: {
control: {
type: 'text',
},
},
},
} as Meta<ConfirmModalProps>

export const WithoutTitle = PrimaryTemplate.bind({})
WithoutTitle.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
description: 'Description',
leftContent: 'Left content',
rightContent: 'Right content',
}
const Template: Story<ConfirmModalCompositionProps> = ConfirmModalComposition

export const WithoutDescription = PrimaryTemplate.bind({})
WithoutDescription.args = {
...DEFAULT_OPTIONAL_MODAL_PROPS,
title: 'Title',
leftContent: 'Left content',
rightContent: 'Right content',
export const Composition = Template.bind({})
Composition.args = {
show: false,
title: 'Are you absolutely sure?',
description: 'This action cannot be undone. This will permanently delete your account and remove your data from our servers.',
}
Loading