add new Modal option
This commit is contained in:
parent
364608a0c6
commit
4953e15369
@ -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<HTMLDivElement, ModalOptions & Props>(
|
||||
dangerousHTML={props.dangerousHTML}
|
||||
showInput={props.mode === 'prompt'}
|
||||
value={value}
|
||||
choices={props.choices}
|
||||
onChange={handleInputChange}
|
||||
inputType={props.inputType}
|
||||
placeholder={props.placeholder}
|
||||
|
@ -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<HTMLInputElement>
|
||||
placeholder?: string
|
||||
invalid?: boolean
|
||||
@ -13,38 +16,12 @@ interface 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 (
|
||||
<div className="modal-body">
|
||||
{main}
|
||||
{props.showInput && (
|
||||
<>
|
||||
<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>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<ModalContent text={props.text} dangerousHTML={props.dangerousHTML}>
|
||||
{props.children}
|
||||
</ModalContent>
|
||||
{props.showInput && <ModalInput {...props} />}
|
||||
</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()
|
||||
})
|
||||
|
||||
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', () => {
|
||||
const resolve = jest.fn()
|
||||
const reject = jest.fn()
|
||||
|
Loading…
Reference in New Issue
Block a user