返回 presentation-ai
mode-toolbar-button.tsx
根目录 / src / components / plate / ui / mode-toolbar-button.tsx
1 "use client";
2
3 import {
4 DropdownMenuItemIndicator,
5 type DropdownMenuProps,
6 } from "@radix-ui/react-dropdown-menu";
7 import { CheckIcon, EyeIcon, PenIcon } from "lucide-react";
8 import { usePlateState } from "platejs/react";
9 import * as React from "react";
10
11 import {
12 DropdownMenu,
13 DropdownMenuContent,
14 DropdownMenuRadioGroup,
15 DropdownMenuRadioItem,
16 DropdownMenuTrigger,
17 } from "@/components/plate/ui/dropdown-menu";
18 import { ToolbarButton } from "./toolbar";
19
20 const item: Record<string, { icon: React.ReactNode; label: string }> = {
21 editing: {
22 icon: <PenIcon />,
23 label: "Editing",
24 },
25 viewing: {
26 icon: <EyeIcon />,
27 label: "Viewing",
28 },
29 };
30
31 export function ModeToolbarButton(props: DropdownMenuProps) {
32 const [readOnly, setReadOnly] = usePlateState("readOnly");
33 const [open, setOpen] = React.useState(false);
34
35 const value = readOnly ? "viewing" : "editing";
36
37 return (
38 <DropdownMenu open={open} onOpenChange={setOpen} modal={false} {...props}>
39 <DropdownMenuTrigger asChild>
40 <ToolbarButton pressed={open} tooltip="Editing mode" isDropdown>
41 {item[value]!.icon}
42 <span className="hidden lg:inline">{item[value]!.label}</span>
43 </ToolbarButton>
44 </DropdownMenuTrigger>
45
46 <DropdownMenuContent className="min-w-45" align="start">
47 <DropdownMenuRadioGroup
48 value={value}
49 onValueChange={(newValue) => {
50 if (newValue === "viewing") {
51 setReadOnly(true);
52 } else {
53 setReadOnly(false);
54 }
55 }}
56 >
57 <DropdownMenuRadioItem
58 className="pl-2 [span]:first:*:hidden [svg]:*:text-muted-foreground"
59 value="editing"
60 >
61 <Indicator />
62 {item.editing!.icon}
63 {item.editing!.label}
64 </DropdownMenuRadioItem>
65
66 <DropdownMenuRadioItem
67 className="pl-2 [span]:first:*:hidden [svg]:*:text-muted-foreground"
68 value="viewing"
69 >
70 <Indicator />
71 {item.viewing!.icon}
72 {item.viewing!.label}
73 </DropdownMenuRadioItem>
74 </DropdownMenuRadioGroup>
75 </DropdownMenuContent>
76 </DropdownMenu>
77 );
78 }
79
80 function Indicator() {
81 return (
82 <span className="pointer-events-none absolute right-2 flex size-3.5 items-center justify-center">
83 <DropdownMenuItemIndicator>
84 <CheckIcon />
85 </DropdownMenuItemIndicator>
86 </span>
87 );
88 }
89
89 lines Plain Text