New Select: width auto sets width based on content (#93800)

* Add inline prop for AutoSizeInput

* Rename to autoSize

* Use conditional props and width auto

* remove variable

* Remove 100% max width
This commit is contained in:
Tobias Skarhed 2024-10-03 10:45:22 +02:00 committed by GitHub
parent bd1741653d
commit e48d166c3e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 4 deletions

View File

@ -18,7 +18,7 @@ const meta: Meta<PropsAndCustomArgs> = {
args: {
loading: undefined,
invalid: undefined,
width: 30,
width: undefined,
placeholder: 'Select an option...',
options: [
{ label: 'Apple', value: 'apple' },
@ -107,6 +107,14 @@ const ManyOptionsStory: StoryFn<PropsAndCustomArgs> = ({ numberOfOptions, ...arg
);
};
export const AutoSize: StoryObj<PropsAndCustomArgs> = {
args: {
width: 'auto',
minWidth: 5,
maxWidth: 200,
},
};
export const ManyOptions: StoryObj<PropsAndCustomArgs> = {
args: {
numberOfOptions: 1e5,

View File

@ -6,6 +6,7 @@ import { useCallback, useId, useMemo, useState } from 'react';
import { useStyles2 } from '../../themes';
import { t } from '../../utils/i18n';
import { Icon } from '../Icon/Icon';
import { AutoSizeInput } from '../Input/AutoSizeInput';
import { Input, Props as InputProps } from '../Input/Input';
import { getComboboxStyles } from './getComboboxStyles';
@ -17,15 +18,33 @@ export type ComboboxOption<T extends string | number = string> = {
description?: string;
};
interface ComboboxProps<T extends string | number>
extends Omit<InputProps, 'prefix' | 'suffix' | 'value' | 'addonBefore' | 'addonAfter' | 'onChange'> {
interface ComboboxBaseProps<T extends string | number>
extends Omit<InputProps, 'prefix' | 'suffix' | 'value' | 'addonBefore' | 'addonAfter' | 'onChange' | 'width'> {
isClearable?: boolean;
createCustomValue?: boolean;
options: Array<ComboboxOption<T>>;
onChange: (option: ComboboxOption<T> | null) => void;
value: T | null;
/**
* Defaults to 100%. Number is a multiple of 8px. 'auto' will size the input to the content.
* */
width?: number | 'auto';
}
type AutoSizeConditionals =
| {
width: 'auto';
minWidth: number;
maxWidth?: number;
}
| {
width?: number;
minWidth?: never;
maxWidth?: never;
};
type ComboboxProps<T extends string | number> = ComboboxBaseProps<T> & AutoSizeConditionals;
function itemToString(item: ComboboxOption<string | number> | null) {
return item?.label ?? item?.value.toString() ?? '';
}
@ -54,6 +73,7 @@ export const Combobox = <T extends string | number>({
isClearable = false,
createCustomValue = false,
id,
width,
'aria-labelledby': ariaLabelledBy,
...restProps
}: ComboboxProps<T>) => {
@ -158,9 +178,12 @@ export const Combobox = <T extends string | number>({
setInputValue(selectedItem?.label ?? value?.toString() ?? '');
}, [selectedItem, setInputValue, value]);
const InputComponent = width === 'auto' ? AutoSizeInput : Input;
return (
<div>
<Input
<InputComponent
width={width === 'auto' ? undefined : width}
suffix={
<>
{!!value && value === selectedItem?.value && isClearable && (