返回 presentation-ai
button-static.tsx
1 import { type TElement } from "platejs";
2 import { SlateElement, type SlateElementProps } from "platejs/static";
3 import type * as React from "react";
4
5 import { cn } from "@/lib/utils";
6 import { type BUTTON_ELEMENT } from "../../lib";
7
8 type ButtonStaticElement = TElement & {
9 alignment?: "center" | "left" | "right";
10 backgroundColor?: string;
11 color?: string;
12 textColor?: string;
13 type: typeof BUTTON_ELEMENT;
14 variant?: "filled" | "outline" | "ghost";
15 size?: "sm" | "md" | "lg";
16 };
17
18 function getJustifyClass(alignment: ButtonStaticElement["alignment"]) {
19 if (alignment === "left") return "justify-start";
20 if (alignment === "right") return "justify-end";
21 return "justify-center";
22 }
23
24 export default function ButtonStatic(
25 props: SlateElementProps<ButtonStaticElement>,
26 ) {
27 const element = props.element as ButtonStaticElement;
28 const variant = element.variant ?? "filled";
29 const size = element.size ?? "md";
30 const alignment = element.alignment ?? "left";
31 const accentColor = element.backgroundColor ?? "var(--presentation-primary)";
32 const textColor = element.textColor ?? element.color;
33 const backgroundColor =
34 element.backgroundColor ?? "var(--presentation-primary)";
35
36 const sizeClasses =
37 size === "sm"
38 ? "px-3 py-1 text-sm"
39 : size === "lg"
40 ? "px-6 py-3 text-lg"
41 : "px-4 py-2 text-base";
42
43 const commonClasses =
44 "inline-flex items-center gap-2 font-medium transition-(--presentation-transition)";
45
46 const variantClasses =
47 variant === "outline"
48 ? "border"
49 : variant === "ghost"
50 ? "bg-transparent"
51 : "";
52
53 const style: React.CSSProperties = (() => {
54 const baseStyle = {
55 borderRadius: "var(--presentation-button-border-radius, 0.5rem)",
56 };
57
58 if (variant === "outline") {
59 return {
60 ...baseStyle,
61 color: textColor ?? accentColor,
62 backgroundColor: "transparent",
63 borderColor: accentColor,
64 } as React.CSSProperties;
65 }
66 if (variant === "ghost") {
67 return {
68 ...baseStyle,
69 color: textColor ?? accentColor,
70 backgroundColor: "transparent",
71 } as React.CSSProperties;
72 }
73 return {
74 ...baseStyle,
75 backgroundColor,
76 color: textColor ?? "var(--presentation-background)",
77 boxShadow: "var(--presentation-button-shadow, 0 2px 4px rgba(0,0,0,0.1))",
78 } as React.CSSProperties;
79 })();
80
81 return (
82 <SlateElement
83 {...props}
84 className={cn(
85 "relative my-1 flex w-full transition-all duration-300",
86 getJustifyClass(alignment),
87 props.className,
88 )}
89 >
90 <div
91 className={cn(
92 "presentation-element",
93 commonClasses,
94 sizeClasses,
95 variantClasses,
96 )}
97 style={style}
98 >
99 {props.children}
100 </div>
101 </SlateElement>
102 );
103 }
104
104 lines Plain Text