New Select: decrease item height (#95952)

pull/96456/head
Laura Fernández 6 months ago committed by GitHub
parent c8aaefd54a
commit 6a8755a8af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      packages/grafana-ui/src/components/Combobox/Combobox.test.tsx
  2. 16
      packages/grafana-ui/src/components/Combobox/Combobox.tsx
  3. 13
      packages/grafana-ui/src/components/Combobox/getComboboxStyles.ts
  4. 16
      packages/grafana-ui/src/components/Combobox/useComboboxFloat.ts
  5. 2
      public/locales/en-US/grafana.json
  6. 2
      public/locales/pseudo-LOCALE/grafana.json

@ -166,7 +166,7 @@ describe('Combobox', () => {
expect(onChangeHandler).toHaveBeenCalledWith(expect.objectContaining({ value: 'custom value' }));
});
it('should proivde custom string when all options are numbers', async () => {
it('should provide custom string when all options are numbers', async () => {
const options = [
{ label: '1', value: 1 },
{ label: '2', value: 2 },
@ -333,7 +333,7 @@ describe('Combobox', () => {
jest.advanceTimersByTime(500); // Custom value while typing
});
const customItem = screen.queryByRole('option', { name: 'fir Create custom value' });
const customItem = screen.queryByRole('option', { name: 'Custom value: fir' });
expect(customItem).toBeInTheDocument();
});

@ -13,8 +13,8 @@ import { Box } from '../Layout/Box/Box';
import { Stack } from '../Layout/Stack/Stack';
import { ScrollContainer } from '../ScrollContainer/ScrollContainer';
import { getComboboxStyles } from './getComboboxStyles';
import { useComboboxFloat, OPTION_HEIGHT } from './useComboboxFloat';
import { getComboboxStyles, MENU_OPTION_HEIGHT } from './getComboboxStyles';
import { useComboboxFloat } from './useComboboxFloat';
import { StaleResultError, useLatestAsyncCall } from './useLatestAsyncCall';
export type ComboboxOption<T extends string | number = string> = {
@ -69,6 +69,9 @@ type AutoSizeConditionals =
type ComboboxProps<T extends string | number> = ComboboxBaseProps<T> & AutoSizeConditionals;
function itemToString<T extends string | number>(item: ComboboxOption<T> | null) {
if (item?.label?.includes('Custom value: ')) {
return item?.value.toString();
}
return item?.label ?? item?.value.toString() ?? '';
}
@ -122,13 +125,18 @@ export const Combobox = <T extends string | number>(props: ComboboxProps<T>) =>
let itemsToSet = items;
if (inputValue && createCustomValue) {
const optionMatchingInput = items.find((opt) => opt.label === inputValue || opt.value === inputValue);
const optionMatchingInput = items.find(
(opt) => opt.label === 'Custom value: ' + inputValue || opt.value === inputValue
);
if (!optionMatchingInput) {
const customValueOption = {
label: t('combobox.custom-value.label', 'Custom value: ') + inputValue,
// Type casting needed to make this work when T is a number
value: inputValue as unknown as T,
/* TODO: Add this back when we do support descriptions and have need for it
description: t('combobox.custom-value.create', 'Create custom value'),
*/
};
itemsToSet = items.slice(0);
@ -174,7 +182,7 @@ export const Combobox = <T extends string | number>(props: ComboboxProps<T>) =>
const virtualizerOptions = {
count: items.length,
getScrollElement: () => scrollRef.current,
estimateSize: () => OPTION_HEIGHT,
estimateSize: () => MENU_OPTION_HEIGHT,
overscan: 4,
};

@ -6,7 +6,12 @@ import { GrafanaTheme2 } from '@grafana/data';
// This should be in sync with the body font size in the theme.
export const MENU_ITEM_FONT_SIZE = 14;
export const MENU_ITEM_FONT_WEIGHT = 500;
export const MENU_ITEM_PADDING_X = 8;
export const MENU_ITEM_PADDING = 8;
export const MENU_ITEM_LINE_HEIGHT = 1.5;
// Used with Downshift to get the height of each item
export const MENU_OPTION_HEIGHT = MENU_ITEM_PADDING * 2 + MENU_ITEM_FONT_SIZE * MENU_ITEM_LINE_HEIGHT;
export const POPOVER_MAX_HEIGHT = MENU_OPTION_HEIGHT * 8.5;
export const getComboboxStyles = (theme: GrafanaTheme2) => {
return {
@ -27,7 +32,7 @@ export const getComboboxStyles = (theme: GrafanaTheme2) => {
}),
option: css({
label: 'grafana-select-option',
padding: MENU_ITEM_PADDING_X,
padding: MENU_ITEM_PADDING,
position: 'absolute',
display: 'flex',
alignItems: 'center',
@ -65,7 +70,7 @@ export const getComboboxStyles = (theme: GrafanaTheme2) => {
fontWeight: 'normal',
fontSize: theme.typography.bodySmall.fontSize,
color: theme.colors.text.secondary,
lineHeight: theme.typography.body.lineHeight,
lineHeight: MENU_ITEM_LINE_HEIGHT,
textOverflow: 'ellipsis',
overflow: 'hidden',
}),
@ -84,7 +89,7 @@ export const getComboboxStyles = (theme: GrafanaTheme2) => {
borderRadius: theme.shape.radius.default,
content: '" "',
display: 'block',
height: '100%',
height: MENU_OPTION_HEIGHT,
position: 'absolute',
width: theme.spacing(0.5),
left: 0,

@ -4,15 +4,17 @@ import { useMemo, useRef, useState } from 'react';
import { measureText } from '../../utils';
import { ComboboxOption } from './Combobox';
import { MENU_ITEM_FONT_SIZE, MENU_ITEM_FONT_WEIGHT, MENU_ITEM_PADDING_X } from './getComboboxStyles';
import {
MENU_ITEM_FONT_SIZE,
MENU_ITEM_FONT_WEIGHT,
MENU_ITEM_PADDING,
MENU_OPTION_HEIGHT,
POPOVER_MAX_HEIGHT,
} from './getComboboxStyles';
// Only consider the first n items when calculating the width of the popover.
const WIDTH_CALCULATION_LIMIT_ITEMS = 100_000;
// Used with Downshift to get the height of each item
export const OPTION_HEIGHT = 45;
const POPOVER_MAX_HEIGHT = OPTION_HEIGHT * 8.5;
// Clearance around the popover to prevent it from being too close to the edge of the viewport
const POPOVER_PADDING = 16;
@ -41,7 +43,7 @@ export const useComboboxFloat = (
const preferredMaxHeight = availableHeight - POPOVER_PADDING;
const width = Math.max(preferredMaxWidth, 0);
const height = Math.min(Math.max(preferredMaxHeight, OPTION_HEIGHT * 6), POPOVER_MAX_HEIGHT);
const height = Math.min(Math.max(preferredMaxHeight, MENU_OPTION_HEIGHT * 6), POPOVER_MAX_HEIGHT);
setPopoverMaxSize({ width, height });
},
@ -68,7 +70,7 @@ export const useComboboxFloat = (
const size = measureText(longestItem, MENU_ITEM_FONT_SIZE, MENU_ITEM_FONT_WEIGHT).width;
return size + MENU_ITEM_PADDING_X * 2 + scrollbarWidth;
return size + MENU_ITEM_PADDING * 2 + scrollbarWidth;
}, [items, scrollbarWidth]);
const floatStyles = {

@ -455,7 +455,7 @@
"title": "Clear value"
},
"custom-value": {
"create": "Create custom value"
"label": "Custom value: "
},
"options": {
"no-found": "No options found."

@ -455,7 +455,7 @@
"title": "Cľęäř väľūę"
},
"custom-value": {
"create": "Cřęäŧę čūşŧőm väľūę"
"label": "Cūşŧőm väľūę: "
},
"options": {
"no-found": "Ńő őpŧįőʼnş ƒőūʼnđ."

Loading…
Cancel
Save