@campxdev/pdfme 1.2.1 → 1.3.0

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.
Files changed (50) hide show
  1. package/dist/cjs/chunks/{index-dHRmLCnu.js → fontSizePxWidget-Drk8HKGH.js} +138 -9
  2. package/dist/cjs/chunks/fontSizeTransform-CQQ_O42f.js +37 -0
  3. package/dist/cjs/chunks/{helper-C2o2tpNj.js → helper-DGH62Z2s.js} +16959 -4
  4. package/dist/cjs/chunks/{index-qB7eb2BC.js → index-CoNR0xQU.js} +10 -2
  5. package/dist/cjs/chunks/{index-CXm3doOM.js → index-CsEKt088.js} +750 -535
  6. package/dist/cjs/chunks/{pluginRegistry-Ba3ANzzx.js → pluginRegistry-D2vr9MUy.js} +1 -1
  7. package/dist/cjs/common.js +11 -3
  8. package/dist/cjs/converter.js +1 -1
  9. package/dist/cjs/generator.js +3 -3
  10. package/dist/cjs/index.js +27 -16
  11. package/dist/cjs/print-designer-editor.js +3389 -3383
  12. package/dist/cjs/schemas.js +500 -38
  13. package/dist/cjs/ui.js +83339 -72691
  14. package/dist/esm/chunks/{index-pDt5vVVj.js → fontSizePxWidget-CbzQrSSM.js} +130 -5
  15. package/dist/esm/chunks/fontSizeTransform-CkTVJdRF.js +34 -0
  16. package/dist/esm/chunks/{helper-D7XF1bxK.js → helper-DSxGxZ0j.js} +16955 -5
  17. package/dist/esm/chunks/{index-D1FuD_XZ.js → index-DJkUkUo9.js} +4 -3
  18. package/dist/esm/chunks/{index-qTsnfbi7.js → index-D_-j4c4P.js} +744 -532
  19. package/dist/esm/chunks/{pluginRegistry-DEA2P0ud.js → pluginRegistry-Bgrz5qWG.js} +1 -1
  20. package/dist/esm/common.js +4 -3
  21. package/dist/esm/converter.js +1 -1
  22. package/dist/esm/generator.js +3 -3
  23. package/dist/esm/index.js +7 -6
  24. package/dist/esm/print-designer-editor.js +3374 -3374
  25. package/dist/esm/schemas.js +472 -13
  26. package/dist/esm/ui.js +83339 -72691
  27. package/dist/types/_vendors/common/constants.d.ts +1 -2
  28. package/dist/types/_vendors/common/fontSizeTransform.d.ts +5 -0
  29. package/dist/types/_vendors/common/googleFontUrls.d.ts +9 -0
  30. package/dist/types/_vendors/common/googleFonts.d.ts +7 -0
  31. package/dist/types/_vendors/common/helper.d.ts +2 -0
  32. package/dist/types/_vendors/common/index.d.ts +4 -2
  33. package/dist/types/_vendors/print-designer-editor/index.d.ts +2 -1
  34. package/dist/types/_vendors/print-designer-editor/types.d.ts +1 -1
  35. package/dist/types/_vendors/print-designer-editor/useDesigner.d.ts +1 -1
  36. package/dist/types/_vendors/schemas/index.d.ts +8 -2
  37. package/dist/types/_vendors/schemas/richText/helper.d.ts +3 -0
  38. package/dist/types/_vendors/schemas/richText/index.d.ts +4 -0
  39. package/dist/types/_vendors/schemas/richText/pdfRender.d.ts +3 -0
  40. package/dist/types/_vendors/schemas/richText/propPanel.d.ts +3 -0
  41. package/dist/types/_vendors/schemas/richText/types.d.ts +7 -0
  42. package/dist/types/_vendors/schemas/richText/uiRender.d.ts +3 -0
  43. package/dist/types/_vendors/schemas/singleVariableText/index.d.ts +4 -0
  44. package/dist/types/_vendors/schemas/singleVariableText/propPanel.d.ts +3 -0
  45. package/dist/types/_vendors/schemas/singleVariableText/types.d.ts +4 -0
  46. package/dist/types/_vendors/schemas/text/fontCache.d.ts +10 -0
  47. package/dist/types/_vendors/schemas/text/fontSizePxWidget.d.ts +9 -0
  48. package/dist/types/_vendors/ui/components/CtlBar.d.ts +1 -1
  49. package/dist/types/_vendors/ui/components/Paper.d.ts +1 -0
  50. package/package.json +1 -1
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./chunks/index-CXm3doOM.js');
4
- var index$1 = require('./chunks/index-dHRmLCnu.js');
3
+ var index = require('./chunks/index-CsEKt088.js');
4
+ var fontSizePxWidget = require('./chunks/fontSizePxWidget-Drk8HKGH.js');
5
5
  var lucide = require('lucide');
