@pdfme/ui 3.4.3 → 4.0.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 (51) hide show
  1. package/dist/index.es.js +60294 -59344
  2. package/dist/index.umd.js +116 -117
  3. package/dist/types/class.d.ts +60 -10
  4. package/dist/types/components/AppContextProvider.d.ts +2 -2
  5. package/dist/types/components/CtlBar.d.ts +2 -0
  6. package/dist/types/components/Designer/Canvas/Padding.d.ts +6 -0
  7. package/dist/types/components/Designer/Canvas/index.d.ts +2 -1
  8. package/dist/types/components/Designer/LeftSidebar.d.ts +8 -0
  9. package/dist/types/components/Designer/index.d.ts +2 -1
  10. package/dist/types/components/Preview.d.ts +1 -1
  11. package/dist/types/components/Renderer.d.ts +4 -3
  12. package/dist/types/constants.d.ts +1 -1
  13. package/dist/types/contexts.d.ts +12 -3
  14. package/dist/types/helper.d.ts +21 -33
  15. package/dist/types/hooks.d.ts +1 -0
  16. package/dist/types/types.d.ts +0 -1
  17. package/package.json +1 -1
  18. package/src/Designer.tsx +8 -3
  19. package/src/Form.tsx +6 -3
  20. package/src/Viewer.tsx +0 -1
  21. package/src/class.ts +28 -5
  22. package/src/components/AppContextProvider.tsx +3 -1
  23. package/src/components/CtlBar.tsx +57 -6
  24. package/src/components/Designer/Canvas/Padding.tsx +54 -0
  25. package/src/components/Designer/Canvas/index.tsx +89 -22
  26. package/src/components/Designer/LeftSidebar.tsx +81 -0
  27. package/src/components/Designer/{Sidebar → RightSidebar}/DetailView/index.tsx +8 -13
  28. package/src/components/Designer/{Sidebar → RightSidebar}/ListView/index.tsx +3 -11
  29. package/src/components/Designer/{Sidebar → RightSidebar}/index.tsx +5 -20
  30. package/src/components/Designer/index.tsx +166 -101
  31. package/src/components/Paper.tsx +1 -2
  32. package/src/components/Preview.tsx +72 -22
  33. package/src/components/Renderer.tsx +12 -11
  34. package/src/constants.ts +1 -1
  35. package/src/helper.ts +114 -118
  36. package/src/hooks.ts +46 -14
  37. package/src/i18n.ts +194 -7
  38. package/src/types.ts +0 -1
  39. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/DetailView/AlignWidget.d.ts +0 -0
  40. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/DetailView/WidgetRenderer.d.ts +0 -0
  41. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/DetailView/index.d.ts +0 -0
  42. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/ListView/Item.d.ts +0 -0
  43. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/ListView/SelectableSortableContainer.d.ts +0 -0
  44. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/ListView/SelectableSortableItem.d.ts +0 -0
  45. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/ListView/index.d.ts +0 -0
  46. /package/dist/types/components/Designer/{Sidebar → RightSidebar}/index.d.ts +0 -0
  47. /package/src/components/Designer/{Sidebar → RightSidebar}/DetailView/AlignWidget.tsx +0 -0
  48. /package/src/components/Designer/{Sidebar → RightSidebar}/DetailView/WidgetRenderer.tsx +0 -0
  49. /package/src/components/Designer/{Sidebar → RightSidebar}/ListView/Item.tsx +0 -0
  50. /package/src/components/Designer/{Sidebar → RightSidebar}/ListView/SelectableSortableContainer.tsx +0 -0
  51. /package/src/components/Designer/{Sidebar → RightSidebar}/ListView/SelectableSortableItem.tsx +0 -0
