From 17aa547a134aec484dcd78ee907b5905b0a076ae Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Thu, 9 Oct 2025 17:12:32 -0300 Subject: [PATCH 1/2] fix: update field ID type and improve field handling This commit modifies the TemplateField interface to allow the ID to be either a string or a number. It also updates the SuperDocTemplateBuilder component to handle the new ID type, ensuring that field insertion, deletion, and selection functions correctly accommodate both types. This change enhances flexibility in managing template fields. --- src/index.tsx | 38 +++++++++++++++++++------------------- src/types.ts | 17 ++++++++++------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index b800db2..a630ab4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -143,7 +143,9 @@ const SuperDocTemplateBuilder = forwardRef< const [templateFields, setTemplateFields] = useState( fields.initial || [], ); - const [selectedFieldId, setSelectedFieldId] = useState(null); + const [selectedFieldId, setSelectedFieldId] = useState( + null, + ); const [menuVisible, setMenuVisible] = useState(false); const [menuPosition, setMenuPosition] = useState(); const [menuQuery, setMenuQuery] = useState(""); @@ -202,13 +204,12 @@ const SuperDocTemplateBuilder = forwardRef< if (!superdocRef.current?.activeEditor) return false; const editor = superdocRef.current.activeEditor; - const fieldId = `field_${Date.now()}`; + const previousFields = templateFields; const success = mode === "inline" ? editor.commands.insertStructuredContentInline?.({ attrs: { - id: fieldId, alias: field.alias, tag: field.metadata ? JSON.stringify(field.metadata) @@ -218,7 +219,6 @@ const SuperDocTemplateBuilder = forwardRef< }) : editor.commands.insertStructuredContentBlock?.({ attrs: { - id: fieldId, alias: field.alias, tag: field.metadata ? JSON.stringify(field.metadata) @@ -228,28 +228,28 @@ const SuperDocTemplateBuilder = forwardRef< }); if (success) { - const newField: Types.TemplateField = { - id: fieldId, - alias: field.alias, - tag: field.category, - }; + const updatedFields = getTemplateFieldsFromEditor(editor); - setTemplateFields((prev) => { - const updated = [...prev, newField]; - onFieldsChange?.(updated); - return updated; - }); + setTemplateFields(updatedFields); + onFieldsChange?.(updatedFields); + + const insertedField = updatedFields.find( + (candidate) => + !previousFields.some((existing) => existing.id === candidate.id), + ); - onFieldInsert?.(newField); + if (insertedField) { + onFieldInsert?.(insertedField); + } } return success; }, - [onFieldInsert, onFieldsChange], + [onFieldInsert, onFieldsChange, templateFields], ); const updateField = useCallback( - (id: string, updates: Partial): boolean => { + (id: string | number, updates: Partial): boolean => { if (!superdocRef.current?.activeEditor) return false; const editor = superdocRef.current.activeEditor; @@ -275,7 +275,7 @@ const SuperDocTemplateBuilder = forwardRef< ); const deleteField = useCallback( - (id: string): boolean => { + (id: string | number): boolean => { const editor = superdocRef.current?.activeEditor; if (!editor) { @@ -348,7 +348,7 @@ const SuperDocTemplateBuilder = forwardRef< ); const selectField = useCallback( - (id: string) => { + (id: string | number) => { if (!superdocRef.current?.activeEditor) return; const editor = superdocRef.current.activeEditor; diff --git a/src/types.ts b/src/types.ts index ebc6915..8f31d17 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,7 +9,7 @@ export interface FieldDefinition { } export interface TemplateField { - id: string; + id: string | number; alias: string; tag?: string; position?: number; @@ -38,8 +38,8 @@ export interface FieldMenuProps { export interface FieldListProps { fields: TemplateField[]; onSelect: (field: TemplateField) => void; - onDelete: (fieldId: string) => void; - selectedFieldId?: string; + onDelete: (fieldId: string | number) => void; + selectedFieldId?: string | number; } export interface DocumentConfig { @@ -87,7 +87,7 @@ export interface SuperDocTemplateBuilderProps { onTrigger?: (event: TriggerEvent) => void; onFieldInsert?: (field: TemplateField) => void; onFieldUpdate?: (field: TemplateField) => void; - onFieldDelete?: (fieldId: string) => void; + onFieldDelete?: (fieldId: string | number) => void; onFieldsChange?: (fields: TemplateField[]) => void; onFieldSelect?: (field: TemplateField | null) => void; onFieldCreate?: ( @@ -105,9 +105,12 @@ export interface SuperDocTemplateBuilderHandle { insertBlockField: ( field: Partial & { alias: string }, ) => boolean; - updateField: (id: string, updates: Partial) => boolean; - deleteField: (id: string) => boolean; - selectField: (id: string) => void; + updateField: ( + id: string | number, + updates: Partial, + ) => boolean; + deleteField: (id: string | number) => boolean; + selectField: (id: string | number) => void; nextField: () => void; previousField: () => void; getFields: () => TemplateField[]; From 2ff4203fd33faf4b4a849118092e24bcc0e5cb9b Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Thu, 9 Oct 2025 17:26:40 -0300 Subject: [PATCH 2/2] refactor: streamline tag mapping in getTemplateFieldsFromEditor function This commit simplifies the mapping logic in the getTemplateFieldsFromEditor function by removing unnecessary filtering. The function now directly returns the mapped tags, enhancing readability and maintainability of the code. --- src/index.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index a630ab4..8a6660d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -28,18 +28,16 @@ const getTemplateFieldsFromEditor = ( const tags = structuredContentHelpers.getStructuredContentTags(editor.state) || []; - return tags - .map((entry: any) => { - const node = entry?.node ?? entry; - const attrs = node?.attrs ?? {}; - - return { - id: attrs.id, - alias: attrs.alias || attrs.label || "", - tag: attrs.tag, - } as Types.TemplateField; - }) - .filter((field: Types.TemplateField) => Boolean(field.id)); + return tags.map((entry: any) => { + const node = entry?.node ?? entry; + const attrs = node?.attrs ?? {}; + + return { + id: attrs.id, + alias: attrs.alias || attrs.label || "", + tag: attrs.tag, + } as Types.TemplateField; + }); }; const areTemplateFieldsEqual = (