From 335f829bebbe28703dce08b130dbf9298c7f02eb Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Thu, 9 Oct 2025 15:27:33 -0300 Subject: [PATCH] feat: add toolbar configuration options to SuperDocTemplateBuilder and update README --- README.md | 8 ++++++ demo/src/App.css | 8 +++--- demo/src/App.tsx | 1 + src/index.tsx | 64 ++++++++++++++++++++++++++++++++++++++++++++---- src/types.ts | 13 ++++++++++ 5 files changed, 85 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9a575c2..d75c53b 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,14 @@ function TemplateEditor() { component: CustomFieldList // Custom list component }} + // Toolbar (optional) + toolbar={true} // Render built-in toolbar container + // toolbar="#my-toolbar" // Mount into existing element + // toolbar={{ // Configure built-in toolbar + // toolbarGroups: ['center'], + // excludeItems: ['italic', 'bold'], + // }} + // Event handlers onReady={() => {}} onTrigger={(event) => {}} diff --git a/demo/src/App.css b/demo/src/App.css index 74d3aef..d19213f 100644 --- a/demo/src/App.css +++ b/demo/src/App.css @@ -21,7 +21,7 @@ header { } .header-content { - max-width: 1400px; + max-width: 1600px; margin: 0 auto; display: flex; justify-content: space-between; @@ -66,7 +66,7 @@ header { /* Container */ .container { - max-width: 1400px; + max-width: 1600px; margin: 2rem auto; padding: 0 2rem; } @@ -229,11 +229,11 @@ header { gap: 0.5rem; } - .superdoc-template-builder > div { + .superdoc-template-builder>div { flex-direction: column !important; } .superdoc-field-list { width: 100% !important; } -} +} \ No newline at end of file diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 69b6bf2..478dcc7 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -175,6 +175,7 @@ export function App() { document={documentConfig} fields={fieldsConfig} list={listConfig} + toolbar={true} onReady={handleReady} onTrigger={handleTrigger} onFieldInsert={handleFieldInsert} diff --git a/src/index.tsx b/src/index.tsx index eddb5ec..197da12 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -68,6 +68,35 @@ const areTemplateFieldsEqual = ( return true; }; +const resolveToolbar = ( + toolbar: Types.SuperDocTemplateBuilderProps["toolbar"], +) => { + if (!toolbar) return null; + + if (toolbar === true) { + return { + selector: "#superdoc-toolbar", + config: {} as Omit, + renderDefaultContainer: true, + }; + } + + if (typeof toolbar === "string") { + return { + selector: toolbar, + config: {} as Omit, + renderDefaultContainer: false, + }; + } + + const { selector, ...config } = toolbar; + return { + selector: selector || "#superdoc-toolbar", + config, + renderDefaultContainer: selector === undefined, + }; +}; + const SuperDocTemplateBuilder = forwardRef< Types.SuperDocTemplateBuilderHandle, Types.SuperDocTemplateBuilderProps @@ -77,6 +106,7 @@ const SuperDocTemplateBuilder = forwardRef< fields = {}, menu = {}, list = {}, + toolbar, onReady, onTrigger, onFieldInsert, @@ -336,7 +366,7 @@ const SuperDocTemplateBuilder = forwardRef< const initSuperDoc = async () => { const { SuperDoc } = await import("superdoc"); - const instance = new SuperDoc({ + const config: Record = { selector: containerRef.current!, document: document?.source, documentMode: document?.mode || "editing", @@ -419,6 +449,21 @@ const SuperDocTemplateBuilder = forwardRef< onReady?.(); }, + }; + + const instance = new SuperDoc({ + ...config, + ...(toolbarSettings && { + toolbar: toolbarSettings.selector, + modules: { + toolbar: { + selector: toolbarSettings.selector, + toolbarGroups: toolbarSettings.config.toolbarGroups || ["center"], + excludeItems: toolbarSettings.config.excludeItems || [], + ...toolbarSettings.config, + }, + }, + }), }); superdocRef.current = instance; @@ -441,6 +486,7 @@ const SuperDocTemplateBuilder = forwardRef< discoverFields, onReady, onTrigger, + toolbar, ]); const handleMenuSelect = useCallback( @@ -519,12 +565,11 @@ const SuperDocTemplateBuilder = forwardRef< const exportTemplate = useCallback( async (options?: { fileName?: string }): Promise => { - const editor = superdocRef.current?.activeEditor; - if (!editor) return; try { - await editor.exportDocx?.({ - fileName: options?.fileName || "document.docx", + await superdocRef.current?.export({ + exportType: ["docx"], + exportedName: options?.fileName ? options?.fileName : "document" }); } catch (error) { console.error("Failed to export DOCX", error); @@ -551,6 +596,8 @@ const SuperDocTemplateBuilder = forwardRef< const MenuComponent = menu.component || FieldMenu; const ListComponent = list.component || FieldList; + const toolbarSettings = resolveToolbar(toolbar); + return (
+ {toolbarSettings?.renderDefaultContainer && ( +
+ )}
; + fonts?: string[] | null; + hideButtons?: boolean; + responsiveToContainer?: boolean; + excludeItems?: string[]; + texts?: Record; + icons?: Record; +} + export interface SuperDocTemplateBuilderProps { document?: DocumentConfig; fields?: FieldsConfig; menu?: MenuConfig; list?: ListConfig; + toolbar?: boolean | string | ToolbarConfig; // Events onReady?: () => void;