返回 oh-my-ppt
ArtTextInspector.tsx
根目录 / src / renderer / src / components / session-detail / element-inspector / ArtTextInspector.tsx
1 import { Sparkles } from 'lucide-react'
2 import {
3 buildArtTextInnerHtml,
4 getArtTextTemplateLabel,
5 isArtTextTemplateId
6 } from '@renderer/lib/artTextTemplates'
7 import { Input } from '../../ui/Input'
8 import { InspectorSection } from './InspectorSection'
9 import type { ElementEditorProps } from './types'
10 import { useT } from '@renderer/i18n'
11
12 export function ArtTextInspector({
13 selection,
14 draft,
15 onDraftChange
16 }: ElementEditorProps): React.JSX.Element {
17 const t = useT()
18 const templateId = selection.snapshot?.attrs.artTextTemplate || draft.artTextTemplateId
19 const templateLabel = getArtTextTemplateLabel(templateId) || t('editMode.artText')
20 const canEditText = isArtTextTemplateId(templateId)
21
22 const updateText = (text: string, commit = false): void => {
23 if (!canEditText) return
24 onDraftChange(
25 {
26 ...draft,
27 text,
28 html: buildArtTextInnerHtml(templateId, text),
29 artTextTemplateId: templateId
30 },
31 commit ? { commit: true, fields: ['html'] } : undefined
32 )
33 }
34
35 return (
36 <InspectorSection
37 title={t('editMode.artText')}
38 icon={<Sparkles className="h-3.5 w-3.5 text-[#7a875f]" />}
39 >
40 <div className="space-y-2.5">
41 <div className="rounded-[1rem] border border-[#ded2bd]/60 bg-[#fffdf8]/70 px-3 py-2">
42 <div className="text-[10px] font-semibold uppercase tracking-[0.12em] text-[#8a806b]">
43 {t('editMode.artTextEffect')}
44 </div>
45 <div className="mt-1 text-xs font-semibold text-[#3f4b35]">{templateLabel}</div>
46 </div>
47
48 <label className="block space-y-1.5">
49 <span className="text-[11px] font-medium text-[#7a875f]">
50 {t('editMode.artTextContent')}
51 </span>
52 <Input
53 value={draft.text}
54 onChange={(event) => updateText(event.target.value)}
55 onBlur={(event) => updateText(event.target.value, true)}
56 disabled={!canEditText}
57 className="h-8 rounded-full border border-[#ded2bd]/72 bg-[#fffdf8]/88 px-2.5 text-xs text-[#3f4b35] shadow-[inset_0_1px_2px_rgba(74,59,42,0.05)] focus-visible:border-[#9bb98a] focus-visible:ring-0 focus-visible:ring-offset-0"
58 />
59 </label>
60
61 <label className="block space-y-1.5">
62 <span className="text-[11px] font-medium text-[#7a875f]">
63 {t('editMode.artTextFontSize')}
64 </span>
65 <Input
66 type="number"
67 min={8}
68 max={160}
69 value={draft.fontSize}
70 onChange={(event) => onDraftChange({ ...draft, fontSize: event.target.value })}
71 onBlur={(event) =>
72 onDraftChange(
73 { ...draft, fontSize: event.target.value },
74 { commit: true, fields: ['fontSize'] }
75 )
76 }
77 className="h-8 rounded-full border border-[#ded2bd]/72 bg-[#fffdf8]/88 px-2.5 text-xs text-[#3f4b35] shadow-[inset_0_1px_2px_rgba(74,59,42,0.05)] focus-visible:border-[#9bb98a] focus-visible:ring-0 focus-visible:ring-offset-0"
78 />
79 </label>
80 </div>
81 </InspectorSection>
82 )
83 }
84
84 lines Plain Text