mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Combobox: Remove circular dependency caused by ComboboxOption type (#99601)
This commit is contained in:
parent
6e705ee67c
commit
6edd4f5a7c
@ -6,9 +6,10 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { Alert } from '../Alert/Alert';
|
import { Alert } from '../Alert/Alert';
|
||||||
import { Field } from '../Forms/Field';
|
import { Field } from '../Forms/Field';
|
||||||
|
|
||||||
import { Combobox, ComboboxOption, ComboboxProps } from './Combobox';
|
import { Combobox, ComboboxProps } from './Combobox';
|
||||||
import mdx from './Combobox.mdx';
|
import mdx from './Combobox.mdx';
|
||||||
import { fakeSearchAPI, generateOptions } from './storyUtils';
|
import { fakeSearchAPI, generateOptions } from './storyUtils';
|
||||||
|
import { ComboboxOption } from './types';
|
||||||
|
|
||||||
type PropsAndCustomArgs<T extends string | number = string> = ComboboxProps<T> & {
|
type PropsAndCustomArgs<T extends string | number = string> = ComboboxProps<T> & {
|
||||||
numberOfOptions: number;
|
numberOfOptions: number;
|
||||||
|
@ -2,7 +2,8 @@ import { act, render, screen, fireEvent } from '@testing-library/react';
|
|||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { Combobox, ComboboxOption } from './Combobox';
|
import { Combobox } from './Combobox';
|
||||||
|
import { ComboboxOption } from './types';
|
||||||
|
|
||||||
// Mock data for the Combobox options
|
// Mock data for the Combobox options
|
||||||
const options: ComboboxOption[] = [
|
const options: ComboboxOption[] = [
|
||||||
|
@ -16,15 +16,10 @@ import { ScrollContainer } from '../ScrollContainer/ScrollContainer';
|
|||||||
import { AsyncError, NotFoundError } from './MessageRows';
|
import { AsyncError, NotFoundError } from './MessageRows';
|
||||||
import { fuzzyFind, itemToString } from './filter';
|
import { fuzzyFind, itemToString } from './filter';
|
||||||
import { getComboboxStyles, MENU_OPTION_HEIGHT, MENU_OPTION_HEIGHT_DESCRIPTION } from './getComboboxStyles';
|
import { getComboboxStyles, MENU_OPTION_HEIGHT, MENU_OPTION_HEIGHT_DESCRIPTION } from './getComboboxStyles';
|
||||||
|
import { ComboboxOption } from './types';
|
||||||
import { useComboboxFloat } from './useComboboxFloat';
|
import { useComboboxFloat } from './useComboboxFloat';
|
||||||
import { StaleResultError, useLatestAsyncCall } from './useLatestAsyncCall';
|
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),
|
// 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.
|
// then the onChange handler emits ComboboxOption with the label as non-undefined.
|
||||||
export interface ComboboxBaseProps<T extends string | number>
|
export interface ComboboxBaseProps<T extends string | number>
|
||||||
|
@ -2,9 +2,9 @@ import { action } from '@storybook/addon-actions';
|
|||||||
import { useArgs, useEffect, useState } from '@storybook/preview-api';
|
import { useArgs, useEffect, useState } from '@storybook/preview-api';
|
||||||
import type { Meta, StoryFn, StoryObj } from '@storybook/react';
|
import type { Meta, StoryFn, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
import { ComboboxOption } from './Combobox';
|
|
||||||
import { MultiCombobox } from './MultiCombobox';
|
import { MultiCombobox } from './MultiCombobox';
|
||||||
import { generateOptions } from './storyUtils';
|
import { generateOptions } from './storyUtils';
|
||||||
|
import { ComboboxOption } from './types';
|
||||||
|
|
||||||
const meta: Meta<typeof MultiCombobox> = {
|
const meta: Meta<typeof MultiCombobox> = {
|
||||||
title: 'Forms/MultiCombobox',
|
title: 'Forms/MultiCombobox',
|
||||||
|
@ -14,18 +14,17 @@ import { Spinner } from '../Spinner/Spinner';
|
|||||||
import { Text } from '../Text/Text';
|
import { Text } from '../Text/Text';
|
||||||
import { Tooltip } from '../Tooltip';
|
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 { NotFoundError } from './MessageRows';
|
||||||
import { OptionListItem } from './OptionListItem';
|
import { OptionListItem } from './OptionListItem';
|
||||||
import { ValuePill } from './ValuePill';
|
import { ValuePill } from './ValuePill';
|
||||||
import { itemFilter, itemToString } from './filter';
|
import { itemFilter, itemToString } from './filter';
|
||||||
import { getComboboxStyles, MENU_OPTION_HEIGHT, MENU_OPTION_HEIGHT_DESCRIPTION } from './getComboboxStyles';
|
import { getComboboxStyles, MENU_OPTION_HEIGHT, MENU_OPTION_HEIGHT_DESCRIPTION } from './getComboboxStyles';
|
||||||
import { getMultiComboboxStyles } from './getMultiComboboxStyles';
|
import { getMultiComboboxStyles } from './getMultiComboboxStyles';
|
||||||
|
import { ALL_OPTION_VALUE, ComboboxOption } from './types';
|
||||||
import { useComboboxFloat } from './useComboboxFloat';
|
import { useComboboxFloat } from './useComboboxFloat';
|
||||||
import { MAX_SHOWN_ITEMS, useMeasureMulti } from './useMeasureMulti';
|
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'> {
|
interface MultiComboboxBaseProps<T extends string | number> extends Omit<ComboboxBaseProps<T>, 'value' | 'onChange'> {
|
||||||
value?: T[] | Array<ComboboxOption<T>>;
|
value?: T[] | Array<ComboboxOption<T>>;
|
||||||
onChange: (items?: T[]) => void;
|
onChange: (items?: T[]) => void;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import uFuzzy from '@leeoniya/ufuzzy';
|
import uFuzzy from '@leeoniya/ufuzzy';
|
||||||
|
|
||||||
import { ComboboxOption } from './Combobox';
|
import { ALL_OPTION_VALUE, ComboboxOption } from './types';
|
||||||
import { ALL_OPTION_VALUE } from './MultiCombobox';
|
|
||||||
|
|
||||||
// https://catonmat.net/my-favorite-regex :)
|
// https://catonmat.net/my-favorite-regex :)
|
||||||
const REGEXP_NON_ASCII = /[^ -~]/m;
|
const REGEXP_NON_ASCII = /[^ -~]/m;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComboboxOption } from './Combobox';
|
import { ComboboxOption } from './types';
|
||||||
|
|
||||||
let fakeApiOptions: Array<ComboboxOption<string>>;
|
let fakeApiOptions: Array<ComboboxOption<string>>;
|
||||||
export async function fakeSearchAPI(urlString: string): Promise<Array<ComboboxOption<string>>> {
|
export async function fakeSearchAPI(urlString: string): Promise<Array<ComboboxOption<string>>> {
|
||||||
|
7
packages/grafana-ui/src/components/Combobox/types.ts
Normal file
7
packages/grafana-ui/src/components/Combobox/types.ts
Normal file
@ -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;
|
||||||
|
};
|
@ -3,7 +3,6 @@ import { useMemo, useRef, useState } from 'react';
|
|||||||
|
|
||||||
import { measureText } from '../../utils';
|
import { measureText } from '../../utils';
|
||||||
|
|
||||||
import { ComboboxOption } from './Combobox';
|
|
||||||
import {
|
import {
|
||||||
MENU_ITEM_FONT_SIZE,
|
MENU_ITEM_FONT_SIZE,
|
||||||
MENU_ITEM_FONT_WEIGHT,
|
MENU_ITEM_FONT_WEIGHT,
|
||||||
@ -11,6 +10,7 @@ import {
|
|||||||
MENU_OPTION_HEIGHT,
|
MENU_OPTION_HEIGHT,
|
||||||
POPOVER_MAX_HEIGHT,
|
POPOVER_MAX_HEIGHT,
|
||||||
} from './getComboboxStyles';
|
} from './getComboboxStyles';
|
||||||
|
import { ComboboxOption } from './types';
|
||||||
|
|
||||||
// Only consider the first n items when calculating the width of the popover.
|
// Only consider the first n items when calculating the width of the popover.
|
||||||
const WIDTH_CALCULATION_LIMIT_ITEMS = 100_000;
|
const WIDTH_CALCULATION_LIMIT_ITEMS = 100_000;
|
||||||
|
@ -3,7 +3,7 @@ import { useMeasure } from 'react-use';
|
|||||||
|
|
||||||
import { measureText } from '../../utils';
|
import { measureText } from '../../utils';
|
||||||
|
|
||||||
import { ComboboxOption } from './Combobox';
|
import { ComboboxOption } from './types';
|
||||||
|
|
||||||
const FONT_SIZE = 12;
|
const FONT_SIZE = 12;
|
||||||
const EXTRA_PILL_SIZE = 50;
|
const EXTRA_PILL_SIZE = 50;
|
||||||
|
@ -3,7 +3,8 @@ import { useCallback, useMemo } from 'react';
|
|||||||
import { BootData } from '@grafana/data';
|
import { BootData } from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
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 {
|
export interface Props {
|
||||||
onChange: (weekStart: string) => void;
|
onChange: (weekStart: string) => void;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { TimeOption } from '@grafana/data';
|
import { TimeOption } from '@grafana/data';
|
||||||
|
|
||||||
import { ComboboxOption } from '../Combobox/Combobox';
|
import { ComboboxOption } from '../Combobox/types';
|
||||||
|
|
||||||
export const quickOptions: TimeOption[] = [
|
export const quickOptions: TimeOption[] = [
|
||||||
{ from: 'now-5m', to: 'now', display: 'Last 5 minutes' },
|
{ from: 'now-5m', to: 'now', display: 'Last 5 minutes' },
|
||||||
|
@ -239,7 +239,8 @@ export { SelectMenuOptions } from './Select/SelectMenu';
|
|||||||
export { getSelectStyles } from './Select/getSelectStyles';
|
export { getSelectStyles } from './Select/getSelectStyles';
|
||||||
export * from './Select/types';
|
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 { HorizontalGroup, VerticalGroup, Container } from './Layout/Layout';
|
||||||
export { Badge, type BadgeColor, type BadgeProps } from './Badge/Badge';
|
export { Badge, type BadgeColor, type BadgeProps } from './Badge/Badge';
|
||||||
|
Loading…
Reference in New Issue
Block a user