lowcoder-comps 0.0.17 → 0.0.19
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 +27 -0
- package/index.html +26 -0
- package/index.tsx +19 -0
- package/jest.config.js +6 -0
- package/package.json +4 -5
- package/src/__test__/allComp.test.tsx +61 -0
- package/src/app-env.d.ts +3 -0
- package/src/comps/calendarComp/calendarComp.tsx +443 -0
- package/src/comps/calendarComp/calendarConstants.tsx +898 -0
- package/src/comps/chartComp/chartComp.tsx +356 -0
- package/src/comps/chartComp/chartConfigs/barChartConfig.tsx +51 -0
- package/src/comps/chartComp/chartConfigs/cartesianAxisConfig.tsx +307 -0
- package/src/comps/chartComp/chartConfigs/chartUrls.tsx +9 -0
- package/src/comps/chartComp/chartConfigs/legendConfig.tsx +55 -0
- package/src/comps/chartComp/chartConfigs/lineChartConfig.tsx +96 -0
- package/src/comps/chartComp/chartConfigs/pieChartConfig.tsx +83 -0
- package/src/comps/chartComp/chartConfigs/scatterChartConfig.tsx +62 -0
- package/src/comps/chartComp/chartConstants.tsx +288 -0
- package/src/comps/chartComp/chartPropertyView.tsx +218 -0
- package/src/comps/chartComp/chartUtils.ts +291 -0
- package/src/comps/chartComp/reactEcharts/core.tsx +194 -0
- package/src/comps/chartComp/reactEcharts/index.ts +21 -0
- package/src/comps/chartComp/reactEcharts/types.ts +76 -0
- package/src/comps/chartComp/seriesComp.tsx +119 -0
- package/src/comps/imageEditorComp/imageEditorClass.tsx +52 -0
- package/src/comps/imageEditorComp/imageEditorConstants.tsx +109 -0
- package/src/comps/imageEditorComp/index.tsx +184 -0
- package/src/comps/mermaidComp/index.tsx +44 -0
- package/src/comps/mermaidComp/mermaid.tsx +29 -0
- package/src/global.ts +1 -0
- package/src/i18n/comps/index.tsx +29 -0
- package/src/i18n/comps/locales/en.ts +150 -0
- package/src/i18n/comps/locales/enObj.tsx +198 -0
- package/src/i18n/comps/locales/index.ts +7 -0
- package/src/i18n/comps/locales/types.tsx +10 -0
- package/src/i18n/comps/locales/zh.ts +145 -0
- package/src/i18n/comps/locales/zhObj.tsx +4 -0
- package/src/index.ts +11 -0
- package/tsconfig.json +22 -0
- package/vite.config.js +10 -0
- package/001f8b13.js +0 -326
- package/085bf0c2.js +0 -46688
- package/256b619e.js +0 -92
- package/29cba276.js +0 -91
- package/2e18581a.js +0 -451
- package/2ff2c7a6.js +0 -6
- package/340c33ea.js +0 -1602
- package/3ad55ad7.js +0 -607
- package/47b0b0ff.js +0 -70
- package/4a5b6fbe.js +0 -798
- package/4abe140e.js +0 -943
- package/4cf5b178.js +0 -34
- package/5cab7b96.js +0 -18619
- package/626b9013.js +0 -7
- package/6798500f.js +0 -793
- package/68b021d0.js +0 -2456
- package/6ab1612a.js +0 -24
- package/6e903063.js +0 -940
- package/72a7048f.js +0 -849
- package/7902f186.js +0 -823
- package/82c1c410.js +0 -86
- package/8517f7c1.js +0 -365
- package/9495ef3b.js +0 -1118
- package/9ea1ddd6.js +0 -447
- package/a01c9944.js +0 -212
- package/a4ce7e8a.js +0 -2827
- package/ad68bdd0.js +0 -236
- package/b499e5a9.js +0 -2103
- package/bdc7b18a.js +0 -1032
- package/be5b66cd.js +0 -832
- package/c4378831.js +0 -117175
- package/ca8f4e3f.js +0 -275
- package/de61c633.js +0 -2679
- package/e04788e2.js +0 -159
- package/f9637058.js +0 -16
- package/f9a47b7c.js +0 -985
- package/ff16c2ec.js +0 -1246
- package/index.js +0 -5
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as echarts from "echarts";
|
|
2
|
+
import "echarts-wordcloud";
|
|
3
|
+
import { EChartsReactProps, EChartsInstance, EChartsOptionWithMap } from "./types";
|
|
4
|
+
import EChartsReactCore from "./core";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* reference: https://github.com/hustcc/echarts-for-react
|
|
8
|
+
* add exception-catch for setOption
|
|
9
|
+
* if query isn't successfully loaded, chart will fail to load and can't reload
|
|
10
|
+
*/
|
|
11
|
+
export type { EChartsReactProps, EChartsOptionWithMap, EChartsInstance };
|
|
12
|
+
|
|
13
|
+
// export the Component the echarts Object.
|
|
14
|
+
export default class EChartsReact extends EChartsReactCore {
|
|
15
|
+
constructor(props: EChartsReactProps) {
|
|
16
|
+
super(props);
|
|
17
|
+
|
|
18
|
+
// initialize as echarts package
|
|
19
|
+
this.echarts = echarts;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CSSProperties } from "react";
|
|
2
|
+
import { EChartsOption } from "echarts";
|
|
3
|
+
import { GoogleMapComponentOption } from "echarts-extension-gmap";
|
|
4
|
+
|
|
5
|
+
export type EChartsOptionWithMap = EChartsOption & GoogleMapComponentOption<any>;
|
|
6
|
+
|
|
7
|
+
export type EChartsInstance = any;
|
|
8
|
+
|
|
9
|
+
export type Opts = {
|
|
10
|
+
readonly devicePixelRatio?: number;
|
|
11
|
+
readonly renderer?: "canvas" | "svg";
|
|
12
|
+
readonly width?: number | null | undefined | "auto";
|
|
13
|
+
readonly height?: number | null | undefined | "auto";
|
|
14
|
+
readonly locale?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type EChartsReactProps = {
|
|
18
|
+
/**
|
|
19
|
+
* echarts library entry, use it for import necessary.
|
|
20
|
+
*/
|
|
21
|
+
readonly echarts?: any;
|
|
22
|
+
/**
|
|
23
|
+
* `className` for container
|
|
24
|
+
*/
|
|
25
|
+
readonly className?: string;
|
|
26
|
+
/**
|
|
27
|
+
* `style` for container
|
|
28
|
+
*/
|
|
29
|
+
readonly style?: CSSProperties;
|
|
30
|
+
/**
|
|
31
|
+
* echarts option
|
|
32
|
+
*/
|
|
33
|
+
readonly option: EChartsOptionWithMap;
|
|
34
|
+
/**
|
|
35
|
+
* echarts theme config, can be:
|
|
36
|
+
* 1. theme name string
|
|
37
|
+
* 2. theme object
|
|
38
|
+
*/
|
|
39
|
+
readonly theme?: string | Record<string, any>;
|
|
40
|
+
/**
|
|
41
|
+
* notMerge config for echarts, default is `false`
|
|
42
|
+
*/
|
|
43
|
+
readonly notMerge?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* lazyUpdate config for echarts, default is `false`
|
|
46
|
+
*/
|
|
47
|
+
readonly lazyUpdate?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* showLoading config for echarts, default is `false`
|
|
50
|
+
*/
|
|
51
|
+
readonly showLoading?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* loadingOption config for echarts, default is `null`
|
|
54
|
+
*/
|
|
55
|
+
readonly loadingOption?: any;
|
|
56
|
+
/**
|
|
57
|
+
* echarts opts config, default is `{}`
|
|
58
|
+
*/
|
|
59
|
+
readonly opts?: Opts;
|
|
60
|
+
/**
|
|
61
|
+
* when after chart reander, do the callback widht echarts instance
|
|
62
|
+
*/
|
|
63
|
+
readonly onChartReady?: (instance: EChartsInstance) => void;
|
|
64
|
+
/**
|
|
65
|
+
* bind events, default is `{}`
|
|
66
|
+
*/
|
|
67
|
+
readonly onEvents?: Record<string, Function>;
|
|
68
|
+
/**
|
|
69
|
+
* should update echarts options
|
|
70
|
+
*/
|
|
71
|
+
readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean;
|
|
72
|
+
/**
|
|
73
|
+
* echarts mode: ui | json | map
|
|
74
|
+
*/
|
|
75
|
+
readonly mode?: 'ui' | 'json' | 'map'
|
|
76
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoolControl,
|
|
3
|
+
StringControl,
|
|
4
|
+
list,
|
|
5
|
+
JSONObject,
|
|
6
|
+
isNumeric,
|
|
7
|
+
genRandomKey,
|
|
8
|
+
Dropdown,
|
|
9
|
+
OptionsType,
|
|
10
|
+
MultiCompBuilder,
|
|
11
|
+
valueComp,
|
|
12
|
+
} from "lowcoder-sdk";
|
|
13
|
+
import { trans } from "i18n/comps";
|
|
14
|
+
|
|
15
|
+
import { ConstructorToComp, ConstructorToDataType, ConstructorToView } from "lowcoder-core";
|
|
16
|
+
import { CompAction, CustomAction, customAction, isMyCustomAction } from "lowcoder-core";
|
|
17
|
+
|
|
18
|
+
export type SeriesCompType = ConstructorToComp<typeof SeriesComp>;
|
|
19
|
+
export type RawSeriesCompType = ConstructorToView<typeof SeriesComp>;
|
|
20
|
+
type SeriesDataType = ConstructorToDataType<typeof SeriesComp>;
|
|
21
|
+
|
|
22
|
+
type ActionDataType = {
|
|
23
|
+
type: "chartDataChanged";
|
|
24
|
+
chartData: Array<JSONObject>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function newSeries(name: string, columnName: string): SeriesDataType {
|
|
28
|
+
return {
|
|
29
|
+
seriesName: name,
|
|
30
|
+
columnName: columnName,
|
|
31
|
+
dataIndex: genRandomKey(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const seriesChildrenMap = {
|
|
36
|
+
columnName: StringControl,
|
|
37
|
+
seriesName: StringControl,
|
|
38
|
+
hide: BoolControl,
|
|
39
|
+
// unique key, for sort
|
|
40
|
+
dataIndex: valueComp<string>(""),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const SeriesTmpComp = new MultiCompBuilder(seriesChildrenMap, (props) => {
|
|
44
|
+
return props;
|
|
45
|
+
})
|
|
46
|
+
.setPropertyViewFn(() => {
|
|
47
|
+
return <></>;
|
|
48
|
+
})
|
|
49
|
+
.build();
|
|
50
|
+
|
|
51
|
+
class SeriesComp extends SeriesTmpComp {
|
|
52
|
+
getPropertyViewWithData(columnOptions: OptionsType): React.ReactNode {
|
|
53
|
+
return (
|
|
54
|
+
<>
|
|
55
|
+
{this.children.seriesName.propertyView({
|
|
56
|
+
label: trans("chart.seriesName"),
|
|
57
|
+
})}
|
|
58
|
+
<Dropdown
|
|
59
|
+
value={this.children.columnName.getView()}
|
|
60
|
+
options={columnOptions}
|
|
61
|
+
label={trans("chart.dataColumns")}
|
|
62
|
+
onChange={(value) => {
|
|
63
|
+
this.children.columnName.dispatchChangeValueAction(value);
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const SeriesListTmpComp = list(SeriesComp);
|
|
72
|
+
|
|
73
|
+
export class SeriesListComp extends SeriesListTmpComp {
|
|
74
|
+
override reduce(action: CompAction): this {
|
|
75
|
+
if (isMyCustomAction<ActionDataType>(action, "chartDataChanged")) {
|
|
76
|
+
// auto generate series
|
|
77
|
+
const actions = this.genExampleSeriesActions(action.value.chartData);
|
|
78
|
+
return this.reduce(this.multiAction(actions));
|
|
79
|
+
}
|
|
80
|
+
return super.reduce(action);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private genExampleSeriesActions(chartData: Array<JSONObject>) {
|
|
84
|
+
const actions: CustomAction[] = [];
|
|
85
|
+
if (!chartData || chartData.length <= 0 || !chartData[0]) {
|
|
86
|
+
return actions;
|
|
87
|
+
}
|
|
88
|
+
let delCnt = 0;
|
|
89
|
+
const existColumns = this.getView().map((s) => s.getView().columnName);
|
|
90
|
+
// delete series not in data
|
|
91
|
+
existColumns.forEach((columnName) => {
|
|
92
|
+
if (chartData[0]?.[columnName] === undefined) {
|
|
93
|
+
actions.push(this.deleteAction(0));
|
|
94
|
+
delCnt++;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
if (existColumns.length > delCnt) {
|
|
98
|
+
// don't generate example if exists
|
|
99
|
+
return actions;
|
|
100
|
+
}
|
|
101
|
+
// generate example series
|
|
102
|
+
const exampleKeys = Object.keys(chartData[0])
|
|
103
|
+
.filter((key) => {
|
|
104
|
+
return !existColumns.includes(key) && isNumeric(chartData[0][key]);
|
|
105
|
+
})
|
|
106
|
+
.slice(0, 3);
|
|
107
|
+
exampleKeys.forEach((key) => actions.push(this.pushAction(newSeries(key, key))));
|
|
108
|
+
return actions;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
dispatchDataChanged(chartData: Array<JSONObject>): void {
|
|
112
|
+
this.dispatch(
|
|
113
|
+
customAction<ActionDataType>({
|
|
114
|
+
type: "chartDataChanged",
|
|
115
|
+
chartData: chartData,
|
|
116
|
+
})
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import TuiImageEditor from "tui-image-editor";
|
|
3
|
+
|
|
4
|
+
export class ImageEditor extends React.Component<any> {
|
|
5
|
+
rootEl = React.createRef<any>();
|
|
6
|
+
|
|
7
|
+
imageEditorInst: TuiImageEditor | undefined;
|
|
8
|
+
props: any;
|
|
9
|
+
constructor(props: any) {
|
|
10
|
+
super(props);
|
|
11
|
+
this.props = props;
|
|
12
|
+
}
|
|
13
|
+
componentDidMount() {
|
|
14
|
+
if (this.rootEl.current !== null) {
|
|
15
|
+
this.imageEditorInst = new TuiImageEditor(this.rootEl.current, {
|
|
16
|
+
...(this.props as any),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
componentWillUnmount() {
|
|
22
|
+
if (this.imageEditorInst !== undefined) {
|
|
23
|
+
this.imageEditorInst.destroy();
|
|
24
|
+
|
|
25
|
+
this.imageEditorInst = undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
shouldComponentUpdate(nextProps: any) {
|
|
30
|
+
if (
|
|
31
|
+
JSON.stringify([this.props.includeUI.menu, this.props.includeUI.loadImage]) !==
|
|
32
|
+
JSON.stringify([nextProps.includeUI.menu, nextProps.includeUI.loadImage])
|
|
33
|
+
) {
|
|
34
|
+
this.imageEditorInst = new TuiImageEditor(this.rootEl.current as any, {
|
|
35
|
+
...nextProps,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getInstance() {
|
|
42
|
+
return this.imageEditorInst;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getRootElement() {
|
|
46
|
+
return this.rootEl.current;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
render() {
|
|
50
|
+
return <div ref={this.rootEl} />;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Button } from "antd";
|
|
3
|
+
import { EventConfigType } from "lowcoder-sdk";
|
|
4
|
+
import { trans } from "i18n/comps";
|
|
5
|
+
|
|
6
|
+
export const saveEvent: EventConfigType = {
|
|
7
|
+
label: trans("imageEditor.save"),
|
|
8
|
+
value: "save",
|
|
9
|
+
description: trans("imageEditor.saveDesc"),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const Container = styled.div`
|
|
13
|
+
height: 100%;
|
|
14
|
+
width: 100%;
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
.tui-image-editor-container.top .tui-image-editor-controls-logo {
|
|
19
|
+
display: none;
|
|
20
|
+
}
|
|
21
|
+
.tui-image-editor-container .tui-image-editor-header-logo,
|
|
22
|
+
.tui-image-editor-container .tui-image-editor-controls-logo {
|
|
23
|
+
display: none;
|
|
24
|
+
}
|
|
25
|
+
.tui-image-editor-container .tui-image-editor-header-buttons button,
|
|
26
|
+
.tui-image-editor-container .tui-image-editor-header-buttons div,
|
|
27
|
+
.tui-image-editor-container .tui-image-editor-controls-buttons button,
|
|
28
|
+
.tui-image-editor-container .tui-image-editor-controls-buttons div {
|
|
29
|
+
display: none;
|
|
30
|
+
}
|
|
31
|
+
.tie-btn-hand {
|
|
32
|
+
display: none !important;
|
|
33
|
+
}
|
|
34
|
+
.tui-image-editor-container .tui-image-editor-menu,
|
|
35
|
+
.tui-image-editor-container .tui-image-editor-help-menu {
|
|
36
|
+
background-color: #f3f4f6 !important;
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
|
|
40
|
+
export const EmbeddedButton = styled(Button)`
|
|
41
|
+
position: absolute;
|
|
42
|
+
right: 8px;
|
|
43
|
+
bottom: 4px;
|
|
44
|
+
z-index: 100;
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
export const customTheme = {
|
|
48
|
+
// image
|
|
49
|
+
"common.bi.image": "",
|
|
50
|
+
"common.bisize.width": "0px",
|
|
51
|
+
"common.bisize.height": "0px",
|
|
52
|
+
"common.backgroundImage": "none",
|
|
53
|
+
"common.backgroundColor": "#f3f4f6",
|
|
54
|
+
"common.border": "1px solid #444",
|
|
55
|
+
|
|
56
|
+
// header
|
|
57
|
+
"header.backgroundImage": "none",
|
|
58
|
+
"header.backgroundColor": "#f3f4f6",
|
|
59
|
+
"header.border": "0px",
|
|
60
|
+
"header.display": "none",
|
|
61
|
+
|
|
62
|
+
// icons default
|
|
63
|
+
"menu.normalIcon.color": "#8a8a8a",
|
|
64
|
+
"menu.activeIcon.color": "#555555",
|
|
65
|
+
"menu.disabledIcon.color": "#434343",
|
|
66
|
+
"menu.hoverIcon.color": "#e9e9e9",
|
|
67
|
+
"submenu.normalIcon.color": "#8a8a8a",
|
|
68
|
+
"submenu.activeIcon.color": "#e9e9e9",
|
|
69
|
+
|
|
70
|
+
"menu.iconSize.width": "24px",
|
|
71
|
+
"menu.iconSize.height": "24px",
|
|
72
|
+
"submenu.iconSize.width": "32px",
|
|
73
|
+
"submenu.iconSize.height": "32px",
|
|
74
|
+
|
|
75
|
+
// submenu primary color
|
|
76
|
+
"submenu.backgroundColor": "#1e1e1e",
|
|
77
|
+
"submenu.partition.color": "#858585",
|
|
78
|
+
|
|
79
|
+
// submenu labels
|
|
80
|
+
"submenu.normalLabel.color": "#858585",
|
|
81
|
+
"submenu.normalLabel.fontWeight": "lighter",
|
|
82
|
+
"submenu.activeLabel.color": "#fff",
|
|
83
|
+
"submenu.activeLabel.fontWeight": "lighter",
|
|
84
|
+
|
|
85
|
+
// checkbox style
|
|
86
|
+
"checkbox.border": "1px solid #ccc",
|
|
87
|
+
"checkbox.backgroundColor": "#fff",
|
|
88
|
+
|
|
89
|
+
// rango style
|
|
90
|
+
"range.pointer.color": "#fff",
|
|
91
|
+
"range.bar.color": "#666",
|
|
92
|
+
"range.subbar.color": "#d1d1d1",
|
|
93
|
+
|
|
94
|
+
"range.disabledPointer.color": "#414141",
|
|
95
|
+
"range.disabledBar.color": "#282828",
|
|
96
|
+
"range.disabledSubbar.color": "#414141",
|
|
97
|
+
|
|
98
|
+
"range.value.color": "#fff",
|
|
99
|
+
"range.value.fontWeight": "lighter",
|
|
100
|
+
"range.value.fontSize": "11px",
|
|
101
|
+
"range.value.border": "1px solid #353535",
|
|
102
|
+
"range.value.backgroundColor": "#151515",
|
|
103
|
+
"range.title.color": "#fff",
|
|
104
|
+
"range.title.fontWeight": "lighter",
|
|
105
|
+
|
|
106
|
+
// colorpicker style
|
|
107
|
+
"colorpicker.button.border": "1px solid #1e1e1e",
|
|
108
|
+
"colorpicker.title.color": "#fff",
|
|
109
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoolControl,
|
|
3
|
+
hiddenPropertyView,
|
|
4
|
+
NameConfig,
|
|
5
|
+
Section,
|
|
6
|
+
sectionNames,
|
|
7
|
+
StringStateControl,
|
|
8
|
+
UICompBuilder,
|
|
9
|
+
withDefault,
|
|
10
|
+
withExposingConfigs,
|
|
11
|
+
eventHandlerControl,
|
|
12
|
+
NameConfigHidden,
|
|
13
|
+
stringExposingStateControl,
|
|
14
|
+
} from "lowcoder-sdk";
|
|
15
|
+
import { useRef } from "react";
|
|
16
|
+
import ReactResizeDetector from "react-resize-detector";
|
|
17
|
+
import _ from "lodash";
|
|
18
|
+
import { RecordConstructorToView } from "lowcoder-core";
|
|
19
|
+
import { Container, customTheme, EmbeddedButton, saveEvent } from "./imageEditorConstants";
|
|
20
|
+
import { ImageEditor } from "./imageEditorClass";
|
|
21
|
+
import { i18nObjs, trans } from "i18n/comps";
|
|
22
|
+
|
|
23
|
+
const childrenMap = {
|
|
24
|
+
src: withDefault(StringStateControl, trans("imageEditor.defaultSrc")),
|
|
25
|
+
name: withDefault(StringStateControl, "Example"),
|
|
26
|
+
crop: withDefault(BoolControl, true),
|
|
27
|
+
flip: withDefault(BoolControl, true),
|
|
28
|
+
rotate: withDefault(BoolControl, true),
|
|
29
|
+
draw: withDefault(BoolControl, true),
|
|
30
|
+
shape: withDefault(BoolControl, true),
|
|
31
|
+
icon: withDefault(BoolControl, true),
|
|
32
|
+
text: withDefault(BoolControl, true),
|
|
33
|
+
mask: withDefault(BoolControl, true),
|
|
34
|
+
filter: withDefault(BoolControl, true),
|
|
35
|
+
dataURI: stringExposingStateControl("dataURI"),
|
|
36
|
+
data: stringExposingStateControl("data"),
|
|
37
|
+
onEvent: eventHandlerControl([saveEvent] as const),
|
|
38
|
+
buttonText: withDefault(StringStateControl, trans("imageEditor.save")),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const ContainerImageEditor = (props: RecordConstructorToView<typeof childrenMap>) => {
|
|
42
|
+
const editorRef = useRef<any>(null);
|
|
43
|
+
const conRef = useRef<HTMLDivElement>(null);
|
|
44
|
+
|
|
45
|
+
const menu = ["crop", "flip", "rotate", "draw", "shape", "icon", "text", "mask", "filter"];
|
|
46
|
+
const menuMap = new Map<string, boolean>();
|
|
47
|
+
menuMap.set("crop", props.crop);
|
|
48
|
+
menuMap.set("flip", props.flip);
|
|
49
|
+
menuMap.set("rotate", props.rotate);
|
|
50
|
+
menuMap.set("draw", props.draw);
|
|
51
|
+
menuMap.set("shape", props.shape);
|
|
52
|
+
menuMap.set("icon", props.icon);
|
|
53
|
+
menuMap.set("text", props.text);
|
|
54
|
+
menuMap.set("mask", props.mask);
|
|
55
|
+
menuMap.set("filter", props.filter);
|
|
56
|
+
let filteredMenu = menu.filter((ele) => {
|
|
57
|
+
return menuMap.get(ele);
|
|
58
|
+
});
|
|
59
|
+
const onResize = () => {
|
|
60
|
+
const editor = editorRef.current;
|
|
61
|
+
const container = conRef.current;
|
|
62
|
+
editor.imageEditorInst.ui.resizeEditor({
|
|
63
|
+
uiSize: { width: container?.clientWidth, height: container?.clientHeight },
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const saveImage = () => {
|
|
68
|
+
let imageEditorInst = editorRef.current.imageEditorInst;
|
|
69
|
+
let dataURL = imageEditorInst.toDataURL();
|
|
70
|
+
props.dataURI.onChange(dataURL);
|
|
71
|
+
props.data.onChange(dataURL.split(",")[1]);
|
|
72
|
+
};
|
|
73
|
+
return (
|
|
74
|
+
<Container ref={conRef}>
|
|
75
|
+
<EmbeddedButton
|
|
76
|
+
type="primary"
|
|
77
|
+
onClick={() => {
|
|
78
|
+
saveImage();
|
|
79
|
+
props.onEvent("save");
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
{props.buttonText.value}
|
|
83
|
+
</EmbeddedButton>
|
|
84
|
+
<ReactResizeDetector onResize={onResize}>
|
|
85
|
+
<div style={{ width: "100%", height: "100%" }}>
|
|
86
|
+
<ImageEditor
|
|
87
|
+
ref={editorRef}
|
|
88
|
+
includeUI={{
|
|
89
|
+
loadImage: {
|
|
90
|
+
path: props.src.value,
|
|
91
|
+
name: props.name.value,
|
|
92
|
+
},
|
|
93
|
+
menu: filteredMenu,
|
|
94
|
+
theme: customTheme,
|
|
95
|
+
uiSize: {
|
|
96
|
+
width: "100%",
|
|
97
|
+
height: "100%",
|
|
98
|
+
},
|
|
99
|
+
menuBarPosition: "bottom",
|
|
100
|
+
locale: i18nObjs.imageEditorLocale ?? {},
|
|
101
|
+
}}
|
|
102
|
+
cssMaxWidth={document.documentElement.clientWidth}
|
|
103
|
+
cssMaxHeight={document.documentElement.clientHeight}
|
|
104
|
+
selectionStyle={{
|
|
105
|
+
cornerSize: 50,
|
|
106
|
+
rotatingPointOffset: 100,
|
|
107
|
+
}}
|
|
108
|
+
usageStatistics={false}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</ReactResizeDetector>
|
|
112
|
+
</Container>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
let ImageEditorBasicComp = (function () {
|
|
116
|
+
return new UICompBuilder(childrenMap, (props) => {
|
|
117
|
+
return <ContainerImageEditor {...props} />;
|
|
118
|
+
})
|
|
119
|
+
.setPropertyViewFn((children) => {
|
|
120
|
+
return (
|
|
121
|
+
<>
|
|
122
|
+
<Section name={sectionNames.basic}>
|
|
123
|
+
{children.src.propertyView({
|
|
124
|
+
label: trans("imageEditor.src"),
|
|
125
|
+
placeholder: "http://xxx.jpg",
|
|
126
|
+
})}
|
|
127
|
+
{children.name.propertyView({
|
|
128
|
+
label: trans("imageEditor.name"),
|
|
129
|
+
})}
|
|
130
|
+
{children.buttonText.propertyView({
|
|
131
|
+
label: trans("imageEditor.buttonText"),
|
|
132
|
+
})}
|
|
133
|
+
</Section>
|
|
134
|
+
<Section name={sectionNames.interaction}>{children.onEvent.getPropertyView()}</Section>
|
|
135
|
+
<Section name={sectionNames.advanced}>
|
|
136
|
+
{children.crop.propertyView({
|
|
137
|
+
label: "Crop",
|
|
138
|
+
})}
|
|
139
|
+
{children.flip.propertyView({
|
|
140
|
+
label: "Flip",
|
|
141
|
+
})}
|
|
142
|
+
{children.rotate.propertyView({
|
|
143
|
+
label: "Rotate",
|
|
144
|
+
})}
|
|
145
|
+
{children.draw.propertyView({
|
|
146
|
+
label: "Draw",
|
|
147
|
+
})}
|
|
148
|
+
{children.shape.propertyView({
|
|
149
|
+
label: "Shape",
|
|
150
|
+
})}
|
|
151
|
+
{children.icon.propertyView({
|
|
152
|
+
label: "Icon",
|
|
153
|
+
})}
|
|
154
|
+
{children.text.propertyView({
|
|
155
|
+
label: "Text",
|
|
156
|
+
})}
|
|
157
|
+
{children.mask.propertyView({
|
|
158
|
+
label: "Mask",
|
|
159
|
+
})}
|
|
160
|
+
{children.filter.propertyView({
|
|
161
|
+
label: "Filter",
|
|
162
|
+
})}
|
|
163
|
+
</Section>
|
|
164
|
+
<Section name={sectionNames.layout}>{hiddenPropertyView(children)}</Section>
|
|
165
|
+
</>
|
|
166
|
+
);
|
|
167
|
+
})
|
|
168
|
+
.build();
|
|
169
|
+
})();
|
|
170
|
+
|
|
171
|
+
ImageEditorBasicComp = class extends ImageEditorBasicComp {
|
|
172
|
+
override autoHeight(): boolean {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export const ImageEditorComp = withExposingConfigs(ImageEditorBasicComp, [
|
|
178
|
+
new NameConfig("src", trans("imageEditor.srcDesc")),
|
|
179
|
+
new NameConfig("name", trans("imageEditor.nameDesc")),
|
|
180
|
+
new NameConfig("dataURI", trans("imageEditor.dataURIDesc")),
|
|
181
|
+
new NameConfig("data", trans("imageEditor.dataDesc")),
|
|
182
|
+
new NameConfig("buttonText", trans("imageEditor.buttonTextDesc")),
|
|
183
|
+
NameConfigHidden,
|
|
184
|
+
]);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UICompBuilder,
|
|
3
|
+
Section,
|
|
4
|
+
withExposingConfigs,
|
|
5
|
+
stringExposingStateControl,
|
|
6
|
+
NameConfig,
|
|
7
|
+
eventHandlerControl,
|
|
8
|
+
withMethodExposing,
|
|
9
|
+
} from "lowcoder-sdk";
|
|
10
|
+
|
|
11
|
+
import Mermaid from "./mermaid";
|
|
12
|
+
|
|
13
|
+
const childrenMap = {
|
|
14
|
+
code: stringExposingStateControl(
|
|
15
|
+
"code",
|
|
16
|
+
`graph LR
|
|
17
|
+
Start --> Stop`
|
|
18
|
+
),
|
|
19
|
+
onEvent: eventHandlerControl([
|
|
20
|
+
{
|
|
21
|
+
label: "onChange",
|
|
22
|
+
value: "change",
|
|
23
|
+
description: "",
|
|
24
|
+
},
|
|
25
|
+
]),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const CompBase = new UICompBuilder(childrenMap, (props: any) => {
|
|
29
|
+
const code = props.code.value;
|
|
30
|
+
return <Mermaid code={code} />;
|
|
31
|
+
})
|
|
32
|
+
.setPropertyViewFn((children: any) => {
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<Section name="Basic">{children.code.propertyView({ label: "code" })}</Section>
|
|
36
|
+
<Section name="Interaction">{children.onEvent.propertyView()}</Section>
|
|
37
|
+
</>
|
|
38
|
+
);
|
|
39
|
+
})
|
|
40
|
+
.build();
|
|
41
|
+
|
|
42
|
+
const AppViewCompTemp = withMethodExposing(CompBase, []);
|
|
43
|
+
|
|
44
|
+
export const MermaidComp = withExposingConfigs(AppViewCompTemp, [new NameConfig("code", "")]);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import mermaid from "mermaid";
|
|
3
|
+
|
|
4
|
+
function escape(str: string): string {
|
|
5
|
+
const entries: { [index: string]: any } = { lt: "<", gt: ">", nbsp: " ", amp: "&", quot: '"' };
|
|
6
|
+
return str
|
|
7
|
+
.replace(/&(lt|gt|nbsp|amp|quot);/gi, function (_, t) {
|
|
8
|
+
return entries[t];
|
|
9
|
+
})
|
|
10
|
+
.trim();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default ({ id = "graphDiv", code = "" }) => {
|
|
14
|
+
const [svg, setSvg] = useState("");
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
mermaid.initialize({ startOnLoad: false });
|
|
18
|
+
}, []);
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!code) return;
|
|
22
|
+
|
|
23
|
+
mermaid.mermaidAPI.render(id, escape(code)).then((res) => {
|
|
24
|
+
setSvg(res.svg);
|
|
25
|
+
});
|
|
26
|
+
}, [code, setSvg]);
|
|
27
|
+
|
|
28
|
+
return <pre className="mermaid" dangerouslySetInnerHTML={{ __html: svg }}></pre>;
|
|
29
|
+
};
|
package/src/global.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "../../lowcoder/src/global";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getI18nObjects, getValueByLocale, Translator } from "lowcoder-core";
|
|
2
|
+
import * as localeData from "./locales";
|
|
3
|
+
import { I18nObjects } from "./locales/types";
|
|
4
|
+
|
|
5
|
+
export const { trans, language } = new Translator<typeof localeData.en>(
|
|
6
|
+
localeData,
|
|
7
|
+
REACT_APP_LANGUAGES
|
|
8
|
+
);
|
|
9
|
+
export const i18nObjs = getI18nObjects<I18nObjects>(localeData, REACT_APP_LANGUAGES);
|
|
10
|
+
|
|
11
|
+
export function getEchartsLocale() {
|
|
12
|
+
return getValueByLocale("EN", (locale) => {
|
|
13
|
+
switch (locale.language) {
|
|
14
|
+
case "en":
|
|
15
|
+
return "EN";
|
|
16
|
+
case "zh":
|
|
17
|
+
return "ZH";
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getCalendarLocale() {
|
|
23
|
+
switch (language) {
|
|
24
|
+
case "zh":
|
|
25
|
+
return "zh-cn";
|
|
26
|
+
default:
|
|
27
|
+
return "en-gb";
|
|
28
|
+
}
|
|
29
|
+
}
|