Files
misode.github.io/src/app/components/forms/Input.tsx
Misode 90eac0f9b8 Project tree view and creation (#203)
* Implement creating and importing new projects

* Add downloading a zip of a project

* Project validation (WIP)

* Add project side panel, remove project pages

* Project file saving

* Add file tree actions to rename and delete

* Fix file creation auto focus

* Add button to save file from menu

* Add project creation

* Fix specificity on version switcher button

* Update default version to 1.19

* List project files by type, remember project and delete project
2022-06-14 16:48:55 +02:00

42 lines
1.3 KiB
TypeScript

import { useEffect, useRef } from 'preact/hooks'
import type { JSXInternal } from 'preact/src/jsx'
type InputProps = JSXInternal.HTMLAttributes<HTMLInputElement>
type BaseInputProps<T> = Omit<InputProps, 'onChange' | 'type'> & {
onChange?: (value: T) => unknown,
onEnter?: (value: T) => unknown,
onCancel?: () => unknown,
}
function BaseInput<T>(name: string, type: string, fn: (value: string) => T) {
const component = (props: BaseInputProps<T>) => {
const onChange = props.onChange && ((evt: Event) => {
const value = (evt.target as HTMLInputElement).value
props.onChange?.(fn(value))
})
const onKeyDown = props.onEnter && ((evt: KeyboardEvent) => {
if (evt.key === 'Enter') {
const value = (evt.target as HTMLInputElement).value
props.onEnter?.(fn(value))
} else if (evt.key === 'Escape') {
props.onCancel?.()
}
})
const ref = useRef<HTMLInputElement>(null)
useEffect(() => {
if (props.autofocus) {
ref.current?.select()
}
}, [props.autofocus])
return <input ref={ref} {...props} {...{ type, onChange, onKeyDown }} />
}
component.displayName = name
return component
}
export const TextInput = BaseInput('TextInput', 'text', v => v)
export const NumberInput = BaseInput('NumberInput', 'number', v => Number(v))
export const RangeInput = BaseInput('RangeInput', 'range', v => Number(v))