add new Modal option
This commit is contained in:
parent
364608a0c6
commit
4953e15369
@ -16,6 +16,7 @@ export type ModalOptions = {
|
|||||||
placeholder?: string
|
placeholder?: string
|
||||||
inputType?: string
|
inputType?: string
|
||||||
validator?(value: any): string | boolean | undefined
|
validator?(value: any): string | boolean | undefined
|
||||||
|
choices?: { text: string; value: string }[]
|
||||||
type?: string
|
type?: string
|
||||||
showHeader?: boolean
|
showHeader?: boolean
|
||||||
center?: boolean
|
center?: boolean
|
||||||
@ -114,6 +115,7 @@ const Modal = React.forwardRef<HTMLDivElement, ModalOptions & Props>(
|
|||||||
dangerousHTML={props.dangerousHTML}
|
dangerousHTML={props.dangerousHTML}
|
||||||
showInput={props.mode === 'prompt'}
|
showInput={props.mode === 'prompt'}
|
||||||
value={value}
|
value={value}
|
||||||
|
choices={props.choices}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
inputType={props.inputType}
|
inputType={props.inputType}
|
||||||
placeholder={props.placeholder}
|
placeholder={props.placeholder}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import ModalContent from './ModalContent'
|
||||||
|
import ModalInput from './ModalInput'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
text?: string
|
text?: string
|
||||||
@ -6,6 +8,7 @@ interface Props {
|
|||||||
showInput: boolean
|
showInput: boolean
|
||||||
inputType?: string
|
inputType?: string
|
||||||
value?: string
|
value?: string
|
||||||
|
choices?: { text: string; value: string }[]
|
||||||
onChange?: React.ChangeEventHandler<HTMLInputElement>
|
onChange?: React.ChangeEventHandler<HTMLInputElement>
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
invalid?: boolean
|
invalid?: boolean
|
||||||
@ -13,38 +16,12 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ModalBody: React.FC<Props> = props => {
|
const ModalBody: React.FC<Props> = props => {
|
||||||
const main = (() => {
|
|
||||||
if (props.children) {
|
|
||||||
return props.children
|
|
||||||
} else if (props.text) {
|
|
||||||
return props.text.split(/\r?\n/).map((line, i) => <p key={i}>{line}</p>)
|
|
||||||
} else if (props.dangerousHTML) {
|
|
||||||
return <div dangerouslySetInnerHTML={{ __html: props.dangerousHTML }} />
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
{main}
|
<ModalContent text={props.text} dangerousHTML={props.dangerousHTML}>
|
||||||
{props.showInput && (
|
{props.children}
|
||||||
<>
|
</ModalContent>
|
||||||
<div className="form-group">
|
{props.showInput && <ModalInput {...props} />}
|
||||||
<input
|
|
||||||
value={props.value}
|
|
||||||
onChange={props.onChange}
|
|
||||||
type={props.inputType}
|
|
||||||
className="form-control"
|
|
||||||
placeholder={props.placeholder}
|
|
||||||
></input>
|
|
||||||
</div>
|
|
||||||
{props.invalid && (
|
|
||||||
<div className="alert alert-danger">
|
|
||||||
<i className="icon far fa-times-circle"></i>
|
|
||||||
<span className="ml-1">{props.validatorMessage}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
26
resources/assets/src/components/ModalContent.tsx
Normal file
26
resources/assets/src/components/ModalContent.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
text?: string
|
||||||
|
dangerousHTML?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModalContent: React.FC<Props> = props => {
|
||||||
|
if (props.children) {
|
||||||
|
return <>{props.children}</>
|
||||||
|
} else if (props.text) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{props.text.split(/\r?\n/).map((line, i) => (
|
||||||
|
<p key={i}>{line}</p>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
} else if (props.dangerousHTML) {
|
||||||
|
return <div dangerouslySetInnerHTML={{ __html: props.dangerousHTML }} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ModalContent
|
52
resources/assets/src/components/ModalInput.tsx
Normal file
52
resources/assets/src/components/ModalInput.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
inputType?: string
|
||||||
|
value?: string
|
||||||
|
choices?: { text: string; value: string }[]
|
||||||
|
onChange?: React.ChangeEventHandler<HTMLInputElement>
|
||||||
|
placeholder?: string
|
||||||
|
invalid?: boolean
|
||||||
|
validatorMessage?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModalInput: React.FC<Props> = props => (
|
||||||
|
<>
|
||||||
|
{props.inputType === 'radios' && props.choices ? (
|
||||||
|
<>
|
||||||
|
{props.choices.map(choice => (
|
||||||
|
<div key={choice.value}>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="modal-radios"
|
||||||
|
id={`modal-radio-${choice.value}`}
|
||||||
|
value={choice.value}
|
||||||
|
onChange={props.onChange}
|
||||||
|
/>
|
||||||
|
<label htmlFor={`modal-radio-${choice.value}`} className="ml-1">
|
||||||
|
{choice.text}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="form-group">
|
||||||
|
<input
|
||||||
|
value={props.value}
|
||||||
|
onChange={props.onChange}
|
||||||
|
type={props.inputType}
|
||||||
|
className="form-control"
|
||||||
|
placeholder={props.placeholder}
|
||||||
|
></input>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{props.invalid && (
|
||||||
|
<div className="alert alert-danger">
|
||||||
|
<i className="icon far fa-times-circle"></i>
|
||||||
|
<span className="ml-1">{props.validatorMessage}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default ModalInput
|
@ -218,6 +218,26 @@ describe('"prompt" mode', () => {
|
|||||||
expect(reject).toBeCalled()
|
expect(reject).toBeCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('radio inputs', () => {
|
||||||
|
const choices = [
|
||||||
|
{ text: 'A', value: 'a' },
|
||||||
|
{ text: 'B', value: 'b' },
|
||||||
|
]
|
||||||
|
const resolve = jest.fn()
|
||||||
|
const { getByText, getByLabelText } = render(
|
||||||
|
<Modal
|
||||||
|
mode="prompt"
|
||||||
|
inputType="radios"
|
||||||
|
choices={choices}
|
||||||
|
onConfirm={resolve}
|
||||||
|
show
|
||||||
|
/>,
|
||||||
|
)
|
||||||
|
fireEvent.click(getByLabelText('B'))
|
||||||
|
fireEvent.click(getByText(trans('general.confirm')))
|
||||||
|
expect(resolve).toBeCalledWith({ value: 'b' })
|
||||||
|
})
|
||||||
|
|
||||||
it('validate input', () => {
|
it('validate input', () => {
|
||||||
const resolve = jest.fn()
|
const resolve = jest.fn()
|
||||||
const reject = jest.fn()
|
const reject = jest.fn()
|
||||||
|
Loading…
Reference in New Issue
Block a user