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()
)
)
)
}