From d8e0c2978619e95920e387cc024ed7a7614cac80 Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Mon, 17 Nov 2025 15:00:21 +0100 Subject: [PATCH 01/24] feat: data-input-type attribute for field components --- .changeset/tidy-laws-repair.md | 5 +++++ src/components/fields/Checkbox/Checkbox.tsx | 5 +++-- src/components/fields/ComboBox/ComboBox.tsx | 1 + .../fields/DatePicker/DateInput.tsx | 3 +++ .../fields/DatePicker/DateInputBase.tsx | 6 ++++++ .../fields/DatePicker/DatePicker.tsx | 3 +++ .../fields/DatePicker/DateRangePicker.tsx | 3 +++ .../DatePicker/DateRangeSeparatedPicker.tsx | 3 +++ .../fields/DatePicker/TimeInput.tsx | 3 +++ src/components/fields/FileInput/FileInput.tsx | 3 ++- .../fields/FilterListBox/FilterListBox.tsx | 1 + .../fields/FilterPicker/FilterPicker.tsx | 1 + src/components/fields/Input/Input.tsx | 21 +++++++------------ src/components/fields/ListBox/ListBox.tsx | 1 + .../fields/NumberInput/NumberInput.tsx | 2 +- .../fields/PasswordInput/PasswordInput.tsx | 2 +- src/components/fields/Picker/Picker.tsx | 1 + src/components/fields/RadioGroup/Radio.tsx | 2 ++ .../fields/RadioGroup/RadioGroup.tsx | 3 +++ .../fields/SearchInput/SearchInput.tsx | 2 +- src/components/fields/Select/Select.tsx | 1 + src/components/fields/Slider/SliderBase.tsx | 8 ++++++- src/components/fields/Switch/Switch.tsx | 12 ++++------- src/components/fields/TextArea/TextArea.tsx | 2 +- .../fields/TextInput/TextInputBase.tsx | 1 + .../TextInputMapper/TextInputMapper.tsx | 10 ++++++++- 26 files changed, 74 insertions(+), 31 deletions(-) create mode 100644 .changeset/tidy-laws-repair.md diff --git a/.changeset/tidy-laws-repair.md b/.changeset/tidy-laws-repair.md new file mode 100644 index 000000000..eb498ac9d --- /dev/null +++ b/.changeset/tidy-laws-repair.md @@ -0,0 +1,5 @@ +--- +"@cube-dev/ui-kit": minor +--- + +Specify `data-input-type` attribute for each field component and improve `qa` prop handling in various field components for consistency. diff --git a/src/components/fields/Checkbox/Checkbox.tsx b/src/components/fields/Checkbox/Checkbox.tsx index b5710cfe4..e531d5bac 100644 --- a/src/components/fields/Checkbox/Checkbox.tsx +++ b/src/components/fields/Checkbox/Checkbox.tsx @@ -230,11 +230,12 @@ function Checkbox( const checkbox = ( <> - + {markIcon} diff --git a/src/components/fields/ComboBox/ComboBox.tsx b/src/components/fields/ComboBox/ComboBox.tsx index f704f5bfc..c7714d128 100644 --- a/src/components/fields/ComboBox/ComboBox.tsx +++ b/src/components/fields/ComboBox/ComboBox.tsx @@ -760,6 +760,7 @@ const ComboBoxInput = forwardRef( styles={inputStyles} mods={mods} data-size={size} + data-input-type="combobox" role="combobox" aria-expanded={isPopoverOpen && hasResults} aria-haspopup="listbox" diff --git a/src/components/fields/DatePicker/DateInput.tsx b/src/components/fields/DatePicker/DateInput.tsx index 561bc456d..5e88a3557 100644 --- a/src/components/fields/DatePicker/DateInput.tsx +++ b/src/components/fields/DatePicker/DateInput.tsx @@ -56,6 +56,7 @@ function DateInput( props = Object.assign({}, DEFAULT_DATE_PROPS, props); let { + qa, autoFocus, isDisabled, inputStyles, @@ -86,6 +87,8 @@ function DateInput( const component = ( ( let styles = extractStyles(props, CONTAINER_STYLES); let { + qa, size, placeholderValue, isDisabled, @@ -119,6 +120,8 @@ function DatePicker( const component = ( ( let styles = extractStyles(props, CONTAINER_STYLES); let { + qa, size, shouldFlip, placeholderValue, @@ -131,6 +132,8 @@ function DateRangePicker( const component = ( ( let styles = extractStyles(props, CONTAINER_STYLES); let { + qa, size, placeholderValue, isDisabled, @@ -181,6 +182,8 @@ function DateRangeSeparatedPicker( const component = ( ( let styles = extractStyles(props, CONTAINER_STYLES); let { + qa, inputStyles, wrapperStyles, autoFocus, @@ -93,6 +94,8 @@ function TimeInput( const timeInput = ( ( theme={validationState === 'invalid' ? 'danger' : theme} size={size} isDisabled={isDisabled || isLoading} + data-input-type="filterpicker" mods={{ placeholder: !hasSelection, ...externalMods, diff --git a/src/components/fields/Input/Input.tsx b/src/components/fields/Input/Input.tsx index d8af62e4b..6adc65cc9 100644 --- a/src/components/fields/Input/Input.tsx +++ b/src/components/fields/Input/Input.tsx @@ -1,5 +1,3 @@ -import { ForwardedRef, forwardRef } from 'react'; - import { FileInput } from '../FileInput/FileInput'; import { NumberInput } from '../NumberInput/NumberInput'; import { PasswordInput } from '../PasswordInput/PasswordInput'; @@ -14,15 +12,10 @@ type CubeInput = typeof TextInput & { File: typeof FileInput; }; -export const Input: CubeInput = Object.assign( - forwardRef(function Input(props, ref: ForwardedRef) { - return ; - }), - { - Text: TextInput, - Password: PasswordInput, - Number: NumberInput, - TextArea: TextArea, - File: FileInput, - }, -); +export const Input: CubeInput = Object.assign(TextInput, { + Text: TextInput, + Password: PasswordInput, + Number: NumberInput, + TextArea: TextArea, + File: FileInput, +}); diff --git a/src/components/fields/ListBox/ListBox.tsx b/src/components/fields/ListBox/ListBox.tsx index 7e5106173..5dba3bf5f 100644 --- a/src/components/fields/ListBox/ListBox.tsx +++ b/src/components/fields/ListBox/ListBox.tsx @@ -919,6 +919,7 @@ export const ListBox = forwardRef(function ListBox( aria-disabled={isDisabled || undefined} mods={{ sections: hasSections }} data-shape={shape} + data-input-type="listbox" style={ shouldVirtualize ? { diff --git a/src/components/fields/NumberInput/NumberInput.tsx b/src/components/fields/NumberInput/NumberInput.tsx index 0fd93e564..ef3e6fbce 100644 --- a/src/components/fields/NumberInput/NumberInput.tsx +++ b/src/components/fields/NumberInput/NumberInput.tsx @@ -91,7 +91,7 @@ function NumberInput( {...otherProps} ref={ref} labelProps={labelProps} - inputProps={inputProps} + inputProps={{ ...inputProps, 'data-input-type': 'numberinput' }} inputRef={inputRef} wrapperProps={groupProps} suffixPosition="after" diff --git a/src/components/fields/PasswordInput/PasswordInput.tsx b/src/components/fields/PasswordInput/PasswordInput.tsx index 394f55cc3..19591d54c 100644 --- a/src/components/fields/PasswordInput/PasswordInput.tsx +++ b/src/components/fields/PasswordInput/PasswordInput.tsx @@ -61,7 +61,7 @@ function PasswordInput( ( theme={validationState === 'invalid' ? 'danger' : theme} size={size} isDisabled={isDisabled || isLoading} + data-input-type="picker" mods={{ placeholder: !hasSelection, ...externalMods, diff --git a/src/components/fields/RadioGroup/Radio.tsx b/src/components/fields/RadioGroup/Radio.tsx index de675e481..3923093fc 100644 --- a/src/components/fields/RadioGroup/Radio.tsx +++ b/src/components/fields/RadioGroup/Radio.tsx @@ -315,6 +315,7 @@ function Radio(props: CubeRadioProps, ref) { > , ref) { props = useFieldProps(props, { defaultValidationTrigger: 'onChange' }); let { + qa, isDisabled, isRequired, labelPosition = 'top', @@ -122,7 +123,9 @@ function RadioGroup(props: WithNullableValue, ref) { let radioGroup = ( } diff --git a/src/components/fields/Select/Select.tsx b/src/components/fields/Select/Select.tsx index 909670d01..2d5072b96 100644 --- a/src/components/fields/Select/Select.tsx +++ b/src/components/fields/Select/Select.tsx @@ -423,6 +423,7 @@ function Select( data-size={size} data-type={type} data-theme={theme} + data-input-type="select" > ) { styles = extractStyles(otherProps, OUTER_STYLES, styles); const sliderField = ( - + {children({ trackRef, diff --git a/src/components/fields/Switch/Switch.tsx b/src/components/fields/Switch/Switch.tsx index 5ff80febf..cab989a61 100644 --- a/src/components/fields/Switch/Switch.tsx +++ b/src/components/fields/Switch/Switch.tsx @@ -189,24 +189,20 @@ function Switch(props: WithNullableSelected, ref) { const switchField = ( - +