From 2e8b48bf15b95a4a22962570cf79ca1a5322470d Mon Sep 17 00:00:00 2001 From: Marek Mihok Date: Tue, 1 Aug 2023 11:28:18 +0200 Subject: [PATCH] feat: Allow dynamic value change for checkbox #1154 (#2090) --- ui/src/checkbox.test.tsx | 23 +++++++++++++++++++---- ui/src/checkbox.tsx | 32 ++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/ui/src/checkbox.test.tsx b/ui/src/checkbox.test.tsx index 7fc87f389e..54f20a5396 100644 --- a/ui/src/checkbox.test.tsx +++ b/ui/src/checkbox.test.tsx @@ -33,6 +33,13 @@ describe('Checkbox.tsx', () => { expect(queryByTestId(name)).toBeInTheDocument() }) + it('Sets args on click', () => { + const { getByTestId } = render() + fireEvent.click(getByTestId(name)) + + expect(wave.args[name]).toBe(true) + }) + it('Does not display checkbox when visible is false', () => { const { queryByTestId } = render() expect(queryByTestId(name)).toBeInTheDocument() @@ -59,11 +66,19 @@ describe('Checkbox.tsx', () => { expect(pushMock).toHaveBeenCalled() }) - it('Sets args on click', () => { - const { getByTestId } = render() - fireEvent.click(getByTestId(name)) - + it('Set args when value is updated to different value', () => { + const { rerender } = render() expect(wave.args[name]).toBe(true) + rerender() + expect(wave.args[name]).toBe(false) }) + it('Set args when value is updated to initial value', () => { + const { getByTestId, rerender } = render() + expect(wave.args[name]).toBe(true) + fireEvent.click(getByTestId(name)) + expect(wave.args[name]).toBe(false) + rerender() + expect(wave.args[name]).toBe(true) + }) }) \ No newline at end of file diff --git a/ui/src/checkbox.tsx b/ui/src/checkbox.tsx index 8b4a4a80ba..670886a853 100644 --- a/ui/src/checkbox.tsx +++ b/ui/src/checkbox.tsx @@ -56,24 +56,32 @@ export interface Checkbox { export const XCheckbox = ({ model: m }: { model: Checkbox }) => { - const onChange = (_e?: React.FormEvent, checked?: B) => { - wave.args[m.name] = checked === null ? null : !!checked - if (m.trigger) wave.push() - } + const + { name, label, value = false, indeterminate, disabled, trigger } = m, + [checked, setChecked] = React.useState(value), + onChange = (_e?: React.FormEvent, checked?: B) => { + wave.args[name] = checked === null ? null : !!checked + setChecked(!!checked) + m.value = !!checked + if (trigger) wave.push() + } - // eslint-disable-next-line react-hooks/exhaustive-deps - React.useEffect(() => { wave.args[m.name] = !!m.value }, []) + React.useEffect(() => { + wave.args[name] = value + setChecked(value) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [value]) return ( } + data-test={name} + inputProps={{ 'data-test': name } as React.ButtonHTMLAttributes} styles={{ checkmark: { display: 'flex' } }} // Fix: Center the checkmark in the checkbox. - label={m.label} - defaultIndeterminate={m.indeterminate} - defaultChecked={m.value} + label={label} + defaultIndeterminate={indeterminate} + checked={checked} onChange={onChange} - disabled={m.disabled} + disabled={disabled} /> ) } \ No newline at end of file