@pdfme/ui 5.5.10-dev.11 → 5.5.10-dev.125
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 +3 -1
- package/__mocks__/converter.ts +3 -0
- package/__mocks__/form-render.js +3 -3
- package/__mocks__/form-render.ts +18 -0
- package/__mocks__/lucide-react.ts +15 -0
- package/package.json +36 -83
- package/src/Designer.tsx +1 -3
- package/src/Form.tsx +1 -3
- package/src/Viewer.tsx +1 -3
- package/src/class.ts +17 -6
- package/src/components/CtlBar.tsx +7 -2
- package/src/components/Designer/PluginIcon.tsx +64 -16
- package/src/components/Designer/RightSidebar/DetailView/AlignWidget.tsx +1 -2
- package/src/components/Designer/RightSidebar/DetailView/WidgetRenderer.tsx +8 -7
- package/src/components/Designer/RightSidebar/DetailView/index.tsx +15 -17
- package/src/components/Designer/RightSidebar/ListView/Item.tsx +3 -5
- package/src/components/Designer/index.tsx +28 -17
- package/src/components/Preview.tsx +40 -14
- package/src/components/Renderer.tsx +73 -27
- package/src/components/Root.tsx +8 -2
- package/src/contexts.ts +1 -1
- package/src/helper.ts +1 -1
- package/src/hooks.ts +102 -67
- package/tsconfig.build.json +15 -0
- package/tsconfig.json +5 -40
- package/tsconfig.typecheck.json +19 -0
- package/vite.config.mts +46 -5
- package/vitest.setup.ts +47 -0
- package/dist/index.es.js +0 -159737
- package/dist/index.umd.js +0 -1060
- package/dist/types/__tests__/assets/helper.d.ts +0 -3
- package/dist/types/__tests__/components/Designer.test.d.ts +0 -1
- package/dist/types/__tests__/components/PluginIcon.test.d.ts +0 -1
- package/dist/types/__tests__/components/Preview.test.d.ts +0 -1
- package/dist/types/__tests__/helper.test.d.ts +0 -1
- package/dist/types/src/Designer.d.ts +0 -21
- package/dist/types/src/Form.d.ts +0 -24
- package/dist/types/src/Viewer.d.ts +0 -15
- package/dist/types/src/class.d.ts +0 -89
- package/dist/types/src/components/AppContextProvider.d.ts +0 -11
- package/dist/types/src/components/CtlBar.d.ts +0 -14
- package/dist/types/src/components/Designer/Canvas/Guides.d.ts +0 -9
- package/dist/types/src/components/Designer/Canvas/Mask.d.ts +0 -4
- package/dist/types/src/components/Designer/Canvas/Moveable.d.ts +0 -37
- package/dist/types/src/components/Designer/Canvas/Padding.d.ts +0 -6
- package/dist/types/src/components/Designer/Canvas/Selecto.d.ts +0 -10
- package/dist/types/src/components/Designer/Canvas/index.d.ts +0 -22
- package/dist/types/src/components/Designer/LeftSidebar.d.ts +0 -8
- package/dist/types/src/components/Designer/PluginIcon.d.ts +0 -10
- package/dist/types/src/components/Designer/RightSidebar/DetailView/AlignWidget.d.ts +0 -4
- package/dist/types/src/components/Designer/RightSidebar/DetailView/ButtonGroupWidget.d.ts +0 -4
- package/dist/types/src/components/Designer/RightSidebar/DetailView/WidgetRenderer.d.ts +0 -7
- package/dist/types/src/components/Designer/RightSidebar/DetailView/index.d.ts +0 -8
- package/dist/types/src/components/Designer/RightSidebar/ListView/Item.d.ts +0 -45
- package/dist/types/src/components/Designer/RightSidebar/ListView/SelectableSortableContainer.d.ts +0 -4
- package/dist/types/src/components/Designer/RightSidebar/ListView/SelectableSortableItem.d.ts +0 -14
- package/dist/types/src/components/Designer/RightSidebar/ListView/index.d.ts +0 -4
- package/dist/types/src/components/Designer/RightSidebar/index.d.ts +0 -4
- package/dist/types/src/components/Designer/RightSidebar/layout.d.ts +0 -15
- package/dist/types/src/components/Designer/index.d.ts +0 -11
- package/dist/types/src/components/ErrorScreen.d.ts +0 -7
- package/dist/types/src/components/Paper.d.ts +0 -20
- package/dist/types/src/components/Preview.d.ts +0 -15
- package/dist/types/src/components/Renderer.d.ts +0 -13
- package/dist/types/src/components/Root.d.ts +0 -9
- package/dist/types/src/components/Spinner.d.ts +0 -3
- package/dist/types/src/components/StaticSchema.d.ts +0 -10
- package/dist/types/src/components/UnitPager.d.ts +0 -10
- package/dist/types/src/constants.d.ts +0 -11
- package/dist/types/src/contexts.d.ts +0 -10
- package/dist/types/src/helper.d.ts +0 -73
- package/dist/types/src/hooks.d.ts +0 -46
- package/dist/types/src/i18n.d.ts +0 -3
- package/dist/types/src/index.d.ts +0 -4
- package/dist/types/src/theme.d.ts +0 -2
- package/dist/types/src/types.d.ts +0 -19
- package/eslint.config.mjs +0 -41
package/README.md
CHANGED
|
@@ -6,4 +6,6 @@ This library provides the following classes, which can be integrated into applic
|
|
|
6
6
|
- `Form`: A form based on templates for collecting input data.
|
|
7
7
|
- `Viewer`: A viewer for displaying PDF files generated with [@pdfme/generator](https://www.npmjs.com/package/@pdfme/generator) using templates and input data.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The published `@pdfme/ui` package ships as a standalone bundle, so consumers do not need to install `react` or `react-dom` separately just to use these classes.
|
|
10
|
+
|
|
11
|
+
For the complete documentation of pdfme, please refer to [this link](https://pdfme.com/docs/getting-started).
|
package/__mocks__/form-render.js
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const formState: Record<string, unknown> = {};
|
|
2
|
+
|
|
3
|
+
export const useForm = () => ({
|
|
4
|
+
resetFields: () => {
|
|
5
|
+
Object.keys(formState).forEach((key) => {
|
|
6
|
+
delete formState[key];
|
|
7
|
+
});
|
|
8
|
+
},
|
|
9
|
+
setValues: (values: Record<string, unknown>) => {
|
|
10
|
+
Object.assign(formState, values);
|
|
11
|
+
},
|
|
12
|
+
getValues: () => formState,
|
|
13
|
+
validateFields: () => Promise.resolve(formState),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const FormRender = () => null;
|
|
17
|
+
|
|
18
|
+
export default FormRender;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const Plus = () => 'Plus';
|
|
2
|
+
export const Minus = () => 'Minus';
|
|
3
|
+
export const ChevronLeft = () => 'ChevronLeft';
|
|
4
|
+
export const ChevronRight = () => 'ChevronRight';
|
|
5
|
+
export const ChevronsLeft = () => 'ChevronsLeft';
|
|
6
|
+
export const ChevronsRight = () => 'ChevronsRight';
|
|
7
|
+
export const Ellipsis = () => 'Ellipsis';
|
|
8
|
+
export const X = () => 'X';
|
|
9
|
+
export const Menu = () => 'Menu';
|
|
10
|
+
export const GripVertical = () => 'GripVertical';
|
|
11
|
+
export const CircleAlert = () => 'CircleAlert';
|
|
12
|
+
export const Lock = () => 'Lock';
|
|
13
|
+
export const ArrowLeft = () => 'ArrowLeft';
|
|
14
|
+
export const ArrowRight = () => 'ArrowRight';
|
|
15
|
+
export const LoaderCircle = () => 'LoaderCircle';
|
package/package.json
CHANGED
|
@@ -1,78 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pdfme/ui",
|
|
3
|
-
"version": "5.5.10-dev.
|
|
4
|
-
"
|
|
5
|
-
"author": "hand-dot",
|
|
6
|
-
"license": "MIT",
|
|
3
|
+
"version": "5.5.10-dev.125",
|
|
4
|
+
"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
5
|
"keywords": [
|
|
8
6
|
"pdf",
|
|
9
|
-
"pdf-generation",
|
|
10
7
|
"pdf-designer",
|
|
8
|
+
"pdf-generation",
|
|
11
9
|
"pdf-viewer",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
10
|
+
"react",
|
|
11
|
+
"typescript"
|
|
14
12
|
],
|
|
15
|
-
"description": "TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!",
|
|
16
13
|
"homepage": "https://pdfme.com",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/pdfme/pdfme/issues"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "hand-dot",
|
|
17
19
|
"repository": {
|
|
18
20
|
"type": "git",
|
|
19
21
|
"url": "git@github.com:pdfme/pdfme.git"
|
|
20
22
|
},
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
+
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"module": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
23
37
|
},
|
|
24
|
-
"main": "dist/index.umd.js",
|
|
25
|
-
"module": "dist/index.es.js",
|
|
26
|
-
"types": "dist/types/src/index.d.ts",
|
|
27
38
|
"scripts": {
|
|
28
|
-
"dev": "
|
|
29
|
-
"
|
|
30
|
-
"devBuildType:watch": "tsc --emitDeclarationOnly --watch",
|
|
31
|
-
"build": "vite build && tsc --emitDeclarationOnly",
|
|
39
|
+
"dev": "vite build --watch",
|
|
40
|
+
"build": "vite build && tsc -p tsconfig.build.json",
|
|
32
41
|
"clean": "rimraf dist",
|
|
33
|
-
"lint": "
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"prettier": "prettier --write 'src/**/*.{ts,tsx}'"
|
|
42
|
+
"lint": "vp lint -c ../../.oxlintrc.json src",
|
|
43
|
+
"fmt": "vp fmt -c ../../.oxfmtrc.json src --write",
|
|
44
|
+
"test": "vitest run --config ../../vitest.config.ts"
|
|
37
45
|
},
|
|
38
46
|
"dependencies": {
|
|
39
47
|
"@dnd-kit/core": "^6.0.8",
|
|
40
48
|
"@dnd-kit/sortable": "^10.0.0",
|
|
49
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
41
50
|
"@pdfme/converter": "*",
|
|
42
51
|
"@scena/react-guides": "^0.28.2",
|
|
43
52
|
"antd": "^5.27.4",
|
|
44
53
|
"dompurify": "^3.3.3",
|
|
45
54
|
"form-render": "^2.5.5",
|
|
46
|
-
"globrex": "^0.1.2",
|
|
47
55
|
"hotkeys-js": "^4.0.2",
|
|
48
56
|
"lucide-react": "^0.577.0",
|
|
49
|
-
"
|
|
50
|
-
"react
|
|
57
|
+
"rc-field-form": "^2.7.1",
|
|
58
|
+
"react": "^18.2.0",
|
|
59
|
+
"react-dom": "^18.2.0",
|
|
51
60
|
"react-moveable": "^0.56.0",
|
|
52
|
-
"react-refresh": "^0.18.0",
|
|
53
61
|
"react-selecto": "^1.12.0"
|
|
54
62
|
},
|
|
55
63
|
"devDependencies": {
|
|
56
64
|
"@pdfme/common": "*",
|
|
57
65
|
"@pdfme/schemas": "*",
|
|
58
66
|
"@testing-library/jest-dom": "^6.8.0",
|
|
59
|
-
"@testing-library/react": "^
|
|
60
|
-
"@types/
|
|
61
|
-
"@types/
|
|
62
|
-
"@types/react": "^17.0.52",
|
|
63
|
-
"@types/react-dom": "^17.0.18",
|
|
64
|
-
"@ungap/structured-clone": "^1.3.0",
|
|
67
|
+
"@testing-library/react": "^16.3.0",
|
|
68
|
+
"@types/react": "^18.2.15",
|
|
69
|
+
"@types/react-dom": "^18.2.7",
|
|
65
70
|
"@vitejs/plugin-react": "^6.0.1",
|
|
66
71
|
"csstype": "^3.2.3",
|
|
67
|
-
"esbuild": "^0.27.4",
|
|
68
|
-
"eslint-plugin-react": "^7.37.5",
|
|
69
|
-
"eslint-plugin-react-hooks": "^7.0.1",
|
|
70
|
-
"is-path-inside": "^4.0.0",
|
|
71
|
-
"jest-canvas-mock": "^2.3.1",
|
|
72
|
-
"jest-environment-jsdom": "^30.3.0",
|
|
73
|
-
"postcss": "^8.5.8",
|
|
74
|
-
"process": "^0.11.10",
|
|
75
|
-
"rollup": "^4.59.0",
|
|
76
72
|
"vite": "^7.3.1",
|
|
77
73
|
"vite-plugin-css-injected-by-js": "^4.0.1",
|
|
78
74
|
"vite-tsconfig-paths": "^6.1.1"
|
|
@@ -80,48 +76,5 @@
|
|
|
80
76
|
"peerDependencies": {
|
|
81
77
|
"@pdfme/common": "latest",
|
|
82
78
|
"@pdfme/schemas": "latest"
|
|
83
|
-
},
|
|
84
|
-
"jest": {
|
|
85
|
-
"testEnvironment": "jest-environment-jsdom",
|
|
86
|
-
"setupFiles": [
|
|
87
|
-
"jest-canvas-mock"
|
|
88
|
-
],
|
|
89
|
-
"setupFilesAfterEnv": [
|
|
90
|
-
"./__tests__/test-helpers.js"
|
|
91
|
-
],
|
|
92
|
-
"moduleNameMapper": {
|
|
93
|
-
"\\.(png|css)$": "<rootDir>/__mocks__/assetsTransformer.js",
|
|
94
|
-
"^@pdfme/converter$": "<rootDir>/../converter/src/index.node.ts",
|
|
95
|
-
"^@pdfme/schemas/utils$": "<rootDir>/../schemas/src/utils.ts",
|
|
96
|
-
"^antd/es/": "antd/lib/",
|
|
97
|
-
"^form-render/es/": "form-render/lib/",
|
|
98
|
-
"^rc-picker/es/": "rc-picker/lib/",
|
|
99
|
-
"^lodash-es$": "lodash",
|
|
100
|
-
"\\^lucide-react$": "<rootDir>/__mocks__/lucide-react.js"
|
|
101
|
-
},
|
|
102
|
-
"resolver": "ts-jest-resolver",
|
|
103
|
-
"moduleFileExtensions": [
|
|
104
|
-
"js",
|
|
105
|
-
"ts",
|
|
106
|
-
"tsx"
|
|
107
|
-
],
|
|
108
|
-
"transform": {
|
|
109
|
-
"^.+\\.tsx?$": [
|
|
110
|
-
"ts-jest",
|
|
111
|
-
{
|
|
112
|
-
"tsconfig": "tsconfig.json"
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
},
|
|
116
|
-
"testMatch": [
|
|
117
|
-
"**/*.test.ts",
|
|
118
|
-
"**/*.test.tsx"
|
|
119
|
-
],
|
|
120
|
-
"transformIgnorePatterns": [
|
|
121
|
-
"/node_modules/(?!lucide-react)"
|
|
122
|
-
]
|
|
123
|
-
},
|
|
124
|
-
"publishConfig": {
|
|
125
|
-
"access": "public"
|
|
126
79
|
}
|
|
127
80
|
}
|
package/src/Designer.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom';
|
|
3
2
|
import {
|
|
4
3
|
cloneDeep,
|
|
5
4
|
Template,
|
|
@@ -64,7 +63,7 @@ class Designer extends BaseUIClass {
|
|
|
64
63
|
|
|
65
64
|
protected render() {
|
|
66
65
|
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
|
67
|
-
|
|
66
|
+
this.mount(
|
|
68
67
|
<AppContextProvider
|
|
69
68
|
lang={this.getLang()}
|
|
70
69
|
font={this.getFont()}
|
|
@@ -99,7 +98,6 @@ class Designer extends BaseUIClass {
|
|
|
99
98
|
size={this.size}
|
|
100
99
|
/>
|
|
101
100
|
</AppContextProvider>,
|
|
102
|
-
this.domContainer,
|
|
103
101
|
);
|
|
104
102
|
}
|
|
105
103
|
}
|
package/src/Form.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom';
|
|
3
2
|
import { PreviewProps } from '@pdfme/common';
|
|
4
3
|
import { PreviewUI } from './class.js';
|
|
5
4
|
import { DESTROYED_ERR_MSG } from './constants.js';
|
|
@@ -63,7 +62,7 @@ class Form extends PreviewUI {
|
|
|
63
62
|
|
|
64
63
|
protected render() {
|
|
65
64
|
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
|
66
|
-
|
|
65
|
+
this.mount(
|
|
67
66
|
<AppContextProvider
|
|
68
67
|
lang={this.getLang()}
|
|
69
68
|
font={this.getFont()}
|
|
@@ -94,7 +93,6 @@ class Form extends PreviewUI {
|
|
|
94
93
|
}}
|
|
95
94
|
/>
|
|
96
95
|
</AppContextProvider>,
|
|
97
|
-
this.domContainer,
|
|
98
96
|
);
|
|
99
97
|
}
|
|
100
98
|
}
|
package/src/Viewer.tsx
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom';
|
|
3
2
|
import { PreviewProps } from '@pdfme/common';
|
|
4
3
|
import { PreviewUI } from './class.js';
|
|
5
4
|
import { DESTROYED_ERR_MSG } from './constants.js';
|
|
@@ -32,7 +31,7 @@ class Viewer extends PreviewUI {
|
|
|
32
31
|
|
|
33
32
|
protected render() {
|
|
34
33
|
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
|
35
|
-
|
|
34
|
+
this.mount(
|
|
36
35
|
<AppContextProvider
|
|
37
36
|
lang={this.getLang()}
|
|
38
37
|
font={this.getFont()}
|
|
@@ -51,7 +50,6 @@ class Viewer extends PreviewUI {
|
|
|
51
50
|
}}
|
|
52
51
|
/>
|
|
53
52
|
</AppContextProvider>,
|
|
54
|
-
this.domContainer,
|
|
55
53
|
);
|
|
56
54
|
}
|
|
57
55
|
}
|
package/src/class.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { createRoot, Root } from 'react-dom/client';
|
|
2
3
|
import { DESTROYED_ERR_MSG, DEFAULT_LANG } from './constants.js';
|
|
3
4
|
import { debounce } from './helper.js';
|
|
4
5
|
import {
|
|
@@ -19,7 +20,7 @@ import {
|
|
|
19
20
|
checkPreviewProps,
|
|
20
21
|
pluginRegistry,
|
|
21
22
|
} from '@pdfme/common';
|
|
22
|
-
import { builtInPlugins } from '@pdfme/schemas';
|
|
23
|
+
import { builtInPlugins } from '@pdfme/schemas/builtins';
|
|
23
24
|
|
|
24
25
|
export abstract class BaseUIClass {
|
|
25
26
|
protected domContainer!: HTMLElement | null;
|
|
@@ -28,6 +29,8 @@ export abstract class BaseUIClass {
|
|
|
28
29
|
|
|
29
30
|
protected size!: Size;
|
|
30
31
|
|
|
32
|
+
private reactRoot: Root | null = null;
|
|
33
|
+
|
|
31
34
|
private lang: Lang = DEFAULT_LANG;
|
|
32
35
|
|
|
33
36
|
private font: Font = getDefaultFont();
|
|
@@ -65,11 +68,12 @@ export abstract class BaseUIClass {
|
|
|
65
68
|
this.domContainer = domContainer;
|
|
66
69
|
this.template = cloneDeep(template);
|
|
67
70
|
this.options = options;
|
|
71
|
+
const container = this.domContainer;
|
|
68
72
|
this.size = {
|
|
69
|
-
height:
|
|
70
|
-
width:
|
|
73
|
+
height: container.clientHeight || window.innerHeight,
|
|
74
|
+
width: container.clientWidth || window.innerWidth,
|
|
71
75
|
};
|
|
72
|
-
this.resizeObserver.observe(
|
|
76
|
+
this.resizeObserver.observe(container);
|
|
73
77
|
|
|
74
78
|
const { lang, font } = options;
|
|
75
79
|
if (lang) {
|
|
@@ -130,12 +134,19 @@ export abstract class BaseUIClass {
|
|
|
130
134
|
|
|
131
135
|
public destroy() {
|
|
132
136
|
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
|
133
|
-
|
|
137
|
+
this.reactRoot?.unmount();
|
|
138
|
+
this.reactRoot = null;
|
|
134
139
|
|
|
135
140
|
this.resizeObserver.unobserve(this.domContainer);
|
|
136
141
|
this.domContainer = null;
|
|
137
142
|
}
|
|
138
143
|
|
|
144
|
+
protected mount(node: ReactNode) {
|
|
145
|
+
if (!this.domContainer) throw Error(DESTROYED_ERR_MSG);
|
|
146
|
+
this.reactRoot ??= createRoot(this.domContainer);
|
|
147
|
+
this.reactRoot.render(node);
|
|
148
|
+
}
|
|
149
|
+
|
|
139
150
|
protected abstract render(): void;
|
|
140
151
|
}
|
|
141
152
|
export abstract class PreviewUI extends BaseUIClass {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
2
|
import { Size } from '@pdfme/common';
|
|
3
3
|
// Import icons from lucide-react
|
|
4
|
-
// Note: In tests, these
|
|
4
|
+
// Note: In tests, these are replaced via the Vitest lucide-react mock.
|
|
5
5
|
import { Plus, Minus, ChevronLeft, ChevronRight, Ellipsis } from 'lucide-react';
|
|
6
6
|
|
|
7
7
|
import type { MenuProps } from 'antd';
|
|
@@ -60,7 +60,12 @@ type PagerProps = {
|
|
|
60
60
|
const Pager = ({ pageCursor, pageNum, setPageCursor, style }: PagerProps) => {
|
|
61
61
|
return (
|
|
62
62
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
63
|
-
<Button
|
|
63
|
+
<Button
|
|
64
|
+
className={UI_CLASSNAME + 'page-prev'}
|
|
65
|
+
type="text"
|
|
66
|
+
disabled={pageCursor <= 0}
|
|
67
|
+
onClick={() => setPageCursor(pageCursor - 1)}
|
|
68
|
+
>
|
|
64
69
|
<ChevronLeft size={16} color={style.textStyle.color} />
|
|
65
70
|
</Button>
|
|
66
71
|
<Text strong style={style.textStyle}>
|
|
@@ -11,26 +11,80 @@ interface PluginIconProps {
|
|
|
11
11
|
styles?: React.CSSProperties;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const SVGIcon = ({
|
|
15
|
-
svgString
|
|
16
|
-
size
|
|
17
|
-
styles
|
|
14
|
+
const SVGIcon = ({
|
|
15
|
+
svgString,
|
|
16
|
+
size,
|
|
17
|
+
styles,
|
|
18
|
+
label,
|
|
19
|
+
}: {
|
|
20
|
+
svgString: string;
|
|
21
|
+
size?: number;
|
|
22
|
+
styles?: React.CSSProperties;
|
|
18
23
|
label: string;
|
|
19
24
|
}) => {
|
|
20
25
|
const processedSVG = useMemo(() => {
|
|
21
26
|
// First sanitize the SVG string using DOMPurify with SVG profile
|
|
22
27
|
const sanitizedSVG = DOMPurify.sanitize(svgString, {
|
|
23
28
|
USE_PROFILES: { svg: true, svgFilters: true },
|
|
24
|
-
ALLOWED_TAGS: [
|
|
25
|
-
|
|
29
|
+
ALLOWED_TAGS: [
|
|
30
|
+
'svg',
|
|
31
|
+
'path',
|
|
32
|
+
'circle',
|
|
33
|
+
'rect',
|
|
34
|
+
'line',
|
|
35
|
+
'polygon',
|
|
36
|
+
'polyline',
|
|
37
|
+
'ellipse',
|
|
38
|
+
'g',
|
|
39
|
+
'defs',
|
|
40
|
+
'title',
|
|
41
|
+
'desc',
|
|
42
|
+
'metadata',
|
|
43
|
+
],
|
|
44
|
+
ALLOWED_ATTR: [
|
|
45
|
+
'class',
|
|
46
|
+
'id',
|
|
47
|
+
'fill',
|
|
48
|
+
'stroke',
|
|
49
|
+
'stroke-width',
|
|
50
|
+
'viewBox',
|
|
51
|
+
'width',
|
|
52
|
+
'height',
|
|
53
|
+
'd',
|
|
54
|
+
'cx',
|
|
55
|
+
'cy',
|
|
56
|
+
'r',
|
|
57
|
+
'x',
|
|
58
|
+
'y',
|
|
59
|
+
'x1',
|
|
60
|
+
'y1',
|
|
61
|
+
'x2',
|
|
62
|
+
'y2',
|
|
63
|
+
'points',
|
|
64
|
+
'rx',
|
|
65
|
+
'ry',
|
|
66
|
+
'transform',
|
|
67
|
+
],
|
|
26
68
|
FORBID_TAGS: ['script', 'foreignObject', 'use', 'embed', 'iframe', 'object', 'link', 'style'],
|
|
27
|
-
FORBID_ATTR: [
|
|
28
|
-
|
|
69
|
+
FORBID_ATTR: [
|
|
70
|
+
'onload',
|
|
71
|
+
'onerror',
|
|
72
|
+
'onclick',
|
|
73
|
+
'onmouseover',
|
|
74
|
+
'onfocus',
|
|
75
|
+
'onblur',
|
|
76
|
+
'href',
|
|
77
|
+
'xlink:href',
|
|
78
|
+
'src',
|
|
79
|
+
'action',
|
|
80
|
+
'formaction',
|
|
81
|
+
],
|
|
82
|
+
KEEP_CONTENT: false,
|
|
29
83
|
});
|
|
30
84
|
|
|
31
85
|
const parser = new DOMParser();
|
|
32
86
|
const doc = parser.parseFromString(sanitizedSVG, 'image/svg+xml');
|
|
33
|
-
|
|
87
|
+
|
|
34
88
|
const svgElement = doc.querySelector('svg');
|
|
35
89
|
if (!svgElement) {
|
|
36
90
|
return null;
|
|
@@ -49,13 +103,7 @@ const SVGIcon = ({ svgString, size, styles, label }: {
|
|
|
49
103
|
return null;
|
|
50
104
|
}
|
|
51
105
|
|
|
52
|
-
return
|
|
53
|
-
<div
|
|
54
|
-
style={styles}
|
|
55
|
-
title={label}
|
|
56
|
-
dangerouslySetInnerHTML={{ __html: processedSVG }}
|
|
57
|
-
/>
|
|
58
|
-
);
|
|
106
|
+
return <div style={styles} title={label} dangerouslySetInnerHTML={{ __html: processedSVG }} />;
|
|
59
107
|
};
|
|
60
108
|
|
|
61
109
|
const PluginIcon = (props: PluginIconProps) => {
|
|
@@ -66,8 +66,7 @@ const AlignWidget = (props: PropPanelWidgetProps) => {
|
|
|
66
66
|
|
|
67
67
|
let basePos = min;
|
|
68
68
|
// Define adjust function with consistent parameter usage
|
|
69
|
-
|
|
70
|
-
let adjust = (_size: number): number => 0;
|
|
69
|
+
let adjust: (size: number) => number = () => 0;
|
|
71
70
|
|
|
72
71
|
if (['center', 'middle'].includes(type)) {
|
|
73
72
|
basePos = (min + max) / 2;
|
|
@@ -6,21 +6,22 @@ type Props = PropPanelWidgetProps & {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
const WidgetRenderer = (props: Props) => {
|
|
9
|
-
const { widget, ...otherProps } = props;
|
|
10
9
|
const ref = useRef<HTMLDivElement>(null);
|
|
11
10
|
|
|
12
11
|
useEffect(() => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const element = ref.current;
|
|
13
|
+
if (element) {
|
|
14
|
+
const { widget, ...otherProps } = props;
|
|
15
|
+
element.innerHTML = '';
|
|
16
|
+
widget({ ...otherProps, rootElement: element });
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
return () => {
|
|
19
|
-
if (
|
|
20
|
-
|
|
20
|
+
if (element) {
|
|
21
|
+
element.innerHTML = '';
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
|
-
}, [props
|
|
24
|
+
}, [props]);
|
|
24
25
|
|
|
25
26
|
return <div ref={ref} />;
|
|
26
27
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useForm } from 'form-render';
|
|
2
|
-
import React, { useRef, useContext,
|
|
2
|
+
import React, { useRef, useContext, useEffect, useCallback, useMemo } from 'react';
|
|
3
3
|
import type {
|
|
4
4
|
Dict,
|
|
5
5
|
ChangeSchemaItem,
|
|
@@ -40,6 +40,8 @@ type DetailViewProps = Pick<
|
|
|
40
40
|
activeSchema: SchemaForUI;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
type WidgetMap = Record<string, (props: PropPanelWidgetProps) => React.JSX.Element>;
|
|
44
|
+
|
|
43
45
|
const DetailView = (props: DetailViewProps) => {
|
|
44
46
|
const { token } = theme.useToken();
|
|
45
47
|
|
|
@@ -59,12 +61,8 @@ const DetailView = (props: DetailViewProps) => {
|
|
|
59
61
|
[i18n],
|
|
60
62
|
);
|
|
61
63
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
}>({});
|
|
65
|
-
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
const newWidgets: typeof widgets = {
|
|
64
|
+
const widgets = useMemo<WidgetMap>(() => {
|
|
65
|
+
const newWidgets: WidgetMap = {
|
|
68
66
|
AlignWidget: (p) => <AlignWidget {...p} {...props} options={options} />,
|
|
69
67
|
Divider: () => (
|
|
70
68
|
<Divider style={{ marginTop: token.marginXS, marginBottom: token.marginXS }} />
|
|
@@ -72,8 +70,11 @@ const DetailView = (props: DetailViewProps) => {
|
|
|
72
70
|
ButtonGroup: (p) => <ButtonGroupWidget {...p} {...props} options={options} />,
|
|
73
71
|
};
|
|
74
72
|
for (const plugin of pluginsRegistry.values()) {
|
|
75
|
-
const
|
|
76
|
-
|
|
73
|
+
const pluginWidgets = (plugin.propPanel.widgets ?? {}) as Record<
|
|
74
|
+
string,
|
|
75
|
+
(props: PropPanelWidgetProps) => void
|
|
76
|
+
>;
|
|
77
|
+
Object.entries(pluginWidgets).forEach(([widgetKey, widgetValue]) => {
|
|
77
78
|
newWidgets[widgetKey] = (p) => (
|
|
78
79
|
<WidgetRenderer
|
|
79
80
|
{...p}
|
|
@@ -86,10 +87,10 @@ const DetailView = (props: DetailViewProps) => {
|
|
|
86
87
|
);
|
|
87
88
|
});
|
|
88
89
|
}
|
|
89
|
-
|
|
90
|
-
}, [
|
|
90
|
+
return newWidgets;
|
|
91
|
+
}, [options, pluginsRegistry, props, token, typedI18n]);
|
|
91
92
|
|
|
92
|
-
useEffect(() => form.resetFields(), [activeSchema.id]);
|
|
93
|
+
useEffect(() => form.resetFields(), [activeSchema.id, form]);
|
|
93
94
|
|
|
94
95
|
useEffect(() => {
|
|
95
96
|
// Create a type-safe copy of the schema with editable property
|
|
@@ -98,7 +99,7 @@ const DetailView = (props: DetailViewProps) => {
|
|
|
98
99
|
const readOnly = typeof values.readOnly === 'boolean' ? values.readOnly : false;
|
|
99
100
|
values.editable = !readOnly;
|
|
100
101
|
form.setValues(values);
|
|
101
|
-
}, [activeSchema]);
|
|
102
|
+
}, [activeSchema, form]);
|
|
102
103
|
|
|
103
104
|
useEffect(() => {
|
|
104
105
|
uniqueSchemaName.current = (value: string): boolean => {
|
|
@@ -114,10 +115,7 @@ const DetailView = (props: DetailViewProps) => {
|
|
|
114
115
|
}, [schemasList, activeSchema]);
|
|
115
116
|
|
|
116
117
|
// Reference to a function that validates schema name uniqueness
|
|
117
|
-
const uniqueSchemaName = useRef(
|
|
118
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
119
|
-
(_unused: string): boolean => true,
|
|
120
|
-
);
|
|
118
|
+
const uniqueSchemaName = useRef<(value: string) => boolean>(() => true);
|
|
121
119
|
|
|
122
120
|
// Use proper type for validator function parameter
|
|
123
121
|
const validateUniqueSchemaName = (_: unknown, value: string): boolean =>
|
|
@@ -46,7 +46,6 @@ interface Props {
|
|
|
46
46
|
// Using React.memo and forwardRef for optimized rendering
|
|
47
47
|
// Using TypeScript interface for prop validation instead of PropTypes
|
|
48
48
|
const Item = React.memo(
|
|
49
|
-
/* eslint-disable react/prop-types */
|
|
50
49
|
React.forwardRef<HTMLLIElement, Props>(function Item(
|
|
51
50
|
{
|
|
52
51
|
icon,
|
|
@@ -60,12 +59,9 @@ const Item = React.memo(
|
|
|
60
59
|
onClick,
|
|
61
60
|
onMouseEnter,
|
|
62
61
|
onMouseLeave,
|
|
63
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
64
62
|
dragging,
|
|
65
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
66
63
|
fadeIn,
|
|
67
64
|
listeners,
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
69
65
|
sorting,
|
|
70
66
|
transition,
|
|
71
67
|
transform,
|
|
@@ -73,8 +69,10 @@ const Item = React.memo(
|
|
|
73
69
|
},
|
|
74
70
|
ref,
|
|
75
71
|
) {
|
|
76
|
-
/* eslint-enable react/prop-types */
|
|
77
72
|
const i18n = useContext(I18nContext);
|
|
73
|
+
void dragging;
|
|
74
|
+
void fadeIn;
|
|
75
|
+
void sorting;
|
|
78
76
|
|
|
79
77
|
useEffect(() => {
|
|
80
78
|
if (!dragOverlay) {
|