mirror of
https://github.com/portainer/portainer.git
synced 2025-07-23 15:29:42 +02:00
refactor(ui/box-selector): replace all selectors [EE-3856] (#7902)
This commit is contained in:
parent
c9253319d9
commit
2dddc1c6b9
80 changed files with 1267 additions and 1011 deletions
|
@ -1,30 +1,39 @@
|
|||
import clsx from 'clsx';
|
||||
import { Check, Minus } from 'lucide-react';
|
||||
|
||||
import './BoxSelector.css';
|
||||
import styles from './BoxSelector.module.css';
|
||||
import { BoxSelectorItem } from './BoxSelectorItem';
|
||||
import { BoxSelectorOption } from './types';
|
||||
import { BoxSelectorOption, Value } from './types';
|
||||
|
||||
export interface Props<T extends number | string> {
|
||||
radioName: string;
|
||||
value: T;
|
||||
onChange(value: T, limitedToBE: boolean): void;
|
||||
options: BoxSelectorOption<T>[];
|
||||
interface IsMultiProps<T extends Value> {
|
||||
isMulti: true;
|
||||
value: T[];
|
||||
onChange(value: T[], limitedToBE: boolean): void;
|
||||
}
|
||||
|
||||
export function BoxSelector<T extends number | string>({
|
||||
interface SingleProps<T extends Value> {
|
||||
isMulti?: never;
|
||||
value: T;
|
||||
onChange(value: T, limitedToBE: boolean): void;
|
||||
}
|
||||
|
||||
type Union<T extends Value> = IsMultiProps<T> | SingleProps<T>;
|
||||
|
||||
export type Props<T extends Value> = Union<T> & {
|
||||
radioName: string;
|
||||
options: ReadonlyArray<BoxSelectorOption<T>> | Array<BoxSelectorOption<T>>;
|
||||
slim?: boolean;
|
||||
};
|
||||
|
||||
export function BoxSelector<T extends Value>({
|
||||
radioName,
|
||||
value,
|
||||
options,
|
||||
onChange,
|
||||
slim = false,
|
||||
...props
|
||||
}: Props<T>) {
|
||||
return (
|
||||
<div className="form-group">
|
||||
<div className="col-sm-12">
|
||||
<div
|
||||
className={clsx('boxselector_wrapper', styles.root)}
|
||||
role="radiogroup"
|
||||
>
|
||||
<div className={styles.root} role="radiogroup">
|
||||
{options
|
||||
.filter((option) => !option.hide)
|
||||
.map((option) => (
|
||||
|
@ -32,14 +41,41 @@ export function BoxSelector<T extends number | string>({
|
|||
key={option.id}
|
||||
radioName={radioName}
|
||||
option={option}
|
||||
onChange={onChange}
|
||||
selectedValue={value}
|
||||
onSelect={handleSelect}
|
||||
disabled={option.disabled && option.disabled()}
|
||||
tooltip={option.tooltip && option.tooltip()}
|
||||
type={props.isMulti ? 'checkbox' : 'radio'}
|
||||
isSelected={isSelected}
|
||||
slim={slim}
|
||||
checkIcon={props.isMulti ? Minus : Check}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
function handleSelect(optionValue: T, limitedToBE: boolean) {
|
||||
if (props.isMulti) {
|
||||
const newValue = isSelected(optionValue)
|
||||
? props.value.filter((v) => v !== optionValue)
|
||||
: [...props.value, optionValue];
|
||||
props.onChange(newValue, limitedToBE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSelected(optionValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
props.onChange(optionValue, limitedToBE);
|
||||
}
|
||||
|
||||
function isSelected(optionValue: T) {
|
||||
if (props.isMulti) {
|
||||
return props.value.includes(optionValue);
|
||||
}
|
||||
|
||||
return props.value === optionValue;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue