@pdfme/ui 1.0.0-beta.7 → 1.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 (75) hide show
  1. package/coverage/clover.xml +6 -0
  2. package/coverage/coverage-final.json +1 -0
  3. package/coverage/lcov-report/base.css +224 -0
  4. package/coverage/lcov-report/block-navigation.js +87 -0
  5. package/coverage/lcov-report/favicon.png +0 -0
  6. package/coverage/lcov-report/index.html +101 -0
  7. package/coverage/lcov-report/prettify.css +1 -0
  8. package/coverage/lcov-report/prettify.js +2 -0
  9. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  10. package/coverage/lcov-report/sorter.js +196 -0
  11. package/coverage/lcov.info +0 -0
  12. package/dist/index.js +1 -1
  13. package/dist/index.js.LICENSE.txt +2 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/types/class.d.ts +5 -4
  16. package/dist/types/components/Designer/Main/Moveable.d.ts +1 -1
  17. package/dist/types/components/Designer/Sidebar/DetailView/ExampleInputEditor.d.ts +4 -1
  18. package/dist/types/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.d.ts +4 -1
  19. package/dist/types/components/Designer/Sidebar/DetailView/TextPropEditor.d.ts +4 -1
  20. package/dist/types/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.d.ts +4 -1
  21. package/dist/types/components/Designer/Sidebar/DetailView/index.d.ts +4 -1
  22. package/dist/types/components/Designer/Sidebar/ListView/Item.d.ts +25 -0
  23. package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableContainer.d.ts +3 -0
  24. package/dist/types/components/Designer/Sidebar/ListView/SelectableSortableItem.d.ts +14 -0
  25. package/dist/types/components/Designer/Sidebar/{ListView.d.ts → ListView/index.d.ts} +2 -2
  26. package/dist/types/components/Designer/Sidebar/index.d.ts +2 -6
  27. package/dist/types/constants.d.ts +1 -0
  28. package/dist/types/contexts.d.ts +1 -1
  29. package/dist/types/helper.d.ts +1 -1
  30. package/dist/types/hooks.d.ts +1 -0
  31. package/dist/types/i18n.d.ts +4 -2
  32. package/package.json +10 -7
  33. package/src/Designer.tsx +4 -2
  34. package/src/Form.tsx +1 -0
  35. package/src/Viewer.tsx +1 -0
  36. package/src/assets/icons/align-horizontal-center.svg +1 -0
  37. package/src/assets/icons/align-horizontal-left.svg +1 -0
  38. package/src/assets/icons/align-horizontal-right.svg +1 -0
  39. package/src/assets/icons/align-vertical-bottom.svg +1 -0
  40. package/src/assets/icons/align-vertical-middle.svg +1 -0
  41. package/src/assets/icons/align-vertical-top.svg +1 -0
  42. package/src/assets/icons/close.svg +4 -0
  43. package/src/assets/icons/horizontal-distribute.svg +1 -0
  44. package/src/assets/icons/vertical-distribute.svg +1 -0
  45. package/src/assets/imageExample.png +0 -0
  46. package/src/class.ts +27 -8
  47. package/src/components/Designer/Main/Moveable.tsx +1 -1
  48. package/src/components/Designer/Main/index.tsx +22 -16
  49. package/src/components/Designer/Sidebar/DetailView/ExampleInputEditor.tsx +28 -6
  50. package/src/components/Designer/Sidebar/DetailView/PositionAndSizeEditor.tsx +115 -24
  51. package/src/components/Designer/Sidebar/DetailView/TextPropEditor.tsx +36 -6
  52. package/src/components/Designer/Sidebar/DetailView/TypeAndKeyEditor.tsx +14 -6
  53. package/src/components/Designer/Sidebar/DetailView/index.tsx +21 -16
  54. package/src/components/Designer/Sidebar/ListView/Item.tsx +113 -0
  55. package/src/components/Designer/Sidebar/ListView/SelectableSortableContainer.tsx +162 -0
  56. package/src/components/Designer/Sidebar/ListView/SelectableSortableItem.tsx +78 -0
  57. package/src/components/Designer/Sidebar/ListView/index.tsx +119 -0
  58. package/src/components/Designer/Sidebar/index.tsx +30 -14
  59. package/src/components/Designer/index.tsx +12 -24
  60. package/src/components/Error.tsx +2 -2
  61. package/src/components/Paper.tsx +11 -3
  62. package/src/components/Preview/Pager/Page.tsx +1 -1
  63. package/src/components/Preview/Pager/Unit.tsx +1 -1
  64. package/src/components/Preview/index.tsx +3 -4
  65. package/src/components/Root.tsx +2 -7
  66. package/src/components/Schemas/BarcodeSchema.tsx +43 -28
  67. package/src/components/Schemas/ImageSchema.tsx +71 -66
  68. package/src/components/Schemas/TextSchema.tsx +6 -3
  69. package/src/constants.ts +2 -0
  70. package/src/helper.ts +43 -37
  71. package/src/hooks.ts +11 -0
  72. package/src/i18n.ts +10 -7
  73. package/tsconfig.json +1 -1
  74. package/webpack.config.js +0 -18
  75. package/src/components/Designer/Sidebar/ListView.tsx +0 -180
