feat: refactor ComposeCanvas to use reactive style props and use complete declarative approach for editor+toolbar

This commit is contained in:
ramvignesh-b
2026-05-01 11:32:23 +05:30
parent 5f56b21823
commit 90b04f2397
3 changed files with 21 additions and 27 deletions
@@ -41,7 +41,6 @@ export type CanvasTools = {
getData: () => CanvasJSON; getData: () => CanvasJSON;
getImages: () => { src: string; file: File }[]; getImages: () => { src: string; file: File }[];
loadData: (data: CanvasJSON) => Promise<void>; loadData: (data: CanvasJSON) => Promise<void>;
setStyle: (style: CanvasStyle) => void;
getStyle: () => CanvasStyle; getStyle: () => CanvasStyle;
}; };
@@ -92,12 +91,14 @@ const DEFAULT_INIT_TEXT = "Take a deep breath...";
interface ComposeCanvasProps { interface ComposeCanvasProps {
readOnly?: boolean; readOnly?: boolean;
initialData?: CanvasJSON | null; initialData?: CanvasJSON | null;
style?: CanvasStyle;
ref?: React.Ref<CanvasTools>; ref?: React.Ref<CanvasTools>;
} }
export function ComposeCanvas({ export function ComposeCanvas({
readOnly = false, readOnly = false,
initialData = null, initialData = null,
style,
ref, ref,
}: ComposeCanvasProps) { }: ComposeCanvasProps) {
// wrapper is the parent div box // wrapper is the parent div box
@@ -230,6 +231,15 @@ export function ComposeCanvas({
[readOnly, syncViewport, focusTextbox], [readOnly, syncViewport, focusTextbox],
); );
useEffect(() => {
if (style && textboxRef.current) {
const textBox = textboxRef.current;
textBox.fontFamily = style.fontFamily || textBox.fontFamily;
textBox.fill = style.fontColor || textBox.fill;
syncViewport();
}
}, [style, syncViewport]);
useEffect(() => { useEffect(() => {
let isMounted = true; let isMounted = true;
let resizeObserver: ResizeObserver | null = null; let resizeObserver: ResizeObserver | null = null;
@@ -356,16 +366,6 @@ export function ComposeCanvas({
await loadContent(data); await loadContent(data);
}, },
setStyle: (style: CanvasStyle) => {
const textBox = textboxRef.current;
if (!textBox) return;
textBox.fontFamily = style.fontFamily || textBox.fontFamily;
textBox.fill = style.fontColor || textBox.fill;
syncViewport();
},
getStyle: () => { getStyle: () => {
const textBox = textboxRef.current; const textBox = textboxRef.current;
+3 -3
View File
@@ -14,7 +14,7 @@ import { Modal } from "../ui/Modal";
import type { CanvasStyle } from "./ComposeCanvas.tsx"; import type { CanvasStyle } from "./ComposeCanvas.tsx";
interface ToolBarProps { interface ToolBarProps {
fileInputRef: React.RefObject<HTMLInputElement | null>; onAddImage: () => void;
sealBtnClicked: boolean; sealBtnClicked: boolean;
setSealBtnClicked: (v: boolean) => void; setSealBtnClicked: (v: boolean) => void;
onSave: (status: "SEALED" | "DRAFT" | "VAULT", date?: Date) => Promise<void>; onSave: (status: "SEALED" | "DRAFT" | "VAULT", date?: Date) => Promise<void>;
@@ -42,7 +42,7 @@ const FONT_COLORS: Map<string, string> = new Map([
]); ]);
export function ToolBar({ export function ToolBar({
fileInputRef, onAddImage,
sealBtnClicked, sealBtnClicked,
setSealBtnClicked, setSealBtnClicked,
onSave, onSave,
@@ -60,7 +60,7 @@ export function ToolBar({
<button <button
type="button" type="button"
className="btn btn-ghost btn-sm group" className="btn btn-ghost btn-sm group"
onClick={() => fileInputRef.current?.click()} onClick={onAddImage}
> >
<ImageIcon size={18} weight="bold" /> <ImageIcon size={18} weight="bold" />
<span className="hidden md:inline group-hover:inline transition-all duration-1000"> <span className="hidden md:inline group-hover:inline transition-all duration-1000">
+7 -13
View File
@@ -476,22 +476,12 @@ export default function Editor() {
{status === "DRAFT" ? ( {status === "DRAFT" ? (
<ToolBar <ToolBar
fileInputRef={fileInputRef} onAddImage={() => fileInputRef.current?.click()}
sealBtnClicked={sealBtnClicked} sealBtnClicked={sealBtnClicked}
setSealBtnClicked={setSealBtnClicked} setSealBtnClicked={setSealBtnClicked}
onSave={handleSave} onSave={handleSave}
setConfirmModal={setConfirmModal} setConfirmModal={setConfirmModal}
onFontChange={(style) => { onFontChange={setCanvasFontStyle}
setCanvasFontStyle({
fontFamily: style.fontFamily,
fontColor: style.fontColor,
});
if (canvasRef?.current?.setStyle)
canvasRef.current.setStyle({
fontFamily: style.fontFamily,
fontColor: style.fontColor,
});
}}
latestFontStyle={canvasFontStyle} latestFontStyle={canvasFontStyle}
/> />
) : ( ) : (
@@ -506,7 +496,11 @@ export default function Editor() {
className="hidden" className="hidden"
/> />
<ComposeCanvas ref={canvasRef} readOnly={status !== "DRAFT"} /> <ComposeCanvas
ref={canvasRef}
readOnly={status !== "DRAFT"}
style={canvasFontStyle}
/>
</div> </div>
</section> </section>
<LogModal <LogModal