summaryrefslogtreecommitdiff
path: root/apps/web/src/components/ui/split-button.tsx
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-08-31 23:25:26 +0200
committerMaze Winther <mazewinther@gmail.com>2025-08-31 23:25:26 +0200
commit2b700b7474ffc728f5318c178244e035c93716b5 (patch)
tree13bd3ade85571448c3945782018e8894792b0d1c /apps/web/src/components/ui/split-button.tsx
parente43d79e4c53a2e2ed57cc20ad013fba120b631bf (diff)
downloadopencut-2b700b7474ffc728f5318c178244e035c93716b5.tar.gz
feat: scenes button to timeline toolbar
Diffstat (limited to 'apps/web/src/components/ui/split-button.tsx')
-rw-r--r--apps/web/src/components/ui/split-button.tsx90
1 files changed, 90 insertions, 0 deletions
diff --git a/apps/web/src/components/ui/split-button.tsx b/apps/web/src/components/ui/split-button.tsx
new file mode 100644
index 00000000..1ef29500
--- /dev/null
+++ b/apps/web/src/components/ui/split-button.tsx
@@ -0,0 +1,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",
+ 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 };