Skip to content

Commit

Permalink
feat: Add confirm component (#53)
Browse files Browse the repository at this point in the history
* feat: Add `modal` component

* feat: Update control params

* feat: Update avatar type

* feat: Update confirm

* docs: Update modal docs

* docs: Update confirm modal docs

* fix: Fixed import path

* feat: Update title and button name
  • Loading branch information
Vibes-INS authored Oct 18, 2021
1 parent 6a7aebf commit 7ec5c63
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 1 deletion.
48 changes: 48 additions & 0 deletions apps/mibao-ui-docs/src/app/pages/confirm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Story, Meta } from '@storybook/react'
import React from 'react'
import {
ConfirmProvider, MibaoProvider, useConfirm, Button as MibaoButton, ConfirmProps
} from 'mibao-ui'
import { Box, Code } from '@chakra-ui/react'

export default {
component: ConfirmProvider,
title: 'Components/Confirm',
argTypes: {
onConfirm: {
action: 'onConfirm'
},
onCancel: {
action: 'onCancel'
}
}
} as Meta

const args: ConfirmProps = {
title: '',
content: 'Content Content Content Content Content Content Content Content',
confirmText: 'OK',
cancelText: 'Cancel'
}

const OpenModalButton: React.FC<ConfirmProps> = (args) => {
const showModal = useConfirm()
return <MibaoButton onClick={() => showModal(args)}>Button</MibaoButton>
}

const Template: Story<ConfirmProps> = (args) => {
return <MibaoProvider>
<Box m={2}>
<Code>
{'const showModal = useConfirm()'} <br/>
{'return <MibaoButton onClick={() => showModal(args)}>Button</MibaoButton>'}
</Code>
</Box>
<ConfirmProvider>
<OpenModalButton {...args} />
</ConfirmProvider>
</MibaoProvider>
}

export const Confirm = Template.bind({})
Confirm.args = args
2 changes: 1 addition & 1 deletion libs/mibao-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export * from './lib/select/select'
export * from './lib/pagination/pagination'
export * from './lib/alert/alert'
export * from './lib/toast/toast'
export * from './lib/confirm/confirm'
export * from './lib/radio/radio'

export * from './lib/table/table'
export * from './lib/button/button'
export * from './lib/modal/modal'
Expand Down
Empty file.
10 changes: 10 additions & 0 deletions libs/mibao-ui/src/lib/confirm/confirm.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { render } from '@testing-library/react'

import { ConfirmProvider } from './confirm'

describe('Confirm', () => {
it('should render successfully', () => {
const { baseElement } = render(<ConfirmProvider />)
expect(baseElement).toBeTruthy()
})
})
94 changes: 94 additions & 0 deletions libs/mibao-ui/src/lib/confirm/confirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import './confirm.module.scss'
import React, { ReactNode, createContext, useState, useContext } from 'react'
import {
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalFooterButtonGroup,
ModalHeader,
ModalOverlay,
useDisclosure
} from '../modal/modal'
import { Button } from '../button/button'

export interface ConfirmProps {
title?: ReactNode
content?: ReactNode
onConfirm?: () => void
confirmText?: ReactNode
onCancel?: () => void
cancelText?: ReactNode
}

const ConfirmContext = createContext<{ props: ConfirmProps | null, showModal: (props: ConfirmProps) => void}>({
props: null,
showModal (props: ConfirmProps) {
this.props = props
}
})

const ConfirmContextProvider = ConfirmContext.Provider

const ConfirmModal: React.FC<{
isOpen: boolean
onOpen: () => void
onClose: () => void
}> = (props) => {
const context = useContext(ConfirmContext)

return <Modal isOpen={props.isOpen} onClose={props.onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>{context.props?.title}</ModalHeader>
<ModalCloseButton />
<ModalBody>
{context.props?.content}
</ModalBody>

<ModalFooter>
<ModalFooterButtonGroup>
<Button isFullWidth variant="solid" colorScheme="primary" onClick={() => {
context.props?.onConfirm?.()
props.onClose?.()
}}>
{ context.props?.confirmText ?? 'OK' }
</Button>

{
context.props?.onCancel && <Button isFullWidth onClick={() => {
context.props?.onCancel?.()
props.onClose?.()
}}>
{ context.props?.cancelText ?? 'Cancel' }
</Button>
}
</ModalFooterButtonGroup>
</ModalFooter>
</ModalContent>
</Modal>
}

export const ConfirmProvider: React.FC = (props) => {
const [modalProps, setModalProps] = useState<ConfirmProps | null>(null)
const { isOpen, onOpen, onClose } = useDisclosure()

return (
<ConfirmContextProvider value={{
props: modalProps,
showModal: (props) => {
onOpen()
setModalProps(props)
}
}}>
<ConfirmModal isOpen={isOpen} onOpen={onOpen} onClose={onClose}/>
{props.children}
</ConfirmContextProvider>
)
}

export function useConfirm () {
const context = useContext(ConfirmContext)
return context.showModal
}

1 comment on commit 7ec5c63

@vercel
Copy link

@vercel vercel bot commented on 7ec5c63 Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.