diff --git a/src/components/Select/Select.module.scss b/src/components/Select/Select.module.scss index c1a6639..440f0b0 100644 --- a/src/components/Select/Select.module.scss +++ b/src/components/Select/Select.module.scss @@ -14,8 +14,6 @@ user-select: none; width: 100%; - min-height: var(--min-height); - padding: calc(0.5rem - var(--border-width)) calc(0.75rem - var(--border-width)); &[data-clearable="true"] { border-top-right-radius: 0; diff --git a/src/components/Select/Select.stories.tsx b/src/components/Select/Select.stories.tsx index 31aa1b8..ba38be9 100644 --- a/src/components/Select/Select.stories.tsx +++ b/src/components/Select/Select.stories.tsx @@ -27,6 +27,12 @@ const meta: Meta = { table: { category: 'Behavior' }, }, onChange: { table: { disable: true } }, + size: { + control: 'select', + options: ['small', 'normal', 'large'], + description: 'The size of the select.', + table: { category: 'Appearance' }, + }, value: { table: { disable: true } }, }, }; @@ -38,6 +44,7 @@ export const Text: Story = { name: 'Text', args: { disabled: false, + size: 'normal', options: [ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, @@ -53,6 +60,7 @@ export const Numeric: Story = { name: 'Numeric', args: { disabled: false, + size: 'normal', options: [ { value: 1, label: 'Critical' }, { value: 2, label: 'High' }, @@ -68,6 +76,7 @@ export const CustomItemComponents: Story = { name: 'Custom Item Components', args: { disabled: false, + size: 'normal', options: [ { value: '7b90a423-1979-4e61-a30b-b19d663b3e43', @@ -94,6 +103,7 @@ export const ControlledValue: Story = { }, args: { disabled: false, + size: 'normal', options: [ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, @@ -109,6 +119,7 @@ export const ManyItems: Story = { name: 'Many (200+) Items', args: { disabled: false, + size: 'normal', options: Array.from({ length: 200 }, (_, i) => ({ value: i + 1, label: `Item ${i + 1}`, diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx index 6cca790..010859c 100644 --- a/src/components/Select/Select.tsx +++ b/src/components/Select/Select.tsx @@ -14,6 +14,7 @@ import { ChevronUp, } from 'lucide-react'; +import { ElementSize } from '../../types'; import { getStyleClassNames, sx } from '../../utils/getStyleClassNames'; import styles from './Select.module.scss'; @@ -34,6 +35,7 @@ export interface SelectProps extends Omit< 'multiple' | 'onChange' | 'placeholder' | + 'size' | 'value' > { defaultValue?: SelectValue | null; @@ -42,6 +44,7 @@ export interface SelectProps extends Omit< onChange?: (value: SelectValue | null) => void; options: SelectOption[]; placeholder?: ReactNode; + size?: ElementSize; value?: SelectValue | null; } @@ -58,6 +61,7 @@ export const Select = forwardRef(({ placeholder = 'Select...', readOnly, required, + size = 'normal', type: _type, value, ...triggerProps @@ -82,11 +86,16 @@ export const Select = forwardRef(({ intent: 'secondary', variant: 'ghost', border: true, + size, }), className)} > {(val: SelectValue | null) => { - const opt = options.find((o) => o.value === val) ?? null; + + /* BaseUI may pass undefined instead of null when the selected value is null, so use loose + * equality for null-valued options to match both. + */ + const opt = options.find((o) => (o.value === null ? val == null : o.value === val)) ?? null; if (opt === null) { return placeholder; } diff --git a/src/style/sizes.module.scss b/src/style/sizes.module.scss index 4c257a5..1c987f7 100644 --- a/src/style/sizes.module.scss +++ b/src/style/sizes.module.scss @@ -19,7 +19,9 @@ box-sizing: border-box; min-width: $size; min-height: $size; - padding: calc(#{$padding} - var(--border-width)); // Assume always used with variants (1px border, even if invisible) + + // Assume always used with variants (1px border, even if invisible) + padding: calc(#{$padding} - var(--border-width)) calc(#{$padding} + 0.125rem - var(--border-width)); &.collapse-padding { margin: 0 calc($padding * -1);