Skip to content

Commit

Permalink
fix: make value behavior consistent #1154
Browse files Browse the repository at this point in the history
  • Loading branch information
aalencar committed Mar 10, 2022
1 parent bdc99f9 commit 995cab2
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 21 deletions.
9 changes: 6 additions & 3 deletions ui/src/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as Fluent from '@fluentui/react'
import { B, Id, S } from 'h2o-wave'
import React from 'react'
import { useControlledComponent } from './hooks'
import { wave } from './ui'

/**
Expand Down Expand Up @@ -57,10 +58,12 @@ export interface Checkbox {
export const
XCheckbox = ({ model: m }: { model: Checkbox }) => {
const onChange = (_e?: React.FormEvent<HTMLElement>, checked?: B) => {
setValue(checked)
wave.args[m.name] = checked === null ? null : !!checked
if (m.trigger) wave.push()
}

},
[value, setValue] = useControlledComponent(m)

// eslint-disable-next-line react-hooks/exhaustive-deps
React.useEffect(() => { wave.args[m.name] = !!m.value }, [])

Expand All @@ -70,7 +73,7 @@ export const
inputProps={{ 'data-test': m.name } as React.ButtonHTMLAttributes<HTMLButtonElement>}
label={m.label}
defaultIndeterminate={m.indeterminate}
defaultChecked={m.value}
checked={value}
onChange={onChange}
disabled={m.disabled}
/>
Expand Down
5 changes: 4 additions & 1 deletion ui/src/choice_group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as Fluent from '@fluentui/react'
import { B, Id, S } from 'h2o-wave'
import React from 'react'
import { useControlledComponent } from './hooks'
import { wave } from './ui'

/**
Expand Down Expand Up @@ -67,9 +68,11 @@ export interface ChoiceGroup {
export const
XChoiceGroup = ({ model: m }: { model: ChoiceGroup }) => {
const
[value, setValue] = useControlledComponent(m),
optionStyles = { choiceFieldWrapper: { marginRight: 15 } },
options = (m.choices || []).map(({ name, label, disabled }): Fluent.IChoiceGroupOption => ({ key: name, text: label || name, disabled, styles: optionStyles })),
onChange = (_e?: React.FormEvent<HTMLElement>, option?: Fluent.IChoiceGroupOption) => {
setValue(option?.key)
if (option) wave.args[m.name] = option.key
if (m.trigger) wave.push()
}
Expand All @@ -83,7 +86,7 @@ export const
data-test={m.name}
label={m.label}
required={m.required}
defaultSelectedKey={m.value}
selectedKey={value}
options={options}
onChange={onChange}
/>
Expand Down
3 changes: 2 additions & 1 deletion ui/src/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as Fluent from '@fluentui/react'
import { B, Id, S } from 'h2o-wave'
import React from 'react'
import { useControlledComponent } from './hooks'
import { wave } from './ui'

/**
Expand Down Expand Up @@ -59,7 +60,7 @@ export interface Combobox {
export const
XCombobox = ({ model: m }: { model: Combobox }) => {
const
[text, setText] = React.useState(m.value),
[text, setText] = useControlledComponent(m),
options = (m.choices || []).map((text, i): Fluent.IComboBoxOption => ({ key: `${i}`, text })),
onChange = (_e: React.FormEvent<Fluent.IComboBox>, option?: Fluent.IComboBoxOption, _index?: number, value?: string) => {
const v = option?.text || value || ''
Expand Down
2 changes: 1 addition & 1 deletion ui/src/copyable_text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const XCopyableText = ({ model }: { model: CopyableText }) => {

return (
<div data-test={name} className={multiline ? css.multiContainer : css.compactContainer}>
<Fluent.TextField componentRef={ref} defaultValue={value} label={label} multiline={multiline} styles={{ root: { width: pc(100) } }} readOnly />
<Fluent.TextField componentRef={ref} value={value} label={label} multiline={multiline} styles={{ root: { width: pc(100) } }} readOnly />
<Fluent.PrimaryButton
title='Copy to clipboard'
onClick={onClick}
Expand Down
16 changes: 11 additions & 5 deletions ui/src/date_picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as Fluent from '@fluentui/react'
import { B, Id, S, U } from 'h2o-wave'
import React from 'react'
import { useControlledComponent } from './hooks'
import { wave } from './ui'

/**
Expand Down Expand Up @@ -56,19 +57,24 @@ const
if (ss.length !== 3) return undefined
const ymd = ss.map(s => parseInt(s, 10)).filter(n => !isNaN(n))
if (ymd.length !== 3) return undefined
return new Date(ymd[0], ymd[1] - 1, ymd[2])
return new Date(ymd[0], ymd[1] - 1, ymd[2], 0, 0, 0)
}

const transform = (value: S) => {
const
parsedVal = value ? parseDate(value) : null
return parsedVal ? new Date(parsedVal) : undefined
}

export const
XDatePicker = ({ model: m }: { model: DatePicker }) => {
const
defaultVal = m.value || null,
parsedVal = defaultVal ? parseDate(defaultVal) : null,
[value, setValue] = React.useState<Date | undefined>(parsedVal ? new Date(parsedVal) : undefined),
[value, setValue] = useControlledComponent(m, transform),
onSelectDate = (d: Date | null | undefined) => {
const val = (d === null || d === undefined) ? defaultVal : formatDate(d)
const val = !d ? defaultVal : formatDate(d)
wave.args[m.name] = val
setValue(val ? new Date(`${val} 00:00:00`) : undefined)
setValue(val)
if (m.trigger) wave.push()
}

Expand Down
15 changes: 15 additions & 0 deletions ui/src/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useCallback, useEffect, useState } from "react"

export function useControlledComponent(props: any, transform?: any) {
const
[value, _setValue] = useState(transform ? transform(props.value) : props.value),
setValue = useCallback((v: any) => {
_setValue(transform ? transform(v) : v)
}, [transform])

useEffect(() => {
setValue(props.value)
}, [props, setValue])

return [value, setValue]
}
9 changes: 7 additions & 2 deletions ui/src/slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as Fluent from '@fluentui/react'
import { B, F, Id, S, U } from 'h2o-wave'
import React from 'react'
import { useControlledComponent } from './hooks'
import { wave } from './ui'

/**
Expand Down Expand Up @@ -63,7 +64,11 @@ export const
const
{ min = 0, max = 100, step = 1, value = 0 } = m,
defaultValue = (value < min) ? min : ((value > max) ? max : value),
onChange = (v: U) => wave.args[m.name] = v,
[val, setVal] = useControlledComponent(m),
onChange = (v: U) => {
setVal(v)
wave.args[m.name] = v
},
onChanged = React.useCallback((_e: MouseEvent | KeyboardEvent | TouchEvent, _value: U) => { if (m.trigger) wave.push() }, [m.trigger])

// eslint-disable-next-line react-hooks/exhaustive-deps
Expand All @@ -77,7 +82,7 @@ export const
min={min}
max={max}
step={step}
defaultValue={defaultValue}
value={val}
showValue
originFromZero={min < 0 && max >= 0}
onChange={onChange}
Expand Down
9 changes: 6 additions & 3 deletions ui/src/textbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as Fluent from '@fluentui/react'
import { B, Id, S } from 'h2o-wave'
import React from 'react'
import { useControlledComponent } from './hooks'
import { debounce, wave } from './ui'

/**
Expand Down Expand Up @@ -74,8 +75,10 @@ export const
v = v || (target as HTMLInputElement).value

wave.args[m.name] = v ?? (m.value || '')
setValue(v)
if (m.trigger) wave.push()
}
},
[value, setValue] = useControlledComponent(m)

// eslint-disable-next-line react-hooks/exhaustive-deps
React.useEffect(() => { wave.args[m.name] = m.value || '' }, [])
Expand All @@ -85,7 +88,7 @@ export const
<Fluent.MaskedTextField
data-test={m.name}
label={m.label}
defaultValue={m.value}
value={value}
mask={m.mask}
errorMessage={m.error}
required={m.required}
Expand All @@ -103,7 +106,7 @@ export const
iconProps={{ iconName: m.icon }}
prefix={m.prefix}
suffix={m.suffix}
defaultValue={m.value}
value={value}
errorMessage={m.error}
required={m.required}
disabled={m.disabled}
Expand Down
14 changes: 9 additions & 5 deletions ui/src/toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import * as Fluent from '@fluentui/react'
import { B, Id, S } from 'h2o-wave'
import React from 'react'
import { useControlledComponent } from './hooks'
import { wave } from './ui'

/**
Expand Down Expand Up @@ -48,10 +49,13 @@ export interface Toggle {

export const
XToggle = ({ model: m }: { model: Toggle }) => {
const onChange = React.useCallback((_e?: React.FormEvent<HTMLElement>, checked?: B) => {
wave.args[m.name] = !!checked
if (m.trigger) wave.push()
}, [m.name, m.trigger])
const
[value, setValue] = useControlledComponent(m),
onChange = React.useCallback((_e?: React.FormEvent<HTMLElement>, checked?: B) => {
setValue(!!checked)
wave.args[m.name] = !!checked
if (m.trigger) wave.push()
}, [m.name, m.trigger])

// eslint-disable-next-line react-hooks/exhaustive-deps
React.useEffect(() => { wave.args[m.name] = !!m.value }, [])
Expand All @@ -60,7 +64,7 @@ export const
<Fluent.Toggle
data-test={m.name}
label={m.label}
defaultChecked={m.value}
checked={value}
onChange={onChange}
disabled={m.disabled}
onText="On"
Expand Down

0 comments on commit 995cab2

Please sign in to comment.