Files
portainer/app/react/components/form-components/DisabledMultiValue.tsx
2026-06-07 15:45:58 +03:00

74 lines
1.7 KiB
TypeScript

import type { ReactNode } from 'react';
import {
components,
type GroupBase,
type MultiValueProps,
type MultiValueRemoveProps,
} from 'react-select';
import { TooltipWithChildren } from '@@/Tip/TooltipWithChildren';
import { type Option } from './PortainerSelect';
/** Extends Option with an optional tooltip shown when the item is disabled. */
export interface DisabledOption<TValue> extends Option<TValue> {
disabledMessage?: ReactNode;
}
export function DisabledMultiValue({
data,
...props
}: MultiValueProps<Option<string>, true, GroupBase<Option<string>>>) {
const disabledMessage = (data as DisabledOption<string>).disabledMessage;
const value = (
<components.MultiValue
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
data={data}
isDisabled={!!data.disabled}
>
<span className={data.disabled ? 'text-muted pr-1' : ''}>
{props.children}
</span>
</components.MultiValue>
);
if (data.disabled && disabledMessage) {
return (
<TooltipWithChildren
message={disabledMessage}
appendTo={() => document.body}
>
<span>{value}</span>
</TooltipWithChildren>
);
}
return value;
}
export function DisabledMultiValueRemove({
data,
...props
}: MultiValueRemoveProps<Option<string>, true, GroupBase<Option<string>>>) {
if (data.disabled) {
return null;
}
return (
<components.MultiValueRemove
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
data={data}
/>
);
}
export function preserveProtectedValues<T>(
selectedValues: T[],
protectedValues: T[]
): T[] {
return [...new Set([...selectedValues, ...protectedValues])];
}