返回 presentation-ai
equation-node-static.tsx
根目录 / src / components / plate / ui / equation-node-static.tsx
1 import { getEquationHtml } from "@platejs/math";
2 import { RadicalIcon } from "lucide-react";
3 import { type TEquationElement } from "platejs";
4 import { SlateElement, type SlateElementProps } from "platejs/static";
5
6 import { cn } from "@/lib/utils";
7
8 export function EquationElementStatic(
9 props: SlateElementProps<TEquationElement>,
10 ) {
11 const { element } = props;
12
13 const html = getEquationHtml({
14 element,
15 options: {
16 displayMode: true,
17 errorColor: "#cc0000",
18 fleqn: false,
19 leqno: false,
20 macros: { "\\f": "#1f(#2)" },
21 output: "htmlAndMathml",
22 strict: "warn",
23 throwOnError: false,
24 trust: false,
25 },
26 });
27
28 return (
29 <SlateElement className="my-1" {...props}>
30 <div
31 className={cn(
32 "group flex items-center justify-center rounded-sm select-none hover:bg-primary/10 data-[selected=true]:bg-primary/10",
33 element.texExpression.length === 0
34 ? "bg-muted p-3 pr-9"
35 : "px-2 py-1",
36 )}
37 >
38 {element.texExpression.length > 0 ? (
39 <span
40 // biome-ignore lint/security/noDangerouslySetInnerHtml: This is safe
41 dangerouslySetInnerHTML={{
42 __html: html,
43 }}
44 />
45 ) : (
46 <div className="flex h-7 w-full items-center gap-2 text-sm whitespace-nowrap text-muted-foreground">
47 <RadicalIcon className="size-6 text-muted-foreground/80" />
48 <div>Add a Tex equation</div>
49 </div>
50 )}
51 </div>
52 {props.children}
53 </SlateElement>
54 );
55 }
56
57 export function InlineEquationElementStatic(
58 props: SlateElementProps<TEquationElement>,
59 ) {
60 const html = getEquationHtml({
61 element: props.element,
62 options: {
63 displayMode: true,
64 errorColor: "#cc0000",
65 fleqn: false,
66 leqno: false,
67 macros: { "\\f": "#1f(#2)" },
68 output: "htmlAndMathml",
69 strict: "warn",
70 throwOnError: false,
71 trust: false,
72 },
73 });
74
75 return (
76 <SlateElement
77 {...props}
78 className="inline-block rounded-sm select-none [&_.katex-display]:my-0"
79 >
80 <div
81 className={cn(
82 'after:absolute after:inset-0 after:-top-0.5 after:-left-1 after:z-1 after:h-[calc(100%)+4px] after:w-[calc(100%+8px)] after:rounded-sm after:content-[""]',
83 "h-6",
84 props.element.texExpression.length === 0 &&
85 "text-muted-foreground after:bg-neutral-500/10",
86 )}
87 >
88 <span
89 className={cn(
90 props.element.texExpression.length === 0 && "hidden",
91 "font-mono leading-none",
92 )}
93 // biome-ignore lint/security/noDangerouslySetInnerHtml: This is safe
94 dangerouslySetInnerHTML={{ __html: html }}
95 />
96 </div>
97 {props.children}
98 </SlateElement>
99 );
100 }
101
101 lines Plain Text