@superdoc-dev/template-builder 1.1.0 → 1.2.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -85
- package/dist/defaults/InfoTooltip.d.ts +3 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1163 -1104
- package/dist/tests/FieldList.test.d.ts +1 -0
- package/dist/tests/FieldMenu.test.d.ts +1 -0
- package/dist/tests/InfoTooltip.test.d.ts +1 -0
- package/dist/tests/utils.test.d.ts +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/utils.d.ts +17 -0
- package/package.json +4 -2
- package/src/styles/field-types.css +26 -0
- /package/dist/{test → tests}/setup.d.ts +0 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ npm install @superdoc-dev/template-builder
|
|
|
12
12
|
|
|
13
13
|
```jsx
|
|
14
14
|
import SuperDocTemplateBuilder from '@superdoc-dev/template-builder';
|
|
15
|
-
import 'superdoc/
|
|
15
|
+
import 'superdoc/style.css';
|
|
16
16
|
|
|
17
17
|
function TemplateEditor() {
|
|
18
18
|
return (
|
|
@@ -23,42 +23,30 @@ function TemplateEditor() {
|
|
|
23
23
|
}}
|
|
24
24
|
fields={{
|
|
25
25
|
available: [
|
|
26
|
-
{ id: '1324567890', label: 'Customer Name'
|
|
27
|
-
{ id: '1324567891', label: 'Invoice Date'
|
|
28
|
-
{ id: '1324567892', label: '
|
|
26
|
+
{ id: '1324567890', label: 'Customer Name' },
|
|
27
|
+
{ id: '1324567891', label: 'Invoice Date' },
|
|
28
|
+
{ id: '1324567892', label: 'Signature', mode: 'block', fieldType: 'signer' },
|
|
29
29
|
],
|
|
30
30
|
}}
|
|
31
|
-
onTrigger={(event) => {
|
|
32
|
-
console.log('User typed trigger at', event.position);
|
|
33
|
-
}}
|
|
34
31
|
onFieldInsert={(field) => {
|
|
35
|
-
console.log('Field inserted:', field.alias);
|
|
32
|
+
console.log('Field inserted:', field.alias, field.fieldType);
|
|
36
33
|
}}
|
|
37
34
|
/>
|
|
38
35
|
);
|
|
39
36
|
}
|
|
40
37
|
```
|
|
41
38
|
|
|
42
|
-
## What You Receive
|
|
43
|
-
|
|
44
|
-
```javascript
|
|
45
|
-
{
|
|
46
|
-
fields: [
|
|
47
|
-
{ id: "1324567890", alias: "Customer Name", tag: "contact" },
|
|
48
|
-
{ id: "1324567891", alias: "Invoice Date", tag: "invoice" }
|
|
49
|
-
],
|
|
50
|
-
document: { /* ProseMirror document JSON */ }
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
39
|
## Features
|
|
55
40
|
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
41
|
+
- **Trigger Detection** - Type `{{` (customizable) to insert fields
|
|
42
|
+
- **Field Management** - Insert, update, delete, and navigate fields
|
|
43
|
+
- **Field Discovery** - Automatically finds existing fields in documents
|
|
44
|
+
- **Field Types** - Distinguish owner vs signer fields with visual styling
|
|
45
|
+
- **Field Creation** - Allow users to create custom fields inline
|
|
46
|
+
- **Linked Fields** - Insert copies of existing fields that share a group
|
|
47
|
+
- **UI Agnostic** - Bring your own menus, panels, and components
|
|
48
|
+
- **SDT Based** - Uses structured content tags for Word compatibility
|
|
49
|
+
- **Export** - Download as `.docx` or get a Blob for API storage
|
|
62
50
|
|
|
63
51
|
## API
|
|
64
52
|
|
|
@@ -75,7 +63,8 @@ function TemplateEditor() {
|
|
|
75
63
|
// Field configuration
|
|
76
64
|
fields={{
|
|
77
65
|
available: FieldDefinition[], // Fields user can insert
|
|
78
|
-
initial: TemplateField[]
|
|
66
|
+
initial: TemplateField[], // Pre-existing fields
|
|
67
|
+
allowCreate: boolean, // Show "Create New Field" in menu
|
|
79
68
|
}}
|
|
80
69
|
|
|
81
70
|
// UI components (optional)
|
|
@@ -97,6 +86,15 @@ function TemplateEditor() {
|
|
|
97
86
|
// excludeItems: ['italic', 'bold'],
|
|
98
87
|
// }}
|
|
99
88
|
|
|
89
|
+
// Content Security Policy nonce (optional)
|
|
90
|
+
cspNonce="abc123"
|
|
91
|
+
|
|
92
|
+
// Telemetry (optional, enabled by default)
|
|
93
|
+
telemetry={{ enabled: true, metadata: { source: 'template-builder' } }}
|
|
94
|
+
|
|
95
|
+
// License key (optional)
|
|
96
|
+
licenseKey="your-license-key"
|
|
97
|
+
|
|
100
98
|
// Event handlers
|
|
101
99
|
onReady={() => {}}
|
|
102
100
|
onTrigger={(event) => {}}
|
|
@@ -105,17 +103,19 @@ function TemplateEditor() {
|
|
|
105
103
|
onFieldDelete={(fieldId) => {}}
|
|
106
104
|
onFieldsChange={(fields) => {}}
|
|
107
105
|
onFieldSelect={(field) => {}}
|
|
106
|
+
onFieldCreate={(field) => {}} // Called when user creates a custom field
|
|
107
|
+
onExport={(event) => {}} // Called after export with fields and blob
|
|
108
108
|
/>
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
### Ref Methods
|
|
112
112
|
|
|
113
113
|
```jsx
|
|
114
|
-
const ref = useRef();
|
|
114
|
+
const ref = useRef<SuperDocTemplateBuilderHandle>(null);
|
|
115
115
|
|
|
116
116
|
// Insert fields
|
|
117
|
-
ref.current.insertField({ alias: 'Customer Name' });
|
|
118
|
-
ref.current.insertBlockField({ alias: '
|
|
117
|
+
ref.current.insertField({ alias: 'Customer Name', fieldType: 'owner' });
|
|
118
|
+
ref.current.insertBlockField({ alias: 'Signature', fieldType: 'signer' });
|
|
119
119
|
|
|
120
120
|
// Update/delete fields
|
|
121
121
|
ref.current.updateField(fieldId, { alias: 'New Name' });
|
|
@@ -123,27 +123,114 @@ ref.current.deleteField(fieldId);
|
|
|
123
123
|
|
|
124
124
|
// Navigation
|
|
125
125
|
ref.current.selectField(fieldId);
|
|
126
|
-
ref.current.nextField();
|
|
127
|
-
ref.current.previousField();
|
|
126
|
+
ref.current.nextField();
|
|
127
|
+
ref.current.previousField();
|
|
128
128
|
|
|
129
129
|
// Get data
|
|
130
130
|
const fields = ref.current.getFields();
|
|
131
|
-
const
|
|
131
|
+
const blob = await ref.current.exportTemplate({ triggerDownload: false });
|
|
132
|
+
|
|
133
|
+
// Access SuperDoc instance
|
|
134
|
+
const superdoc = ref.current.getSuperDoc();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Field Types
|
|
138
|
+
|
|
139
|
+
Fields can have a `fieldType` property to distinguish between different roles (e.g. `'owner'` vs `'signer'`). This is stored in the SDT tag metadata and flows through the entire system.
|
|
140
|
+
|
|
141
|
+
### Defining field types
|
|
142
|
+
|
|
143
|
+
```jsx
|
|
144
|
+
const availableFields = [
|
|
145
|
+
{ id: '1', label: 'Company Name', fieldType: 'owner' },
|
|
146
|
+
{ id: '2', label: 'Signer Name', fieldType: 'signer' },
|
|
147
|
+
{ id: '3', label: 'Date' }, // defaults to 'owner'
|
|
148
|
+
];
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Visual styling
|
|
152
|
+
|
|
153
|
+
Import the optional CSS to color-code fields in the editor by type:
|
|
154
|
+
|
|
155
|
+
```jsx
|
|
156
|
+
import '@superdoc-dev/template-builder/field-types.css';
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Customize colors via CSS variables:
|
|
160
|
+
|
|
161
|
+
```css
|
|
162
|
+
:root {
|
|
163
|
+
--superdoc-field-owner-color: #629be7; /* default blue */
|
|
164
|
+
--superdoc-field-signer-color: #d97706; /* default amber */
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Accessing field type in callbacks
|
|
169
|
+
|
|
170
|
+
All field callbacks include `fieldType`:
|
|
171
|
+
|
|
172
|
+
```jsx
|
|
173
|
+
onFieldInsert={(field) => {
|
|
174
|
+
console.log(field.fieldType); // 'owner' | 'signer' | ...
|
|
175
|
+
}}
|
|
176
|
+
|
|
177
|
+
onFieldsChange={(fields) => {
|
|
178
|
+
const signerFields = fields.filter(f => f.fieldType === 'signer');
|
|
179
|
+
}}
|
|
132
180
|
```
|
|
133
181
|
|
|
182
|
+
## Custom Field Creation
|
|
183
|
+
|
|
184
|
+
Enable inline field creation in the dropdown menu:
|
|
185
|
+
|
|
186
|
+
```jsx
|
|
187
|
+
<SuperDocTemplateBuilder
|
|
188
|
+
fields={{
|
|
189
|
+
available: [...],
|
|
190
|
+
allowCreate: true,
|
|
191
|
+
}}
|
|
192
|
+
onFieldCreate={async (field) => {
|
|
193
|
+
// field.id starts with 'custom_'
|
|
194
|
+
// field.fieldType is 'owner' or 'signer' (user-selected)
|
|
195
|
+
const saved = await api.createField(field);
|
|
196
|
+
return { ...field, id: saved.id }; // return modified field or void
|
|
197
|
+
}}
|
|
198
|
+
/>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
The create form lets users pick inline/block mode and owner/signer field type.
|
|
202
|
+
|
|
203
|
+
## Linked Fields (Groups)
|
|
204
|
+
|
|
205
|
+
When a user selects an existing field from the menu, a linked copy is inserted. Linked fields share a group ID and stay in sync. The menu shows an "Existing Fields" section with grouped entries.
|
|
206
|
+
|
|
207
|
+
When the last field in a group is deleted, the remaining field's group tag is automatically removed.
|
|
208
|
+
|
|
134
209
|
## Custom Components
|
|
135
210
|
|
|
136
211
|
### Field Menu
|
|
137
212
|
|
|
138
213
|
```jsx
|
|
139
|
-
const CustomFieldMenu = ({
|
|
214
|
+
const CustomFieldMenu = ({
|
|
215
|
+
isVisible,
|
|
216
|
+
position,
|
|
217
|
+
availableFields,
|
|
218
|
+
filteredFields, // filtered by typed query after {{
|
|
219
|
+
filterQuery, // the query text
|
|
220
|
+
allowCreate,
|
|
221
|
+
existingFields, // fields already in the document
|
|
222
|
+
onSelect,
|
|
223
|
+
onSelectExisting,
|
|
224
|
+
onClose,
|
|
225
|
+
onCreateField,
|
|
226
|
+
}) => {
|
|
140
227
|
if (!isVisible) return null;
|
|
141
228
|
|
|
142
229
|
return (
|
|
143
230
|
<div style={{ position: 'fixed', left: position?.left, top: position?.top }}>
|
|
144
|
-
{
|
|
231
|
+
{filteredFields.map((field) => (
|
|
145
232
|
<button key={field.id} onClick={() => onSelect(field)}>
|
|
146
|
-
{field.label}
|
|
233
|
+
{field.label} {field.fieldType && `(${field.fieldType})`}
|
|
147
234
|
</button>
|
|
148
235
|
))}
|
|
149
236
|
<button onClick={onClose}>Cancel</button>
|
|
@@ -163,9 +250,9 @@ const CustomFieldList = ({ fields, onSelect, onDelete, selectedFieldId }) => {
|
|
|
163
250
|
<div
|
|
164
251
|
key={field.id}
|
|
165
252
|
onClick={() => onSelect(field)}
|
|
166
|
-
style={{ background: selectedFieldId === field.id ? '
|
|
253
|
+
style={{ background: selectedFieldId === field.id ? 'lightblue' : 'white' }}
|
|
167
254
|
>
|
|
168
|
-
{field.alias}
|
|
255
|
+
{field.alias} {field.fieldType && `[${field.fieldType}]`}
|
|
169
256
|
<button onClick={() => onDelete(field.id)}>Delete</button>
|
|
170
257
|
</div>
|
|
171
258
|
))}
|
|
@@ -180,7 +267,7 @@ Enable Tab/Shift+Tab navigation:
|
|
|
180
267
|
|
|
181
268
|
```jsx
|
|
182
269
|
function TemplateEditor() {
|
|
183
|
-
const ref = useRef();
|
|
270
|
+
const ref = useRef<SuperDocTemplateBuilderHandle>(null);
|
|
184
271
|
|
|
185
272
|
const handleKeyDown = (e) => {
|
|
186
273
|
if (e.key === 'Tab') {
|
|
@@ -203,65 +290,55 @@ function TemplateEditor() {
|
|
|
203
290
|
|
|
204
291
|
## Export Template
|
|
205
292
|
|
|
206
|
-
The `exportTemplate` method supports two modes
|
|
293
|
+
The `exportTemplate` method supports two modes via `ExportConfig`:
|
|
207
294
|
|
|
208
|
-
###
|
|
295
|
+
### Download Mode (Default)
|
|
209
296
|
|
|
210
|
-
|
|
297
|
+
```jsx
|
|
298
|
+
await ref.current?.exportTemplate();
|
|
299
|
+
await ref.current?.exportTemplate({ fileName: 'invoice-template' });
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Blob Mode (for Database/API)
|
|
211
303
|
|
|
212
304
|
```jsx
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
};
|
|
305
|
+
const blob = await ref.current?.exportTemplate({
|
|
306
|
+
fileName: 'invoice-template',
|
|
307
|
+
triggerDownload: false,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
if (blob) {
|
|
311
|
+
const formData = new FormData();
|
|
312
|
+
formData.append('template', blob, 'invoice-template.docx');
|
|
313
|
+
await fetch('/api/templates', { method: 'POST', body: formData });
|
|
314
|
+
}
|
|
222
315
|
```
|
|
223
316
|
|
|
224
|
-
###
|
|
317
|
+
### onExport Callback
|
|
225
318
|
|
|
226
|
-
|
|
319
|
+
Fires after every export with the field list and optional blob:
|
|
227
320
|
|
|
228
321
|
```jsx
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
fileName
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (blob) {
|
|
237
|
-
// Send to your API/database
|
|
238
|
-
const formData = new FormData();
|
|
239
|
-
formData.append('template', blob, 'invoice-template.docx');
|
|
240
|
-
|
|
241
|
-
await fetch('/api/templates', {
|
|
242
|
-
method: 'POST',
|
|
243
|
-
body: formData,
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
};
|
|
322
|
+
<SuperDocTemplateBuilder
|
|
323
|
+
onExport={(event) => {
|
|
324
|
+
console.log(event.fields); // TemplateField[]
|
|
325
|
+
console.log(event.fileName); // string
|
|
326
|
+
console.log(event.blob); // Blob | undefined (only in blob mode)
|
|
327
|
+
}}
|
|
328
|
+
/>
|
|
247
329
|
```
|
|
248
330
|
|
|
249
|
-
|
|
331
|
+
## Telemetry
|
|
250
332
|
|
|
251
|
-
|
|
252
|
-
interface ExportConfig {
|
|
253
|
-
fileName?: string; // Default: "document"
|
|
254
|
-
triggerDownload?: boolean; // Default: true
|
|
255
|
-
}
|
|
333
|
+
Telemetry is enabled by default with `source: 'template-builder'` metadata. You can override or extend the configuration:
|
|
256
334
|
|
|
257
|
-
|
|
258
|
-
|
|
335
|
+
```jsx
|
|
336
|
+
<SuperDocTemplateBuilder
|
|
337
|
+
telemetry={{ enabled: true, metadata: { source: 'my-app', environment: 'production' } }}
|
|
338
|
+
/>
|
|
259
339
|
```
|
|
260
340
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
- `Promise<void>` when `triggerDownload: true` (download happens automatically)
|
|
264
|
-
- `Promise<Blob>` when `triggerDownload: false` (returns the docx data)
|
|
341
|
+
For more details, see the [Telemetry](https://docs.superdoc.dev/resources/telemetry) documentation.
|
|
265
342
|
|
|
266
343
|
## TypeScript
|
|
267
344
|
|
|
@@ -274,10 +351,11 @@ import type {
|
|
|
274
351
|
FieldDefinition,
|
|
275
352
|
TriggerEvent,
|
|
276
353
|
ExportConfig,
|
|
354
|
+
ExportEvent,
|
|
355
|
+
FieldMenuProps,
|
|
356
|
+
FieldListProps,
|
|
277
357
|
SuperDocTemplateBuilderHandle,
|
|
278
358
|
} from '@superdoc-dev/template-builder';
|
|
279
|
-
|
|
280
|
-
const ref = useRef<SuperDocTemplateBuilderHandle>(null);
|
|
281
359
|
```
|
|
282
360
|
|
|
283
361
|
## License
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var ze=Object.create;var ge=Object.defineProperty;var Be=Object.getOwnPropertyDescriptor;var We=Object.getOwnPropertyNames;var Le=Object.getPrototypeOf,He=Object.prototype.hasOwnProperty;var Pe=(n,o,d,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let l of We(o))!He.call(n,l)&&l!==d&&ge(n,l,{get:()=>o[l],enumerable:!(i=Be(o,l))||i.enumerable});return n};var Ae=(n,o,d)=>(d=n!=null?ze(Le(n)):{},Pe(o||!n||!n.__esModule?ge(d,"default",{value:n,enumerable:!0}):d,n));Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("react/jsx-runtime"),s=require("react"),ye=({isVisible:n,position:o,availableFields:d,filteredFields:i,filterQuery:l,allowCreate:p,onSelect:I,onClose:z,onCreateField:A,existingFields:f=[],onSelectExisting:S})=>{const[y,w]=s.useState(!1),[x,B]=s.useState(""),[W,R]=s.useState("inline"),[U,te]=s.useState(!0),[q,g]=s.useState(!0);s.useEffect(()=>{n||(w(!1),B(""),R("inline"))},[n]);const L=s.useMemo(()=>({position:"absolute",left:o?.left,top:o?.top,zIndex:1e3,background:"white",border:"1px solid #ddd",borderRadius:"4px",boxShadow:"0 2px 8px rgba(0,0,0,0.1)",padding:"8px 0",width:"280px"}),[o]),E=i??d,V=!!l;if(s.useEffect(()=>{V&&g(!0)},[V]),!n)return null;const O=async()=>{const u=x.trim();if(!u)return;const H={id:`custom_${Date.now()}`,label:u,mode:W};try{if(A){const b=await A(H);I(b||H)}else I(H)}finally{w(!1),B(""),R("inline")}};return t.jsxs("div",{className:"superdoc-field-menu",style:L,children:[V&&t.jsx("div",{style:{padding:"8px 16px",borderBottom:"1px solid #f0f0f0",marginBottom:"4px"},children:t.jsxs("div",{style:{fontSize:"12px",color:"#6b7280"},children:["Filtering results for",t.jsx("span",{style:{fontWeight:600,color:"#111827",marginLeft:"4px"},children:l})]})}),p&&!y&&t.jsx("div",{className:"field-menu-item",onClick:()=>w(!0),style:{padding:"8px 16px",cursor:"pointer",color:"#0066cc",fontWeight:500},children:"+ Create New Field"}),p&&y&&t.jsxs("div",{style:{padding:"8px 16px"},children:[t.jsx("input",{type:"text",value:x,placeholder:"Field name...",onChange:u=>B(u.target.value),onKeyDown:u=>{u.key==="Enter"&&O(),u.key==="Escape"&&(w(!1),B(""),R("inline"))},autoFocus:!0,style:{width:"100%",padding:"4px 8px",border:"1px solid #ddd",borderRadius:"3px"}}),t.jsxs("div",{style:{marginTop:"8px",display:"flex",gap:"12px",fontSize:"13px"},children:[t.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"4px",cursor:"pointer"},children:[t.jsx("input",{type:"radio",value:"inline",checked:W==="inline",onChange:()=>R("inline")}),"Inline"]}),t.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"4px",cursor:"pointer"},children:[t.jsx("input",{type:"radio",value:"block",checked:W==="block",onChange:()=>R("block")}),"Block"]})]}),t.jsxs("div",{style:{marginTop:"8px",display:"flex",gap:"8px"},children:[t.jsx("button",{onClick:O,disabled:!x.trim(),style:{padding:"4px 12px",background:x.trim()?"#0066cc":"#ccc",color:"white",border:"none",borderRadius:"3px",cursor:x.trim()?"pointer":"not-allowed"},children:"Create"}),t.jsx("button",{onClick:()=>{w(!1),B(""),R("inline")},style:{padding:"4px 12px",background:"white",border:"1px solid #ddd",borderRadius:"3px",cursor:"pointer"},children:"Cancel"})]})]}),p&&d.length>0&&t.jsx("div",{style:{borderTop:"1px solid #eee",margin:"4px 0"}}),f.length>0&&(()=>{const u=new Map;f.forEach(b=>{const J=b.group||`individual-${b.id}`,Y=u.get(J)||[];Y.push(b),u.set(J,Y)});const H=Array.from(u.values()).map(b=>({...b[0],count:b.length}));return t.jsxs("div",{style:{borderBottom:"1px solid #f0f0f0"},children:[t.jsxs("button",{type:"button",onClick:()=>te(!U),style:{width:"100%",display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 16px",background:"transparent",border:"none",cursor:"pointer",fontWeight:500,fontSize:"13px",color:"#374151",textAlign:"left"},children:[t.jsxs("span",{children:["Existing Fields (",H.length,")"]}),t.jsx("span",{"aria-hidden":!0,style:{display:"inline-block",width:"8px",height:"8px",borderRight:"2px solid #666",borderBottom:"2px solid #666",transform:U?"rotate(45deg)":"rotate(-45deg)",transition:"transform 0.2s ease"}})]}),U&&t.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:H.map(b=>t.jsxs("div",{className:"field-menu-item",onClick:()=>S?.(b),style:{padding:"8px 16px",cursor:"pointer",display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:"8px"},children:[t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx("div",{style:{fontWeight:500,fontSize:"13px"},children:b.alias||b.id}),t.jsx("div",{style:{fontSize:"11px",color:"#9ca3af",marginTop:"2px"},children:b.group?`group (${b.count} fields)`:`ID: ${b.id}`})]}),t.jsx("span",{style:{fontSize:"11px",color:"#6b7280",padding:"2px 6px",background:"#f3f4f6",borderRadius:"3px",textTransform:"capitalize",flexShrink:0},children:b.mode||"inline"})]},b.group||b.id))})]})})(),E.length===0?t.jsx("div",{style:{padding:"16px",fontSize:"13px",color:"#6b7280",textAlign:"center"},children:"No matching fields"}):t.jsxs("div",{style:{borderBottom:"1px solid #f0f0f0"},children:[t.jsxs("button",{type:"button",onClick:()=>g(!q),style:{width:"100%",display:"flex",alignItems:"center",justifyContent:"space-between",padding:"8px 16px",background:"transparent",border:"none",cursor:"pointer",fontWeight:500,fontSize:"13px",color:"#374151",textAlign:"left"},children:[t.jsxs("span",{children:["Available Fields (",E.length,")"]}),t.jsx("span",{"aria-hidden":!0,style:{display:"inline-block",width:"8px",height:"8px",borderRight:"2px solid #666",borderBottom:"2px solid #666",transform:q?"rotate(45deg)":"rotate(-45deg)",transition:"transform 0.2s ease"}})]}),q&&t.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:E.map(u=>t.jsxs("div",{className:"field-menu-item",onClick:()=>I(u),style:{padding:"8px 16px",cursor:"pointer",display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:"8px"},children:[t.jsxs("div",{style:{flex:1,minWidth:0},children:[t.jsx("div",{style:{fontWeight:500,fontSize:"13px"},children:u.label||u.id}),t.jsxs("div",{style:{fontSize:"11px",color:"#9ca3af",marginTop:"2px"},children:["ID: ",u.id]})]}),t.jsx("span",{style:{fontSize:"11px",color:"#6b7280",padding:"2px 6px",background:"#f3f4f6",borderRadius:"3px",textTransform:"capitalize",flexShrink:0},children:u.mode||"inline"})]},u.id))})]}),t.jsx("div",{style:{borderTop:"1px solid #eee",marginTop:"4px"},children:t.jsx("button",{onClick:z,style:{width:"100%",padding:"6px 16px",background:"#f3f4f6",border:"none",borderRadius:"0 0 4px 4px",cursor:"pointer"},children:"Close"})})]})},Ve=n=>{const o=n.split("-");return o.length>2?o[o.length-1].substring(0,6):n.substring(0,6)},me=({field:n,onSelect:o,onDelete:d,isSelected:i,isGrouped:l=!1})=>t.jsxs("div",{onClick:()=>o(n),style:{position:"relative",padding:"10px 12px",background:i?"#eff6ff":"#f9fafb",border:i?"1px solid #3b82f6":"1px solid #e5e7eb",borderRadius:"6px",cursor:"pointer",transition:"all 0.2s",fontSize:l?"13px":"14px"},onMouseEnter:p=>{i||(p.currentTarget.style.background="#f3f4f6")},onMouseLeave:p=>{i||(p.currentTarget.style.background="#f9fafb")},title:n.alias,children:[t.jsx("button",{onClick:p=>{p.stopPropagation(),d(n.id)},style:{position:"absolute",top:"6px",right:"6px",padding:"4px",background:"transparent",border:"none",cursor:"pointer",color:"#9ca3af",transition:"color 0.2s",display:"flex",alignItems:"center",justifyContent:"center"},onMouseEnter:p=>{p.currentTarget.style.color="#ef4444"},onMouseLeave:p=>{p.currentTarget.style.color="#9ca3af"},title:"Delete field",children:t.jsx("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:t.jsx("path",{d:"M6 2V1.5C6 1.22386 6.22386 1 6.5 1H9.5C9.77614 1 10 1.22386 10 1.5V2M2 4H14M12.6667 4L12.1991 11.0129C12.129 12.065 12.0939 12.5911 11.8667 12.99C11.6666 13.3412 11.3648 13.6235 11.0011 13.7998C10.588 14 10.0607 14 9.00623 14H6.99377C5.93927 14 5.41202 14 4.99889 13.7998C4.63517 13.6235 4.33339 13.3412 4.13332 12.99C3.90607 12.5911 3.871 12.065 3.80086 11.0129L3.33333 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),t.jsxs("div",{style:{paddingRight:"24px"},children:[t.jsx("div",{style:{fontWeight:"500",fontSize:l?"12px":"14px",color:l?"#6b7280":"#111827"},children:n.alias||n.id}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px",fontSize:"11px",color:"#9ca3af",marginTop:"2px"},children:[t.jsxs("span",{children:["ID: ",n.id]}),n.mode&&t.jsx("span",{style:{fontSize:"9px",padding:"2px 5px",borderRadius:"3px",background:n.mode==="block"?"#dbeafe":"#f3f4f6",color:n.mode==="block"?"#1e40af":"#4b5563",fontWeight:"500"},children:n.mode})]})]})]}),ve=({fields:n,onSelect:o,onDelete:d,selectedFieldId:i})=>{const[l,p]=s.useState(new Set),{groupedFields:I,ungroupedFields:z}=s.useMemo(()=>{const f={},S=[];return n.forEach(y=>{y.group?(f[y.group]||(f[y.group]=[]),f[y.group].push(y)):S.push(y)}),{groupedFields:f,ungroupedFields:S}},[n]),A=f=>{p(S=>{const y=new Set(S);return y.has(f)?y.delete(f):y.add(f),y})};return t.jsxs("div",{className:"superdoc-field-list",style:{width:"250px",background:"white",border:"1px solid #e5e7eb",borderRadius:"8px",padding:"16px"},children:[t.jsxs("h3",{style:{margin:"0 0 16px 0",fontSize:"16px",fontWeight:"600"},children:["Template Fields (",n.length,")"]}),n.length===0?t.jsxs("div",{style:{color:"#9ca3af",fontSize:"14px",textAlign:"center",padding:"20px 0"},children:["No fields yet. Type ","{{"," to add a field."]}):t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[z.map(f=>t.jsx(me,{field:f,onSelect:o,onDelete:d,isSelected:i===f.id},f.id)),Object.entries(I).map(([f,S])=>{const y=l.has(f),w=S[0];return t.jsxs("div",{children:[t.jsx("div",{style:{position:"relative",padding:"12px",background:"#f9fafb",border:"1px solid #e5e7eb",borderRadius:"6px",cursor:"pointer",transition:"all 0.2s"},onClick:()=>A(f),onMouseEnter:x=>{x.currentTarget.style.background="#f3f4f6"},onMouseLeave:x=>{x.currentTarget.style.background="#f9fafb"},children:t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px"},children:[t.jsx("span",{style:{fontSize:"12px",color:"#6b7280"},children:y?"▼":"▶"}),t.jsxs("div",{style:{flex:1},children:[t.jsx("div",{style:{fontWeight:"500",fontSize:"14px"},children:w.alias}),t.jsxs("div",{style:{fontSize:"11px",color:"#9ca3af",marginTop:"2px"},children:["group: ",Ve(f)," (",S.length," fields)"]})]})]})}),y&&t.jsx("div",{style:{marginLeft:"16px",marginTop:"4px",display:"flex",flexDirection:"column",gap:"4px"},children:S.map(x=>t.jsx(me,{field:x,onSelect:o,onDelete:d,isSelected:i===x.id,isGrouped:!0},x.id))})]},f)})]})]})},$=n=>{const o=n.helpers?.structuredContentCommands;return o?.getStructuredContentTags?(o.getStructuredContentTags(n.state)||[]).map(i=>{const l=i?.node??i,p=l?.attrs??{},z=(l?.type?.name||"").includes("Block")?"block":"inline";return{id:p.id,alias:p.alias||p.label||"",tag:p.tag,mode:z,group:o.getGroup?.(p.tag)??void 0}}):[]},he=(n,o)=>{if(n===o)return!0;if(n.length!==o.length)return!1;for(let d=0;d<n.length;d+=1){const i=n[d],l=o[d];if(!l||i.id!==l.id||i.alias!==l.alias||i.tag!==l.tag||i.position!==l.position||i.mode!==l.mode||i.group!==l.group)return!1}return!0},Oe=n=>{if(!n)return null;if(n===!0)return{selector:"#superdoc-toolbar",config:{},renderDefaultContainer:!0};if(typeof n=="string")return{selector:n,config:{},renderDefaultContainer:!1};const{selector:o,...d}=n;return{selector:o||"#superdoc-toolbar",config:d,renderDefaultContainer:o===void 0}},ee=10,Ge=250,_e=300,be=n=>{const o=window.innerWidth-Ge-ee,d=window.innerHeight-_e-ee,i=Math.min(n.left,o),l=Math.min(n.top,d);return new DOMRect(Math.max(i,ee),Math.max(l,ee),n.width,n.height)},je=s.forwardRef((n,o)=>{const{document:d,fields:i={},menu:l={},list:p={},toolbar:I,cspNonce:z,onReady:A,onTrigger:f,onFieldInsert:S,onFieldUpdate:y,onFieldDelete:w,onFieldsChange:x,onFieldSelect:B,onFieldCreate:W,onExport:R,className:U,style:te,documentHeight:q="600px"}=n,[g,L]=s.useState(i.initial||[]),[E,V]=s.useState(null),[O,u]=s.useState(!1),[H,b]=s.useState(),[J,Y]=s.useState(""),[Ce,Fe]=s.useState(()=>i.available||[]),ne=s.useRef(null),F=s.useRef(null),T=s.useRef(null),ae=s.useRef(i);ae.current=i;const D=s.useRef(null),de=s.useRef(O);s.useEffect(()=>{de.current=O},[O]);const K=l.trigger||"{{",re=ae.current.available||[],P=s.useMemo(()=>Oe(I),[I]),ce=s.useCallback(e=>{const r=e.trim().toLowerCase();return r?re.filter(a=>a.label.toLowerCase().includes(r)):re},[re]),se=s.useCallback(e=>{Y(e),Fe(ce(e))},[ce]),N=s.useCallback(()=>{se("")},[se]),Q=s.useCallback((e,r)=>{if(!F.current?.activeEditor)return!1;const a=F.current.activeEditor,v=g,C=e==="inline"?a.commands.insertStructuredContentInline?.({attrs:{alias:r.alias,tag:r.metadata?JSON.stringify(r.metadata):void 0},text:r.defaultValue||r.alias}):a.commands.insertStructuredContentBlock?.({attrs:{alias:r.alias,tag:r.metadata?JSON.stringify(r.metadata):void 0},text:r.defaultValue||r.alias});if(C){const m=$(a);L(m),x?.(m);const k=m.find(j=>!v.some(c=>c.id===j.id));k&&S?.(k)}return C??!1},[S,x,g]),X=s.useCallback((e,r)=>{if(!F.current?.activeEditor)return!1;const v=F.current.activeEditor.commands.updateStructuredContentById?.(e,{attrs:r});return v&&L(C=>{const m=C.map(j=>j.id===e?{...j,...r}:j);x?.(m);const k=m.find(j=>j.id===e);return k&&y?.(k),m}),v??!1},[y,x]),oe=s.useCallback(e=>{const r=F.current?.activeEditor;if(!r){let c=!1;return L(h=>{if(!h.some(M=>M.id===e))return h;const _=h.filter(M=>M.id!==e);return c=!0,x?.(_),w?.(e),_}),c&&V(h=>h===e?null:h),c}const v=g.find(c=>c.id===e)?.group;let C=!1;try{C=r.commands.deleteStructuredContentById?.(e)??!1}catch(c){console.warn("[TemplateBuilder] Failed to delete structured content:",e,c),C=!1}let m=$(r);const k=m.some(c=>c.id===e);if(!C&&k&&(m=m.filter(c=>c.id!==e)),v){const c=m.filter(h=>h.group===v);if(c.length===1){const h=c[0];r.commands.updateStructuredContentById?.(h.id,{attrs:{tag:void 0}}),m=$(r)}}let j=!1;return L(c=>{if(he(c,m))return c;const h=c.some(M=>M.id===e),_=m.some(M=>M.id===e);return h&&!_&&(j=!0),x?.(m),j&&w?.(e),m}),j&&V(c=>c===e?null:c),C||j},[w,x,g]),G=s.useCallback(e=>{if(!F.current?.activeEditor)return;F.current.activeEditor.commands.selectStructuredContentById?.(e),V(e);const a=g.find(v=>v.id===e);a&&B?.(a)},[g,B]),ie=s.useCallback(e=>{if(!e)return;const r=$(e);L(a=>he(a,r)?a:(x?.(r),r))},[x]);s.useEffect(()=>{if(!ne.current)return;let e=!1,r=null;return(async()=>{const{SuperDoc:v}=await import("superdoc");if(e)return;const C={comments:!1,...P&&{toolbar:{selector:P.selector,toolbarGroups:P.config.toolbarGroups||["center"],excludeItems:P.config.excludeItems||[],...P.config}}},m=()=>{if(!e){if(r?.activeEditor){const k=r.activeEditor;k.on("update",({editor:j})=>{const{state:c}=j,{from:h}=c.selection;if(h>=K.length){const le=h-K.length;if(c.doc.textBetween(le,h)===K){const pe=j.view.coordsAtPos(h),xe=be(new DOMRect(pe.left,pe.top,0,0)),fe=()=>{const Z=F.current?.activeEditor;if(!Z)return;const De=Z.state.selection.from,Ne=Z.state.tr.delete(le,De);Z.view.dispatch(Ne)};T.current=fe,D.current=h,b(xe),u(!0),N(),f?.({position:{from:le,to:h},bounds:xe,cleanup:fe});return}}if(!de.current)return;if(D.current==null){u(!1),N();return}if(h<D.current){u(!1),D.current=null,N();return}const _=c.doc.textBetween(D.current,h);se(_);const M=j.view.coordsAtPos(h),Re=be(new DOMRect(M.left,M.top,0,0));b(Re)}),k.on("update",()=>{ie(k)}),ie(k)}A?.()}};r=new v({selector:ne.current,document:d?.source,documentMode:d?.mode||"editing",modules:C,toolbar:P?.selector,cspNonce:z,onReady:m}),F.current=r})(),()=>{e=!0,T.current=null,D.current=null,r&&typeof r.destroy=="function"&&r.destroy(),F.current=null}},[d?.source,d?.mode,K,ie,A,f,P,z]);const ke=s.useCallback(async e=>{T.current&&(T.current(),T.current=null),D.current=null,N();const r=e.mode||"inline";if(e.id.startsWith("custom_")&&W){const a=await W(e);if(a){const v=a.mode||r;Q(v,{alias:a.label,metadata:a.metadata,defaultValue:a.defaultValue}),u(!1);return}}Q(r,{alias:e.label,metadata:e.metadata,defaultValue:e.defaultValue}),u(!1)},[Q,W,N]),Se=s.useCallback(e=>{T.current&&(T.current(),T.current=null),D.current=null,N();const r=F.current?.activeEditor;if(!r)return;const a=r.helpers?.structuredContentCommands;if(!a)return;const v=e.group||`group-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,C=a.createTagObject?.({group:v});if((e.mode||"inline")==="inline"?r.commands.insertStructuredContentInline?.({attrs:{alias:e.alias,tag:C},text:e.alias}):r.commands.insertStructuredContentBlock?.({attrs:{alias:e.alias,tag:C},text:e.alias})){e.group||X(e.id,{tag:C}),u(!1);const j=$(r);L(j),x?.(j)}},[X,N,x]),we=s.useCallback(()=>{u(!1),D.current=null,N(),T.current&&(T.current(),T.current=null)},[N]),Te=s.useCallback(()=>{if(!F.current?.activeEditor||g.length===0)return;const e=g.findIndex(a=>a.id===E),r=e>=0?(e+1)%g.length:0;G(g[r].id)},[g,E,G]),Ee=s.useCallback(()=>{if(!F.current?.activeEditor||g.length===0)return;const e=g.findIndex(a=>a.id===E),r=e>0?e-1:g.length-1;G(g[r].id)},[g,E,G]),Me=s.useCallback(async e=>{const{fileName:r="document",triggerDownload:a=!0}=e||{},v=await F.current?.export({exportType:["docx"],exportedName:r,triggerDownload:a}),C=F.current?.activeEditor;if(C){const m=$(C);R?.({fields:m,blob:a?void 0:v,fileName:r})}return v},[R]);s.useImperativeHandle(o,()=>({insertField:e=>Q("inline",e),insertBlockField:e=>Q("block",e),updateField:X,deleteField:oe,selectField:G,nextField:Te,previousField:Ee,getFields:()=>g,exportTemplate:Me,getSuperDoc:()=>F.current}));const Ie=l.component||ye,ue=p.component||ve;return t.jsxs("div",{className:`superdoc-template-builder ${U||""}`,style:te,children:[t.jsxs("div",{style:{display:"flex",gap:"20px"},children:[p.position==="left"&&t.jsx("div",{className:"superdoc-template-builder-sidebar",children:t.jsx(ue,{fields:g,onSelect:e=>G(e.id),onDelete:oe,onUpdate:e=>X(e.id,e),selectedFieldId:E||void 0})}),t.jsxs("div",{className:"superdoc-template-builder-document",style:{flex:1},children:[P?.renderDefaultContainer&&t.jsx("div",{id:"superdoc-toolbar",className:"superdoc-template-builder-toolbar","data-testid":"template-builder-toolbar"}),t.jsx("div",{ref:ne,className:"superdoc-template-builder-editor",style:{height:q},"data-testid":"template-builder-editor"})]}),p.position==="right"&&t.jsx("div",{className:"superdoc-template-builder-sidebar",children:t.jsx(ue,{fields:g,onSelect:e=>G(e.id),onDelete:oe,onUpdate:e=>X(e.id,e),selectedFieldId:E||void 0})})]}),t.jsx(Ie,{isVisible:O,position:H,availableFields:i.available||[],filteredFields:Ce,filterQuery:J,allowCreate:i.allowCreate||!1,onSelect:ke,onClose:we,onCreateField:W,existingFields:g,onSelectExisting:Se})]})});je.displayName="SuperDocTemplateBuilder";exports.FieldList=ve;exports.FieldMenu=ye;exports.default=je;
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require(`react`),t=require(`react/jsx-runtime`);const n=(e,t)=>{if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1){let r=e[n],i=t[n];if(!i||r.id!==i.id||r.alias!==i.alias||r.tag!==i.tag||r.position!==i.position||r.mode!==i.mode||r.group!==i.group||r.fieldType!==i.fieldType)return!1}return!0},r=e=>{if(!e)return null;if(e===!0)return{selector:`#superdoc-toolbar`,config:{},renderDefaultContainer:!0};if(typeof e==`string`)return{selector:e,config:{},renderDefaultContainer:!1};let{selector:t,...n}=e;return{selector:t||`#superdoc-toolbar`,config:n,renderDefaultContainer:t===void 0}},i=e=>{let t=e?.superdocStore?.documents;return!Array.isArray(t)||t.length===0?null:t[0].getPresentationEditor?.()??null};var a={signer:{background:`#fef3c7`,color:`#b45309`}},o={background:`#f3f4f6`,color:`#6b7280`};const s=e=>a[e]??o,c=10,l=250,u=300,d=e=>{let t=window.innerWidth-250-10,n=window.innerHeight-300-10,r=Math.min(e.left,t),i=Math.min(e.top,n);return new DOMRect(Math.max(r,10),Math.max(i,10),e.width,e.height)},f=({text:n})=>{let[r,i]=(0,e.useState)(!1);return(0,t.jsxs)(`span`,{style:{position:`relative`,display:`inline-flex`},onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),onClick:e=>e.stopPropagation(),children:[(0,t.jsxs)(`svg`,{width:`14`,height:`14`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,style:{cursor:`help`,flexShrink:0},children:[(0,t.jsx)(`circle`,{cx:`8`,cy:`8`,r:`7`,stroke:`#9ca3af`,strokeWidth:`1.5`}),(0,t.jsx)(`text`,{x:`8`,y:`11.5`,textAnchor:`middle`,fontSize:`10`,fontWeight:`600`,fontFamily:`system-ui, sans-serif`,fill:`#6b7280`,children:`?`})]}),r&&(0,t.jsx)(`span`,{style:{position:`absolute`,bottom:`100%`,left:`50%`,transform:`translateX(-50%)`,marginBottom:`6px`,padding:`6px 10px`,background:`#1f2937`,color:`#fff`,fontSize:`11px`,lineHeight:`1.4`,borderRadius:`4px`,whiteSpace:`normal`,width:`200px`,textAlign:`center`,zIndex:1001,pointerEvents:`none`,fontWeight:400},children:n})]})},p=({isVisible:n,position:r,availableFields:i,filteredFields:a,filterQuery:o,allowCreate:c,onSelect:l,onClose:u,onCreateField:d,existingFields:p=[],onSelectExisting:m})=>{let[h,g]=(0,e.useState)(!1),[_,v]=(0,e.useState)(``),[y,b]=(0,e.useState)(`inline`),[x,S]=(0,e.useState)(`owner`),[C,w]=(0,e.useState)(!0),[T,E]=(0,e.useState)(!0);(0,e.useEffect)(()=>{n||(g(!1),v(``),b(`inline`),S(`owner`))},[n]);let D=(0,e.useMemo)(()=>({position:`fixed`,left:r?.left,top:r?.top,zIndex:1e3,background:`white`,border:`1px solid #ddd`,borderRadius:`4px`,boxShadow:`0 2px 8px rgba(0,0,0,0.1)`,padding:`8px 0`,width:`280px`,maxHeight:`calc(100vh - ${(r?.top??0)+10}px)`,overflowY:`auto`}),[r]),O=a??i,k=!!o;if((0,e.useEffect)(()=>{k&&E(!0)},[k]),!n)return null;let A=async()=>{let e=_.trim();if(!e)return;let t={id:`custom_${Date.now()}`,label:e,mode:y,fieldType:x};try{l(d&&await d(t)||t)}finally{g(!1),v(``),b(`inline`),S(`owner`)}};return(0,t.jsxs)(`div`,{className:`superdoc-field-menu`,style:D,children:[k&&(0,t.jsx)(`div`,{style:{padding:`8px 16px`,borderBottom:`1px solid #f0f0f0`,marginBottom:`4px`},children:(0,t.jsxs)(`div`,{style:{fontSize:`12px`,color:`#6b7280`},children:[`Filtering results for`,(0,t.jsx)(`span`,{style:{fontWeight:600,color:`#111827`,marginLeft:`4px`},children:o})]})}),c&&!h&&(0,t.jsx)(`div`,{className:`field-menu-item`,onClick:()=>g(!0),style:{padding:`8px 16px`,cursor:`pointer`,color:`#0066cc`,fontWeight:500},children:`+ Create New Field`}),c&&h&&(0,t.jsxs)(`div`,{style:{padding:`8px 16px`},children:[(0,t.jsx)(`input`,{type:`text`,value:_,placeholder:`Field name...`,onChange:e=>v(e.target.value),onKeyDown:e=>{e.key===`Enter`&&A(),e.key===`Escape`&&(g(!1),v(``),b(`inline`))},autoFocus:!0,style:{width:`100%`,padding:`4px 8px`,border:`1px solid #ddd`,borderRadius:`3px`}}),(0,t.jsxs)(`div`,{style:{marginTop:`8px`,display:`flex`,gap:`12px`,fontSize:`13px`},children:[(0,t.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:`4px`,cursor:`pointer`},children:[(0,t.jsx)(`input`,{type:`radio`,name:`fieldMode`,value:`inline`,checked:y===`inline`,onChange:()=>b(`inline`)}),`Inline`]}),(0,t.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:`4px`,cursor:`pointer`},children:[(0,t.jsx)(`input`,{type:`radio`,name:`fieldMode`,value:`block`,checked:y===`block`,onChange:()=>b(`block`)}),`Block`]})]}),(0,t.jsxs)(`div`,{style:{marginTop:`8px`,display:`flex`,gap:`12px`,fontSize:`13px`},children:[(0,t.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:`4px`,cursor:`pointer`},children:[(0,t.jsx)(`input`,{type:`radio`,name:`fieldType`,value:`owner`,checked:x===`owner`,onChange:()=>S(`owner`)}),`Owner`]}),(0,t.jsxs)(`label`,{style:{display:`flex`,alignItems:`center`,gap:`4px`,cursor:`pointer`},children:[(0,t.jsx)(`input`,{type:`radio`,name:`fieldType`,value:`signer`,checked:x===`signer`,onChange:()=>S(`signer`)}),`Signer`]})]}),(0,t.jsxs)(`div`,{style:{marginTop:`8px`,display:`flex`,gap:`8px`},children:[(0,t.jsx)(`button`,{onClick:A,disabled:!_.trim(),style:{padding:`4px 12px`,background:_.trim()?`#0066cc`:`#ccc`,color:`white`,border:`none`,borderRadius:`3px`,cursor:_.trim()?`pointer`:`not-allowed`},children:`Create`}),(0,t.jsx)(`button`,{onClick:()=>{g(!1),v(``),b(`inline`),S(`owner`)},style:{padding:`4px 12px`,background:`white`,border:`1px solid #ddd`,borderRadius:`3px`,cursor:`pointer`},children:`Cancel`})]})]}),c&&i.length>0&&(0,t.jsx)(`div`,{style:{borderTop:`1px solid #eee`,margin:`4px 0`}}),p.length>0&&(()=>{let e=new Map;p.forEach(t=>{let n=t.group||`individual-${t.id}`,r=e.get(n)||[];r.push(t),e.set(n,r)});let n=Array.from(e.values()).map(e=>({...e[0],count:e.length}));return(0,t.jsxs)(`div`,{style:{borderBottom:`1px solid #f0f0f0`},children:[(0,t.jsxs)(`button`,{type:`button`,onClick:()=>w(!C),style:{width:`100%`,display:`flex`,alignItems:`center`,justifyContent:`space-between`,padding:`8px 16px`,background:`transparent`,border:`none`,cursor:`pointer`,fontWeight:500,fontSize:`13px`,color:`#374151`,textAlign:`left`},children:[(0,t.jsxs)(`span`,{style:{display:`flex`,alignItems:`center`,gap:`4px`},children:[`Existing Fields (`,n.length,`)`,(0,t.jsx)(f,{text:`Insert a linked copy of a field already in the document. Linked fields share the same group and stay in sync.`})]}),(0,t.jsx)(`span`,{"aria-hidden":!0,style:{display:`inline-block`,width:`8px`,height:`8px`,borderRight:`2px solid #666`,borderBottom:`2px solid #666`,transform:C?`rotate(45deg)`:`rotate(-45deg)`,transition:`transform 0.2s ease`}})]}),C&&(0,t.jsx)(`div`,{children:n.map(e=>(0,t.jsxs)(`div`,{className:`field-menu-item`,onClick:()=>m?.(e),style:{padding:`8px 16px`,cursor:`pointer`,display:`flex`,alignItems:`flex-start`,justifyContent:`space-between`,gap:`8px`},children:[(0,t.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,t.jsx)(`div`,{style:{fontWeight:500,fontSize:`13px`},children:e.alias||e.id}),(0,t.jsx)(`div`,{style:{fontSize:`11px`,color:`#9ca3af`,marginTop:`2px`},children:e.group?`group (${e.count} fields)`:`ID: ${e.id}`})]}),(0,t.jsxs)(`div`,{style:{display:`flex`,gap:`4px`,flexShrink:0},children:[e.fieldType&&(0,t.jsx)(`span`,{style:{fontSize:`11px`,padding:`2px 6px`,borderRadius:`3px`,textTransform:`capitalize`,...s(e.fieldType),fontWeight:500},children:e.fieldType}),(0,t.jsx)(`span`,{style:{fontSize:`11px`,color:`#6b7280`,padding:`2px 6px`,background:`#f3f4f6`,borderRadius:`3px`,textTransform:`capitalize`},children:e.mode||`inline`})]})]},e.group||e.id))})]})})(),O.length===0?(0,t.jsx)(`div`,{style:{padding:`16px`,fontSize:`13px`,color:`#6b7280`,textAlign:`center`},children:`No matching fields`}):(0,t.jsxs)(`div`,{style:{borderBottom:`1px solid #f0f0f0`},children:[(0,t.jsxs)(`button`,{type:`button`,onClick:()=>E(!T),style:{width:`100%`,display:`flex`,alignItems:`center`,justifyContent:`space-between`,padding:`8px 16px`,background:`transparent`,border:`none`,cursor:`pointer`,fontWeight:500,fontSize:`13px`,color:`#374151`,textAlign:`left`},children:[(0,t.jsxs)(`span`,{style:{display:`flex`,alignItems:`center`,gap:`4px`},children:[`Available Fields (`,O.length,`)`,(0,t.jsx)(f,{text:`Insert a new, independent field instance into the document.`})]}),(0,t.jsx)(`span`,{"aria-hidden":!0,style:{display:`inline-block`,width:`8px`,height:`8px`,borderRight:`2px solid #666`,borderBottom:`2px solid #666`,transform:T?`rotate(45deg)`:`rotate(-45deg)`,transition:`transform 0.2s ease`}})]}),T&&(0,t.jsx)(`div`,{children:O.map(e=>(0,t.jsxs)(`div`,{className:`field-menu-item`,onClick:()=>l(e),style:{padding:`8px 16px`,cursor:`pointer`,display:`flex`,alignItems:`flex-start`,justifyContent:`space-between`,gap:`8px`},children:[(0,t.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,t.jsx)(`div`,{style:{fontWeight:500,fontSize:`13px`},children:e.label||e.id}),(0,t.jsxs)(`div`,{style:{fontSize:`11px`,color:`#9ca3af`,marginTop:`2px`},children:[`ID: `,e.id]})]}),(0,t.jsxs)(`div`,{style:{display:`flex`,gap:`4px`,flexShrink:0},children:[e.fieldType&&(0,t.jsx)(`span`,{style:{fontSize:`11px`,padding:`2px 6px`,borderRadius:`3px`,textTransform:`capitalize`,...s(e.fieldType),fontWeight:500},children:e.fieldType}),(0,t.jsx)(`span`,{style:{fontSize:`11px`,color:`#6b7280`,padding:`2px 6px`,background:`#f3f4f6`,borderRadius:`3px`,textTransform:`capitalize`},children:e.mode||`inline`})]})]},e.id))})]}),(0,t.jsx)(`div`,{style:{borderTop:`1px solid #eee`,marginTop:`4px`},children:(0,t.jsx)(`button`,{onClick:u,style:{width:`100%`,padding:`6px 16px`,background:`#f3f4f6`,border:`none`,borderRadius:`0 0 4px 4px`,cursor:`pointer`},children:`Close`})})]})};var m=e=>{let t=e.split(`-`);return t.length>2?t[t.length-1].substring(0,6):e.substring(0,6)},h=({field:e,onSelect:n,onDelete:r,isSelected:i,isGrouped:a=!1})=>(0,t.jsxs)(`div`,{onClick:()=>n(e),style:{position:`relative`,padding:`10px 12px`,background:i?`#eff6ff`:`#f9fafb`,border:i?`1px solid #3b82f6`:`1px solid #e5e7eb`,borderRadius:`6px`,cursor:`pointer`,transition:`all 0.2s`,fontSize:a?`13px`:`14px`},onMouseEnter:e=>{i||(e.currentTarget.style.background=`#f3f4f6`)},onMouseLeave:e=>{i||(e.currentTarget.style.background=`#f9fafb`)},title:e.alias,children:[(0,t.jsx)(`button`,{onClick:t=>{t.stopPropagation(),r(e.id)},style:{position:`absolute`,top:`6px`,right:`6px`,padding:`4px`,background:`transparent`,border:`none`,cursor:`pointer`,color:`#9ca3af`,transition:`color 0.2s`,display:`flex`,alignItems:`center`,justifyContent:`center`},onMouseEnter:e=>{e.currentTarget.style.color=`#ef4444`},onMouseLeave:e=>{e.currentTarget.style.color=`#9ca3af`},title:`Delete field`,children:(0,t.jsx)(`svg`,{width:`14`,height:`14`,viewBox:`0 0 16 16`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:(0,t.jsx)(`path`,{d:`M6 2V1.5C6 1.22386 6.22386 1 6.5 1H9.5C9.77614 1 10 1.22386 10 1.5V2M2 4H14M12.6667 4L12.1991 11.0129C12.129 12.065 12.0939 12.5911 11.8667 12.99C11.6666 13.3412 11.3648 13.6235 11.0011 13.7998C10.588 14 10.0607 14 9.00623 14H6.99377C5.93927 14 5.41202 14 4.99889 13.7998C4.63517 13.6235 4.33339 13.3412 4.13332 12.99C3.90607 12.5911 3.871 12.065 3.80086 11.0129L3.33333 4`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})}),(0,t.jsxs)(`div`,{style:{paddingRight:`24px`},children:[(0,t.jsx)(`div`,{style:{fontWeight:`500`,fontSize:a?`12px`:`14px`,color:a?`#6b7280`:`#111827`},children:e.alias||e.id}),(0,t.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`6px`,fontSize:`11px`,color:`#9ca3af`,marginTop:`2px`},children:[(0,t.jsxs)(`span`,{children:[`ID: `,e.id]}),e.mode&&(0,t.jsx)(`span`,{style:{fontSize:`9px`,padding:`2px 5px`,borderRadius:`3px`,background:e.mode===`block`?`#dbeafe`:`#f3f4f6`,color:e.mode===`block`?`#1e40af`:`#4b5563`,fontWeight:`500`},children:e.mode}),e.fieldType&&(0,t.jsx)(`span`,{style:{fontSize:`9px`,padding:`2px 5px`,borderRadius:`3px`,...s(e.fieldType),fontWeight:`500`},children:e.fieldType})]})]})]});const g=({fields:n,onSelect:r,onDelete:i,selectedFieldId:a})=>{let[o,s]=(0,e.useState)(new Set),{groupedFields:c,ungroupedFields:l}=(0,e.useMemo)(()=>{let e={},t=[];return n.forEach(n=>{n.group?(e[n.group]||(e[n.group]=[]),e[n.group].push(n)):t.push(n)}),{groupedFields:e,ungroupedFields:t}},[n]),u=e=>{s(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})};return(0,t.jsxs)(`div`,{className:`superdoc-field-list`,style:{width:`250px`,background:`white`,border:`1px solid #e5e7eb`,borderRadius:`8px`,padding:`16px`},children:[(0,t.jsxs)(`h3`,{style:{margin:`0 0 16px 0`,fontSize:`16px`,fontWeight:`600`},children:[`Template Fields (`,n.length,`)`]}),n.length===0?(0,t.jsxs)(`div`,{style:{color:`#9ca3af`,fontSize:`14px`,textAlign:`center`,padding:`20px 0`},children:[`No fields yet. Type `,`{{`,` to add a field.`]}):(0,t.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:`8px`},children:[l.map(e=>(0,t.jsx)(h,{field:e,onSelect:r,onDelete:i,isSelected:a===e.id},e.id)),Object.entries(c).map(([e,n])=>{let s=o.has(e),c=n[0];return(0,t.jsxs)(`div`,{children:[(0,t.jsx)(`div`,{style:{position:`relative`,padding:`12px`,background:`#f9fafb`,border:`1px solid #e5e7eb`,borderRadius:`6px`,cursor:`pointer`,transition:`all 0.2s`},onClick:()=>u(e),onMouseEnter:e=>{e.currentTarget.style.background=`#f3f4f6`},onMouseLeave:e=>{e.currentTarget.style.background=`#f9fafb`},children:(0,t.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`8px`},children:[(0,t.jsx)(`span`,{style:{fontSize:`12px`,color:`#6b7280`},children:s?`▼`:`▶`}),(0,t.jsxs)(`div`,{style:{flex:1},children:[(0,t.jsx)(`div`,{style:{fontWeight:`500`,fontSize:`14px`},children:c.alias}),(0,t.jsxs)(`div`,{style:{fontSize:`11px`,color:`#9ca3af`,marginTop:`2px`},children:[`group: `,m(e),` (`,n.length,` fields)`]})]})]})}),s&&(0,t.jsx)(`div`,{style:{marginLeft:`16px`,marginTop:`4px`,display:`flex`,flexDirection:`column`,gap:`4px`},children:n.map(e=>(0,t.jsx)(h,{field:e,onSelect:r,onDelete:i,isSelected:a===e.id,isGrouped:!0},e.id))})]},e)})]})]})};var _=e=>{let t=e.helpers?.structuredContentCommands;return t?.getStructuredContentTags?(t.getStructuredContentTags(e.state)||[]).map(e=>{let n=e?.node??e,r=n?.attrs??{},i=(n?.type?.name||``).includes(`Block`)?`block`:`inline`,a=(()=>{try{return typeof r.tag==`string`&&r.tag.startsWith(`{`)?JSON.parse(r.tag):null}catch{return null}})();return{id:r.id,alias:r.alias||r.label||``,tag:r.tag,mode:i,group:t.getGroup?.(r.tag)??void 0,fieldType:a?.fieldType??`owner`}}):[]},v=(0,e.forwardRef)((a,o)=>{let{document:s,fields:c={},menu:l={},list:u={},toolbar:f,cspNonce:m,telemetry:h,licenseKey:v,onReady:y,onTrigger:b,onFieldInsert:x,onFieldUpdate:S,onFieldDelete:C,onFieldsChange:w,onFieldSelect:T,onFieldCreate:E,onExport:D,className:O,style:k,documentHeight:A=`600px`}=a,[j,M]=(0,e.useState)(c.initial||[]),[N,P]=(0,e.useState)(null),[F,I]=(0,e.useState)(!1),[ee,te]=(0,e.useState)(),[ne,re]=(0,e.useState)(``),[ie,ae]=(0,e.useState)(()=>c.available||[]),L=(0,e.useRef)(null),R=(0,e.useRef)(null),z=(0,e.useRef)(null),B=(0,e.useRef)(c);B.current=c;let V=(0,e.useRef)(null),oe=(0,e.useRef)(F);(0,e.useEffect)(()=>{oe.current=F},[F]);let H=l.trigger||`{{`,U=B.current.available||[],W=(0,e.useMemo)(()=>r(f),[f]),G=(0,e.useMemo)(()=>({enabled:h?.enabled??!0,metadata:{source:`template-builder`,...h?.metadata}}),[h?.enabled,JSON.stringify(h?.metadata)]),K=(0,e.useCallback)(e=>{let t=e.trim().toLowerCase();return t?U.filter(e=>e.label.toLowerCase().includes(t)):U},[U]),q=(0,e.useCallback)(e=>{re(e),ae(K(e))},[K]),J=(0,e.useCallback)(()=>{q(``)},[q]),Y=(0,e.useCallback)((e,t)=>{if(!R.current?.activeEditor)return!1;let n=R.current.activeEditor,r=j,i=t.metadata||t.fieldType?JSON.stringify({...t.metadata,...t.fieldType?{fieldType:t.fieldType}:{}}):void 0,a=e===`inline`?n.commands.insertStructuredContentInline?.({attrs:{alias:t.alias,tag:i},text:t.defaultValue||t.alias}):n.commands.insertStructuredContentBlock?.({attrs:{alias:t.alias,tag:i},text:t.defaultValue||t.alias});if(a){let e=_(n);M(e),w?.(e);let t=e.find(e=>!r.some(t=>t.id===e.id));t&&x?.(t)}return a??!1},[x,w,j]),X=(0,e.useCallback)((e,t)=>{if(!R.current?.activeEditor)return!1;let n=R.current.activeEditor.commands.updateStructuredContentById?.(e,{attrs:t});return n&&M(n=>{let r=n.map(n=>n.id===e?{...n,...t}:n);w?.(r);let i=r.find(t=>t.id===e);return i&&S?.(i),r}),n??!1},[S,w]),Z=(0,e.useCallback)(e=>{let t=R.current?.activeEditor;if(!t){let t=!1;return M(n=>{if(!n.some(t=>t.id===e))return n;let r=n.filter(t=>t.id!==e);return t=!0,w?.(r),C?.(e),r}),t&&P(t=>t===e?null:t),t}let r=j.find(t=>t.id===e)?.group,i=!1;try{i=t.commands.deleteStructuredContentById?.(e)??!1}catch(t){console.warn(`[TemplateBuilder] Failed to delete structured content:`,e,t),i=!1}let a=_(t),o=a.some(t=>t.id===e);if(!i&&o&&(a=a.filter(t=>t.id!==e)),r){let e=a.filter(e=>e.group===r);if(e.length===1){let n=e[0];t.commands.updateStructuredContentById?.(n.id,{attrs:{tag:void 0}}),a=_(t)}}let s=!1;return M(t=>{if(n(t,a))return t;let r=t.some(t=>t.id===e),i=a.some(t=>t.id===e);return r&&!i&&(s=!0),w?.(a),s&&C?.(e),a}),s&&P(t=>t===e?null:t),i||s},[C,w,j]),Q=(0,e.useCallback)(e=>{if(!R.current?.activeEditor)return;R.current.activeEditor.commands.selectStructuredContentById?.(e),P(e);let t=j.find(t=>t.id===e);t&&T?.(t)},[j,T]),$=(0,e.useCallback)(e=>{if(!e)return;let t=_(e);M(e=>n(e,t)?e:(w?.(t),t))},[w]);(0,e.useEffect)(()=>{if(!L.current)return;let e=!1,t=null;return(async()=>{let{SuperDoc:n}=await import(`superdoc`);if(e)return;let r={comments:!1,...W&&{toolbar:{selector:W.selector,toolbarGroups:W.config.toolbarGroups||[`center`],excludeItems:W.config.excludeItems||[],...W.config}}},a=()=>{if(!e){if(t?.activeEditor){let e=t.activeEditor,n=i(t);e.on(`update`,({editor:e})=>{let{state:t}=e,{from:r}=t.selection;if(r>=H.length){let i=r-H.length;if(t.doc.textBetween(i,r)===H){let t=n?.coordsAtPos(r)??e.view.coordsAtPos(r),a=d(new DOMRect(t.left,t.bottom??t.top,0,0)),o=()=>{let e=R.current?.activeEditor;if(!e)return;let t=e.state.selection.from,n=e.state.tr.delete(i,t);e.view.dispatch(n)};z.current=o,V.current=r,te(a),I(!0),J(),b?.({position:{from:i,to:r},bounds:a,cleanup:o});return}}if(!oe.current)return;if(V.current==null){I(!1),J();return}if(r<V.current){I(!1),V.current=null,J();return}q(t.doc.textBetween(V.current,r));let i=n?.coordsAtPos(r)??e.view.coordsAtPos(r);te(d(new DOMRect(i.left,i.bottom??i.top,0,0)))}),e.on(`update`,()=>{$(e)}),$(e)}y?.()}};t=new n({selector:L.current,document:s?.source,documentMode:s?.mode||`editing`,modules:r,toolbar:W?.selector,cspNonce:m,telemetry:G,...v&&{licenseKey:v},onReady:a}),R.current=t})(),()=>{e=!0,z.current=null,V.current=null,t&&typeof t.destroy==`function`&&t.destroy(),R.current=null}},[s?.source,s?.mode,H,$,y,b,W,m,G,v]);let se=(0,e.useCallback)(async e=>{z.current&&=(z.current(),null),V.current=null,J();let t=e.mode||`inline`;if(e.id.startsWith(`custom_`)&&E){let n=await E(e);if(n){Y(n.mode||t,{alias:n.label,metadata:n.metadata,defaultValue:n.defaultValue,fieldType:n.fieldType}),I(!1);return}}Y(t,{alias:e.label,metadata:e.metadata,defaultValue:e.defaultValue,fieldType:e.fieldType}),I(!1)},[Y,E,J]),ce=(0,e.useCallback)(e=>{z.current&&=(z.current(),null),V.current=null,J();let t=R.current?.activeEditor;if(!t)return;let n=t.helpers?.structuredContentCommands;if(!n)return;let r=e.group||`group-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,i=n.createTagObject?.({group:r,...e.fieldType?{fieldType:e.fieldType}:{}});if((e.mode||`inline`)===`inline`?t.commands.insertStructuredContentInline?.({attrs:{alias:e.alias,tag:i},text:e.alias}):t.commands.insertStructuredContentBlock?.({attrs:{alias:e.alias,tag:i},text:e.alias})){e.group||X(e.id,{tag:i}),I(!1);let n=_(t);M(n),w?.(n)}},[X,J,w]),le=(0,e.useCallback)(()=>{I(!1),V.current=null,J(),z.current&&=(z.current(),null)},[J]),ue=(0,e.useCallback)(()=>{if(!R.current?.activeEditor||j.length===0)return;let e=j.findIndex(e=>e.id===N);Q(j[e>=0?(e+1)%j.length:0].id)},[j,N,Q]),de=(0,e.useCallback)(()=>{if(!R.current?.activeEditor||j.length===0)return;let e=j.findIndex(e=>e.id===N);Q(j[e>0?e-1:j.length-1].id)},[j,N,Q]),fe=(0,e.useCallback)(async e=>{let{fileName:t=`document`,triggerDownload:n=!0}=e||{},r=await R.current?.export({exportType:[`docx`],exportedName:t,triggerDownload:n}),i=R.current?.activeEditor;if(i){let e=_(i);D?.({fields:e,blob:n?void 0:r,fileName:t})}return r},[D]);(0,e.useImperativeHandle)(o,()=>({insertField:e=>Y(`inline`,e),insertBlockField:e=>Y(`block`,e),updateField:X,deleteField:Z,selectField:Q,nextField:ue,previousField:de,getFields:()=>j,exportTemplate:fe,getSuperDoc:()=>R.current}));let pe=l.component||p,me=u.component||g;return(0,t.jsxs)(`div`,{className:`superdoc-template-builder ${O||``}`,style:k,children:[(0,t.jsxs)(`div`,{style:{display:`flex`,gap:`20px`},children:[u.position===`left`&&(0,t.jsx)(`div`,{className:`superdoc-template-builder-sidebar`,children:(0,t.jsx)(me,{fields:j,onSelect:e=>Q(e.id),onDelete:Z,onUpdate:e=>X(e.id,e),selectedFieldId:N||void 0})}),(0,t.jsxs)(`div`,{className:`superdoc-template-builder-document`,style:{flex:1},children:[W?.renderDefaultContainer&&(0,t.jsx)(`div`,{id:`superdoc-toolbar`,className:`superdoc-template-builder-toolbar`,"data-testid":`template-builder-toolbar`}),(0,t.jsx)(`div`,{ref:L,className:`superdoc-template-builder-editor`,style:{height:A},"data-testid":`template-builder-editor`})]}),u.position===`right`&&(0,t.jsx)(`div`,{className:`superdoc-template-builder-sidebar`,children:(0,t.jsx)(me,{fields:j,onSelect:e=>Q(e.id),onDelete:Z,onUpdate:e=>X(e.id,e),selectedFieldId:N||void 0})})]}),(0,t.jsx)(pe,{isVisible:F,position:ee,availableFields:c.available||[],filteredFields:ie,filterQuery:ne,allowCreate:c.allowCreate||!1,onSelect:se,onClose:le,onCreateField:E,existingFields:j,onSelectExisting:ce})]})});v.displayName=`SuperDocTemplateBuilder`;var y=v;exports.FieldList=g,exports.FieldMenu=p,exports.default=y;
|