summaryrefslogtreecommitdiff
path: root/apps/web/src/components/ui/split-button.tsx
blob: ca3b518c703568ab2f5a97367eeb242d9747e28e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { Button, ButtonProps } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { ReactNode, forwardRef } from "react";
import { cn } from "@/lib/utils";

interface SplitButtonProps {
  children: ReactNode;
  className?: string;
}

interface SplitButtonSideProps extends Omit<ButtonProps, "variant" | "size"> {
  children: ReactNode;
}

const SplitButton = forwardRef<HTMLDivElement, SplitButtonProps>(
  ({ children, className, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={cn(
          "inline-flex rounded-full h-7 border border-input bg-panel-accent overflow-hidden",
          className
        )}
        {...props}
      >
        {children}
      </div>
    );
  }
);
SplitButton.displayName = "SplitButton";

const SplitButtonSide = forwardRef<
  HTMLButtonElement,
  SplitButtonSideProps & { paddingClass: string }
>(({ children, className, paddingClass, onClick, ...props }, ref) => {
  return (
    <Button
      ref={ref}
      variant="text"
      className={cn(
        "h-full rounded-none bg-panel-accent !opacity-100 border-0 gap-0 font-normal transition-colors disabled:text-muted-foreground",
        onClick
          ? "hover:bg-foreground/10 hover:opacity-100 cursor-pointer"
          : "cursor-default select-text",
        paddingClass,
        className
      )}
      onClick={onClick}
      {...props}
    >
      {typeof children === "string" ? (
        <span className="font-normal cursor-text">{children}</span>
      ) : (
        children
      )}
    </Button>
  );
});
SplitButtonSide.displayName = "SplitButtonSide";

const SplitButtonLeft = forwardRef<HTMLButtonElement, SplitButtonSideProps>(
  ({ ...props }, ref) => {
    return <SplitButtonSide ref={ref} paddingClass="pl-3 pr-2" {...props} />;
  }
);
SplitButtonLeft.displayName = "SplitButtonLeft";

const SplitButtonRight = forwardRef<HTMLButtonElement, SplitButtonSideProps>(
  ({ ...props }, ref) => {
    return <SplitButtonSide ref={ref} paddingClass="pl-2 pr-3" {...props} />;
  }
);
SplitButtonRight.displayName = "SplitButtonRight";

const SplitButtonSeparator = forwardRef<HTMLDivElement, { className?: string }>(
  ({ className, ...props }, ref) => {
    return (
      <Separator
        ref={ref}
        orientation="vertical"
        className={cn("h-full bg-foreground/15", className)}
        {...props}
      />
    );
  }
);
SplitButtonSeparator.displayName = "SplitButtonSeparator";

export { SplitButton, SplitButtonLeft, SplitButtonRight, SplitButtonSeparator };