6
- var helper = require('./chunks/helper-C2o2tpNj.js');
6
+ var helper = require('./chunks/helper-DGH62Z2s.js');
7
7
  var AirDatepicker = require('air-datepicker');
8
8
  var localeAr = require('air-datepicker/locale/ar');
9
9
  var localeBg = require('air-datepicker/locale/bg');
@@ -108,11 +108,470 @@ var localeUk__default = /*#__PURE__*/_interopDefault(localeUk);
108
108
  var localeZh__default = /*#__PURE__*/_interopDefault(localeZh);
109
109
  var dateFns__namespace = /*#__PURE__*/_interopNamespace(dateFns);
110
110
 
111
- const textSchema = {
112
- pdf: index.pdfRender,
113
- ui: index.uiRender,
114
- propPanel: index.propPanel,
115
- icon: index.createSvgStr(lucide.TextCursorInput),
111
+ const pdfRender$2 = async (arg) => {
112
+ const { value, schema, pageContext, ...rest } = arg;
113
+ // Static mode: no template text → render value directly as plain text
114
+ if (!schema.text) {
115
+ await index.pdfRender({ value, schema, ...rest });
116
+ return;
117
+ }
118
+ // readOnly: value is already resolved by generate.ts via replacePlaceholders
119
+ if (schema.readOnly) {
120
+ await index.pdfRender({ value, schema, ...rest });
121
+ return;
122
+ }
123
+ // Dynamic mode (form): substitute variables in template
124
+ if (!fontSizePxWidget.validateVariables(value, schema)) {
125
+ return;
126
+ }
127
+ const renderArgs = {
128
+ value: fontSizePxWidget.substituteVariables(schema.text, value || '{}', pageContext),
129
+ schema,
130
+ ...rest,
131
+ };
132
+ await index.pdfRender(renderArgs);
133
+ };
134
+
135
+ const insertVariableWidget = fontSizePxWidget.createInsertVariableWidget('text');
136
+ const mapDynamicVariables = (props) => {
137
+ const { rootElement, changeSchemas, activeSchema } = props;
138
+ const mvtSchema = activeSchema;
139
+ const text = mvtSchema.text ?? '';
140
+ if (!text) {
141
+ rootElement.style.display = 'none';
142
+ return;
143
+ }
144
+ const variables = JSON.parse(mvtSchema.content || '{}');
145
+ const variablesChanged = updateVariablesFromText(text, variables);
146
+ const varNames = Object.keys(variables);
147
+ if (variablesChanged) {
148
+ changeSchemas([
149
+ { key: 'content', value: JSON.stringify(variables), schemaId: activeSchema.id },
150
+ { key: 'variables', value: varNames, schemaId: activeSchema.id },
151
+ { key: 'readOnly', value: varNames.length === 0, schemaId: activeSchema.id },
152
+ ]);
153
+ }
154
+ // No UI needed — sample data is auto-generated from variable paths
155
+ rootElement.style.display = 'none';
156
+ };
157
+ const propPanel$1 = {
158
+ schema: (propPanelProps) => {
159
+ if (typeof index.propPanel.schema !== 'function') {
160
+ throw new Error('Oops, is text schema no longer a function?');
161
+ }
162
+ // Safely call schema function with proper type handling
163
+ const parentSchema = typeof index.propPanel.schema === 'function' ? index.propPanel.schema(propPanelProps) : {};
164
+ return {
165
+ insertVariablePicker: {
166
+ type: 'void',
167
+ widget: 'insertVariableWidget',
168
+ bind: false,
169
+ span: 24,
170
+ },
171
+ '----': { type: 'void', widget: 'Divider' },
172
+ ...parentSchema,
173
+ dynamicVariables: {
174
+ type: 'object',
175
+ widget: 'mapDynamicVariables',
176
+ bind: false,
177
+ span: 0,
178
+ },
179
+ };
180
+ },
181
+ widgets: { ...(index.propPanel.widgets || {}), mapDynamicVariables, insertVariableWidget },
182
+ defaultSchema: {
183
+ ...index.propPanel.defaultSchema,
184
+ readOnly: false,
185
+ type: 'text',
186
+ text: 'Type Something...',
187
+ width: 50,
188
+ height: 15,
189
+ content: '{}',
190
+ variables: [],
191
+ },
192
+ };
193
+ /** Known JS globals/keywords that should NOT be treated as user-defined variables */
194
+ const RESERVED_NAMES$1 = new Set([
195
+ 'true', 'false', 'null', 'undefined', 'typeof', 'instanceof', 'in',
196
+ 'void', 'delete', 'new', 'this', 'NaN', 'Infinity',
197
+ 'Math', 'String', 'Number', 'Boolean', 'Array', 'Object', 'Date', 'JSON',
198
+ 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent',
199
+ 'encodeURI', 'encodeURIComponent', 'date', 'dateTime',
200
+ 'currentPage', 'totalPages',
201
+ ]);
202
+ /**
203
+ * Extract full dot-notation paths from an expression string.
204
+ * E.g. "student.marks.sem1 > 80" → ["student.marks.sem1"]
205
+ * Handles method calls: "student.name.toUpperCase()" → ["student.name"]
206
+ * Skips string literals and reserved names.
207
+ */
208
+ const extractDotPaths = (expr) => {
209
+ // Replace string literals with spaces (preserving positions for nextChar lookup)
210
+ const cleaned = expr.replace(/'[^']*'|"[^"]*"|`[^`]*`/g, (m) => ' '.repeat(m.length));
211
+ const pathRegex = /[a-zA-Z_$][a-zA-Z0-9_$]*(?:\.[a-zA-Z_$][a-zA-Z0-9_$]*)*/g;
212
+ const paths = new Set();
213
+ let m;
214
+ while ((m = pathRegex.exec(cleaned)) !== null) {
215
+ let path = m[0];
216
+ // If followed by '(', the last segment is a method call — trim it
217
+ const nextChar = cleaned[m.index + path.length];
218
+ if (nextChar === '(') {
219
+ const lastDot = path.lastIndexOf('.');
220
+ if (lastDot !== -1) {
221
+ path = path.substring(0, lastDot);
222
+ }
223
+ else {
224
+ // Standalone function call like parseInt(...) — skip
225
+ continue;
226
+ }
227
+ }
228
+ const root = path.split('.')[0];
229
+ if (!RESERVED_NAMES$1.has(root))
230
+ paths.add(path);
231
+ }
232
+ return Array.from(paths);
233
+ };
234
+ /**
235
+ * Build a nested default object from dot-paths.
236
+ * E.g. ["student.name", "student.marks.sem1"] →
237
+ * { name: "NAME", marks: { sem1: "SEM1" } }
238
+ * Merges into an existing object, only adding missing leaves.
239
+ * Returns true if anything was added.
240
+ */
241
+ const buildNestedDefault = (obj, paths) => {
242
+ let added = false;
243
+ for (const path of paths) {
244
+ const parts = path.split('.');
245
+ if (parts.length <= 1)
246
+ continue; // no nested parts
247
+ let current = obj;
248
+ for (let i = 1; i < parts.length - 1; i++) {
249
+ if (!(parts[i] in current) || typeof current[parts[i]] !== 'object' || current[parts[i]] === null) {
250
+ current[parts[i]] = {};
251
+ added = true;
252
+ }
253
+ current = current[parts[i]];
254
+ }
255
+ const leaf = parts[parts.length - 1];
256
+ if (!(leaf in current)) {
257
+ current[leaf] = path.replace(/\./g, '_').toUpperCase();
258
+ added = true;
259
+ }
260
+ }
261
+ return added;
262
+ };
263
+ const updateVariablesFromText = (text, variables) => {
264
+ // Find all {...} blocks and extract dot-notation paths from each
265
+ const blockRegex = /\{([^{}]+)\}/g;
266
+ const allPaths = new Set();
267
+ let blockMatch;
268
+ while ((blockMatch = blockRegex.exec(text)) !== null) {
269
+ for (const path of extractDotPaths(blockMatch[1])) {
270
+ allPaths.add(path);
271
+ }
272
+ }
273
+ // Group paths by root identifier
274
+ const rootToPaths = new Map();
275
+ for (const path of allPaths) {
276
+ const root = path.split('.')[0];
277
+ if (!rootToPaths.has(root))
278
+ rootToPaths.set(root, []);
279
+ rootToPaths.get(root).push(path);
280
+ }
281
+ const allRoots = new Set(rootToPaths.keys());
282
+ let changed = false;
283
+ for (const [root, paths] of rootToPaths) {
284
+ const hasNested = paths.some((p) => p.includes('.'));
285
+ if (hasNested) {
286
+ // Parse existing value or start fresh
287
+ let obj = {};
288
+ if (root in variables) {
289
+ try {
290
+ const parsed = JSON.parse(variables[root]);
291
+ if (typeof parsed === 'object' && parsed !== null) {
292
+ obj = parsed;
293
+ }
294
+ }
295
+ catch {
296
+ /* not JSON, will rebuild */
297
+ }
298
+ }
299
+ const added = buildNestedDefault(obj, paths);
300
+ if (!(root in variables) || added) {
301
+ variables[root] = JSON.stringify(obj);
302
+ changed = true;
303
+ }
304
+ }
305
+ else {
306
+ if (!(root in variables)) {
307
+ variables[root] = root.toUpperCase();
308
+ changed = true;
309
+ }
310
+ }
311
+ }
312
+ // Remove variables whose root is no longer referenced
313
+ for (const varName of Object.keys(variables)) {
314
+ if (!allRoots.has(varName)) {
315
+ delete variables[varName];
316
+ changed = true;
317
+ }
318
+ }
319
+ return changed;
320
+ };
321
+
322
+ const uiRender$2 = async (arg) => {
323
+ const { value, schema, rootElement, mode, onChange, pageContext, ...rest } = arg;
324
+ // Static mode: no template text → delegate to plain text behavior
325
+ if (!schema.text) {
326
+ await index.uiRender(arg);
327
+ return;
328
+ }
329
+ // Dynamic mode: template with optional variables
330
+ let text = schema.text;
331
+ let numVariables = (schema.variables || []).length;
332
+ if (mode === 'form' && numVariables > 0) {
333
+ await formUiRender(arg);
334
+ return;
335
+ }
336
+ await index.uiRender({
337
+ value: index.isEditable(mode, schema) ? text : fontSizePxWidget.substituteVariables(text, value, pageContext),
338
+ schema,
339
+ mode: mode === 'form' ? 'viewer' : mode, // if no variables for form it's just a viewer
340
+ rootElement,
341
+ onChange: (arg) => {
342
+ if (!Array.isArray(arg)) {
343
+ if (onChange) {
344
+ onChange({ key: 'text', value: arg.value });
345
+ }
346
+ }
347
+ else {
348
+ throw new Error('onChange is not an array, the parent text plugin has changed...');
349
+ }
350
+ },
351
+ ...rest,
352
+ });
353
+ const textBlock = rootElement.querySelector('#text-' + String(schema.id));
354
+ if (!textBlock) {
355
+ throw new Error('Text block not found. Ensure the text block has an id of "text-" + schema.id');
356
+ }
357
+ if (mode === 'designer') {
358
+ textBlock.addEventListener('keyup', (event) => {
359
+ text = textBlock.textContent || '';
360
+ if (keyPressShouldBeChecked(event)) {
361
+ const newNumVariables = countUniqueVariableNames(text);
362
+ if (numVariables !== newNumVariables) {
363
+ if (onChange) {
364
+ onChange({ key: 'text', value: text });
365
+ }
366
+ numVariables = newNumVariables;
367
+ }
368
+ }
369
+ });
370
+ }
371
+ };
372
+ /** Re-evaluate all expression spans inside a container using current variable values */
373
+ const refreshExpressionSpans = (container, variables, pageCtx) => {
374
+ container.querySelectorAll('[data-expr]').forEach((span) => {
375
+ const expr = span.getAttribute('data-expr');
376
+ span.textContent = fontSizePxWidget.substituteVariables(`{${expr}}`, variables, pageCtx);
377
+ });
378
+ };
379
+ const formUiRender = async (arg) => {
380
+ const { value, schema, rootElement, onChange, stopEditing, theme, _cache, options, pageContext } = arg;
381
+ const rawText = schema.text;
382
+ if (rootElement.parentElement) {
383
+ // remove the outline for the whole schema, we'll apply outlines on each individual variable field instead
384
+ rootElement.parentElement.style.outline = '';
385
+ }
386
+ const variables = value
387
+ ? JSON.parse(value) || {}
388
+ : {};
389
+ const substitutedText = fontSizePxWidget.substituteVariables(rawText, variables, pageContext);
390
+ const font = options?.font || helper.getDefaultFont();
391
+ const fontKitFont = await index.getFontKitFont(schema.fontName, font, _cache);
392
+ const textBlock = index.buildStyledTextContainer(arg, fontKitFont, substitutedText);
393
+ // Tokenize rawText into static text, simple-identifier variables (editable), and
394
+ // complex expressions (evaluated, static). This supports both {name} and {price * 1.1}.
395
+ const tokens = tokenizeTemplate(rawText, variables, pageContext);
396
+ // Find variables that have inline editable spans (standalone {var} tokens)
397
+ const inlineVarNames = new Set(tokens.filter((t) => t.type === 'simpleVar')
398
+ .map(t => t.name));
399
+ // Variables that only appear inside expressions — need separate input fields
400
+ const expressionOnlyVars = (schema.variables || []).filter(v => !inlineVarNames.has(v));
401
+ if (expressionOnlyVars.length > 0) {
402
+ const varSection = document.createElement('div');
403
+ Object.assign(varSection.style, {
404
+ width: '100%',
405
+ padding: '2px 4px',
406
+ boxSizing: 'border-box',
407
+ display: 'flex',
408
+ flexWrap: 'wrap',
409
+ gap: '4px',
410
+ marginBottom: '2px',
411
+ });
412
+ for (const varName of expressionOnlyVars) {
413
+ const row = document.createElement('div');
414
+ Object.assign(row.style, { display: 'flex', alignItems: 'center', gap: '2px' });
415
+ const label = document.createElement('label');
416
+ label.textContent = varName + ':';
417
+ Object.assign(label.style, {
418
+ fontSize: '9px', whiteSpace: 'nowrap', color: theme.colorText,
419
+ });
420
+ const input = document.createElement('input');
421
+ input.type = 'text';
422
+ input.value = variables[varName] ?? '';
423
+ Object.assign(input.style, {
424
+ width: '60px',
425
+ fontSize: '9px',
426
+ border: `1px dashed ${theme.colorPrimary}`,
427
+ borderRadius: '2px',
428
+ padding: '1px 3px',
429
+ outline: 'none',
430
+ });
431
+ input.addEventListener('input', (e) => {
432
+ variables[varName] = e.target.value;
433
+ if (onChange)
434
+ onChange({ key: 'content', value: JSON.stringify(variables) });
435
+ refreshExpressionSpans(textBlock, variables, pageContext);
436
+ });
437
+ row.appendChild(label);
438
+ row.appendChild(input);
439
+ varSection.appendChild(row);
440
+ }
441
+ rootElement.insertBefore(varSection, textBlock);
442
+ }
443
+ for (const token of tokens) {
444
+ if (token.type === 'text') {
445
+ const span = document.createElement('span');
446
+ span.style.letterSpacing = 'inherit';
447
+ span.textContent = token.text;
448
+ textBlock.appendChild(span);
449
+ }
450
+ else if (token.type === 'simpleVar') {
451
+ const varName = token.name;
452
+ const span = document.createElement('span');
453
+ span.style.outline = `${theme.colorPrimary} dashed 1px`;
454
+ index.makeElementPlainTextContentEditable(span);
455
+ span.textContent = variables[varName] ?? '';
456
+ span.addEventListener('blur', (e) => {
457
+ const newValue = e.target.textContent || '';
458
+ if (newValue !== variables[varName]) {
459
+ variables[varName] = newValue;
460
+ if (onChange)
461
+ onChange({ key: 'content', value: JSON.stringify(variables) });
462
+ if (stopEditing)
463
+ stopEditing();
464
+ refreshExpressionSpans(textBlock, variables, pageContext);
465
+ }
466
+ });
467
+ textBlock.appendChild(span);
468
+ }
469
+ else {
470
+ // Complex expression — show evaluated result as static span with data-expr for re-evaluation
471
+ const span = document.createElement('span');
472
+ span.style.letterSpacing = 'inherit';
473
+ span.textContent = token.evaluated;
474
+ span.setAttribute('data-expr', token.raw);
475
+ textBlock.appendChild(span);
476
+ }
477
+ }
478
+ };
479
+ // Simple identifier regex — matches {name}, {orderId}, etc. but NOT {price * 1.1}
480
+ const SIMPLE_VAR_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
481
+ /** Tokenize a template string into static text, simple-identifier vars, and complex expressions. */
482
+ const tokenizeTemplate = (rawText, variables, pageCtx) => {
483
+ const tokens = [];
484
+ let i = 0;
485
+ while (i < rawText.length) {
486
+ if (rawText[i] !== '{') {
487
+ const start = i;
488
+ while (i < rawText.length && rawText[i] !== '{')
489
+ i++;
490
+ tokens.push({ type: 'text', text: rawText.slice(start, i) });
491
+ }
492
+ else {
493
+ // Find matching closing brace (handle nested braces)
494
+ let depth = 1;
495
+ let j = i + 1;
496
+ while (j < rawText.length && depth > 0) {
497
+ if (rawText[j] === '{')
498
+ depth++;
499
+ else if (rawText[j] === '}')
500
+ depth--;
501
+ j++;
502
+ }
503
+ const inner = rawText.slice(i + 1, j - 1);
504
+ if (SIMPLE_VAR_RE.test(inner)) {
505
+ tokens.push({ type: 'simpleVar', name: inner });
506
+ }
507
+ else {
508
+ // Evaluate the expression using substituteVariables on just this segment
509
+ const evaluated = fontSizePxWidget.substituteVariables(`{${inner}}`, variables, pageCtx);
510
+ tokens.push({ type: 'expression', evaluated, raw: inner });
511
+ }
512
+ i = j;
513
+ }
514
+ }
515
+ return tokens;
516
+ };
517
+ /** Reserved names — JS globals and expression builtins (must match propPanel's set) */
518
+ const RESERVED_NAMES = new Set([
519
+ 'true', 'false', 'null', 'undefined', 'typeof', 'instanceof', 'in',
520
+ 'void', 'delete', 'new', 'this', 'NaN', 'Infinity',
521
+ 'Math', 'String', 'Number', 'Boolean', 'Array', 'Object', 'Date', 'JSON',
522
+ 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent',
523
+ 'encodeURI', 'encodeURIComponent', 'date', 'dateTime',
524
+ 'currentPage', 'totalPages',
525
+ ]);
526
+ /** Count unique user-defined variable identifiers in all {...} blocks */
527
+ const countUniqueVariableNames = (content) => {
528
+ const blockRegex = /\{([^{}]+)\}/g;
529
+ const allIds = new Set();
530
+ let blockMatch;
531
+ while ((blockMatch = blockRegex.exec(content)) !== null) {
532
+ const cleaned = blockMatch[1].replace(/'[^']*'|"[^"]*"|`[^`]*`/g, '');
533
+ const tokenRegex = /\.?[a-zA-Z_$][a-zA-Z0-9_$]*/g;
534
+ let m;
535
+ while ((m = tokenRegex.exec(cleaned)) !== null) {
536
+ const token = m[0];
537
+ if (!token.startsWith('.') && !RESERVED_NAMES.has(token)) {
538
+ allIds.add(token);
539
+ }
540
+ }
541
+ }
542
+ return allIds.size;
543
+ };
544
+ /**
545
+ * An optimisation to try to minimise jank while typing.
546
+ * Only check whether variables were modified based on certain key presses.
547
+ * Regex would otherwise be performed on every key press (which isn't terrible, but this code helps).
548
+ */
549
+ const keyPressShouldBeChecked = (event) => {
550
+ if (event.key === 'ArrowUp' ||
551
+ event.key === 'ArrowDown' ||
552
+ event.key === 'ArrowLeft' ||
553
+ event.key === 'ArrowRight') {
554
+ return false;
555
+ }
556
+ const selection = window.getSelection();
557
+ const contenteditable = event.target;
558
+ const isCursorAtEnd = selection?.focusOffset === contenteditable?.textContent?.length;
559
+ if (isCursorAtEnd) {
560
+ return event.key === '}' || event.key === 'Backspace' || event.key === 'Delete';
561
+ }
562
+ const isCursorAtStart = selection?.anchorOffset === 0;
563
+ if (isCursorAtStart) {
564
+ return event.key === '{' || event.key === 'Backspace' || event.key === 'Delete';
565
+ }
566
+ return true;
567
+ };
568
+
569
+ const schema$3 = {
570
+ pdf: pdfRender$2,
571
+ ui: uiRender$2,
572
+ propPanel: propPanel$1,
573
+ icon: index.createSvgStr(lucide.Type),
574
+ uninterruptedEditMode: true,
116
575
  };
117
576
 
118
577
  const isValidSVG = (svgString) => {
@@ -224,12 +683,12 @@ const getBarcodeCacheKey = (schema, value) => {
224
683
  };
225
684
  const pdfRender$1 = async (arg) => {
226
685
  const { value, schema, pdfDoc, page, _cache } = arg;
227
- if (!index$1.validateBarcodeInput(schema.type, value))
686
+ if (!fontSizePxWidget.validateBarcodeInput(schema.type, value))
228
687
  return;
229
688
  const inputBarcodeCacheKey = getBarcodeCacheKey(schema, value);
230
689
  let image = _cache.get(inputBarcodeCacheKey);
231
690
  if (!image) {
232
- const imageBuf = await index$1.createBarCode({
691
+ const imageBuf = await fontSizePxWidget.createBarCode({
233
692
  ...schema,
234
693
  type: schema.type,
235
694
  input: value,
@@ -243,11 +702,11 @@ const pdfRender$1 = async (arg) => {
243
702
  };
244
703
 
245
704
  const defaultColors = {
246
- backgroundColor: index$1.DEFAULT_BARCODE_BG_COLOR,
247
- barColor: index$1.DEFAULT_BARCODE_COLOR,
705
+ backgroundColor: fontSizePxWidget.DEFAULT_BARCODE_BG_COLOR,
706
+ barColor: fontSizePxWidget.DEFAULT_BARCODE_COLOR,
248
707
  };
249
- const defaultTextColors = { textColor: index$1.DEFAULT_BARCODE_COLOR };
250
- const defaultIncludetext = { includetext: index$1.DEFAULT_BARCODE_INCLUDETEXT };
708
+ const defaultTextColors = { textColor: fontSizePxWidget.DEFAULT_BARCODE_COLOR };
709
+ const defaultIncludetext = { includetext: fontSizePxWidget.DEFAULT_BARCODE_INCLUDETEXT };
251
710
  const position = { x: 0, y: 0 };
252
711
  const default40x20 = { width: 40, height: 20 };
253
712
  const barcodeDefaults = [
@@ -255,7 +714,7 @@ const barcodeDefaults = [
255
714
  defaultSchema: {
256
715
  name: '',
257
716
  type: 'qrcode',
258
- content: 'https://pdfme.com/',
717
+ content: '',
259
718
  position,
260
719
  ...defaultColors,
261
720
  width: 30,
@@ -485,7 +944,7 @@ const blobToDataURL = (blob) => new Promise((resolve, reject) => {
485
944
  reader.readAsDataURL(blob);
486
945
  });
487
946
  const createBarcodeImage = async (schema, value) => {
488
- const imageBuf = await index$1.createBarCode({
947
+ const imageBuf = await fontSizePxWidget.createBarCode({
489
948
  ...schema,
490
949
  input: value,
491
950
  });
@@ -551,7 +1010,7 @@ const uiRender$1 = async (arg) => {
551
1010
  if (!value)
552
1011
  return;
553
1012
  try {
554
- if (!index$1.validateBarcodeInput(schema.type, value))
1013
+ if (!fontSizePxWidget.validateBarcodeInput(schema.type, value))
555
1014
  throw new Error('[@campxdev/schemas/barcodes] Invalid barcode input');
556
1015
  const imgElm = await createBarcodeImageElm(schema, value);
557
1016
  container.appendChild(imgElm);
@@ -562,7 +1021,7 @@ const uiRender$1 = async (arg) => {
562
1021
  }
563
1022
  };
564
1023
 
565
- const barcodes = index$1.BARCODE_TYPES.reduce((acc, type) => Object.assign(acc, {
1024
+ const barcodes = fontSizePxWidget.BARCODE_TYPES.reduce((acc, type) => Object.assign(acc, {
566
1025
  [type]: {
567
1026
  pdf: pdfRender$1,
568
1027
  ui: uiRender$1,
@@ -571,8 +1030,8 @@ const barcodes = index$1.BARCODE_TYPES.reduce((acc, type) => Object.assign(acc,
571
1030
  },
572
1031
  }), {});
573
1032
 
574
- const rectanglePdfRender = index$1.rectangle.pdf;
575
- const cellPdfRender = index$1.cellSchema.pdf;
1033
+ const rectanglePdfRender = fontSizePxWidget.rectangle.pdf;
1034
+ const cellPdfRender = fontSizePxWidget.cellSchema.pdf;
576
1035
  async function drawCell(arg, cell) {
577
1036
  await cellPdfRender({
578
1037
  ...arg,
@@ -686,7 +1145,7 @@ function createButton(options) {
686
1145
  button.onclick = options.onClick;
687
1146
  return button;
688
1147
  }
689
- const cellUiRender = index$1.cellSchema.ui;
1148
+ const cellUiRender = fontSizePxWidget.cellSchema.ui;
690
1149
  const convertToCellStyle = (styles) => ({
691
1150
  fontName: styles.fontName,
692
1151
  alignment: styles.alignment,
@@ -1261,7 +1720,7 @@ const getPlugin = ({ type, icon }) => {
1261
1720
  justifyContent: index.mapVerticalAlignToFlex(index.VERTICAL_ALIGN_MIDDLE),
1262
1721
  };
1263
1722
  Object.assign(textElement.style, textElementStyle);
1264
- await textSchema.ui({
1723
+ await index.textSchema.ui({
1265
1724
  ...arg,
1266
1725
  rootElement: textElement,
1267
1726
  mode: 'viewer',
@@ -1372,7 +1831,7 @@ const getPlugin = ({ type, icon }) => {
1372
1831
  if (!value)
1373
1832
  return void 0;
1374
1833
  const locale = getAirDatepickerLocale(schema.locale || options.lang || defaultLocale);
1375
- return textSchema.pdf({
1834
+ return index.textSchema.pdf({
1376
1835
  ...arg,
1377
1836
  value: getFmtValue(value, type, schema, locale),
1378
1837
  schema: {
@@ -1609,7 +2068,7 @@ const addOptions = (props) => {
1609
2068
  const schema$2 = {
1610
2069
  ui: async (arg) => {
1611
2070
  const { schema, value, onChange, rootElement, mode } = arg;
1612
- await textSchema.ui(Object.assign(arg, { mode: 'viewer' }));
2071
+ await index.textSchema.ui(Object.assign(arg, { mode: 'viewer' }));
1613
2072
  if (mode !== 'viewer' && !(mode === 'form' && schema.readOnly)) {
1614
2073
  const buttonWidth = 30;
1615
2074
  const selectButton = document.createElement('button');
@@ -1653,9 +2112,9 @@ const schema$2 = {
1653
2112
  rootElement.appendChild(selectElement);
1654
2113
  }
1655
2114
  },
1656
- pdf: textSchema.pdf,
2115
+ pdf: index.textSchema.pdf,
1657
2116
  propPanel: {
1658
- ...textSchema.propPanel,
2117
+ ...index.textSchema.propPanel,
1659
2118
  widgets: { ...index.propPanel.widgets, addOptions },
1660
2119
  schema: (propPanelProps) => {
1661
2120
  if (typeof index.propPanel.schema !== 'function') {
@@ -1677,7 +2136,7 @@ const schema$2 = {
1677
2136
  };
1678
2137
  },
1679
2138
  defaultSchema: {
1680
- ...textSchema.propPanel.defaultSchema,
2139
+ ...index.textSchema.propPanel.defaultSchema,
1681
2140
  type: 'select',
1682
2141
  content: 'option1',
1683
2142
  options: ['option1', 'option2'],
@@ -1822,23 +2281,26 @@ const schema = {
1822
2281
 
1823
2282
  exports.builtInPlugins = index.builtInPlugins;
1824
2283
  exports.getDynamicHeightsForTable = index.getDynamicHeightsForTable;
1825
- exports.multiVariableText = index.schema;
1826
- exports.dynamicBarcode = index$1.dynamicBarcode;
1827
- exports.dynamicQrCode = index$1.dynamicQrCode;
1828
- exports.dynamicTable = index$1.dynamicTableSchema;
1829
- exports.ellipse = index$1.ellipse;
1830
- exports.image = index$1.imageSchema;
1831
- exports.line = index$1.lineSchema;
1832
- exports.rectangle = index$1.rectangle;
1833
- exports.signature = index$1.signature;
1834
- exports.variableBarcodes = index$1.variableBarcodes;
2284
+ exports.richText = index.schema;
2285
+ exports.singleVariableText = index.schema$1;
2286
+ exports.text = index.textSchema;
2287
+ exports.dynamicBarcode = fontSizePxWidget.dynamicBarcode;
2288
+ exports.dynamicQrCode = fontSizePxWidget.dynamicQrCode;
2289
+ exports.dynamicTable = fontSizePxWidget.dynamicTableSchema;
2290
+ exports.ellipse = fontSizePxWidget.ellipse;
2291
+ exports.fontSizePxWidget = fontSizePxWidget.fontSizePxWidget;
2292
+ exports.image = fontSizePxWidget.imageSchema;
2293
+ exports.line = fontSizePxWidget.lineSchema;
2294
+ exports.rectangle = fontSizePxWidget.rectangle;
2295
+ exports.signature = fontSizePxWidget.signature;
2296
+ exports.variableBarcodes = fontSizePxWidget.variableBarcodes;
1835
2297
  exports.barcodes = barcodes;
1836
2298
  exports.checkbox = schema;
1837
2299
  exports.date = date;
1838
2300
  exports.dateTime = dateTime;
2301
+ exports.multiVariableText = schema$3;
1839
2302
  exports.radioGroup = schema$1;
1840
2303
  exports.select = schema$2;
1841
2304
  exports.svg = svgSchema;
1842
2305
  exports.table = tableSchema;
1843
- exports.text = textSchema;
1844
2306
  exports.time = time;