返回 presentation-ai
date-node.tsx
根目录 / src / components / plate / ui / date-node.tsx
1 "use client";
2
3 import { type TDateElement } from "platejs";
4 import {
5 PlateElement,
6 useReadOnly,
7 type PlateElementProps,
8 } from "platejs/react";
9
10 import { Calendar } from "@/components/plate/ui/calendar";
11 import {
12 Popover,
13 PopoverContent,
14 PopoverTrigger,
15 } from "@/components/plate/ui/popover";
16 import { cn } from "@/lib/utils";
17
18 function formatDateElementLabel(date: string) {
19 return new Date(date).toLocaleDateString(undefined, {
20 day: "numeric",
21 month: "long",
22 year: "numeric",
23 });
24 }
25
26 export function DateElement(props: PlateElementProps<TDateElement>) {
27 const { editor, element } = props;
28
29 const readOnly = useReadOnly();
30
31 const trigger = (
32 <span
33 className={cn(
34 "w-fit cursor-pointer rounded-sm bg-muted px-1 text-muted-foreground",
35 )}
36 contentEditable={false}
37 draggable
38 >
39 {element.date ? (
40 formatDateElementLabel(element.date)
41 ) : (
42 <span>Pick a date</span>
43 )}
44 </span>
45 );
46
47 if (readOnly) {
48 return trigger;
49 }
50
51 return (
52 <PlateElement
53 {...props}
54 className="inline-block"
55 attributes={{
56 ...props.attributes,
57 contentEditable: false,
58 }}
59 >
60 <Popover>
61 <PopoverTrigger asChild>{trigger}</PopoverTrigger>
62 <PopoverContent className="w-auto p-0">
63 <Calendar
64 selected={new Date(element.date as string)}
65 onSelect={(date) => {
66 if (!date) return;
67
68 editor.tf.setNodes(
69 { date: date.toDateString() },
70 { at: element },
71 );
72 }}
73 mode="single"
74 initialFocus
75 />
76 </PopoverContent>
77 </Popover>
78 {props.children}
79 </PlateElement>
80 );
81 }
82
82 lines Plain Text