2023-04-26 02:37:29 +00:00
|
|
|
import styles from './InlineForm.module.scss'
|
|
|
|
import { Icon } from '../../_shared/Icon'
|
2023-05-04 04:43:52 +00:00
|
|
|
import { createSignal } from 'solid-js'
|
2023-04-26 02:37:29 +00:00
|
|
|
import { clsx } from 'clsx'
|
2023-05-29 17:14:58 +00:00
|
|
|
import { Popover } from '../../_shared/Popover'
|
|
|
|
import { useLocalize } from '../../../context/localize'
|
2023-04-26 02:37:29 +00:00
|
|
|
|
|
|
|
type Props = {
|
|
|
|
onClose: () => void
|
|
|
|
onClear?: () => void
|
|
|
|
onSubmit: (value: string) => void
|
2023-05-09 23:15:26 +00:00
|
|
|
validate?: (value: string) => string | Promise<string>
|
2023-04-26 02:37:29 +00:00
|
|
|
initialValue?: string
|
2023-05-04 04:43:52 +00:00
|
|
|
showInput?: boolean
|
|
|
|
placeholder: string
|
|
|
|
autoFocus?: boolean
|
2023-04-26 02:37:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const InlineForm = (props: Props) => {
|
2023-05-29 17:14:58 +00:00
|
|
|
const { t } = useLocalize()
|
2023-04-26 02:37:29 +00:00
|
|
|
const [formValue, setFormValue] = createSignal(props.initialValue || '')
|
2023-05-04 04:43:52 +00:00
|
|
|
const [formValueError, setFormValueError] = createSignal<string | undefined>()
|
2023-04-26 02:37:29 +00:00
|
|
|
|
2023-05-12 13:45:31 +00:00
|
|
|
const handleFormInput = (e) => {
|
|
|
|
const value = e.currentTarget.value
|
2023-05-04 04:43:52 +00:00
|
|
|
setFormValueError()
|
2023-04-26 02:37:29 +00:00
|
|
|
setFormValue(value)
|
|
|
|
}
|
|
|
|
|
|
|
|
const handleSaveButtonClick = async () => {
|
2023-05-04 04:43:52 +00:00
|
|
|
if (props.validate) {
|
2023-05-09 23:15:26 +00:00
|
|
|
const errorMessage = await props.validate(formValue())
|
|
|
|
if (errorMessage) {
|
|
|
|
setFormValueError(errorMessage)
|
|
|
|
return
|
2023-05-04 04:43:52 +00:00
|
|
|
}
|
2023-04-26 02:37:29 +00:00
|
|
|
}
|
2023-05-09 23:15:26 +00:00
|
|
|
|
|
|
|
props.onSubmit(formValue())
|
|
|
|
props.onClose()
|
2023-04-26 02:37:29 +00:00
|
|
|
}
|
|
|
|
|
2023-05-12 13:45:31 +00:00
|
|
|
const handleKeyDown = async (e) => {
|
2023-04-26 02:37:29 +00:00
|
|
|
setFormValueError('')
|
|
|
|
|
2023-05-12 13:45:31 +00:00
|
|
|
if (e.key === 'Enter') {
|
|
|
|
e.preventDefault()
|
2023-04-26 02:37:29 +00:00
|
|
|
await handleSaveButtonClick()
|
|
|
|
}
|
|
|
|
|
2023-05-12 13:45:31 +00:00
|
|
|
if (e.key === 'Escape' && props.onClear) {
|
|
|
|
props.onClear()
|
2023-04-26 02:37:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2023-05-04 04:43:52 +00:00
|
|
|
<div class={styles.InlineForm}>
|
2023-04-26 02:37:29 +00:00
|
|
|
<div class={styles.form}>
|
2023-05-04 04:43:52 +00:00
|
|
|
<input
|
|
|
|
autofocus={props.autoFocus ?? true}
|
|
|
|
type="text"
|
2023-05-10 01:46:39 +00:00
|
|
|
value={props.initialValue ?? ''}
|
2023-05-04 04:43:52 +00:00
|
|
|
placeholder={props.placeholder}
|
2023-05-12 13:45:31 +00:00
|
|
|
onKeyDown={handleKeyDown}
|
|
|
|
onInput={handleFormInput}
|
2023-05-04 04:43:52 +00:00
|
|
|
/>
|
2023-05-29 17:14:58 +00:00
|
|
|
<Popover content={t('Add link')}>
|
|
|
|
{(triggerRef: (el) => void) => (
|
|
|
|
<button
|
|
|
|
ref={triggerRef}
|
|
|
|
type="button"
|
|
|
|
onClick={handleSaveButtonClick}
|
|
|
|
disabled={Boolean(formValueError())}
|
|
|
|
>
|
|
|
|
<Icon name="status-done" />
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
</Popover>
|
|
|
|
<Popover content={props.initialValue ? t('Unlink') : t('Cancel')}>
|
|
|
|
{(triggerRef: (el) => void) => (
|
|
|
|
<button ref={triggerRef} type="button" onClick={props.onClear}>
|
|
|
|
{props.initialValue ? <Icon name="editor-unlink" /> : <Icon name="status-cancel" />}
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
</Popover>
|
2023-04-26 02:37:29 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class={clsx(styles.linkError, { [styles.visible]: Boolean(formValueError()) })}>
|
|
|
|
{formValueError()}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|