List components #31
@ -0,0 +1,68 @@
|
|||||||
|
import Combobox, { type ComboboxOption, type ComboboxSize } from '../Combobox/Combobox';
|
||||||
|
import ListCard from '../ListCard/ListCard';
|
||||||
|
|
||||||
|
export interface ParticipantPickerProps {
|
||||||
|
options: ComboboxOption[];
|
||||||
|
value: string[];
|
||||||
|
onChange: (value: string[]) => void;
|
||||||
|
placeholder?: string;
|
||||||
|
label?: string;
|
||||||
|
noResultsText?: string;
|
||||||
|
size?: ComboboxSize;
|
||||||
|
fullWidth?: boolean;
|
||||||
|
customWidth?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const widthClasses: Record<ComboboxSize, string> = {
|
||||||
|
sm: 'w-(--text-input-default-width-md)',
|
||||||
|
md: 'w-(--text-input-default-width-md)',
|
||||||
|
lg: 'w-(--text-input-default-width-lg)',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ParticipantPicker({
|
||||||
|
options,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
placeholder = 'Sök...',
|
||||||
|
label,
|
||||||
|
noResultsText = 'Inga resultat',
|
||||||
|
size = 'md',
|
||||||
|
fullWidth = false,
|
||||||
|
customWidth,
|
||||||
|
}: ParticipantPickerProps) {
|
||||||
|
const handleRemove = (valueToRemove: string) => {
|
||||||
|
onChange(value.filter((v) => v !== valueToRemove));
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedOptions = options.filter((opt) => value.includes(opt.value));
|
||||||
|
|
||||||
|
const containerClasses = fullWidth ? 'flex flex-col gap-(--spacing-sm) w-full' : customWidth ? 'flex flex-col gap-(--spacing-sm)' : `flex flex-col gap-(--spacing-sm) ${widthClasses[size]}`;
|
||||||
|
const containerStyle = customWidth ? { width: customWidth } : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={containerClasses} style={containerStyle}>
|
||||||
|
<Combobox
|
||||||
|
options={options}
|
||||||
|
value={value}
|
||||||
|
onChange={(v) => onChange(v as string[])}
|
||||||
|
placeholder={placeholder}
|
||||||
|
label={label}
|
||||||
|
noResultsText={noResultsText}
|
||||||
|
size={size}
|
||||||
|
fullWidth
|
||||||
|
multiple
|
||||||
|
/>
|
||||||
|
{selectedOptions.length > 0 && (
|
||||||
|
<div className="flex flex-col gap-(--spacing-sm)">
|
||||||
|
{selectedOptions.map((option) => (
|
||||||
|
<ListCard
|
||||||
|
key={option.value}
|
||||||
|
title={option.label}
|
||||||
|
onRemove={() => handleRemove(option.value)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user