webapp/src/components/_shared/GrowingTextarea/GrowingTextarea.tsx

60 lines
1.6 KiB
TypeScript
Raw Normal View History

2023-05-11 11:33:01 +00:00
import { clsx } from 'clsx'
import styles from './GrowingTextarea.module.scss'
import { createSignal, Show } from 'solid-js'
2023-05-11 11:33:01 +00:00
type Props = {
class?: string
placeholder: string
initialValue?: string
value: (string) => void
maxLength?: number
2023-05-11 11:33:01 +00:00
}
export const GrowingTextarea = (props: Props) => {
const [value, setValue] = createSignal('')
const [isFocused, setIsFocused] = createSignal(false)
2023-05-11 11:33:01 +00:00
const handleChangeValue = (event) => {
setValue(event.target.value)
props.value(event.target.value)
}
const handleKeyDown = async (event) => {
if (event.key === 'Enter' && event.shiftKey) {
return
}
if (event.key === 'Enter' && !event.shiftKey && value()?.trim().length > 0) {
event.preventDefault()
}
}
return (
<div class={clsx(styles.GrowingTextarea)}>
<div class={clsx(styles.growWrap, props.class)} data-replicated-value={value()}>
<textarea
rows={1}
maxlength={props.maxLength}
2023-05-11 11:33:01 +00:00
autocomplete="off"
class={clsx(styles.textInput, props.class)}
value={props.initialValue}
onKeyDown={handleKeyDown}
onInput={(event) => handleChangeValue(event)}
placeholder={props.placeholder}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
2023-05-11 11:33:01 +00:00
/>
</div>
<Show when={props.maxLength && value()}>
<div
class={clsx(styles.maxLength, {
[styles.visible]: isFocused(),
[styles.limited]: value().length === props.maxLength
})}
>
{`${value().length} / ${props.maxLength}`}
</div>
</Show>
2023-05-11 11:33:01 +00:00
</div>
)
}