返回 presentation-ai
ZoomControl.tsx
根目录 / src / components / presentation / controls / ZoomControl.tsx
1 "use client";
2
3 import { Check } from "lucide-react";
4
5 import { Button } from "@/components/ui/button";
6 import {
7 DropdownMenu,
8 DropdownMenuContent,
9 DropdownMenuItem,
10 DropdownMenuTrigger,
11 } from "@/components/ui/dropdown-menu";
12 import { usePresentationState } from "@/states/presentation-state";
13
14 const ZOOM_LEVELS = [
15 { value: 1.8, label: "180%" },
16 { value: 1.7, label: "170%" },
17 { value: 1.6, label: "160%" },
18 { value: 1.5, label: "150%" },
19 { value: 1.4, label: "140%" },
20 { value: 1.3, label: "130%" },
21 { value: 1.2, label: "120%" },
22 { value: 1.1, label: "110%" },
23 { value: 1, label: "100%" },
24 { value: 0.9, label: "90%" },
25 { value: 0.8, label: "80%" },
26 { value: 0.7, label: "70%" },
27 { value: 0.6, label: "60%" },
28 { value: 0.5, label: "50%" },
29 ];
30
31 export function ZoomControl() {
32 const zoomLevel = usePresentationState((s) => s.zoomLevel);
33 const setZoomLevel = usePresentationState((s) => s.setZoomLevel);
34
35 const displayPercentage = Math.round(zoomLevel * 100);
36
37 return (
38 <DropdownMenu>
39 <DropdownMenuTrigger asChild>
40 <Button
41 variant="ghost"
42 size="sm"
43 className="h-8 rounded-full px-2 text-xs text-foreground hover:bg-accent hover:text-accent-foreground"
44 >
45 {displayPercentage}%
46 </Button>
47 </DropdownMenuTrigger>
48 <DropdownMenuContent align="end" className="w-28">
49 {ZOOM_LEVELS.map((level) => (
50 <DropdownMenuItem
51 key={level.value}
52 className="flex items-center justify-between"
53 onClick={() => setZoomLevel(level.value)}
54 >
55 <span>{level.label}</span>
56 {zoomLevel === level.value && <Check className="size-4" />}
57 </DropdownMenuItem>
58 ))}
59 <DropdownMenuItem
60 className="flex items-center justify-between"
61 onClick={() => setZoomLevel(1)}
62 >
63 <span>Fit</span>
64 {zoomLevel === 1 && <Check className="size-4" />}
65 </DropdownMenuItem>
66 </DropdownMenuContent>
67 </DropdownMenu>
68 );
69 }
70
70 lines Plain Text