import { h, Html, Rx, RxAble } from 'lib/rx' import * as rx from 'lib/rx' import * as L from 'lib/loadable' import * as icons from 'lib/icons' interface InputParams { label: string type?: string initValue?: string select?: boolean onUpdate: (value: string) => void required?: boolean } export function input({ label, type, initValue, select, onUpdate, required }: InputParams): Html { return h('label', { className: 'g-Label' }, label, h('input', { type: type ?? 'text', className: 'g-Input', onmount: (element: HTMLInputElement) => { if (select) { element.select() } }, oninput: (event: Event) => { let value = (event.target as HTMLInputElement).value onUpdate(type == 'password' ? value : value.trim()) }, value: initValue, required } ) ) } interface TextareaParams { label: string initValue?: string select?: boolean onUpdate: (value: string) => void required?: boolean } export function textarea({ label, initValue, select, onUpdate, required }: TextareaParams): Html { return h('label', { className: 'g-Label' }, label, h('textarea', { className: 'g-Textarea', onmount: (element: HTMLInputElement) => { if (select) { element.select() } }, oninput: (event: Event) => onUpdate((event.target as HTMLInputElement).value.trim()), value: initValue, required } ) ) } interface SelectParams { label: string initValue: string values: { [key: string]: string } onUpdate: (value: string) => void required?: boolean } export function select({ label, initValue, values, onUpdate, required }: SelectParams): Html { let keys = Object.keys(values) keys.sort((a, b) => values[a].localeCompare(values[b])) return h('label', { className: 'g-Label' }, label, h('select', { className: 'g-Select', onchange: (event: Event) => { const element = event.target as HTMLSelectElement onUpdate(element.value) }, required }, h('option', { label: ' ' }), keys.map(key => h('option', { value: key, selected: initValue == key }, values[key] ) ) ) ) } export function error(requestVar: Rx>): Html { return requestVar.map(l => L.isFailure(l) ? h('div', { className: 'g-FormError' }, l.error) : undefined ) } interface SubmitParams { label: string className?: string disabled?: RxAble requestVar?: Rx> } export function submit({ label, className, disabled, requestVar }: SubmitParams): Html { const loadingClassname = requestVar ? requestVar.map(l => L.isLoading(l) ? 'g-Button--Loading' : '') : rx.pure('') return h('div', { className: 'g-Form__SubmitParent' }, h('input', { type: 'submit', className: loadingClassname.map(lc => `g-Button g-Button--Primary ${className ?? ''} ${lc}`), value: label, disabled }), loadingClassname.map(l => l && h('div', { className: 'g-Form__SubmitSpinner' }, icons.spinner() ) ) ) } interface ButtonParams { style?: string label: string className?: string disabled?: RxAble requestVar?: Rx> onClick: () => void, } export function button({ style, label, className, disabled, requestVar, onClick }: ButtonParams): Html { const loadingClassname = requestVar ? requestVar.map(l => L.isLoading(l) ? 'g-Button--Loading' : '') : rx.pure('') return h('div', { className: 'g-Form__SubmitParent' }, h('input', { type: 'button', style, className: loadingClassname.map(lc => `g-Button g-Button--Primary ${className ?? ''} ${lc}`), disabled, onclick: () => onClick(), value: label } ), loadingClassname.map(l => l && h('div', { className: 'g-Form__SubmitSpinner' }, icons.spinner() ) ) ) }