webapp/src/components/Editor/InlineForm/InlineForm.tsx

102 lines
2.7 KiB
TypeScript
Raw Normal View History

import styles from './InlineForm.module.scss'
import { Icon } from '../../_shared/Icon'
2023-07-28 19:53:21 +00:00
import { createSignal, onMount } from 'solid-js'
import { clsx } from 'clsx'
2023-05-29 17:14:58 +00:00
import { Popover } from '../../_shared/Popover'
import { useLocalize } from '../../../context/localize'
type Props = {
onClose: () => void
onClear?: () => void
onSubmit: (value: string) => void
validate?: (value: string) => string | Promise<string>
initialValue?: string
showInput?: boolean
placeholder: string
}
export const InlineForm = (props: Props) => {
2023-05-29 17:14:58 +00:00
const { t } = useLocalize()
const [formValue, setFormValue] = createSignal(props.initialValue || '')
const [formValueError, setFormValueError] = createSignal<string | undefined>()
2023-07-28 19:53:21 +00:00
const inputRef: { current: HTMLInputElement } = { current: null }
const handleFormInput = (e) => {
const value = e.currentTarget.value
setFormValueError()
setFormValue(value)
}
const handleSaveButtonClick = async () => {
if (props.validate) {
const errorMessage = await props.validate(formValue())
if (errorMessage) {
setFormValueError(errorMessage)
return
}
}
props.onSubmit(formValue())
props.onClose()
}
const handleKeyDown = async (e) => {
setFormValueError('')
if (e.key === 'Enter') {
e.preventDefault()
await handleSaveButtonClick()
}
if (e.key === 'Escape' && props.onClear) {
props.onClear()
}
}
const handleClear = () => {
props.initialValue ? props.onClear() : props.onClose()
}
2023-07-28 19:53:21 +00:00
onMount(() => {
inputRef.current.focus()
})
return (
<div class={styles.InlineForm}>
<div class={styles.form}>
<input
2023-07-28 19:53:21 +00:00
ref={(el) => (inputRef.current = el)}
type="text"
value={props.initialValue ?? ''}
placeholder={props.placeholder}
onKeyDown={handleKeyDown}
onInput={handleFormInput}
/>
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('Remove link') : t('Cancel')}>
2023-05-29 17:14:58 +00:00
{(triggerRef: (el) => void) => (
<button ref={triggerRef} type="button" onClick={handleClear}>
2023-05-29 17:14:58 +00:00
{props.initialValue ? <Icon name="editor-unlink" /> : <Icon name="status-cancel" />}
</button>
)}
</Popover>
</div>
<div class={clsx(styles.linkError, { [styles.visible]: Boolean(formValueError()) })}>
{formValueError()}
</div>
</div>
)
}