From 4953e15369840b3c61ead526e288044a9c686952 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Tue, 28 Jan 2020 10:41:10 +0800 Subject: [PATCH] add new Modal option --- resources/assets/src/components/Modal.tsx | 2 + resources/assets/src/components/ModalBody.tsx | 37 +++---------- .../assets/src/components/ModalContent.tsx | 26 ++++++++++ .../assets/src/components/ModalInput.tsx | 52 +++++++++++++++++++ .../assets/tests/components/Modal.test.tsx | 20 +++++++ 5 files changed, 107 insertions(+), 30 deletions(-) create mode 100644 resources/assets/src/components/ModalContent.tsx create mode 100644 resources/assets/src/components/ModalInput.tsx diff --git a/resources/assets/src/components/Modal.tsx b/resources/assets/src/components/Modal.tsx index 5fb8fa4f..f4206243 100644 --- a/resources/assets/src/components/Modal.tsx +++ b/resources/assets/src/components/Modal.tsx @@ -16,6 +16,7 @@ export type ModalOptions = { placeholder?: string inputType?: string validator?(value: any): string | boolean | undefined + choices?: { text: string; value: string }[] type?: string showHeader?: boolean center?: boolean @@ -114,6 +115,7 @@ const Modal = React.forwardRef( dangerousHTML={props.dangerousHTML} showInput={props.mode === 'prompt'} value={value} + choices={props.choices} onChange={handleInputChange} inputType={props.inputType} placeholder={props.placeholder} diff --git a/resources/assets/src/components/ModalBody.tsx b/resources/assets/src/components/ModalBody.tsx index 8c97a164..ef66893b 100644 --- a/resources/assets/src/components/ModalBody.tsx +++ b/resources/assets/src/components/ModalBody.tsx @@ -1,4 +1,6 @@ import React from 'react' +import ModalContent from './ModalContent' +import ModalInput from './ModalInput' interface Props { text?: string @@ -6,6 +8,7 @@ interface Props { showInput: boolean inputType?: string value?: string + choices?: { text: string; value: string }[] onChange?: React.ChangeEventHandler placeholder?: string invalid?: boolean @@ -13,38 +16,12 @@ interface Props { } const ModalBody: React.FC = props => { - const main = (() => { - if (props.children) { - return props.children - } else if (props.text) { - return props.text.split(/\r?\n/).map((line, i) =>

{line}

) - } else if (props.dangerousHTML) { - return
- } - })() - return (
- {main} - {props.showInput && ( - <> -
- -
- {props.invalid && ( -
- - {props.validatorMessage} -
- )} - - )} + + {props.children} + + {props.showInput && }
) } diff --git a/resources/assets/src/components/ModalContent.tsx b/resources/assets/src/components/ModalContent.tsx new file mode 100644 index 00000000..cb0ac8a5 --- /dev/null +++ b/resources/assets/src/components/ModalContent.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +interface Props { + text?: string + dangerousHTML?: string +} + +const ModalContent: React.FC = props => { + if (props.children) { + return <>{props.children} + } else if (props.text) { + return ( + <> + {props.text.split(/\r?\n/).map((line, i) => ( +

{line}

+ ))} + + ) + } else if (props.dangerousHTML) { + return
+ } + + return <> +} + +export default ModalContent diff --git a/resources/assets/src/components/ModalInput.tsx b/resources/assets/src/components/ModalInput.tsx new file mode 100644 index 00000000..a0dcf4d6 --- /dev/null +++ b/resources/assets/src/components/ModalInput.tsx @@ -0,0 +1,52 @@ +import React from 'react' + +interface Props { + inputType?: string + value?: string + choices?: { text: string; value: string }[] + onChange?: React.ChangeEventHandler + placeholder?: string + invalid?: boolean + validatorMessage?: string +} + +const ModalInput: React.FC = props => ( + <> + {props.inputType === 'radios' && props.choices ? ( + <> + {props.choices.map(choice => ( +
+ + +
+ ))} + + ) : ( +
+ +
+ )} + {props.invalid && ( +
+ + {props.validatorMessage} +
+ )} + +) + +export default ModalInput diff --git a/resources/assets/tests/components/Modal.test.tsx b/resources/assets/tests/components/Modal.test.tsx index 41a9725c..4554f235 100644 --- a/resources/assets/tests/components/Modal.test.tsx +++ b/resources/assets/tests/components/Modal.test.tsx @@ -218,6 +218,26 @@ describe('"prompt" mode', () => { expect(reject).toBeCalled() }) + it('radio inputs', () => { + const choices = [ + { text: 'A', value: 'a' }, + { text: 'B', value: 'b' }, + ] + const resolve = jest.fn() + const { getByText, getByLabelText } = render( + , + ) + fireEvent.click(getByLabelText('B')) + fireEvent.click(getByText(trans('general.confirm'))) + expect(resolve).toBeCalledWith({ value: 'b' }) + }) + it('validate input', () => { const resolve = jest.fn() const reject = jest.fn()