Skip to content

Commit 37f7423

Browse files
committed
Adds a new prop for choosing which side the mutli select check box icon appears
1 parent 708e765 commit 37f7423

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

apps/webapp/app/components/primitives/Select.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,21 +443,54 @@ export function SelectList(props: SelectListProps) {
443443
export interface SelectItemProps extends Ariakit.SelectItemProps {
444444
icon?: React.ReactNode;
445445
checkIcon?: React.ReactNode;
446+
checkPosition?: "left" | "right";
446447
shortcut?: ShortcutDefinition;
447448
}
448449

449450
const selectItemClasses =
450451
"group cursor-pointer px-1 pt-1 text-2sm text-text-dimmed focus-custom last:pb-1";
451452

453+
function LeftCheckbox({ checked }: { checked: boolean }) {
454+
return (
455+
<div
456+
className={cn(
457+
"flex size-4 flex-none items-center justify-center rounded border",
458+
checked ? "border-indigo-500 bg-indigo-600" : "border-charcoal-600 bg-charcoal-700"
459+
)}
460+
>
461+
{checked && (
462+
<svg className="size-3 text-white" viewBox="0 0 12 12" fill="none">
463+
<path
464+
d="M2.5 6L5 8.5L9.5 3.5"
465+
stroke="currentColor"
466+
strokeWidth="1.5"
467+
strokeLinecap="round"
468+
strokeLinejoin="round"
469+
/>
470+
</svg>
471+
)}
472+
</div>
473+
);
474+
}
475+
452476
export function SelectItem({
453477
icon,
454478
checkIcon = <Ariakit.SelectItemCheck className="size-8 flex-none text-text-bright" />,
479+
checkPosition = "right",
455480
shortcut,
456481
...props
457482
}: SelectItemProps) {
458483
const combobox = Ariakit.useComboboxContext();
459484
const render = combobox ? <Ariakit.ComboboxItem render={props.render} /> : undefined;
460485
const ref = React.useRef<HTMLDivElement>(null);
486+
const select = Ariakit.useSelectContext();
487+
const selectValue = select?.useState("value");
488+
489+
const isChecked = React.useMemo(() => {
490+
if (!props.value || selectValue == null) return false;
491+
if (Array.isArray(selectValue)) return selectValue.includes(props.value);
492+
return selectValue === props.value;
493+
}, [selectValue, props.value]);
461494

462495
useShortcutKeys({
463496
shortcut: shortcut,
@@ -484,10 +517,16 @@ export function SelectItem({
484517
)}
485518
ref={ref}
486519
>
487-
<div className="flex h-8 w-full items-center gap-1 rounded-sm px-2 group-data-[active-item=true]:bg-tertiary">
520+
<div
521+
className={cn(
522+
"flex h-8 w-full items-center rounded-sm px-2 hover:bg-tertiary group-data-[active-item=true]:bg-tertiary",
523+
checkPosition === "left" ? "gap-2" : "gap-1"
524+
)}
525+
>
526+
{checkPosition === "left" && <LeftCheckbox checked={isChecked} />}
488527
{icon}
489528
<div className="grow truncate">{props.children || props.value}</div>
490-
{checkIcon}
529+
{checkPosition === "right" && checkIcon}
491530
{shortcut && (
492531
<ShortcutKey
493532
className={cn("size-4 flex-none transition duration-0 group-hover:border-charcoal-600")}

0 commit comments

Comments
 (0)