Skip to content

Commit

Permalink
Combobox: Remove circular dependency caused by ComboboxOption type (g…
Browse files Browse the repository at this point in the history
  • Loading branch information
joshhunt authored Jan 27, 2025
1 parent 6e705ee commit 6edd4f5
Show file tree
Hide file tree
Showing 13 changed files with 24 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import React, { useEffect, useState } from 'react';
import { Alert } from '../Alert/Alert';
import { Field } from '../Forms/Field';

import { Combobox, ComboboxOption, ComboboxProps } from './Combobox';
import { Combobox, ComboboxProps } from './Combobox';
import mdx from './Combobox.mdx';
import { fakeSearchAPI, generateOptions } from './storyUtils';
import { ComboboxOption } from './types';

type PropsAndCustomArgs<T extends string | number = string> = ComboboxProps<T> & {
numberOfOptions: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { act, render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';

import { Combobox, ComboboxOption } from './Combobox';
import { Combobox } from './Combobox';
import { ComboboxOption } from './types';

// Mock data for the Combobox options
const options: ComboboxOption[] = [
Expand Down
7 changes: 1 addition & 6 deletions packages/grafana-ui/src/components/Combobox/Combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,10 @@ import { ScrollContainer } from '../ScrollContainer/ScrollContainer';
import { AsyncError, NotFoundError } from './MessageRows';
import { fuzzyFind, itemToString } from './filter';
import { getComboboxStyles, MENU_OPTION_HEIGHT, MENU_OPTION_HEIGHT_DESCRIPTION } from './getComboboxStyles';
import { ComboboxOption } from './types';
import { useComboboxFloat } from './useComboboxFloat';
import { StaleResultError, useLatestAsyncCall } from './useLatestAsyncCall';

export type ComboboxOption<T extends string | number = string> = {
label?: string;
value: T;
description?: string;
};

// TODO: It would be great if ComboboxOption["label"] was more generic so that if consumers do pass it in (for async),
// then the onChange handler emits ComboboxOption with the label as non-undefined.
export interface ComboboxBaseProps<T extends string | number>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { action } from '@storybook/addon-actions';
import { useArgs, useEffect, useState } from '@storybook/preview-api';
import type { Meta, StoryFn, StoryObj } from '@storybook/react';

import { ComboboxOption } from './Combobox';
import { MultiCombobox } from './MultiCombobox';
import { generateOptions } from './storyUtils';
import { ComboboxOption } from './types';

const meta: Meta<typeof MultiCombobox> = {
title: 'Forms/MultiCombobox',
Expand Down
5 changes: 2 additions & 3 deletions packages/grafana-ui/src/components/Combobox/MultiCombobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@ import { Spinner } from '../Spinner/Spinner';
import { Text } from '../Text/Text';
import { Tooltip } from '../Tooltip';

import { ComboboxOption, ComboboxBaseProps, AutoSizeConditionals, VIRTUAL_OVERSCAN_ITEMS } from './Combobox';
import { ComboboxBaseProps, AutoSizeConditionals, VIRTUAL_OVERSCAN_ITEMS } from './Combobox';
import { NotFoundError } from './MessageRows';
import { OptionListItem } from './OptionListItem';
import { ValuePill } from './ValuePill';
import { itemFilter, itemToString } from './filter';
import { getComboboxStyles, MENU_OPTION_HEIGHT, MENU_OPTION_HEIGHT_DESCRIPTION } from './getComboboxStyles';
import { getMultiComboboxStyles } from './getMultiComboboxStyles';
import { ALL_OPTION_VALUE, ComboboxOption } from './types';
import { useComboboxFloat } from './useComboboxFloat';
import { MAX_SHOWN_ITEMS, useMeasureMulti } from './useMeasureMulti';

export const ALL_OPTION_VALUE = '__GRAFANA_INTERNAL_MULTICOMBOBOX_ALL_OPTION__';

interface MultiComboboxBaseProps<T extends string | number> extends Omit<ComboboxBaseProps<T>, 'value' | 'onChange'> {
value?: T[] | Array<ComboboxOption<T>>;
onChange: (items?: T[]) => void;
Expand Down
3 changes: 1 addition & 2 deletions packages/grafana-ui/src/components/Combobox/filter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import uFuzzy from '@leeoniya/ufuzzy';

import { ComboboxOption } from './Combobox';
import { ALL_OPTION_VALUE } from './MultiCombobox';
import { ALL_OPTION_VALUE, ComboboxOption } from './types';

// https://catonmat.net/my-favorite-regex :)
const REGEXP_NON_ASCII = /[^ -~]/m;
Expand Down
2 changes: 1 addition & 1 deletion packages/grafana-ui/src/components/Combobox/storyUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComboboxOption } from './Combobox';
import { ComboboxOption } from './types';

let fakeApiOptions: Array<ComboboxOption<string>>;
export async function fakeSearchAPI(urlString: string): Promise<Array<ComboboxOption<string>>> {
Expand Down
7 changes: 7 additions & 0 deletions packages/grafana-ui/src/components/Combobox/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const ALL_OPTION_VALUE = '__GRAFANA_INTERNAL_MULTICOMBOBOX_ALL_OPTION__';

export type ComboboxOption<T extends string | number = string> = {
label?: string;
value: T;
description?: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ 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,
MENU_OPTION_HEIGHT,
POPOVER_MAX_HEIGHT,
} from './getComboboxStyles';
import { ComboboxOption } from './types';

// Only consider the first n items when calculating the width of the popover.
const WIDTH_CALCULATION_LIMIT_ITEMS = 100_000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useMeasure } from 'react-use';

import { measureText } from '../../utils';

import { ComboboxOption } from './Combobox';
import { ComboboxOption } from './types';

const FONT_SIZE = 12;
const EXTRA_PILL_SIZE = 50;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useCallback, useMemo } from 'react';
import { BootData } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';

import { Combobox, ComboboxOption } from '../Combobox/Combobox';
import { Combobox } from '../Combobox/Combobox';
import { ComboboxOption } from '../Combobox/types';

export interface Props {
onChange: (weekStart: string) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TimeOption } from '@grafana/data';

import { ComboboxOption } from '../Combobox/Combobox';
import { ComboboxOption } from '../Combobox/types';

export const quickOptions: TimeOption[] = [
{ from: 'now-5m', to: 'now', display: 'Last 5 minutes' },
Expand Down
3 changes: 2 additions & 1 deletion packages/grafana-ui/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ export { SelectMenuOptions } from './Select/SelectMenu';
export { getSelectStyles } from './Select/getSelectStyles';
export * from './Select/types';

export { Combobox, type ComboboxOption } from './Combobox/Combobox';
export { Combobox } from './Combobox/Combobox';
export { type ComboboxOption } from './Combobox/types';

export { HorizontalGroup, VerticalGroup, Container } from './Layout/Layout';
export { Badge, type BadgeColor, type BadgeProps } from './Badge/Badge';
Expand Down

0 comments on commit 6edd4f5

Please sign in to comment.