website/components/Input.tsx

43 lines
992 B
TypeScript

import { useSignal, useSignalEffect } from '@preact/signals'
import { JSX } from 'preact'
export function Input(
{ label, name, ...props }:
& { label: string; name: string }
& JSX.InputHTMLAttributes<HTMLInputElement>,
) {
if (props.type === 'password') {
const password = useSignal('')
const hash = useSignal('')
const salt = crypto.randomUUID()
useSignalEffect(() => {
crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode(salt + password.value),
).then((digest) => hash.value = new TextDecoder().decode(digest))
})
return (
<label>
<span>{label}</span>
<input
{...props}
spellcheck={false}
onInput={(event) =>
password.value = (event.target as HTMLInputElement).value}
/>
<input type='text' hidden value={hash} name={name} />
<input type='text' hidden value={salt} name={`${name}_salt`} />
</label>
)
}
return (
<label>
<span>{label}</span>
<input {...props} name={name} />
</label>
)
}