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