diff --git a/packages/grafana-ui/src/components/Combobox/Combobox.story.tsx b/packages/grafana-ui/src/components/Combobox/Combobox.story.tsx index d5846b3025a..386e6fe56b9 100644 --- a/packages/grafana-ui/src/components/Combobox/Combobox.story.tsx +++ b/packages/grafana-ui/src/components/Combobox/Combobox.story.tsx @@ -18,7 +18,7 @@ const meta: Meta = { 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 = ({ numberOfOptions, ...arg ); }; +export const AutoSize: StoryObj = { + args: { + width: 'auto', + minWidth: 5, + maxWidth: 200, + }, +}; + export const ManyOptions: StoryObj = { args: { numberOfOptions: 1e5, diff --git a/packages/grafana-ui/src/components/Combobox/Combobox.tsx b/packages/grafana-ui/src/components/Combobox/Combobox.tsx index 33eeed308eb..d38df728201 100644 --- a/packages/grafana-ui/src/components/Combobox/Combobox.tsx +++ b/packages/grafana-ui/src/components/Combobox/Combobox.tsx @@ -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 = { description?: string; }; -interface ComboboxProps - extends Omit { +interface ComboboxBaseProps + extends Omit { isClearable?: boolean; createCustomValue?: boolean; options: Array>; onChange: (option: ComboboxOption | 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 = ComboboxBaseProps & AutoSizeConditionals; + function itemToString(item: ComboboxOption | null) { return item?.label ?? item?.value.toString() ?? ''; } @@ -54,6 +73,7 @@ export const Combobox = ({ isClearable = false, createCustomValue = false, id, + width, 'aria-labelledby': ariaLabelledBy, ...restProps }: ComboboxProps) => { @@ -158,9 +178,12 @@ export const Combobox = ({ setInputValue(selectedItem?.label ?? value?.toString() ?? ''); }, [selectedItem, setInputValue, value]); + const InputComponent = width === 'auto' ? AutoSizeInput : Input; + return (
- {!!value && value === selectedItem?.value && isClearable && (