@@ -10,19 +10,57 @@ export declare abstract class BaseUIClass {
10
10
  private readonly setSize;
11
11
  resizeObserver: ResizeObserver;
12
12
  constructor(props: UIProps);
13
- protected getLang(): "en" | "th" | "ja" | "ar" | "pl" | "it" | "de";
13
+ protected getLang(): "en" | "th" | "pl" | "ja" | "ar" | "it" | "de" | "es" | "fr";
14
14
  protected getFont(): Record<string, {
15
- data: (string | Uint8Array | ArrayBuffer) & (string | Uint8Array | ArrayBuffer | undefined);
15
+ data: (string | ArrayBuffer | Uint8Array) & (string | ArrayBuffer | Uint8Array | undefined);
16
16
  fallback?: boolean | undefined;
17
17
  subset?: boolean | undefined;
18
18
  }>;
19
19
  protected getPluginsRegistry(): Plugins;
20
20
  protected getOptions(): {};
21
- getTemplate(): {
22
- schemas: Record<string, import("zod").objectOutputType<{
21
+ getTemplate(): import("zod").objectOutputType<{
22
+ schemas: import("zod").ZodArray<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{
23
23
  type: import("zod").ZodString;
24
+ icon: import("zod").ZodOptional<import("zod").ZodString>;
25
+ content: import("zod").ZodOptional<import("zod").ZodString>;
26
+ position: import("zod").ZodObject<{
27
+ x: import("zod").ZodNumber;
28
+ y: import("zod").ZodNumber;
29
+ }, "strip", import("zod").ZodTypeAny, {
30
+ x: number;
31
+ y: number;
32
+ }, {
33
+ x: number;
34
+ y: number;
35
+ }>;
36
+ width: import("zod").ZodNumber;
37
+ height: import("zod").ZodNumber;
38
+ rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
39
+ opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
40
+ readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
41
+ }, "passthrough", import("zod").ZodTypeAny, import("zod").objectOutputType<{
42
+ type: import("zod").ZodString;
43
+ icon: import("zod").ZodOptional<import("zod").ZodString>;
44
+ content: import("zod").ZodOptional<import("zod").ZodString>;
45
+ position: import("zod").ZodObject<{
46
+ x: import("zod").ZodNumber;
47
+ y: import("zod").ZodNumber;
48
+ }, "strip", import("zod").ZodTypeAny, {
49
+ x: number;
50
+ y: number;
51
+ }, {
52
+ x: number;
53
+ y: number;
54
+ }>;
55
+ width: import("zod").ZodNumber;
56
+ height: import("zod").ZodNumber;
57
+ rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
58
+ opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
24
59
  readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
25
- readOnlyValue: import("zod").ZodOptional<import("zod").ZodString>;
60
+ }, import("zod").ZodTypeAny, "passthrough">, import("zod").objectInputType<{
61
+ type: import("zod").ZodString;
62
+ icon: import("zod").ZodOptional<import("zod").ZodString>;
63
+ content: import("zod").ZodOptional<import("zod").ZodString>;
26
64
  position: import("zod").ZodObject<{
27
65
  x: import("zod").ZodNumber;
28
66
  y: import("zod").ZodNumber;
@@ -37,11 +75,23 @@ export declare abstract class BaseUIClass {
37
75
  height: import("zod").ZodNumber;
38
76
  rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
39
77
  opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
40
- }, import("zod").ZodTypeAny, "passthrough">>[];
41
- basePdf: (string | Uint8Array | ArrayBuffer) & (string | Uint8Array | ArrayBuffer | undefined);
42
- sampledata?: Record<string, string>[] | undefined;
43
- columns?: string[] | undefined;
44
- };
78
+ readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
79
+ }, import("zod").ZodTypeAny, "passthrough">>>, "many">;
80
+ basePdf: import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodType<ArrayBuffer, import("zod").ZodTypeDef, ArrayBuffer>, import("zod").ZodType<Uint8Array, import("zod").ZodTypeDef, Uint8Array>, import("zod").ZodObject<{
81
+ width: import("zod").ZodNumber;
82
+ height: import("zod").ZodNumber;
83
+ padding: import("zod").ZodTuple<[import("zod").ZodNumber, import("zod").ZodNumber, import("zod").ZodNumber, import("zod").ZodNumber], null>;
84
+ }, "strip", import("zod").ZodTypeAny, {
85
+ width: number;
86
+ height: number;
87
+ padding: [number, number, number, number];
88
+ }, {
89
+ width: number;
90
+ height: number;
91
+ padding: [number, number, number, number];
92
+ }>]>;
93
+ pdfmeVersion: import("zod").ZodOptional<import("zod").ZodString>;
94
+ }, import("zod").ZodTypeAny, "passthrough">;
45
95
  updateTemplate(template: Template): void;
46
96
  updateOptions(options: UIOptions): void;
47
97
  destroy(): void;
@@ -7,5 +7,5 @@ type Props = {
7
7
  plugins: Plugins;
8
8
  options: UIOptions;
9
9
  };
10
- declare const _default: ({ children, lang, font, plugins, options }: Props) => React.JSX.Element;
11
- export default _default;
10
+ declare const AppContextProvider: ({ children, lang, font, plugins, options }: Props) => React.JSX.Element;
11
+ export default AppContextProvider;
@@ -7,6 +7,8 @@ type CtlBarProps = {
7
7
  setPageCursor: (page: number) => void;
8
8
  zoomLevel: number;
9
9
  setZoomLevel: (zoom: number) => void;
10
+ addPageAfter?: () => void;
11
+ removePage?: () => void;
10
12
  };
11
13
  declare const CtlBar: (props: CtlBarProps) => React.JSX.Element;
12
14
  export default CtlBar;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { BasePdf } from '@pdfme/common';
3
+ declare const Padding: ({ basePdf }: {
4
+ basePdf: BasePdf;
5
+ }) => React.JSX.Element;
6
+ export default Padding;
@@ -1,6 +1,7 @@
1
1
  import React, { MutableRefObject } from 'react';
2
- import { SchemaForUI, Size, ChangeSchemas } from '@pdfme/common';
2
+ import { SchemaForUI, Size, ChangeSchemas, BasePdf } from '@pdfme/common';
3
3
  interface Props {
4
+ basePdf: BasePdf;
4
5
  height: number;
5
6
  hoveringSchemaId: string | null;
6
7
  onChangeHoveringSchemaId: (id: string | null) => void;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { BasePdf } from '@pdfme/common';
3
+ declare const LeftSidebar: ({ height, scale, basePdf }: {
4
+ height: number;
5
+ scale: number;
6
+ basePdf: BasePdf;
7
+ }) => React.JSX.Element;
8
+ export default LeftSidebar;
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
  import { Template, DesignerProps, Size } from '@pdfme/common';
3
3
  declare const TemplateEditor: ({ template, size, onSaveTemplate, onChangeTemplate, onPageCursorChange, }: Omit<DesignerProps, "domContainer"> & {
4
- onSaveTemplate: (t: Template) => void;
5
4
  size: Size;
5
+ onSaveTemplate: (t: Template) => void;
6
+ onChangeTemplate: (t: Template) => void;
6
7
  } & {
7
8
  onChangeTemplate: (t: Template) => void;
8
9
  onPageCursorChange: (newPageCursor: number) => void;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { PreviewProps, Size } from '@pdfme/common';
2
+ import { PreviewProps, Size } from '@pdfme/common';
3
3
  declare const Preview: ({ template, inputs, size, onChangeInput, }: Omit<PreviewProps, "domContainer"> & {
4
4
  onChangeInput?: ((args: {
5
5
  index: number;
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
- import { UIRenderProps, SchemaForUI, Schema } from '@pdfme/common';
3
- type RendererProps = Omit<UIRenderProps<Schema>, 'value' | 'schema' | 'onChange' | 'rootElement' | 'options' | 'theme' | 'i18n' | 'pdfJs' | '_cache'> & {
2
+ import { UIRenderProps, SchemaForUI, BasePdf, Schema } from '@pdfme/common';
3
+ type RendererProps = Omit<UIRenderProps<Schema>, 'schema' | 'rootElement' | 'options' | 'theme' | 'i18n' | 'pdfJs' | '_cache'> & {
4
+ basePdf: BasePdf;
4
5
  schema: SchemaForUI;
5
- onChange: (value: string) => void;
6
+ value: string;
6
7
  outline: string;
7
8
  onChangeHoveringSchemaId?: (id: string | null) => void;
8
9
  scale: number;
@@ -3,5 +3,5 @@ export declare const DESTROYED_ERR_MSG = "[@pdfme/ui] this instance is already d
3
3
  export declare const SELECTABLE_CLASSNAME = "selectable";
4
4
  export declare const RULER_HEIGHT = 30;
5
5
  export declare const PAGE_GAP = 10;
6
- export declare const SIDEBAR_WIDTH = 350;
6
+ export declare const RIGHT_SIDEBAR_WIDTH = 400;
7
7
  export declare const BACKGROUND_COLOR = "rgb(74, 74, 74)";
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { Plugins, UIOptions } from '@pdfme/common';
3
- export declare const I18nContext: import("react").Context<(key: "height" | "width" | "type" | "rotate" | "opacity" | "cancel" | "field" | "fieldName" | "align" | "edit" | "plsInputName" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName" | "hexColorPrompt" | "schemas.color" | "schemas.borderWidth" | "schemas.borderColor" | "schemas.textColor" | "schemas.bgColor" | "schemas.horizontal" | "schemas.vertical" | "schemas.left" | "schemas.center" | "schemas.right" | "schemas.top" | "schemas.middle" | "schemas.bottom" | "schemas.text.fontName" | "schemas.text.size" | "schemas.text.spacing" | "schemas.text.textAlign" | "schemas.text.verticalAlign" | "schemas.text.lineHeight" | "schemas.text.min" | "schemas.text.max" | "schemas.text.fit" | "schemas.text.dynamicFontSize" | "schemas.barcodes.barColor" | "schemas.barcodes.includetext", dict?: {
3
+ export declare const I18nContext: import("react").Context<(key: "type" | "width" | "height" | "rotate" | "opacity" | "cancel" | "field" | "fieldName" | "align" | "edit" | "plsInputName" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "editField" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName" | "addPageAfter" | "removePage" | "removePageConfirm" | "hexColorPrompt" | "schemas.color" | "schemas.borderWidth" | "schemas.borderColor" | "schemas.backgroundColor" | "schemas.textColor" | "schemas.bgColor" | "schemas.horizontal" | "schemas.vertical" | "schemas.left" | "schemas.center" | "schemas.right" | "schemas.top" | "schemas.middle" | "schemas.bottom" | "schemas.padding" | "schemas.text.fontName" | "schemas.text.size" | "schemas.text.spacing" | "schemas.text.textAlign" | "schemas.text.verticalAlign" | "schemas.text.lineHeight" | "schemas.text.min" | "schemas.text.max" | "schemas.text.fit" | "schemas.text.dynamicFontSize" | "schemas.barcodes.barColor" | "schemas.barcodes.includetext" | "schemas.table.alternateBackgroundColor" | "schemas.table.tableStyle" | "schemas.table.headStyle" | "schemas.table.bodyStyle" | "schemas.table.columnStyle", dict?: {
4
4
  cancel: string;
5
5
  field: string;
6
6
  fieldName: string;
@@ -15,17 +15,20 @@ export declare const I18nContext: import("react").Context<(key: "height" | "widt
15
15
  notUniq: string;
16
16
  noKeyName: string;
17
17
  fieldsList: string;
18
- addNewField: string;
19
18
  editField: string;
20
19
  type: string;
21
20
  errorOccurred: string;
22
21
  errorBulkUpdateFieldName: string;
23
22
  commitBulkUpdateFieldName: string;
24
23
  bulkUpdateFieldName: string;
24
+ addPageAfter: string;
25
+ removePage: string;
26
+ removePageConfirm: string;
25
27
  hexColorPrompt: string;
26
28
  'schemas.color': string;
27
29
  'schemas.borderWidth': string;
28
30
  'schemas.borderColor': string;
31
+ 'schemas.backgroundColor': string;
29
32
  'schemas.textColor': string;
30
33
  'schemas.bgColor': string;
31
34
  'schemas.horizontal': string;
@@ -36,6 +39,7 @@ export declare const I18nContext: import("react").Context<(key: "height" | "widt
36
39
  'schemas.top': string;
37
40
  'schemas.middle': string;
38
41
  'schemas.bottom': string;
42
+ 'schemas.padding': string;
39
43
  'schemas.text.fontName': string;
40
44
  'schemas.text.size': string;
41
45
  'schemas.text.spacing': string;
@@ -48,9 +52,14 @@ export declare const I18nContext: import("react").Context<(key: "height" | "widt
48
52
  'schemas.text.dynamicFontSize': string;
49
53
  'schemas.barcodes.barColor': string;
50
54
  'schemas.barcodes.includetext': string;
55
+ 'schemas.table.alternateBackgroundColor': string;
56
+ 'schemas.table.tableStyle': string;
57
+ 'schemas.table.headStyle': string;
58
+ 'schemas.table.bodyStyle': string;
59
+ 'schemas.table.columnStyle': string;
51
60
  } | undefined) => string>;
52
61
  export declare const FontContext: import("react").Context<Record<string, {
53
- data: (string | Uint8Array | ArrayBuffer) & (string | Uint8Array | ArrayBuffer | undefined);
62
+ data: (string | ArrayBuffer | Uint8Array) & (string | ArrayBuffer | Uint8Array | undefined);
54
63
  fallback?: boolean | undefined;
55
64
  subset?: boolean | undefined;
56
65
  }>>;
@@ -1,4 +1,4 @@
1
- import { Template, SchemaForUI, Size } from '@pdfme/common';
1
+ import { Template, BasePdf, SchemaForUI, Size, Plugins } from '@pdfme/common';
2
2
  export declare const uuid: () => string;
3
3
  export declare const set: <T extends object>(obj: T, path: string | string[], value: any) => void;
4
4
  export declare const debounce: <T extends Function>(cb: T, wait?: number) => T;
@@ -24,7 +24,7 @@ export declare const getPdfPageSizes: (pdfBlob: Blob) => Promise<{
24
24
  }[]>;
25
25
  export declare const pdf2Pngs: (pdfBlob: Blob, width: number) => Promise<string[]>;
26
26
  export declare const b64toBlob: (base64: string) => Blob;
27
- export declare const templateSchemas2SchemasList: (_template: Template) => Promise<{
27
+ export declare const template2SchemasList: (_template: Template) => Promise<{
28
28
  width: number;
29
29
  height: number;
30
30
  type: string;
@@ -32,39 +32,15 @@ export declare const templateSchemas2SchemasList: (_template: Template) => Promi
32
32
  x: number;
33
33
  y: number;
34
34
  };
35
- data: string;
36
35
  id: string;
37
36
  key: string;
38
37
  opacity?: number | undefined;
39
38
  rotate?: number | undefined;
39
+ icon?: string | undefined;
40
+ content?: string | undefined;
40
41
  readOnly?: boolean | undefined;
41
- readOnlyValue?: string | undefined;
42
42
  }[][]>;
43
- export declare const generateColumnsAndSampledataIfNeeded: (template: Template) => {
44
- schemas: Record<string, import("zod").objectOutputType<{
45
- type: import("zod").ZodString;
46
- readOnly: import("zod").ZodOptional<import("zod").ZodBoolean>;
47
- readOnlyValue: import("zod").ZodOptional<import("zod").ZodString>;
48
- position: import("zod").ZodObject<{
49
- x: import("zod").ZodNumber;
50
- y: import("zod").ZodNumber;
51
- }, "strip", import("zod").ZodTypeAny, {
52
- x: number;
53
- y: number;
54
- }, {
55
- x: number;
56
- y: number;
57
- }>;
58
- width: import("zod").ZodNumber;
59
- height: import("zod").ZodNumber;
60
- rotate: import("zod").ZodOptional<import("zod").ZodNumber>;
61
- opacity: import("zod").ZodOptional<import("zod").ZodNumber>;
62
- }, import("zod").ZodTypeAny, "passthrough">>[];
63
- basePdf: (string | Uint8Array | ArrayBuffer) & (string | Uint8Array | ArrayBuffer | undefined);
64
- sampledata?: Record<string, string>[] | undefined;
65
- columns?: string[] | undefined;
66
- };
67
- export declare const fmtTemplate: (template: Template, schemasList: SchemaForUI[][]) => Template;
43
+ export declare const schemasList2template: (schemasList: SchemaForUI[][], basePdf: BasePdf) => Template;
68
44
  export declare const getUniqSchemaKey: (arg: {
69
45
  copiedSchemaKey: string;
70
46
  schema: SchemaForUI[];
@@ -80,9 +56,21 @@ export declare const moveCommandToChangeSchemasArg: (props: {
80
56
  value: number;
81
57
  schemaId: string;
82
58
  }[];
83
- export declare const getPagesScrollTopByIndex: (pageSizes: {
84
- width: number;
85
- height: number;
86
- }[], index: number, scale: number) => number;
59
+ export declare const getPagesScrollTopByIndex: (pageSizes: Size[], index: number, scale: number) => number;
87
60
  export declare const getSidebarContentHeight: (sidebarHeight: number) => number;
61
+ export declare const changeSchemas: (args: {
62
+ objs: {
63
+ key: string;
64
+ value: any;
65
+ schemaId: string;
66
+ }[];
67
+ schemas: SchemaForUI[];
68
+ basePdf: BasePdf;
69
+ pluginsRegistry: Plugins;
70
+ pageSize: {
71
+ width: number;
72
+ height: number;
73
+ };
74
+ commitSchemas: (newSchemas: SchemaForUI[]) => void;
75
+ }) => void;
88
76
  export {};
@@ -14,6 +14,7 @@ export declare const useUIPreProcessor: ({ template, size, zoomLevel }: UIPrePro
14
14
  }[];
15
15
  scale: number;
16
16
  error: Error | null;
17
+ refresh: (template: Template) => Promise<void>;
17
18
  };
18
19
  type ScrollPageCursorProps = {
19
20
  ref: RefObject<HTMLDivElement>;
@@ -11,7 +11,6 @@ export type SidebarProps = {
11
11
  onEdit: (id: string) => void;
12
12
  onEditEnd: () => void;
13
13
  changeSchemas: ChangeSchemas;
14
- addSchema: () => void;
15
14
  deselectSchema: () => void;
16
15
  sidebarOpen: boolean;
17
16
  setSidebarOpen: (sidebarOpen: boolean) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdfme/ui",
3
- "version": "3.4.3",
3
+ "version": "4.0.0",
4
4
  "sideEffects": false,
5
5
  "author": "hand-dot",
6
6
  "license": "MIT",
package/src/Designer.tsx CHANGED
@@ -1,6 +1,12 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom';
3
- import { Template, DesignerProps, checkDesignerProps, checkTemplate } from '@pdfme/common';
3
+ import {
4
+ Template,
5
+ DesignerProps,
6
+ checkDesignerProps,
7
+ checkTemplate,
8
+ PDFME_VERSION,
9
+ } from '@pdfme/common';
4
10
  import { BaseUIClass } from './class';
5
11
  import { DESTROYED_ERR_MSG } from './constants.js';
6
12
  import DesignerComponent from './components/Designer/index';
@@ -15,8 +21,6 @@ class Designer extends BaseUIClass {
15
21
  constructor(props: DesignerProps) {
16
22
  super(props);
17
23
  checkDesignerProps(props);
18
-
19
- this.render();
20
24
  }
21
25
 
22
26
  public saveTemplate() {
@@ -67,6 +71,7 @@ class Designer extends BaseUIClass {
67
71
  }}
68
72
  onChangeTemplate={(template) => {
69
73
  this.template = template;
74
+ this.template.pdfmeVersion = PDFME_VERSION;
70
75
  if (this.onChangeTemplateCallback) {
71
76
  this.onChangeTemplateCallback(template);
72
77
  }
package/src/Form.tsx CHANGED
@@ -11,7 +11,6 @@ class Form extends PreviewUI {
11
11
 
12
12
  constructor(props: PreviewProps) {
13
13
  super(props);
14
- this.render();
15
14
  }
16
15
 
17
16
  public onChangeInput(cb: (arg: { index: number; value: string; key: string }) => void) {
@@ -36,8 +35,12 @@ class Form extends PreviewUI {
36
35
  if (this.onChangeInputCallback) {
37
36
  this.onChangeInputCallback({ index, value, key });
38
37
  }
39
- this.inputs[index][key] = value;
40
- this.render();
38
+ if (this.inputs && this.inputs[index]) {
39
+ if (this.inputs[index][key] !== value) {
40
+ this.inputs[index][key] = value;
41
+ this.render();
42
+ }
43
+ }
41
44
  }}
42
45
  />
43
46
  </AppContextProvider>,
package/src/Viewer.tsx CHANGED
@@ -9,7 +9,6 @@ import AppContextProvider from './components/AppContextProvider';
9
9
  class Viewer extends PreviewUI {
10
10
  constructor(props: PreviewProps) {
11
11
  super(props);
12
- this.render();
13
12
  }
14
13
 
15
14
  protected render() {
package/src/class.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import ReactDOM from 'react-dom';
2
2
  import { DESTROYED_ERR_MSG, DEFAULT_LANG } from './constants.js';
3
- import { debounce, generateColumnsAndSampledataIfNeeded, cloneDeep } from './helper.js';
3
+ import { debounce, cloneDeep } from './helper.js';
4
4
  import {
5
5
  Template,
6
6
  Size,
@@ -50,7 +50,7 @@ export abstract class BaseUIClass {
50
50
 
51
51
  const { domContainer, template, options = {}, plugins = {} } = props;
52
52
  this.domContainer = domContainer;
53
- this.template = generateColumnsAndSampledataIfNeeded(cloneDeep(template));
53
+ this.template = cloneDeep(template);
54
54
  this.options = options;
55
55
  this.size = {
56
56
  height: this.domContainer.clientHeight || window.innerHeight,
@@ -131,8 +131,7 @@ export abstract class PreviewUI extends BaseUIClass {
131
131
  constructor(props: PreviewProps) {
132
132
  super(props);
133
133
  checkPreviewProps(props);
134
-
135
- this.inputs = cloneDeep(props.inputs);
134
+ this.inputs = convertToStingObjectArray(cloneDeep(props.inputs));
136
135
  }
137
136
 
138
137
  public getInputs() {
@@ -144,9 +143,33 @@ export abstract class PreviewUI extends BaseUIClass {
144
143
  public setInputs(inputs: { [key: string]: string }[]) {
145
144
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
146
145
  checkInputs(inputs);
147
- this.inputs = cloneDeep(inputs);
146
+
147
+ this.inputs = convertToStingObjectArray(inputs);
148
148
  this.render();
149
149
  }
150
150
 
151
151
  protected abstract render(): void;
152
152
  }
153
+
154
+ type DataItem = {
155
+ [key: string]: string | string[][];
156
+ };
157
+
158
+ type StringifiedDataItem = {
159
+ [key: string]: string;
160
+ };
161
+
162
+ function convertToStingObjectArray(data: DataItem[]): StringifiedDataItem[] {
163
+ return data.map((item) => {
164
+ const stringifiedItem: StringifiedDataItem = {};
165
+ Object.keys(item).forEach((key) => {
166
+ const value = item[key];
167
+ if (Array.isArray(value)) {
168
+ stringifiedItem[key] = JSON.stringify(value);
169
+ } else {
170
+ stringifiedItem[key] = value;
171
+ }
172
+ });
173
+ return stringifiedItem;
174
+ });
175
+ }
@@ -38,7 +38,7 @@ const deepMerge = <T extends Record<string, any>, U extends Record<string, any>>
38
38
  return output;
39
39
  };
40
40
 
41
- export default ({ children, lang, font, plugins, options }: Props) => {
41
+ const AppContextProvider = ({ children, lang, font, plugins, options }: Props) => {
42
42
  let theme = defaultTheme;
43
43
  if (options.theme) {
44
44
  theme = deepMerge(theme, options.theme);
@@ -61,3 +61,5 @@ export default ({ children, lang, font, plugins, options }: Props) => {
61
61
  </ThemeConfigProvider>
62
62
  );
63
63
  };
64
+
65
+ export default AppContextProvider;
@@ -1,7 +1,15 @@
1
- import React from 'react';
1
+ import React, { useContext } from 'react';
2
2
  import { Size } from '@pdfme/common';
3
- import { MinusOutlined, PlusOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons';
4
- import { theme, Typography, Button } from 'antd';
3
+ import {
4
+ MinusOutlined,
5
+ PlusOutlined,
6
+ LeftOutlined,
7
+ RightOutlined,
8
+ EllipsisOutlined,
9
+ } from '@ant-design/icons';
10
+ import type { MenuProps } from 'antd';
11
+ import { theme, Typography, Button, Dropdown } from 'antd';
12
+ import { I18nContext } from '../contexts';
5
13
 
6
14
  const { Text } = Typography;
7
15
 
@@ -68,6 +76,18 @@ const Pager = ({ pageCursor, pageNum, setPageCursor, style }: PagerProps) => {
68
76
  );
69
77
  };
70
78
 
79
+ type ContextMenuProps = {
80
+ items: MenuProps['items'];
81
+ style: { textStyle: TextStyle };
82
+ };
83
+ const ContextMenu = ({ items, style }: ContextMenuProps) => (
84
+ <Dropdown menu={{ items }} placement="top" arrow trigger={['click']}>
85
+ <Button type="text">
86
+ <EllipsisOutlined style={{ color: style.textStyle.color }} />
87
+ </Button>
88
+ </Dropdown>
89
+ );
90
+
71
91
  type CtlBarProps = {
72
92
  size: Size;
73
93
  pageCursor: number;
@@ -75,14 +95,42 @@ type CtlBarProps = {
75
95
  setPageCursor: (page: number) => void;
76
96
  zoomLevel: number;
77
97
  setZoomLevel: (zoom: number) => void;
98
+ addPageAfter?: () => void;
99
+ removePage?: () => void;
78
100
  };
79
101
 
80
102
  const CtlBar = (props: CtlBarProps) => {
81
103
  const { token } = theme.useToken();
104
+ const i18n = useContext(I18nContext);
105
+
106
+ const {
107
+ size,
108
+ pageCursor,
109
+ pageNum,
110
+ setPageCursor,
111
+ zoomLevel,
112
+ setZoomLevel,
113
+ addPageAfter,
114
+ removePage,
115
+ } = props;
116
+
117
+ const contextMenuItems: MenuProps['items'] = [];
118
+ if (addPageAfter) {
119
+ contextMenuItems.push({
120
+ key: '1',
121
+ label: <div onClick={addPageAfter}>{i18n('addPageAfter')}</div>,
122
+ });
123
+ }
124
+ if (removePage && pageNum > 1 && pageCursor !== 0) {
125
+ contextMenuItems.push({
126
+ key: '2',
127
+ label: <div onClick={removePage}>{i18n('removePage')}</div>,
128
+ });
129
+ }
82
130
 
83
131
  const barWidth = 300;
84
- const { size, pageCursor, pageNum, setPageCursor, zoomLevel, setZoomLevel } = props;
85
- const width = pageNum > 1 ? barWidth : barWidth / 2;
132
+ const contextMenuWidth = contextMenuItems.length > 0 ? 50 : 0;
133
+ const width = (pageNum > 1 ? barWidth : barWidth / 2) + contextMenuWidth;
86
134
 
87
135
  const textStyle = {
88
136
  color: token.colorWhite,
@@ -96,7 +144,7 @@ const CtlBar = (props: CtlBarProps) => {
96
144
  style={{
97
145
  display: 'flex',
98
146
  alignItems: 'center',
99
- justifyContent: 'center',
147
+ justifyContent: 'space-evenly',
100
148
  position: 'relative',
101
149
  zIndex: 1,
102
150
  left: `calc(50% - ${width / 2}px)`,
@@ -117,6 +165,9 @@ const CtlBar = (props: CtlBarProps) => {
117
165
  />
118
166
  )}
119
167
  <Zoom style={{ textStyle }} zoomLevel={zoomLevel} setZoomLevel={setZoomLevel} />
168
+ {contextMenuItems.length > 0 && (
169
+ <ContextMenu items={contextMenuItems} style={{ textStyle }} />
170
+ )}
120
171
  </div>
121
172
  </div>
122
173
  );
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import type * as CSS from 'csstype';
3
+ import { ZOOM, BasePdf, isBlankPdf } from '@pdfme/common';
4
+ import { theme } from 'antd';
5
+
6
+ const getPaddingStyle = (i: number, p: number, color: string): CSS.Properties => {
7
+ const style: CSS.Properties = {
8
+ position: 'absolute',
9
+ background: color,
10
+ opacity: 0.25,
11
+ pointerEvents: 'none',
12
+ };
13
+ switch (i) {
14
+ case 0:
15
+ style.top = 0;
16
+ style.height = `${p * ZOOM}px`;
17
+ style.left = 0;
18
+ style.right = 0;
19
+ break;
20
+ case 1:
21
+ style.right = 0;
22
+ style.width = `${p * ZOOM}px`;
23
+ style.top = 0;
24
+ style.bottom = 0;
25
+ break;
26
+ case 2:
27
+ style.bottom = 0;
28
+ style.height = `${p * ZOOM}px`;
29
+ style.left = 0;
30
+ style.right = 0;
31
+ break;
32
+ case 3:
33
+ style.left = 0;
34
+ style.width = `${p * ZOOM}px`;
35
+ style.top = 0;
36
+ style.bottom = 0;
37
+ break;
38
+ default:
39
+ break;
40
+ }
41
+
42
+ return style;
43
+ };
44
+
45
+ const Padding = ({ basePdf }: { basePdf: BasePdf }) => {
46
+ return <>
47
+ {isBlankPdf(basePdf) &&
48
+ basePdf.padding.map((p, i) => (
49
+ <div key={String(i)} style={getPaddingStyle(i, p, theme.useToken().token.colorError)} />
50
+ ))}
51
+ </>
52
+ }
53
+
54
+ export default Padding;