From e93a56d7534a9287f81ee15aa7bb3ab8b23aff52 Mon Sep 17 00:00:00 2001 From: Amruth Pillai Date: Sat, 4 Jul 2026 21:29:57 +0200 Subject: [PATCH] refactor(web): finding 1 - extract TypographyGroupFields component Extract useTypographyForm helper (captures form creation + sync) and TypographyForm type. Extract TypographyGroupFields component with prefix "body" | "heading" to replace 2x4 duplicated form.Field blocks. Font Weight label ("Font Weights" vs "Font Weight") is preserved per prefix. Claude-Session: https://claude.ai/code/session_012Bnvt1MghwHj4qQRxuQUGa --- .../-sidebar/right/sections/typography.tsx | 186 ++++-------------- 1 file changed, 40 insertions(+), 146 deletions(-) diff --git a/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/typography.tsx b/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/typography.tsx index 8cb5d6140..669011fe5 100644 --- a/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/typography.tsx +++ b/apps/web/src/routes/builder/$resumeId/-sidebar/right/sections/typography.tsx @@ -29,6 +29,21 @@ const formSchema = typographySchema; type FormValues = z.infer; type FontWeight = FormValues["body"]["fontWeights"][number]; +type TypographyPrefix = "body" | "heading"; + +function useTypographyForm(typography: FormValues | undefined, persist: (data: FormValues) => void) { + const form = useAppForm({ + defaultValues: typography, + validators: { onChange: formSchema }, + onSubmit: ({ value }) => { + persist(value); + }, + }); + useSyncFormValues(form, typography); + return form; +} + +type TypographyForm = ReturnType; function TypographySectionForm() { const resume = useResume(); @@ -42,22 +57,12 @@ function TypographySectionForm() { }); }; - const form = useAppForm({ - defaultValues: typography, - validators: { onChange: formSchema }, - onSubmit: ({ value }) => { - persist(value); - }, - }); - useSyncFormValues(form, typography); + const form = useTypographyForm(typography, persist); const handleAutoSave = () => { persist(form.state.values); }; - const bodyFontFamily = useStore(form.store, (s) => s.values.body.fontFamily); - const headingFontFamily = useStore(form.store, (s) => s.values.heading.fontFamily); - return (
Body} /> - - - {(field) => ( - 0} - > - - Font Family - - { - if (value === null) return; - field.handleChange(value); - const nextWeights = getNextWeights(value); - if (nextWeights) form.setFieldValue("body.fontWeights", nextWeights); - handleAutoSave(); - }} - /> - } - /> - - - )} - - - - {(field) => ( - 0} - > - - Font Weights - - { - if (value?.length === 0) return; - field.handleChange(value as FontWeight[]); - handleAutoSave(); - }} - /> - } - /> - - - )} - - - - {(field) => ( - 0}> - - Font Size - - - { - const value = e.target.value; - if (value === "") field.handleChange("" as unknown as number); - else field.handleChange(Number(value)); - handleAutoSave(); - }} - /> - } - /> - - pt - - - - )} - - - - {(field) => ( - 0}> - - Line Height - - - { - const value = e.target.value; - if (value === "") field.handleChange("" as unknown as number); - else field.handleChange(Number(value)); - handleAutoSave(); - }} - /> - } - /> - - x - - - - )} - - + Heading} /> + + + ); +} - +type TypographyGroupFieldsProps = { + form: TypographyForm; + prefix: TypographyPrefix; + handleAutoSave: () => void; +}; + +function TypographyGroupFields({ form, prefix, handleAutoSave }: TypographyGroupFieldsProps) { + const fontFamily = useStore(form.store, (s) => s.values[prefix].fontFamily); + + return ( + <> + {(field) => ( @@ -224,20 +120,18 @@ function TypographySectionForm() { )} - + {(field) => ( 0} > - - Font Weight - + {prefix === "body" ? Font Weights : Font Weight} { if (value?.length === 0) return; field.handleChange(value as FontWeight[]); @@ -251,7 +145,7 @@ function TypographySectionForm() { )} - + {(field) => ( 0}> @@ -285,7 +179,7 @@ function TypographySectionForm() { )} - + {(field) => ( 0}> @@ -318,7 +212,7 @@ function TypographySectionForm() { )} - + ); }