From 8288e5ac85cc93062a0a0d4271f02870b1ba3063 Mon Sep 17 00:00:00 2001 From: Johan Persson Date: Thu, 26 Feb 2026 11:22:05 +0100 Subject: [PATCH] Migrate Select component from useStyles to useDefinition Signed-off-by: Johan Persson --- packages/ui/report.api.md | 47 +++++--- packages/ui/src/components/Select/Select.tsx | 31 ++--- .../src/components/Select/SelectContent.tsx | 32 ++---- .../src/components/Select/SelectListBox.tsx | 40 +++---- .../src/components/Select/SelectTrigger.tsx | 19 ++- .../ui/src/components/Select/definition.ts | 108 +++++++++++++++--- packages/ui/src/components/Select/types.ts | 15 ++- 7 files changed, 175 insertions(+), 117 deletions(-) diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index 962706f818..a94dfd359b 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -1962,36 +1962,49 @@ export const Select: ForwardRefExoticComponent< // @public export const SelectDefinition: { + readonly styles: { + readonly [key: string]: string; + }; readonly classNames: { readonly root: 'bui-Select'; readonly popover: 'bui-SelectPopover'; - readonly trigger: 'bui-SelectTrigger'; - readonly chevron: 'bui-SelectTriggerChevron'; - readonly value: 'bui-SelectValue'; - readonly list: 'bui-SelectList'; - readonly item: 'bui-SelectItem'; - readonly itemIndicator: 'bui-SelectItemIndicator'; - readonly itemLabel: 'bui-SelectItemLabel'; - readonly searchWrapper: 'bui-SelectSearchWrapper'; - readonly search: 'bui-SelectSearch'; - readonly searchClear: 'bui-SelectSearchClear'; - readonly noResults: 'bui-SelectNoResults'; }; - readonly dataAttributes: { - readonly size: readonly ['small', 'medium']; + readonly propDefs: { + readonly icon: {}; + readonly size: { + readonly dataAttribute: true; + readonly default: 'small'; + }; + readonly options: {}; + readonly searchable: {}; + readonly searchPlaceholder: {}; + readonly label: {}; + readonly secondaryLabel: {}; + readonly description: {}; + readonly isRequired: {}; + readonly className: {}; }; }; // @public (undocumented) -export interface SelectProps - extends SelectProps_2, - Omit { +export type SelectOwnProps = { icon?: ReactNode; + size?: 'small' | 'medium' | Partial>; options?: Array; searchable?: boolean; searchPlaceholder?: string; + label?: FieldLabelProps['label']; + secondaryLabel?: FieldLabelProps['secondaryLabel']; + description?: FieldLabelProps['description']; + isRequired?: boolean; + className?: string; +}; + +// @public (undocumented) +export interface SelectProps + extends SelectOwnProps, + Omit, keyof SelectOwnProps> { selectionMode?: T; - size?: 'small' | 'medium' | Partial>; } // @public (undocumented) diff --git a/packages/ui/src/components/Select/Select.tsx b/packages/ui/src/components/Select/Select.tsx index 04231d1cd9..48fd08184c 100644 --- a/packages/ui/src/components/Select/Select.tsx +++ b/packages/ui/src/components/Select/Select.tsx @@ -18,13 +18,11 @@ import { forwardRef, useEffect } from 'react'; import { Select as AriaSelect, Popover } from 'react-aria-components'; import clsx from 'clsx'; import { SelectProps } from './types'; -import { useStyles } from '../../hooks/useStyles'; +import { useDefinition } from '../../hooks/useDefinition'; import { SelectDefinition } from './definition'; import { PopoverDefinition } from '../Popover/definition'; import { FieldLabel } from '../FieldLabel'; import { FieldError } from '../FieldError'; -import styles from './Select.module.css'; -import stylesPopover from '../Popover/Popover.module.css'; import { SelectTrigger } from './SelectTrigger'; import { SelectContent } from './SelectContent'; @@ -33,30 +31,28 @@ export const Select = forwardRef< HTMLDivElement, SelectProps<'single' | 'multiple'> >((props, ref) => { - const { classNames: popoverClassNames } = useStyles(PopoverDefinition); - const { classNames, dataAttributes, cleanedProps } = useStyles( + const { ownProps, restProps, dataAttributes } = useDefinition( SelectDefinition, { - size: 'small', placeholder: 'Select an option', ...props, }, ); const { - className, + classes, label, description, options, icon, searchable, searchPlaceholder, - 'aria-label': ariaLabel, - 'aria-labelledby': ariaLabelledBy, isRequired, secondaryLabel, - ...rest - } = cleanedProps; + } = ownProps; + + const ariaLabel = restProps['aria-label']; + const ariaLabelledBy = restProps['aria-labelledby']; useEffect(() => { if (!label && !ariaLabel && !ariaLabelledBy) { @@ -70,12 +66,10 @@ export const Select = forwardRef< return ( diff --git a/packages/ui/src/components/Select/SelectContent.tsx b/packages/ui/src/components/Select/SelectContent.tsx index b14acb3c48..2797e92d2d 100644 --- a/packages/ui/src/components/Select/SelectContent.tsx +++ b/packages/ui/src/components/Select/SelectContent.tsx @@ -22,11 +22,9 @@ import { } from 'react-aria-components'; import { useFilter } from 'react-aria'; import { RiCloseCircleLine } from '@remixicon/react'; -import clsx from 'clsx'; -import { useStyles } from '../../hooks/useStyles'; -import { SelectDefinition } from './definition'; +import { useDefinition } from '../../hooks/useDefinition'; +import { SelectContentDefinition } from './definition'; import { SelectListBox } from './SelectListBox'; -import styles from './Select.module.css'; import type { Option } from './types'; interface SelectContentProps { @@ -35,13 +33,10 @@ interface SelectContentProps { options?: Array