Improve UI
This commit is contained in:
parent
5fe192d25a
commit
ae29662c92
14 changed files with 221 additions and 313 deletions
|
|
@ -1,89 +0,0 @@
|
|||
import { useCallback } from 'react';
|
||||
|
||||
interface CheckboxListProps {
|
||||
items: string[];
|
||||
selected: string[] | Set<string>;
|
||||
onChange: (selected: string[]) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function CheckboxList({ items, selected, onChange, className = '' }: CheckboxListProps) {
|
||||
const selectedSet = selected instanceof Set ? selected : new Set(selected);
|
||||
|
||||
const handleToggle = useCallback(
|
||||
(item: string) => {
|
||||
const newSelected = selectedSet.has(item)
|
||||
? [...selectedSet].filter((v) => v !== item)
|
||||
: [...selectedSet, item];
|
||||
onChange(newSelected);
|
||||
},
|
||||
[selectedSet, onChange]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={`space-y-0.5 ${className}`}>
|
||||
{items.map((item) => (
|
||||
<label
|
||||
key={item}
|
||||
className="flex items-center gap-1.5 text-sm cursor-pointer dark:text-warm-300"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selectedSet.has(item)}
|
||||
onChange={() => handleToggle(item)}
|
||||
className="rounded accent-teal-600"
|
||||
/>
|
||||
{item}
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface CheckboxListWithSetProps {
|
||||
items: string[];
|
||||
selected: Set<string>;
|
||||
onChange: (selected: Set<string>) => void;
|
||||
className?: string;
|
||||
itemClassName?: string;
|
||||
}
|
||||
|
||||
export function CheckboxListWithSet({
|
||||
items,
|
||||
selected,
|
||||
onChange,
|
||||
className = '',
|
||||
itemClassName = '',
|
||||
}: CheckboxListWithSetProps) {
|
||||
const handleToggle = useCallback(
|
||||
(item: string) => {
|
||||
const newSet = new Set(selected);
|
||||
if (newSet.has(item)) {
|
||||
newSet.delete(item);
|
||||
} else {
|
||||
newSet.add(item);
|
||||
}
|
||||
onChange(newSet);
|
||||
},
|
||||
[selected, onChange]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{items.map((item) => (
|
||||
<label
|
||||
key={item}
|
||||
className={`flex items-center gap-2 cursor-pointer dark:text-warm-300 ${itemClassName}`}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selected.has(item)}
|
||||
onChange={() => handleToggle(item)}
|
||||
className="rounded accent-teal-600"
|
||||
/>
|
||||
<span className="text-sm flex-1">{item}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
// Shared icon components with consistent sizing and styling
|
||||
|
||||
interface IconProps {
|
||||
className?: string;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue