From e48d166c3eed99f6e849c29f03127e891d9d0d46 Mon Sep 17 00:00:00 2001 From: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:45:22 +0200 Subject: [PATCH] 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 --- .../components/Combobox/Combobox.story.tsx | 10 ++++++- .../src/components/Combobox/Combobox.tsx | 29 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) 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 && (