Add maxLength counter in Growing Textarea (#95)
This commit is contained in:
parent
065630decb
commit
20ca55e1b2
|
@ -144,6 +144,7 @@ export const EditView = (props: EditViewProps) => {
|
|||
class={styles.titleInput}
|
||||
placeholder={t('Header')}
|
||||
initialValue={form.title}
|
||||
maxLength={100}
|
||||
/>
|
||||
<Show when={formErrors.title}>
|
||||
<div class={styles.validationError}>{formErrors.title}</div>
|
||||
|
@ -154,6 +155,7 @@ export const EditView = (props: EditViewProps) => {
|
|||
class={styles.subtitleInput}
|
||||
placeholder={t('Subheader')}
|
||||
initialValue={form.subtitle}
|
||||
maxLength={100}
|
||||
/>
|
||||
<Editor
|
||||
shoutId={props.shout.id}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
.GrowingTextarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
.growWrap {
|
||||
display: grid;
|
||||
|
@ -42,4 +43,34 @@
|
|||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.maxLength {
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
right: 0.6rem;
|
||||
bottom: -1.2rem;
|
||||
font-size: 1.1rem;
|
||||
border: 3px solid rgba(#ccc, 0.5);
|
||||
padding: 0.5rem;
|
||||
border-radius: 1.3rem;
|
||||
line-height: 1;
|
||||
user-select: none;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
|
||||
&.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.limited {
|
||||
animation: blink 0.8s;
|
||||
animation-iteration-count: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% {
|
||||
border-color: #000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import { clsx } from 'clsx'
|
||||
import styles from './GrowingTextarea.module.scss'
|
||||
import { createSignal } from 'solid-js'
|
||||
import { createSignal, Show } from 'solid-js'
|
||||
|
||||
type Props = {
|
||||
class?: string
|
||||
placeholder: string
|
||||
initialValue?: string
|
||||
value: (string) => void
|
||||
maxLength?: number
|
||||
}
|
||||
|
||||
export const GrowingTextarea = (props: Props) => {
|
||||
const [value, setValue] = createSignal('')
|
||||
const [isFocused, setIsFocused] = createSignal(false)
|
||||
const handleChangeValue = (event) => {
|
||||
setValue(event.target.value)
|
||||
props.value(event.target.value)
|
||||
|
@ -31,14 +33,27 @@ export const GrowingTextarea = (props: Props) => {
|
|||
<div class={clsx(styles.growWrap, props.class)} data-replicated-value={value()}>
|
||||
<textarea
|
||||
rows={1}
|
||||
maxlength={props.maxLength}
|
||||
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)}
|
||||
/>
|
||||
</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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user