>>([]);
return (
- <>
+
{
prefix={getPrefix(args.icon)}
{...args}
/>
- >
+
);
};
+
MultiSelectBasic.args = {
isClearable: false,
closeMenuOnSelect: false,
maxVisibleValues: 5,
+ noMultiValueWrap: false,
};
export const MultiSelectAsync: Story = (args) => {
diff --git a/packages/grafana-ui/src/components/Select/SelectBase.tsx b/packages/grafana-ui/src/components/Select/SelectBase.tsx
index c47d9cf3c5c..661c97995e8 100644
--- a/packages/grafana-ui/src/components/Select/SelectBase.tsx
+++ b/packages/grafana-ui/src/components/Select/SelectBase.tsx
@@ -1,6 +1,6 @@
import { t } from 'i18next';
import React, { ComponentProps, useCallback, useEffect, useRef, useState } from 'react';
-import { default as ReactSelect } from 'react-select';
+import { default as ReactSelect, IndicatorsContainerProps, Props as ReactSelectProps } from 'react-select';
import { default as ReactAsyncSelect } from 'react-select/async';
import { default as AsyncCreatable } from 'react-select/async-creatable';
import Creatable from 'react-select/creatable';
@@ -25,31 +25,6 @@ import { useCustomSelectStyles } from './resetSelectStyles';
import { ActionMeta, InputActionMeta, SelectBaseProps } from './types';
import { cleanValue, findSelectedValue, omitDescriptions } from './utils';
-interface ExtraValuesIndicatorProps {
- maxVisibleValues?: number | undefined;
- selectedValuesCount: number;
- menuIsOpen: boolean;
- showAllSelectedWhenOpen: boolean;
-}
-
-const renderExtraValuesIndicator = (props: ExtraValuesIndicatorProps) => {
- const { maxVisibleValues, selectedValuesCount, menuIsOpen, showAllSelectedWhenOpen } = props;
-
- if (
- maxVisibleValues !== undefined &&
- selectedValuesCount > maxVisibleValues &&
- !(showAllSelectedWhenOpen && menuIsOpen)
- ) {
- return (
-
- (+{selectedValuesCount - maxVisibleValues})
-
- );
- }
-
- return null;
-};
-
const CustomControl = (props: any) => {
const {
children,
@@ -88,6 +63,12 @@ const CustomControl = (props: any) => {
);
};
+interface SelectPropsWithExtras extends ReactSelectProps {
+ maxVisibleValues?: number | undefined;
+ showAllSelectedWhenOpen: boolean;
+ noMultiValueWrap?: boolean;
+}
+
export function SelectBase({
allowCustomValue = false,
allowCreateWhileLoading = false,
@@ -145,6 +126,7 @@ export function SelectBase({
tabSelectsValue = true,
value,
virtualized = false,
+ noMultiValueWrap,
width,
isValidNewOption,
formatOptionLabel,
@@ -274,6 +256,7 @@ export function SelectBase({
showAllSelectedWhenOpen,
tabSelectsValue,
value: isMulti ? selectedValue : selectedValue?.[0],
+ noMultiValueWrap,
};
if (allowCustomValue) {
@@ -305,31 +288,8 @@ export function SelectBase({
MenuList: SelectMenuComponent,
Group: SelectOptionGroup,
ValueContainer,
- IndicatorsContainer(props: any) {
- const { selectProps } = props;
- const { value, showAllSelectedWhenOpen, maxVisibleValues, menuIsOpen } = selectProps;
-
- if (maxVisibleValues !== undefined) {
- const selectedValuesCount = value.length;
- const indicatorChildren = [...props.children];
- indicatorChildren.splice(
- -1,
- 0,
- renderExtraValuesIndicator({
- maxVisibleValues,
- selectedValuesCount,
- showAllSelectedWhenOpen,
- menuIsOpen,
- })
- );
- return {indicatorChildren};
- }
-
- return ;
- },
- IndicatorSeparator() {
- return <>>;
- },
+ IndicatorsContainer: CustomIndicatorsContainer,
+ IndicatorSeparator: IndicatorSeparator,
Control: CustomControl,
Option: SelectMenuOptions,
ClearIndicator(props: any) {
@@ -361,9 +321,7 @@ export function SelectBase({
);
},
- DropdownIndicator(props) {
- return ;
- },
+ DropdownIndicator: DropdownIndicator,
SingleValue(props: any) {
return ;
},
@@ -394,3 +352,37 @@ function defaultFormatCreateLabel(input: string) {
);
}
+
+type CustomIndicatorsContainerProps = IndicatorsContainerProps & {
+ selectProps: SelectPropsWithExtras;
+ children: React.ReactNode;
+};
+
+function CustomIndicatorsContainer(props: CustomIndicatorsContainerProps) {
+ const { showAllSelectedWhenOpen, maxVisibleValues, menuIsOpen } = props.selectProps;
+
+ const value = props.getValue();
+
+ if (maxVisibleValues !== undefined && Array.isArray(props.children)) {
+ const selectedValuesCount = value.length;
+
+ if (selectedValuesCount > maxVisibleValues && !(showAllSelectedWhenOpen && menuIsOpen)) {
+ const indicatorChildren = [...props.children];
+ indicatorChildren.splice(
+ -1,
+ 0,
+
+ (+{selectedValuesCount - maxVisibleValues})
+
+ );
+
+ return {indicatorChildren};
+ }
+ }
+
+ return ;
+}
+
+function IndicatorSeparator() {
+ return <>>;
+}
diff --git a/packages/grafana-ui/src/components/Select/ValueContainer.tsx b/packages/grafana-ui/src/components/Select/ValueContainer.tsx
index b7c6f957fcb..9025a4a1d0d 100644
--- a/packages/grafana-ui/src/components/Select/ValueContainer.tsx
+++ b/packages/grafana-ui/src/components/Select/ValueContainer.tsx
@@ -30,8 +30,15 @@ class UnthemedValueContainer extends Component {
renderContainer(children?: ReactNode) {
const { isMulti, theme } = this.props;
+ const noWrap = this.props.selectProps?.noMultiValueWrap && !this.props.selectProps?.menuIsOpen;
const styles = getSelectStyles(theme);
- const className = cx(styles.valueContainer, isMulti && styles.valueContainerMulti);
+
+ const className = cx(
+ styles.valueContainer,
+ isMulti && styles.valueContainerMulti,
+ noWrap && styles.valueContainerMultiNoWrap
+ );
+
return {children}
;
}
}
diff --git a/packages/grafana-ui/src/components/Select/getSelectStyles.ts b/packages/grafana-ui/src/components/Select/getSelectStyles.ts
index 420ccdfb15b..84ce715aab2 100644
--- a/packages/grafana-ui/src/components/Select/getSelectStyles.ts
+++ b/packages/grafana-ui/src/components/Select/getSelectStyles.ts
@@ -96,6 +96,9 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => {
flexWrap: 'wrap',
display: 'flex',
}),
+ valueContainerMultiNoWrap: css({
+ flexWrap: 'nowrap',
+ }),
loadingMessage: css({
label: 'grafana-select-loading-message',
padding: theme.spacing(1),
@@ -113,6 +116,8 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => {
padding: theme.spacing(0.25, 0, 0.25, 1),
color: theme.colors.text.primary,
fontSize: theme.typography.size.sm,
+ overflow: 'hidden',
+ whiteSpace: 'nowrap',
'&:hover': {
background: theme.colors.emphasize(theme.colors.background.secondary),
diff --git a/packages/grafana-ui/src/components/Select/mockOptions.tsx b/packages/grafana-ui/src/components/Select/mockOptions.tsx
index 12d56b0bdc0..7af01826de6 100644
--- a/packages/grafana-ui/src/components/Select/mockOptions.tsx
+++ b/packages/grafana-ui/src/components/Select/mockOptions.tsx
@@ -24,6 +24,7 @@ export const generateOptions = (desc = false) => {
'Ok Vicente',
'Garry Spitz',
'Han Harnish',
+ 'A very long value that is very long and takes up a lot of space and should be truncated preferrably if it does not fit',
];
return values.map>((name) => ({
diff --git a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts
index fb844575d66..3f1e31abff7 100644
--- a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts
+++ b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts
@@ -30,7 +30,10 @@ export default function resetSelectStyles(theme: GrafanaTheme2) {
maxHeight,
}),
multiValue: () => ({}),
- multiValueLabel: () => ({}),
+ multiValueLabel: () => ({
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ }),
multiValueRemove: () => ({}),
noOptionsMessage: () => ({}),
option: () => ({}),
diff --git a/packages/grafana-ui/src/components/Select/types.ts b/packages/grafana-ui/src/components/Select/types.ts
index e3fe5c6b766..0cbe644ed70 100644
--- a/packages/grafana-ui/src/components/Select/types.ts
+++ b/packages/grafana-ui/src/components/Select/types.ts
@@ -99,6 +99,8 @@ export interface SelectCommonProps {
) => boolean;
/** Message to display isLoading=true*/
loadingMessage?: string;
+ /** Disables wrapping of multi value values when closed */
+ noMultiValueWrap?: boolean;
}
export interface SelectAsyncProps {
diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts
index 72c8be994c5..e4240c1daf2 100644
--- a/packages/grafana-ui/src/components/index.ts
+++ b/packages/grafana-ui/src/components/index.ts
@@ -227,7 +227,6 @@ export { FieldArray } from './Forms/FieldArray';
// Select
export { default as resetSelectStyles } from './Select/resetSelectStyles';
export * from './Select/Select';
-export { DropdownIndicator } from './Select/DropdownIndicator';
export { getSelectStyles } from './Select/getSelectStyles';
export * from './Select/types';