Skip to content

Commit e88acca

Browse files
authored
fix(Field): id generation (#824)
1 parent a419ac6 commit e88acca

File tree

21 files changed

+112
-56
lines changed

21 files changed

+112
-56
lines changed

.changeset/mighty-mails-float.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cube-dev/ui-kit": patch
3+
---
4+
5+
Generate id even for input components that are not connected to a form.

.changeset/quick-tools-kiss.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cube-dev/ui-kit": patch
3+
---
4+
5+
Prevent form prop from leaking to the DOM.

.cursor/rules/coding.mdc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ alwaysApply: true
1414

1515
- Use named imports from react (like `useCallback`) instead of using the `React` instance. Avoid: `React.useCallback`.
1616
- Prefer stable `useEvent` callbacks when it's possible.
17+
18+
# Knowledge rules
19+
- If you find any essential knowledge that is not yet listed anywhere, then add it to Claude.md file in the nearest folder this knowledge applies to. Create file if it's not yet exist. Make sure this essential knowledge is as compact as possible.

src/components/fields/Checkbox/Checkbox.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ function Checkbox(
142142
labelPosition,
143143
inputStyles,
144144
isHidden,
145+
form,
145146
...otherProps
146147
} = props;
147148

src/components/fields/Checkbox/CheckboxGroup.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ function CheckboxGroup(props: WithNullableValue<CubeCheckboxGroupProps>, ref) {
8282
labelProps: baseLabelProps,
8383
labelSuffix,
8484
inputStyles,
85+
form,
8586
...otherProps
8687
} = props;
8788
let domRef = useDOMRef(ref);

src/components/fields/ComboBox/ComboBox.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import React, {
88
RefObject,
99
useCallback,
1010
useEffect,
11-
useId,
1211
useMemo,
1312
useRef,
1413
useState,
@@ -1031,13 +1030,10 @@ export const ComboBox = forwardRef(function ComboBox<T extends object>(
10311030
onFocus,
10321031
onBlur,
10331032
onKeyDown,
1033+
form,
10341034
...otherProps
10351035
} = props;
10361036

1037-
// Generate ID for label-input linking if not provided
1038-
const generatedId = useId();
1039-
const inputId = id || generatedId;
1040-
10411037
// Generate a unique ID for this combobox instance
10421038
const comboBoxId = useMemo(() => generateRandomId(), []);
10431039

@@ -1580,7 +1576,7 @@ export const ComboBox = forwardRef(function ComboBox<T extends object>(
15801576
{prefix ? <div data-element="Prefix">{prefix}</div> : null}
15811577
<ComboBoxInput
15821578
inputRef={inputRef}
1583-
id={inputId}
1579+
id={id}
15841580
value={effectiveInputValue}
15851581
placeholder={placeholder}
15861582
isDisabled={isDisabled}
@@ -1688,7 +1684,6 @@ export const ComboBox = forwardRef(function ComboBox<T extends object>(
16881684
const finalProps = {
16891685
...propsWithoutChildren,
16901686
styles: fieldStyles,
1691-
labelProps: { ...props.labelProps, for: inputId },
16921687
};
16931688

16941689
return wrapWithField<Omit<CubeComboBoxProps<T>, 'children'>>(

src/components/fields/FileInput/FileInput.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ function FileInput(props: CubeFileInputProps, ref) {
174174
type = 'file',
175175
inputProps,
176176
accept,
177+
form,
177178
...otherProps
178179
} = props;
179180

src/components/fields/FilterListBox/FilterListBox.tsx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import React, {
66
ReactNode,
77
RefObject,
88
useCallback,
9-
useId,
109
useLayoutEffect,
1110
useMemo,
1211
useRef,
@@ -276,13 +275,10 @@ export const FilterListBox = forwardRef(function FilterListBox<
276275
searchValue: controlledSearchValue,
277276
onSearchChange,
278277
_internalCollection,
278+
form,
279279
...otherProps
280280
} = props;
281281

282-
// Generate ID for label-input linking if not provided
283-
const generatedId = useId();
284-
const inputId = id || generatedId;
285-
286282
// Preserve the original `children` (may be a render function) before we
287283
// potentially overwrite it.
288284
let children: ReactNode = renderChildren as ReactNode;
@@ -909,7 +905,7 @@ export const FilterListBox = forwardRef(function FilterListBox<
909905
)}
910906
<SearchInputElement
911907
ref={searchInputRef}
912-
id={inputId}
908+
id={id}
913909
data-is-prefix={isLoading ? '' : undefined}
914910
type="search"
915911
placeholder={searchPlaceholder}
@@ -1006,14 +1002,6 @@ export const FilterListBox = forwardRef(function FilterListBox<
10061002

10071003
const finalProps = { ...props, styles: undefined };
10081004

1009-
// Ensure labelProps has the for attribute for label-input linking
1010-
if (!finalProps.labelProps) {
1011-
finalProps.labelProps = {};
1012-
}
1013-
if (!finalProps.labelProps.for) {
1014-
finalProps.labelProps.for = inputId;
1015-
}
1016-
10171005
return wrapWithField<Omit<CubeFilterListBoxProps<T>, 'children'>>(
10181006
filterListBoxField,
10191007
ref,

src/components/fields/FilterPicker/FilterPicker.tsx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
RefObject,
88
useCallback,
99
useEffect,
10-
useId,
1110
useMemo,
1211
useRef,
1312
useState,
@@ -250,6 +249,7 @@ export const FilterPicker = forwardRef(function FilterPicker<T extends object>(
250249
searchValue,
251250
onSearchChange,
252251
sortSelectedToTop: sortSelectedToTopProp,
252+
form,
253253
...otherProps
254254
} = props;
255255

@@ -260,10 +260,6 @@ export const FilterPicker = forwardRef(function FilterPicker<T extends object>(
260260

261261
styles = extractStyles(otherProps, PROP_STYLES, styles);
262262

263-
// Generate ID for label-trigger linking if not provided
264-
const generatedId = useId();
265-
const triggerId = id || generatedId;
266-
267263
// Generate a unique ID for this FilterPicker instance
268264
const filterPickerId = useMemo(() => generateRandomId(), []);
269265

@@ -727,7 +723,7 @@ export const FilterPicker = forwardRef(function FilterPicker<T extends object>(
727723
<ItemButton
728724
ref={triggerRef as any}
729725
data-popover-trigger
730-
id={triggerId}
726+
id={id}
731727
type={type}
732728
theme={validationState === 'invalid' ? 'danger' : theme}
733729
size={size}
@@ -952,14 +948,6 @@ export const FilterPicker = forwardRef(function FilterPicker<T extends object>(
952948
styles: undefined,
953949
};
954950

955-
// Ensure labelProps has the for attribute for label-trigger linking
956-
if (!finalProps.labelProps) {
957-
finalProps.labelProps = {};
958-
}
959-
if (!finalProps.labelProps.for) {
960-
finalProps.labelProps.for = triggerId;
961-
}
962-
963951
return wrapWithField<Omit<CubeFilterPickerProps<T>, 'children' | 'tooltip'>>(
964952
filterPickerField,
965953
ref as any,

src/components/fields/LegacyComboBox/LegacyComboBox.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ export const LegacyComboBox = forwardRef(function LegacyComboBox<
208208
selectedKey,
209209
defaultSelectedKey,
210210
isClearable,
211+
form,
211212
...otherProps
212213
} = props;
213214

0 commit comments

Comments
 (0)