@@ -1,13 +1,13 @@
1
- import { Template, Size, UIProps, PreviewProps } from '@pdfme/common';
1
+ import { Template, Size, UIProps, UIOptions, PreviewProps } from '@pdfme/common';
2
2
  export declare abstract class BaseUIClass {
3
3
  protected domContainer: HTMLElement | null;
4
4
  protected template: Template;
5
5
  protected size: Size;
6
- private readonly lang;
7
- private readonly font;
6
+ private lang;
7
+ private font;
8
8
  private readonly setSize;
9
9
  constructor(props: UIProps);
10
- protected getI18n(): (key: "type" | "field" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "previewWarnMsg" | "previewErrMsg" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "errorOccurred") => string;
10
+ protected getI18n(): (key: "type" | "field" | "cancel" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName") => string;
11
11
  protected getFont(): Record<string, {
12
12
  fallback?: boolean | undefined;
13
13
  subset?: boolean | undefined;
@@ -54,6 +54,7 @@ export declare abstract class BaseUIClass {
54
54
  basePdf: string | ArrayBuffer | Uint8Array;
55
55
  };
56
56
  updateTemplate(template: Template): void;
57
+ updateOptions(options: UIOptions): void;
57
58
  destroy(): void;
58
59
  protected abstract render(): void;
59
60
  }
@@ -25,7 +25,7 @@ declare type Props = {
25
25
  onResizeGroupEnd: ((e: OnResizeGroupEnd) => void) & (({ targets }: {
26
26
  targets: (HTMLElement | SVGElement)[];
27
27
  }) => void);
28
- onClick: ((e: OnClick) => void) & (() => void);
28
+ onClick: (e: OnClick) => void;
29
29
  };
30
30
  declare const _default: React.ForwardRefExoticComponent<Props & React.RefAttributes<any>>;
31
31
  export default _default;
@@ -1,3 +1,6 @@
1
+ import { SchemaForUI } from '@pdfme/common';
1
2
  import { SidebarProps } from '..';
2
- declare const ExampleInputEditor: (props: Pick<SidebarProps, 'changeSchemas' | 'activeSchema'>) => JSX.Element;
3
+ declare const ExampleInputEditor: (props: Pick<SidebarProps, 'changeSchemas'> & {
4
+ activeSchema: SchemaForUI;
5
+ }) => JSX.Element;
3
6
  export default ExampleInputEditor;
@@ -1,3 +1,6 @@
1
+ import { SchemaForUI } from '@pdfme/common';
1
2
  import { SidebarProps } from '..';
2
- declare const PositionAndSizeEditor: (props: Pick<SidebarProps, 'pageSize' | 'changeSchemas' | 'activeSchema'>) => JSX.Element;
3
+ declare const PositionAndSizeEditor: (props: Pick<SidebarProps, 'pageSize' | 'schemas' | 'changeSchemas' | 'activeElements'> & {
4
+ activeSchema: SchemaForUI;
5
+ }) => JSX.Element;
3
6
  export default PositionAndSizeEditor;
@@ -1,3 +1,6 @@
1
+ import { SchemaForUI } from '@pdfme/common';
1
2
  import { SidebarProps } from '..';
2
- declare const TextPropEditor: (props: Pick<SidebarProps, 'changeSchemas' | 'activeSchema'>) => JSX.Element;
3
+ declare const TextPropEditor: (props: Pick<SidebarProps, 'changeSchemas'> & {
4
+ activeSchema: SchemaForUI;
5
+ }) => JSX.Element;
3
6
  export default TextPropEditor;
@@ -1,3 +1,6 @@
1
+ import { SchemaForUI } from '@pdfme/common';
1
2
  import { SidebarProps } from '..';
2
- declare const TypeAndKeyEditor: (props: Pick<SidebarProps, 'schemas' | 'changeSchemas' | 'activeSchema'>) => JSX.Element;
3
+ declare const TypeAndKeyEditor: (props: Pick<SidebarProps, 'schemas' | 'changeSchemas'> & {
4
+ activeSchema: SchemaForUI;
5
+ }) => JSX.Element;
3
6
  export default TypeAndKeyEditor;
@@ -1,3 +1,6 @@
1
+ import { SchemaForUI } from '@pdfme/common';
1
2
  import { SidebarProps } from '..';
2
- declare const DetailView: (props: Pick<SidebarProps, 'schemas' | 'pageSize' | 'changeSchemas' | 'activeSchema'>) => JSX.Element;
3
+ declare const DetailView: (props: Pick<SidebarProps, 'schemas' | 'pageSize' | 'changeSchemas' | 'activeElements'> & {
4
+ activeSchema: SchemaForUI;
5
+ }) => JSX.Element;
3
6
  export default DetailView;
@@ -0,0 +1,25 @@
1
+ import React from 'react';
2
+ import { DraggableSyntheticListeners } from '@dnd-kit/core';
3
+ interface Props {
4
+ value: React.ReactNode;
5
+ style?: React.CSSProperties;
6
+ status?: 'is-warning' | 'is-danger';
7
+ title?: string;
8
+ dragOverlay?: boolean;
9
+ onClick?: () => void;
10
+ onMouseEnter?: () => void;
11
+ onMouseLeave?: () => void;
12
+ dragging?: boolean;
13
+ sorting?: boolean;
14
+ transition?: string;
15
+ transform?: {
16
+ x: number;
17
+ y: number;
18
+ scaleX: number;
19
+ scaleY: number;
20
+ } | null;
21
+ fadeIn?: boolean;
22
+ listeners?: DraggableSyntheticListeners;
23
+ }
24
+ declare const Item: React.MemoExoticComponent<React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLLIElement>>>;
25
+ export default Item;
@@ -0,0 +1,3 @@
1
+ import { SidebarProps } from '../';
2
+ declare const SelectableSortableContainer: (props: Pick<SidebarProps, 'schemas' | 'onEdit' | 'onSortEnd' | 'height' | 'hoveringSchemaId' | 'onChangeHoveringSchemaId'>) => JSX.Element;
3
+ export default SelectableSortableContainer;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { SchemaForUI } from '@pdfme/common';
3
+ interface Props {
4
+ isSelected: boolean;
5
+ style?: React.CSSProperties;
6
+ onSelect: (id: string, isShiftSelect: boolean) => void;
7
+ onEdit: (id: string) => void;
8
+ schema: SchemaForUI;
9
+ schemas: SchemaForUI[];
10
+ onMouseEnter: () => void;
11
+ onMouseLeave: () => void;
12
+ }
13
+ declare const SelectableSortableItem: ({ isSelected, style, onSelect, onEdit, schema, schemas, onMouseEnter, onMouseLeave, }: Props) => JSX.Element;
14
+ export default SelectableSortableItem;
@@ -1,3 +1,3 @@
1
- import { SidebarProps } from '.';
2
- declare const ListView: (props: Pick<SidebarProps, 'schemas' | 'onSortEnd' | 'onEdit' | 'size' | 'hoveringSchemaId' | 'onChangeHoveringSchemaId'>) => JSX.Element;
1
+ import { SidebarProps } from '..';
2
+ declare const ListView: (props: Pick<SidebarProps, 'schemas' | 'onSortEnd' | 'onEdit' | 'size' | 'hoveringSchemaId' | 'onChangeHoveringSchemaId' | 'changeSchemas'>) => JSX.Element;
3
3
  export default ListView;
@@ -5,13 +5,9 @@ export declare type SidebarProps = {
5
5
  onChangeHoveringSchemaId: (id: string | null) => void;
6
6
  size: Size;
7
7
  pageSize: Size;
8
- activeElement: HTMLElement | null;
9
- activeSchema: SchemaForUI;
8
+ activeElements: HTMLElement[];
10
9
  schemas: SchemaForUI[];
11
- onSortEnd: ({ oldIndex, newIndex }: {
12
- oldIndex: number;
13
- newIndex: number;
14
- }) => void;
10
+ onSortEnd: (sortedSchemas: SchemaForUI[]) => void;
15
11
  onEdit: (id: string) => void;
16
12
  onEditEnd: () => void;
17
13
  changeSchemas: (objs: {
@@ -3,3 +3,4 @@ export declare const DESTROYED_ERR_MSG = "this instance is already destroyed";
3
3
  export declare const ZOOM = 3.7795275591;
4
4
  export declare const SELECTABLE_CLASSNAME = "selectable";
5
5
  export declare const RULER_HEIGHT = 30;
6
+ export declare const SIDEBAR_WIDTH = 300;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- export declare const I18nContext: import("react").Context<(key: "type" | "field" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "previewWarnMsg" | "previewErrMsg" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "errorOccurred") => string>;
2
+ export declare const I18nContext: import("react").Context<(key: "type" | "field" | "cancel" | "fieldName" | "require" | "uniq" | "inputExample" | "edit" | "plsSelect" | "plsInputName" | "plsAddNewField" | "fieldMustUniq" | "notUniq" | "noKeyName" | "fieldsList" | "addNewField" | "editField" | "goToFirst" | "goToPrevious" | "goToNext" | "goToEnd" | "select" | "errorOccurred" | "errorBulkUpdateFieldName" | "commitBulkUpdateFieldName" | "bulkUpdateFieldName") => string>;
3
3
  export declare const FontContext: import("react").Context<Record<string, {
4
4
  fallback?: boolean | undefined;
5
5
  subset?: boolean | undefined;
@@ -3,7 +3,6 @@ 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;
5
5
  export declare const round: (number: number, precision: number) => number;
6
- export declare const arrayMove: <T>(array: T[], from: number, to: number) => T[];
7
6
  export declare const cloneDeep: <T>(value: T) => T;
8
7
  export declare const flatten: <T>(arr: T[][]) => T[];
9
8
  declare const esc = "esc";
@@ -16,6 +15,7 @@ export declare const initShortCuts: (arg: {
16
15
  redo: () => void;
17
16
  undo: () => void;
18
17
  save: () => void;
18
+ selectAll: () => void;
19
19
  }) => void;
20
20
  export declare const destroyShortCuts: () => void;
21
21
  export declare const readFiles: (files: FileList | null, type: 'text' | 'dataURL' | 'arrayBuffer') => Promise<string | ArrayBuffer>;
@@ -23,4 +23,5 @@ declare type ScrollPageCursorProps = {
23
23
  onChangePageCursor: (page: number) => void;
24
24
  };
25
25
  export declare const useScrollPageCursor: ({ rootRef, pageSizes, scale, pageCursor, onChangePageCursor, }: ScrollPageCursorProps) => void;
26
+ export declare const useMountStatus: () => boolean;
26
27
  export {};
@@ -1,6 +1,7 @@
1
1
  import { Lang } from '@pdfme/common';
2
2
  declare type DictEn = typeof dictEn;
3
3
  declare const dictEn: {
4
+ cancel: string;
4
5
  field: string;
5
6
  fieldName: string;
6
7
  require: string;
@@ -17,14 +18,15 @@ declare const dictEn: {
17
18
  addNewField: string;
18
19
  editField: string;
19
20
  type: string;
20
- previewWarnMsg: string;
21
- previewErrMsg: string;
22
21
  goToFirst: string;
23
22
  goToPrevious: string;
24
23
  goToNext: string;
25
24
  goToEnd: string;
26
25
  select: string;
27
26
  errorOccurred: string;
27
+ errorBulkUpdateFieldName: string;
28
+ commitBulkUpdateFieldName: string;
29
+ bulkUpdateFieldName: string;
28
30
  };
29
31
  export declare const curriedI18n: (lang: Lang) => (key: keyof DictEn) => string;
30
32
  export {};
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@pdfme/ui",
3
- "version": "1.0.0-beta.7",
3
+ "version": "1.0.0",
4
4
  "author": "hand-dot",
5
5
  "license": "MIT",
6
6
  "description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
7
7
  "homepage": "https://pdfme.com",
8
- "repository": "git@github.com:pdfme/pdfme.git",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git@github.com:pdfme/pdfme.git"
11
+ },
9
12
  "bugs": {
10
13
  "url": "https://github.com/pdfme/pdfme/issues"
11
14
  },
@@ -16,7 +19,7 @@
16
19
  "node": ">=14"
17
20
  },
18
21
  "scripts": {
19
- "develop": "webpack-dev-server --mode development",
22
+ "develop": "webpack --watch --mode development",
20
23
  "build": "NODE_ENV=production webpack --mode production",
21
24
  "clean": "rimraf dist",
22
25
  "lint": "tsc --noEmit",
@@ -26,7 +29,9 @@
26
29
  "prune": "ts-prune src"
27
30
  },
28
31
  "dependencies": {
29
- "@pdfme/common": "^1.0.0-beta.7",
32
+ "@dnd-kit/core": "^5.0.1",
33
+ "@dnd-kit/sortable": "^6.0.0",
34
+ "@pdfme/common": "^1.0.0-beta.11",
30
35
  "@scena/react-guides": "^0.16.0",
31
36
  "hotkeys-js": "^3.8.7",
32
37
  "pdfjs-dist": "^2.12.313",
@@ -34,7 +39,6 @@
34
39
  "react-dom": "^17.0.2",
35
40
  "react-moveable": "^0.30.3",
36
41
  "react-selecto": "^1.12.0",
37
- "react-sortable-hoc": "^2.0.0",
38
42
  "worker-loader": "^3.0.8"
39
43
  },
40
44
  "devDependencies": {
@@ -46,7 +50,6 @@
46
50
  "@types/react-dom": "^17.0.9",
47
51
  "eslint-plugin-react": "^7.28.0",
48
52
  "eslint-plugin-react-hooks": "^4.3.0",
49
- "html-webpack-plugin": "^5.3.2",
50
53
  "jest-canvas-mock": "^2.3.1",
51
54
  "process": "^0.11.10"
52
55
  },
@@ -80,4 +83,4 @@
80
83
  "publishConfig": {
81
84
  "access": "public"
82
85
  }
83
- }
86
+ }
package/src/Designer.tsx CHANGED
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom';
3
- import { Template, DesignerProps, checkDesignerProps } from '@pdfme/common';
3
+ import { Template, DesignerProps, checkDesignerProps, checkTemplate } from '@pdfme/common';
4
4
  import { BaseUIClass } from './class';
5
5
  import { DESTROYED_ERR_MSG } from './constants';
6
6
  import { I18nContext, FontContext } from './contexts';
7
7
  import DesignerComponent from './components/Designer';
8
+ import { cloneDeep } from './helper';
8
9
 
9
10
  class Designer extends BaseUIClass {
10
11
  private onSaveTemplateCallback?: (template: Template) => void;
@@ -25,8 +26,9 @@ class Designer extends BaseUIClass {
25
26
  }
26
27
 
27
28
  public updateTemplate(template: Template) {
29
+ checkTemplate(template);
28
30
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
29
- this.template = template;
31
+ this.template = cloneDeep(template);
30
32
  if (this.onChangeTemplateCallback) {
31
33
  this.onChangeTemplateCallback(template);
32
34
  }
package/src/Form.tsx CHANGED
@@ -11,6 +11,7 @@ class Form extends PreviewUI {
11
11
 
12
12
  constructor(props: PreviewProps) {
13
13
  super(props);
14
+ this.render();
14
15
  }
15
16
 
16
17
  public onChangeInput(cb: (arg: { index: number; value: string; key: string }) => void) {
package/src/Viewer.tsx CHANGED
@@ -9,6 +9,7 @@ import Preview from './components/Preview';
9
9
  class Viewer extends PreviewUI {
10
10
  constructor(props: PreviewProps) {
11
11
  super(props);
12
+ this.render();
12
13
  }
13
14
 
14
15
  protected render() {
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><polygon points="11,2 13,2 13,7 21,7 21,10 13,10 13,14 18,14 18,17 13,17 13,22 11,22 11,17 6,17 6,14 11,14 11,10 3,10 3,7 11,7"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M4,22H2V2h2V22z M22,7H6v3h16V7z M16,14H6v3h10V14z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M20,2h2v20h-2V2z M2,10h16V7H2V10z M8,17h10v-3H8V17z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M22,22H2v-2h20V22z M10,2H7v16h3V2z M17,8h-3v10h3V8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><polygon points="22,11 17,11 17,6 14,6 14,11 10,11 10,3 7,3 7,11 1.84,11 1.84,13 7,13 7,21 10,21 10,13 14,13 14,18 17,18 17,13 22,13"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M22,2v2H2V2H22z M7,22h3V6H7V22z M14,16h3V6h-3V16z"/></svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000">
2
+ <path d="M0 0h24v24H0V0z" fill="none" />
3
+ <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
4
+ </svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M4,22H2V2h2V22z M22,2h-2v20h2V2z M13.5,7h-3v10h3V7z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M22,2v2H2V2H22z M7,10.5v3h10v-3H7z M2,20v2h20v-2H2z"/></svg>
Binary file
package/src/class.ts CHANGED
@@ -1,16 +1,20 @@
1
1
  import ReactDOM from 'react-dom';
2
2
  import { curriedI18n } from './i18n';
3
3
  import { DESTROYED_ERR_MSG, DEFAULT_LANG } from './constants';
4
- import { debounce, flatten } from './helper';
4
+ import { debounce, flatten, cloneDeep } from './helper';
5
5
  import {
6
6
  Template,
7
7
  Size,
8
8
  Lang,
9
9
  Font,
10
10
  UIProps,
11
+ UIOptions,
11
12
  PreviewProps,
12
13
  getDefaultFont,
13
14
  checkUIProps,
15
+ checkTemplate,
16
+ checkInputs,
17
+ checkUIOptions,
14
18
  checkPreviewProps,
15
19
  } from '@pdfme/common';
16
20
 
@@ -57,9 +61,9 @@ export abstract class BaseUIClass {
57
61
 
58
62
  protected size!: Size;
59
63
 
60
- private readonly lang: Lang = DEFAULT_LANG;
64
+ private lang: Lang = DEFAULT_LANG;
61
65
 
62
- private readonly font: Font = getDefaultFont();
66
+ private font: Font = getDefaultFont();
63
67
 
64
68
  private readonly setSize = debounce(() => {
65
69
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
@@ -76,7 +80,7 @@ export abstract class BaseUIClass {
76
80
  const { domContainer, template, options } = props;
77
81
  const { lang, font } = options || {};
78
82
  this.domContainer = domContainer;
79
- this.template = generateColumnsAndSampledataIfNeeded(template);
83
+ this.template = generateColumnsAndSampledataIfNeeded(cloneDeep(template));
80
84
  this.size = {
81
85
  height: this.domContainer.clientHeight || window.innerHeight,
82
86
  width: this.domContainer.clientWidth || window.innerWidth,
@@ -106,8 +110,23 @@ export abstract class BaseUIClass {
106
110
  }
107
111
 
108
112
  public updateTemplate(template: Template) {
113
+ checkTemplate(template);
109
114
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
110
- this.template = template;
115
+
116
+ this.template = cloneDeep(template);
117
+ this.render();
118
+ }
119
+
120
+ public updateOptions(options: UIOptions) {
121
+ checkUIOptions(options);
122
+ const { lang, font } = options || {};
123
+
124
+ if (lang) {
125
+ this.lang = lang;
126
+ }
127
+ if (font) {
128
+ this.font = font;
129
+ }
111
130
  this.render();
112
131
  }
113
132
 
@@ -127,8 +146,7 @@ export abstract class PreviewUI extends BaseUIClass {
127
146
  super(props);
128
147
  checkPreviewProps(props);
129
148
 
130
- this.inputs = props.inputs;
131
- this.render();
149
+ this.inputs = cloneDeep(props.inputs);
132
150
  }
133
151
 
134
152
  public getInputs() {
@@ -139,7 +157,8 @@ export abstract class PreviewUI extends BaseUIClass {
139
157
 
140
158
  public setInputs(inputs: { [key: string]: string }[]) {
141
159
  if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
142
- this.inputs = inputs;
160
+ checkInputs(inputs);
161
+ this.inputs = cloneDeep(inputs);
143
162
  this.render();
144
163
  }
145
164
 
@@ -25,7 +25,7 @@ type Props = {
25
25
  (({ target }: { target: HTMLElement | SVGElement }) => void);
26
26
  onResizeGroupEnd: ((e: OnResizeGroupEnd) => void) &
27
27
  (({ targets }: { targets: (HTMLElement | SVGElement)[] }) => void);
28
- onClick: ((e: OnClick) => void) & (() => void);
28
+ onClick: (e: OnClick) => void;
29
29
  };
30
30
 
31
31
  const _Moveable = (
@@ -7,7 +7,7 @@ import React, {
7
7
  forwardRef,
8
8
  useCallback,
9
9
  } from 'react';
10
- import { OnDrag, OnResize } from 'react-moveable';
10
+ import { OnDrag, OnResize, OnClick } from 'react-moveable';
11
11
  import { SchemaForUI, Size } from '@pdfme/common';
12
12
  import { ZOOM, RULER_HEIGHT } from '../../../constants';
13
13
  import { usePrevious } from '../../../hooks';
@@ -39,7 +39,7 @@ const DeleteButton = ({ activeElements: aes }: { activeElements: HTMLElement[] }
39
39
  color: 'white',
40
40
  border: 'none',
41
41
  fontWeight: 'bold',
42
- borderRadius: 3,
42
+ borderRadius: 2,
43
43
  background: 'rgb(68, 170, 255)',
44
44
  }}
45
45
  >
@@ -121,16 +121,15 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
121
121
  }, [initEvents, destroyEvents]);
122
122
 
123
123
  useEffect(() => {
124
+ moveable.current?.updateRect();
124
125
  if (prevSchemas === null) {
125
- moveable.current?.updateRect();
126
-
127
126
  return;
128
127
  }
129
128
 
130
- const prevSchemaKeys = Object.keys(prevSchemas[pageCursor] || {});
131
- const schemaKeys = Object.keys(schemasList[pageCursor] || {});
129
+ const prevSchemaKeys = JSON.stringify(prevSchemas[pageCursor] || {});
130
+ const schemaKeys = JSON.stringify(schemasList[pageCursor] || {});
132
131
 
133
- if (prevSchemaKeys.join() === schemaKeys.join()) {
132
+ if (prevSchemaKeys === schemaKeys) {
134
133
  moveable.current?.updateRect();
135
134
  }
136
135
  }, [pageCursor, schemasList, prevSchemas]);
@@ -201,15 +200,13 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
201
200
  const getGuideLines = (guides: GuidesInterface[], index: number) =>
202
201
  guides[index] && guides[index].getGuides().map((g) => g * ZOOM);
203
202
 
204
- const onClickMoveable = () => {
203
+ const onClickMoveable = (e: OnClick) => {
204
+ e.inputEvent.stopPropagation();
205
205
  setEditing(true);
206
206
  const ic = inputRef.current;
207
207
  if (!ic) return;
208
- ic.disabled = false;
209
208
  ic.focus();
210
- if (ic.type === 'file') {
211
- ic.click();
212
- } else {
209
+ if (ic.type !== 'file') {
213
210
  ic.setSelectionRange(ic.value.length, ic.value.length);
214
211
  }
215
212
  };
@@ -241,8 +238,17 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
241
238
  removeSchemas(activeElements.map((ae) => ae.id));
242
239
  }
243
240
  }}
244
- onSelect={(e) => {
245
- onEdit(e.selected as HTMLElement[]);
241
+ onSelect={({ added, removed, selected, inputEvent }) => {
242
+ const isClick = inputEvent.type === 'mousedown';
243
+ let newActiveElements: HTMLElement[] = isClick ? (selected as HTMLElement[]) : [];
244
+ if (!isClick && added.length > 0) {
245
+ newActiveElements = activeElements.concat(added as HTMLElement[]);
246
+ }
247
+ if (!isClick && removed.length > 0) {
248
+ newActiveElements = activeElements.filter((ae) => !removed.includes(ae));
249
+ }
250
+
251
+ onEdit(newActiveElements);
246
252
  }}
247
253
  />
248
254
  <Paper
@@ -298,12 +304,12 @@ const Main = (props: Props, ref: Ref<HTMLDivElement>) => {
298
304
  )}
299
305
  renderSchema={({ schema }) => (
300
306
  <SchemaUI
301
- key={schema.key}
307
+ key={schema.id}
302
308
  schema={schema}
303
309
  onChangeHoveringSchemaId={onChangeHoveringSchemaId}
304
310
  editable={editing && activeElements.map((ae) => ae.id).includes(schema.id)}
305
311
  onChange={(value) => changeSchemas([{ key: 'data', value, schemaId: schema.id }])}
306
- border={hoveringSchemaId === schema.id ? '2px solid #18a0fb' : '1px dashed #4af'}
312
+ border={hoveringSchemaId === schema.id ? '1px solid #18a0fb' : '1px dashed #4af'}
307
313
  ref={inputRef}
308
314
  />
309
315
  )}
@@ -1,33 +1,52 @@
1
1
  import React, { useContext } from 'react';
2
+ import { SchemaForUI } from '@pdfme/common';
2
3
  import { readFiles } from '../../../../helper';
3
4
  import { I18nContext } from '../../../../contexts';
4
5
  import { SidebarProps } from '..';
6
+ import closeIcon from '../../../../assets/icons/close.svg';
5
7
 
6
- const ExampleInputEditor = (props: Pick<SidebarProps, 'changeSchemas' | 'activeSchema'>) => {
8
+ const ExampleInputEditor = (
9
+ props: Pick<SidebarProps, 'changeSchemas'> & { activeSchema: SchemaForUI }
10
+ ) => {
7
11
  const { changeSchemas, activeSchema } = props;
8
12
  const i18n = useContext(I18nContext);
9
13
 
10
14
  return (
11
15
  <div>
12
- <label style={{ marginBottom: 0 }}>{i18n('inputExample')}</label>
16
+ <label>{i18n('inputExample')}</label>
13
17
  {activeSchema.type === 'image' ? (
14
- <div style={{ position: 'relative', textAlign: 'center' }}>
18
+ <div style={{ position: 'relative' }}>
15
19
  {activeSchema.data ? (
16
20
  <div style={{ margin: '0 auto' }}>
17
21
  <button
18
- style={{ position: 'absolute', top: 0, left: 0 }}
22
+ style={{
23
+ position: 'absolute',
24
+ top: 0,
25
+ left: 0,
26
+ display: 'flex',
27
+ justifyContent: 'center',
28
+ alignItems: 'center',
29
+ color: '#333',
30
+ background: '#f2f2f2',
31
+ cursor: 'pointer',
32
+ borderRadius: 2,
33
+ border: '1px solid #767676',
34
+ height: 20,
35
+ width: 20,
36
+ }}
19
37
  aria-label="close"
20
38
  onClick={() =>
21
39
  changeSchemas([{ key: 'data', value: '', schemaId: activeSchema.id }])
22
40
  }
23
41
  >
24
- x
42
+ <img src={closeIcon} alt="Close icon" width={10} />
25
43
  </button>
26
44
  <img style={{ maxHeight: 180 }} src={activeSchema.data} alt="Input Example" />
27
45
  </div>
28
46
  ) : (
29
47
  <label>
30
48
  <input
49
+ style={{ color: '#333', background: 'none' }}
31
50
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
32
51
  const { files } = e.target;
33
52
  readFiles(files, 'dataURL').then((result) => {
@@ -50,7 +69,10 @@ const ExampleInputEditor = (props: Pick<SidebarProps, 'changeSchemas' | 'activeS
50
69
  }
51
70
  style={{
52
71
  width: '100%',
53
- backgroundColor: activeSchema.data ? '#fff' : '#ffa19b',
72
+ border: '1px solid #767676',
73
+ borderRadius: 2,
74
+ color: '#333',
75
+ background: activeSchema.data ? 'none' : '#ffa19b',
54
76
  }}
55
77
  value={activeSchema.data}
56
78
  />