Skip to content
This repository was archived by the owner on Jan 30, 2026. It is now read-only.

Commit a1ecf7d

Browse files
authored
feat: add toolbar configuration options to SuperDocTemplateBuilder and update README (#7)
1 parent f966422 commit a1ecf7d

File tree

5 files changed

+85
-9
lines changed

5 files changed

+85
-9
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ function TemplateEditor() {
9292
component: CustomFieldList // Custom list component
9393
}}
9494

95+
// Toolbar (optional)
96+
toolbar={true} // Render built-in toolbar container
97+
// toolbar="#my-toolbar" // Mount into existing element
98+
// toolbar={{ // Configure built-in toolbar
99+
// toolbarGroups: ['center'],
100+
// excludeItems: ['italic', 'bold'],
101+
// }}
102+
95103
// Event handlers
96104
onReady={() => {}}
97105
onTrigger={(event) => {}}

demo/src/App.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ header {
2121
}
2222

2323
.header-content {
24-
max-width: 1400px;
24+
max-width: 1600px;
2525
margin: 0 auto;
2626
display: flex;
2727
justify-content: space-between;
@@ -66,7 +66,7 @@ header {
6666

6767
/* Container */
6868
.container {
69-
max-width: 1400px;
69+
max-width: 1600px;
7070
margin: 2rem auto;
7171
padding: 0 2rem;
7272
}
@@ -229,11 +229,11 @@ header {
229229
gap: 0.5rem;
230230
}
231231

232-
.superdoc-template-builder > div {
232+
.superdoc-template-builder>div {
233233
flex-direction: column !important;
234234
}
235235

236236
.superdoc-field-list {
237237
width: 100% !important;
238238
}
239-
}
239+
}

demo/src/App.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ export function App() {
175175
document={documentConfig}
176176
fields={fieldsConfig}
177177
list={listConfig}
178+
toolbar={true}
178179
onReady={handleReady}
179180
onTrigger={handleTrigger}
180181
onFieldInsert={handleFieldInsert}

src/index.tsx

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,35 @@ const areTemplateFieldsEqual = (
6868
return true;
6969
};
7070

71+
const resolveToolbar = (
72+
toolbar: Types.SuperDocTemplateBuilderProps["toolbar"],
73+
) => {
74+
if (!toolbar) return null;
75+
76+
if (toolbar === true) {
77+
return {
78+
selector: "#superdoc-toolbar",
79+
config: {} as Omit<Types.ToolbarConfig, "selector">,
80+
renderDefaultContainer: true,
81+
};
82+
}
83+
84+
if (typeof toolbar === "string") {
85+
return {
86+
selector: toolbar,
87+
config: {} as Omit<Types.ToolbarConfig, "selector">,
88+
renderDefaultContainer: false,
89+
};
90+
}
91+
92+
const { selector, ...config } = toolbar;
93+
return {
94+
selector: selector || "#superdoc-toolbar",
95+
config,
96+
renderDefaultContainer: selector === undefined,
97+
};
98+
};
99+
71100
const SuperDocTemplateBuilder = forwardRef<
72101
Types.SuperDocTemplateBuilderHandle,
73102
Types.SuperDocTemplateBuilderProps
@@ -77,6 +106,7 @@ const SuperDocTemplateBuilder = forwardRef<
77106
fields = {},
78107
menu = {},
79108
list = {},
109+
toolbar,
80110
onReady,
81111
onTrigger,
82112
onFieldInsert,
@@ -336,7 +366,7 @@ const SuperDocTemplateBuilder = forwardRef<
336366
const initSuperDoc = async () => {
337367
const { SuperDoc } = await import("superdoc");
338368

339-
const instance = new SuperDoc({
369+
const config: Record<string, unknown> = {
340370
selector: containerRef.current!,
341371
document: document?.source,
342372
documentMode: document?.mode || "editing",
@@ -419,6 +449,21 @@ const SuperDocTemplateBuilder = forwardRef<
419449

420450
onReady?.();
421451
},
452+
};
453+
454+
const instance = new SuperDoc({
455+
...config,
456+
...(toolbarSettings && {
457+
toolbar: toolbarSettings.selector,
458+
modules: {
459+
toolbar: {
460+
selector: toolbarSettings.selector,
461+
toolbarGroups: toolbarSettings.config.toolbarGroups || ["center"],
462+
excludeItems: toolbarSettings.config.excludeItems || [],
463+
...toolbarSettings.config,
464+
},
465+
},
466+
}),
422467
});
423468

424469
superdocRef.current = instance;
@@ -441,6 +486,7 @@ const SuperDocTemplateBuilder = forwardRef<
441486
discoverFields,
442487
onReady,
443488
onTrigger,
489+
toolbar,
444490
]);
445491

446492
const handleMenuSelect = useCallback(
@@ -519,12 +565,11 @@ const SuperDocTemplateBuilder = forwardRef<
519565

520566
const exportTemplate = useCallback(
521567
async (options?: { fileName?: string }): Promise<void> => {
522-
const editor = superdocRef.current?.activeEditor;
523-
if (!editor) return;
524568

525569
try {
526-
await editor.exportDocx?.({
527-
fileName: options?.fileName || "document.docx",
570+
await superdocRef.current?.export({
571+
exportType: ["docx"],
572+
exportedName: options?.fileName ? options?.fileName : "document"
528573
});
529574
} catch (error) {
530575
console.error("Failed to export DOCX", error);
@@ -551,6 +596,8 @@ const SuperDocTemplateBuilder = forwardRef<
551596
const MenuComponent = menu.component || FieldMenu;
552597
const ListComponent = list.component || FieldList;
553598

599+
const toolbarSettings = resolveToolbar(toolbar);
600+
554601
return (
555602
<div
556603
className={`superdoc-template-builder ${className || ""}`}
@@ -571,6 +618,13 @@ const SuperDocTemplateBuilder = forwardRef<
571618

572619
{/* Document */}
573620
<div className="superdoc-template-builder-document" style={{ flex: 1 }}>
621+
{toolbarSettings?.renderDefaultContainer && (
622+
<div
623+
id="superdoc-toolbar"
624+
className="superdoc-template-builder-toolbar"
625+
data-testid="template-builder-toolbar"
626+
/>
627+
)}
574628
<div
575629
ref={containerRef}
576630
className="superdoc-template-builder-editor"

src/types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,24 @@ export interface ListConfig {
6363
position?: "left" | "right";
6464
}
6565

66+
export interface ToolbarConfig {
67+
selector?: string;
68+
toolbarGroups?: string[];
69+
groups?: Record<string, string[]>;
70+
fonts?: string[] | null;
71+
hideButtons?: boolean;
72+
responsiveToContainer?: boolean;
73+
excludeItems?: string[];
74+
texts?: Record<string, string>;
75+
icons?: Record<string, any>;
76+
}
77+
6678
export interface SuperDocTemplateBuilderProps {
6779
document?: DocumentConfig;
6880
fields?: FieldsConfig;
6981
menu?: MenuConfig;
7082
list?: ListConfig;
83+
toolbar?: boolean | string | ToolbarConfig;
7184

7285
// Events
7386
onReady?: () => void;

0 commit comments

Comments
 (0)