返回 oh-my-ppt
PrimaryActions.tsx
根目录 / src / renderer / src / components / session-detail / workspace / toolbar / PrimaryActions.tsx
1 import { Check, Loader2, Redo2, RotateCcw, Undo2 } from 'lucide-react'
2 import { cn } from '@renderer/lib/utils'
3 import { useT } from '@renderer/i18n'
4 import { useSessionDetailRuntimeStore } from '@renderer/store'
5 import { Tooltip, TooltipContent, TooltipTrigger } from '../../../ui/Tooltip'
6
7 export function PrimaryActions({
8 disabled,
9 isSavingEdits,
10 canUndo,
11 canRedo,
12 hasPendingEdits
13 }: {
14 disabled: boolean
15 isSavingEdits: boolean
16 canUndo: boolean
17 canRedo: boolean
18 hasPendingEdits: boolean
19 }): React.JSX.Element {
20 const t = useT()
21 const actions = useSessionDetailRuntimeStore((state) => state.workspaceRibbonActions)
22
23 return (
24 <div className="flex shrink-0 items-center gap-1 rounded-[0.95rem] bg-[#e8e0d0]/54 px-1 py-0.5 shadow-[inset_0_1px_0_rgba(255,255,255,0.42)]">
25 <Tooltip>
26 <TooltipTrigger asChild>
27 <button
28 type="button"
29 className={cn(
30 'inline-flex h-6 shrink-0 items-center justify-center rounded-full px-2.5 text-[10px] font-bold leading-none transition-colors disabled:pointer-events-none disabled:opacity-45',
31 hasPendingEdits
32 ? 'bg-[#5d6b4d] text-white shadow-[0_4px_10px_rgba(62,74,50,0.15)] hover:bg-[#3e4a32]'
33 : 'bg-[#fffaf1]/72 text-[#8a9a7b] shadow-[inset_0_1px_0_rgba(255,255,255,0.54)]'
34 )}
35 onClick={() => actions?.onSaveCurrentPage()}
36 disabled={disabled || !hasPendingEdits}
37 aria-label={t('sessionDetail.saveCurrentPageTooltip')}
38 >
39 {isSavingEdits ? (
40 <Loader2 className="mr-1 h-2.5 w-2.5 animate-spin text-current" />
41 ) : (
42 <Check className="mr-1 h-2.5 w-2.5 text-current" />
43 )}
44 {t('sessionDetail.saveCurrentPage')}
45 </button>
46 </TooltipTrigger>
47 <TooltipContent side="bottom">{t('sessionDetail.saveCurrentPageTooltip')}</TooltipContent>
48 </Tooltip>
49 <Tooltip>
50 <TooltipTrigger asChild>
51 <button
52 type="button"
53 className={cn(
54 'inline-flex h-[22px] w-[22px] items-center justify-center rounded-full transition-colors disabled:pointer-events-none disabled:opacity-45',
55 hasPendingEdits
56 ? 'text-[#b8860b] hover:bg-[#f5deb3]/54 hover:text-[#8b6914]'
57 : 'text-[#a4aa9a]'
58 )}
59 onClick={() => actions?.onDiscardAllEdits()}
60 disabled={disabled || !hasPendingEdits}
61 aria-label={t('sessionDetail.discardAllEditsTooltip')}
62 >
63 <RotateCcw className="h-3 w-3" />
64 </button>
65 </TooltipTrigger>
66 <TooltipContent side="bottom">{t('sessionDetail.discardAllEditsTooltip')}</TooltipContent>
67 </Tooltip>
68 <div className="ml-0.5 flex items-center gap-0.5 rounded-full bg-[#f5f1e8]/48 p-0.5 shadow-[inset_0_1px_3px_rgba(74,59,42,0.045)]">
69 <Tooltip>
70 <TooltipTrigger asChild>
71 <button
72 type="button"
73 className="inline-flex h-[22px] w-[22px] items-center justify-center rounded-full text-[#5d6b4d] transition-colors hover:bg-[#d4e4c1]/64 hover:text-[#3e4a32] disabled:pointer-events-none disabled:text-[#a4aa9a] disabled:opacity-45"
74 onClick={() => actions?.onUndo()}
75 disabled={disabled || !canUndo}
76 aria-label={t('sessionDetail.undoCurrentPageTooltip')}
77 >
78 <Undo2 className="h-3 w-3" />
79 </button>
80 </TooltipTrigger>
81 <TooltipContent side="bottom">{t('sessionDetail.undoCurrentPageTooltip')}</TooltipContent>
82 </Tooltip>
83 <Tooltip>
84 <TooltipTrigger asChild>
85 <button
86 type="button"
87 className="inline-flex h-[22px] w-[22px] items-center justify-center rounded-full text-[#5d6b4d] transition-colors hover:bg-[#d4e4c1]/64 hover:text-[#3e4a32] disabled:pointer-events-none disabled:text-[#a4aa9a] disabled:opacity-45"
88 onClick={() => actions?.onRedo()}
89 disabled={disabled || !canRedo}
90 aria-label={t('sessionDetail.redoCurrentPageTooltip')}
91 >
92 <Redo2 className="h-3 w-3" />
93 </button>
94 </TooltipTrigger>
95 <TooltipContent side="bottom">{t('sessionDetail.redoCurrentPageTooltip')}</TooltipContent>
96 </Tooltip>
97 </div>
98 </div>
99 )
100 }
101
101 lines Plain Text