From 9b5ec0f44af55c1554d0a090d88c943362d417f2 Mon Sep 17 00:00:00 2001 From: tom Date: Mon, 29 Sep 2025 16:21:46 -0400 Subject: [PATCH 1/4] fix radio buttons --- src/components/Radio.tsx | 9 ++++++--- src/components/forms/controlled/inputTypes.tsx | 2 +- src/components/forms/uncontrolled/inputTypes.tsx | 8 +++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/Radio.tsx b/src/components/Radio.tsx index 98d309487..df0fec23d 100644 --- a/src/components/Radio.tsx +++ b/src/components/Radio.tsx @@ -54,7 +54,10 @@ const LabelWithTooltipWrapper = styled.div` type RadioProps = PropsWithChildren< Omit, 'type'>>; -export const Radio = ({ children, disabled, ...props }: RadioProps & {tooltipText?: string}) => { +export const Radio = ({ children, disabled, labelAs, ...props }: RadioProps & { + tooltipText?: string; + labelAs?: string; +}) => { const state = useTooltipTriggerState({delay: 0}); const ref = React.useRef(null); @@ -64,7 +67,7 @@ export const Radio = ({ children, disabled, ...props }: RadioProps & {tooltipTex return props.tooltipText ?
- + state.open()} isDisabled={disabled} aria-disabled={disabled} {...props} /> {children} {state.isOpen && ( @@ -73,7 +76,7 @@ export const Radio = ({ children, disabled, ...props }: RadioProps & {tooltipTex
- : + : {children} ; diff --git a/src/components/forms/controlled/inputTypes.tsx b/src/components/forms/controlled/inputTypes.tsx index 83a617dcb..6bbc129c9 100644 --- a/src/components/forms/controlled/inputTypes.tsx +++ b/src/components/forms/controlled/inputTypes.tsx @@ -70,7 +70,7 @@ export const TextArea = (props: MakeControlled) => export const Radio = (props: MakeControlled) => { const {data, namespace, setInput} = useFormHelpers(); - const onChangeValue = (value: boolean | undefined) => { + const onChangeValue = (value: string) => { props.onChangeValue?.(value); setInput.field(props.name)(value); }; diff --git a/src/components/forms/uncontrolled/inputTypes.tsx b/src/components/forms/uncontrolled/inputTypes.tsx index 3e7ff3e4f..17df3dff0 100644 --- a/src/components/forms/uncontrolled/inputTypes.tsx +++ b/src/components/forms/uncontrolled/inputTypes.tsx @@ -161,7 +161,7 @@ export const Select = ({ * radio element */ type RadioProps = React.ComponentPropsWithoutRef<'input'> & InputProps & { - onChangeValue?: (value: boolean | undefined) => void; + onChangeValue?: (value: string) => void; wrapperProps?: React.ComponentPropsWithoutRef<'label'>; tooltipText?: string; }; @@ -182,8 +182,10 @@ export const Radio = ({ }: RadioProps) => { return - { - onChangeValue?.(!!e.target.checked); + { + if (e.target.checked) { + onChangeValue?.(e.target.value); + } props.onChange?.(e); }}> {label} From 27f7e894a87dc8df10a5b857f9ae3294a5a14aa1 Mon Sep 17 00:00:00 2001 From: tom Date: Tue, 30 Sep 2025 10:12:31 -0400 Subject: [PATCH 2/4] add range input --- .../forms/controlled/inputTypes.tsx | 24 +++++++++- .../forms/uncontrolled/inputType.stories.tsx | 11 ++++- .../forms/uncontrolled/inputTypes.tsx | 45 +++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/components/forms/controlled/inputTypes.tsx b/src/components/forms/controlled/inputTypes.tsx index 6bbc129c9..89cf8f18c 100644 --- a/src/components/forms/controlled/inputTypes.tsx +++ b/src/components/forms/controlled/inputTypes.tsx @@ -43,7 +43,7 @@ export const TextInput = (props: MakeControlled) return ; }; @@ -171,3 +171,25 @@ export const File = (props: MakeControlled) => { onChangeValue={onChangeValue} />; }; + +export const RangeInput = (props: MakeControlled) => { + const {data, namespace, setInput} = useFormHelpers(); + + const onChangeValue = (value: number | undefined) => { + props.onChangeValue?.(value); + setInput.field(props.name)(value); + }; + + const value = data[props.name]; + const numberValue = parseFloat((value ?? '').toString()); + const formValue = isNaN(numberValue) ? '' : numberValue; + + useEmptyDisabledValue(props, formValue, onChangeValue); + + return ; +} diff --git a/src/components/forms/uncontrolled/inputType.stories.tsx b/src/components/forms/uncontrolled/inputType.stories.tsx index 9218ac3cc..f87b196dd 100644 --- a/src/components/forms/uncontrolled/inputType.stories.tsx +++ b/src/components/forms/uncontrolled/inputType.stories.tsx @@ -1,5 +1,5 @@ import styled from "styled-components"; -import { Checkbox } from "./inputTypes"; +import { Checkbox, RangeInput } from "./inputTypes"; const CheckboxGroup = styled.div` @@ -39,4 +39,11 @@ export const disabledCheckbox = () => <> {renderCheckboxes({error: [], disabled: true, label: 'Checkbox Label', variant: 'disabled', size: 1.6})} {renderCheckboxes({error: [], disabled: true, label: 'Checkbox Label', variant: 'disabled', size: 1.8})} {renderCheckboxes({error: [], disabled: true, label: 'Checkbox Label', variant: 'disabled', size: 2.0})} -; \ No newline at end of file +; + +export const slider = () => <> + + +; diff --git a/src/components/forms/uncontrolled/inputTypes.tsx b/src/components/forms/uncontrolled/inputTypes.tsx index 17df3dff0..52f442f9f 100644 --- a/src/components/forms/uncontrolled/inputTypes.tsx +++ b/src/components/forms/uncontrolled/inputTypes.tsx @@ -273,3 +273,48 @@ export const File = ({label, help, wrapperProps, onChangeValue, uploader, value, ; }; + +const RangeInputWrapper = styled(FormInputWrapper)` + datalist { + display: flex; + justify-content: space-between; + writing-mode:unset; + flex-direction: row; + padding: 0 1em; + + option { + width: 0; + text-align: center; + display: flex; + justify-content: center; + } + } +`; +type RangeProps = React.ComponentPropsWithoutRef<'input'> & InputProps & { + wrapperProps?: React.ComponentPropsWithoutRef<'label'>; + onChangeValue?: (value: number) => void; + labels?: {value: number; label: string}[]; +}; +export const RangeInput = ({label, help, wrapperProps, onChangeValue, labels, ...props}: RangeProps) => { + const datalistId = React.useMemo(() => `datalist-${Math.random().toString(36).substring(2, 15)}`, []); + + return + {label}: + 0 ? datalistId : undefined} + onChange={e => { + const newValue = Number(e.target.value); + onChangeValue?.(newValue); + props.onChange?.(e); + }} + /> + {labels && labels.length > 0 && ( + + {labels.map(label => ( + + )} + + ; +} From bfb64e5bfbed32ebe86a34e7f62986dbd739b5f8 Mon Sep 17 00:00:00 2001 From: tom Date: Tue, 30 Sep 2025 10:30:32 -0400 Subject: [PATCH 3/4] types --- src/components/forms/uncontrolled/inputTypes.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/forms/uncontrolled/inputTypes.tsx b/src/components/forms/uncontrolled/inputTypes.tsx index 52f442f9f..50fa0374c 100644 --- a/src/components/forms/uncontrolled/inputTypes.tsx +++ b/src/components/forms/uncontrolled/inputTypes.tsx @@ -292,7 +292,7 @@ const RangeInputWrapper = styled(FormInputWrapper)` `; type RangeProps = React.ComponentPropsWithoutRef<'input'> & InputProps & { wrapperProps?: React.ComponentPropsWithoutRef<'label'>; - onChangeValue?: (value: number) => void; + onChangeValue?: (value: number | undefined) => void; labels?: {value: number; label: string}[]; }; export const RangeInput = ({label, help, wrapperProps, onChangeValue, labels, ...props}: RangeProps) => { @@ -303,8 +303,8 @@ export const RangeInput = ({label, help, wrapperProps, onChangeValue, labels, .. 0 ? datalistId : undefined} onChange={e => { - const newValue = Number(e.target.value); - onChangeValue?.(newValue); + const newValue = parseFloat(e.target.value); + onChangeValue?.(isNaN(newValue) ? undefined : newValue); props.onChange?.(e); }} /> From eb843c07ca2c5aa8bdc4e857455c501d13e07d89 Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 22 Oct 2025 16:48:43 -0400 Subject: [PATCH 4/4] correct types for controlled radio/checkboxes --- src/components/forms/controlled/inputTypes.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/forms/controlled/inputTypes.tsx b/src/components/forms/controlled/inputTypes.tsx index 89cf8f18c..8358f61e4 100644 --- a/src/components/forms/controlled/inputTypes.tsx +++ b/src/components/forms/controlled/inputTypes.tsx @@ -7,6 +7,11 @@ type MakeControlled> = name: string; emptyDisabledValue?: boolean; }; +type MakeControlledCheckbox> = + Omit, 'checked'> & { + name: string; + emptyDisabledValue?: boolean; + }; const useEmptyDisabledValue = ( props: {disabled?: boolean; emptyDisabledValue?: boolean}, @@ -67,7 +72,7 @@ export const TextArea = (props: MakeControlled) => />; }; -export const Radio = (props: MakeControlled) => { +export const Radio = (props: MakeControlledCheckbox) => { const {data, namespace, setInput} = useFormHelpers(); const onChangeValue = (value: string) => { @@ -85,7 +90,7 @@ export const Radio = (props: MakeControlled) => { />; }; -export const Checkbox = (props: MakeControlled) => { +export const Checkbox = (props: MakeControlledCheckbox) => { const {data, namespace, setInput} = useFormHelpers(); const onChangeValue = (value: boolean | undefined) => {