lowcoder-comps 0.0.29 → 0.0.31

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 (86) hide show
  1. package/README.md +120 -0
  2. package/index.html +26 -0
  3. package/index.tsx +21 -0
  4. package/jest.config.js +6 -0
  5. package/package.json +3 -4
  6. package/src/__test__/allComp.test.tsx +61 -0
  7. package/src/app-env.d.ts +3 -0
  8. package/src/comps/calendarComp/calendarComp.tsx +633 -0
  9. package/src/comps/calendarComp/calendarConstants.tsx +1048 -0
  10. package/src/comps/calendarComp/errorBoundary.tsx +30 -0
  11. package/src/comps/chartComp/chartComp.tsx +442 -0
  12. package/src/comps/chartComp/chartConfigs/barChartConfig.tsx +51 -0
  13. package/src/comps/chartComp/chartConfigs/cartesianAxisConfig.tsx +307 -0
  14. package/src/comps/chartComp/chartConfigs/chartUrls.tsx +9 -0
  15. package/src/comps/chartComp/chartConfigs/legendConfig.tsx +55 -0
  16. package/src/comps/chartComp/chartConfigs/lineChartConfig.tsx +96 -0
  17. package/src/comps/chartComp/chartConfigs/pieChartConfig.tsx +83 -0
  18. package/src/comps/chartComp/chartConfigs/scatterChartConfig.tsx +62 -0
  19. package/src/comps/chartComp/chartConstants.tsx +299 -0
  20. package/src/comps/chartComp/chartPropertyView.tsx +235 -0
  21. package/src/comps/chartComp/chartUtils.ts +291 -0
  22. package/src/comps/chartComp/reactEcharts/core.tsx +194 -0
  23. package/src/comps/chartComp/reactEcharts/index.ts +21 -0
  24. package/src/comps/chartComp/reactEcharts/types.ts +76 -0
  25. package/src/comps/chartComp/seriesComp.tsx +119 -0
  26. package/src/comps/imageEditorComp/imageEditorClass.tsx +52 -0
  27. package/src/comps/imageEditorComp/imageEditorConstants.tsx +109 -0
  28. package/src/comps/imageEditorComp/index.tsx +184 -0
  29. package/src/comps/mermaidComp/index.tsx +44 -0
  30. package/src/comps/mermaidComp/mermaid.tsx +29 -0
  31. package/src/global.ts +1 -0
  32. package/src/i18n/comps/index.tsx +29 -0
  33. package/src/i18n/comps/locales/en.ts +163 -0
  34. package/src/i18n/comps/locales/enObj.tsx +198 -0
  35. package/src/i18n/comps/locales/index.ts +7 -0
  36. package/src/i18n/comps/locales/types.tsx +10 -0
  37. package/src/i18n/comps/locales/zh.ts +156 -0
  38. package/src/i18n/comps/locales/zhObj.tsx +4 -0
  39. package/src/index.ts +11 -0
  40. package/tsconfig.json +22 -0
  41. package/vite.config.js +10 -0
  42. package/2085da13.js +0 -960
  43. package/250691b5.js +0 -5
  44. package/256b619e.js +0 -92
  45. package/274f545c.js +0 -881
  46. package/289305a1.js +0 -208
  47. package/2eae45c2.js +0 -34
  48. package/2ff2c7a6.js +0 -6
  49. package/2ff7471d.js +0 -9
  50. package/335b22a2.js +0 -220
  51. package/38c826fe.js +0 -1127
  52. package/44011c1d.js +0 -818
  53. package/4fc06812.js +0 -64
  54. package/56a787cf.js +0 -915
  55. package/590941ff.js +0 -86
  56. package/6341867f.js +0 -804
  57. package/657fd065.js +0 -8
  58. package/78a5e50d.js +0 -1579
  59. package/820c3641.js +0 -25
  60. package/88b4e75a.js +0 -2967
  61. package/8d999722.js +0 -1102
  62. package/92e85b65.js +0 -65
  63. package/989caea2.js +0 -505
  64. package/99b984d1.js +0 -237
  65. package/9e5f02d6.js +0 -19104
  66. package/a40faea7.js +0 -11624
  67. package/abac9104.js +0 -1536
  68. package/af2f19b3.js +0 -819
  69. package/af5ee3de.js +0 -268
  70. package/b24707c2.js +0 -48428
  71. package/b68f8b69.js +0 -1276
  72. package/ba68ba65.js +0 -391
  73. package/bafb8599.js +0 -319
  74. package/bba60c35.js +0 -2501
  75. package/bd7c2a8e.js +0 -1089
  76. package/c71dadea.js +0 -455
  77. package/d05c1762.js +0 -933
  78. package/d073ab24.js +0 -134353
  79. package/d838cd10.js +0 -769
  80. package/dc36a6eb.js +0 -796
  81. package/ed143450.js +0 -1284
  82. package/ee8ec8f2.js +0 -2284
  83. package/f6755210.js +0 -1269
  84. package/f9637058.js +0 -16
  85. package/fba4c8e4.js +0 -447
  86. package/index.js +0 -5
@@ -0,0 +1,30 @@
1
+ import { default as Button } from "antd/es/button";
2
+ import React from "react";
3
+
4
+ export default class ErrorBoundary extends React.Component<any, { errorMessage?: string }> {
5
+ constructor(props: any) {
6
+ super(props);
7
+ this.state = {};
8
+ }
9
+
10
+ static getDerivedStateFromError(error: any) {
11
+ // Update state so the next render will show the fallback UI.
12
+ return { errorMessage: error.toString() };
13
+ }
14
+
15
+ componentDidCatch(error: any, errorInfo: any) {}
16
+
17
+ render() {
18
+ if (this.state.errorMessage) {
19
+ return (
20
+ <>
21
+ <p>{this.state.errorMessage}</p>
22
+ <Button type="primary" onClick={() => this.setState({ errorMessage: "" })}>
23
+ Retry
24
+ </Button>
25
+ </>
26
+ );
27
+ }
28
+ return this.props.children;
29
+ }
30
+ }
@@ -0,0 +1,442 @@
1
+ import {
2
+ changeChildAction,
3
+ changeValueAction,
4
+ CompAction,
5
+ CompActionTypes,
6
+ wrapChildAction,
7
+ } from "lowcoder-core";
8
+ import { AxisFormatterComp, EchartsAxisType } from "./chartConfigs/cartesianAxisConfig";
9
+ import { chartChildrenMap, ChartSize, getDataKeys } from "./chartConstants";
10
+ import { chartPropertyView } from "./chartPropertyView";
11
+ import _ from "lodash";
12
+ import { useContext, useEffect, useMemo, useRef, useState } from "react";
13
+ import ReactResizeDetector from "react-resize-detector";
14
+ import ReactECharts from "./reactEcharts";
15
+ import {
16
+ childrenToProps,
17
+ depsConfig,
18
+ genRandomKey,
19
+ JSONObject,
20
+ JSONValue,
21
+ NameConfig,
22
+ ToViewReturn,
23
+ UICompBuilder,
24
+ withDefault,
25
+ withExposingConfigs,
26
+ withMethodExposing,
27
+ withViewFn,
28
+ ThemeContext,
29
+ chartColorPalette,
30
+ getPromiseAfterDispatch,
31
+ } from "lowcoder-sdk";
32
+ import { getEchartsLocale, trans } from "i18n/comps";
33
+ import { ItemColorComp } from "comps/chartComp/chartConfigs/lineChartConfig";
34
+ import {
35
+ echartsConfigOmitChildren,
36
+ getEchartsConfig,
37
+ getSelectedPoints,
38
+ loadGoogleMapsScript,
39
+ } from "comps/chartComp/chartUtils";
40
+ import 'echarts-extension-gmap';
41
+ import log from "loglevel";
42
+
43
+ let clickEventCallback = () => {};
44
+
45
+ let ChartTmpComp = (function () {
46
+ return new UICompBuilder(chartChildrenMap, () => null)
47
+ .setPropertyViewFn(chartPropertyView)
48
+ .build();
49
+ })();
50
+
51
+ ChartTmpComp = withViewFn(ChartTmpComp, (comp) => {
52
+ const apiKey = comp.children.mapApiKey.getView();
53
+ const mode = comp.children.mode.getView();
54
+ const mapCenterPosition = {
55
+ lng: comp.children.mapCenterLng.getView(),
56
+ lat: comp.children.mapCenterLat.getView(),
57
+ }
58
+ const mapZoomlevel = comp.children.mapZoomLevel.getView();
59
+ const onUIEvent = comp.children.onUIEvent.getView();
60
+ const onMapEvent = comp.children.onMapEvent.getView();
61
+ const onEvent = comp.children.onEvent.getView();
62
+
63
+ const echartsCompRef = useRef<ReactECharts | null>();
64
+ const [chartSize, setChartSize] = useState<ChartSize>();
65
+ const [mapScriptLoaded, setMapScriptLoaded] = useState(false);
66
+ const firstResize = useRef(true);
67
+ const theme = useContext(ThemeContext);
68
+ const defaultChartTheme = {
69
+ color: chartColorPalette,
70
+ backgroundColor: "#fff",
71
+ };
72
+
73
+ let themeConfig = defaultChartTheme;
74
+ try {
75
+ themeConfig = theme?.theme.chart ? JSON.parse(theme?.theme.chart) : defaultChartTheme;
76
+ } catch (error) {
77
+ log.error('theme chart error: ', error);
78
+ }
79
+
80
+ const triggerClickEvent = async (dispatch: any, action: CompAction<JSONValue>) => {
81
+ await getPromiseAfterDispatch(
82
+ dispatch,
83
+ action,
84
+ { autoHandleAfterReduce: true }
85
+ );
86
+ onEvent('click');
87
+ }
88
+
89
+ useEffect(() => {
90
+ // click events for JSON/Map mode
91
+ if (mode === 'ui') return;
92
+
93
+ const echartsCompInstance = echartsCompRef?.current?.getEchartsInstance();
94
+ if (!echartsCompInstance) {
95
+ return _.noop;
96
+ }
97
+ echartsCompInstance?.on("click", (param: any) => {
98
+ document.dispatchEvent(new CustomEvent("clickEvent", {
99
+ bubbles: true,
100
+ detail: {
101
+ action: 'click',
102
+ data: param.data,
103
+ }
104
+ }));
105
+ triggerClickEvent(
106
+ comp.dispatch,
107
+ changeChildAction("lastInteractionData", param.data, false)
108
+ );
109
+ });
110
+ return () => {
111
+ echartsCompInstance?.off("click");
112
+ document.removeEventListener('clickEvent', clickEventCallback)
113
+ };
114
+ }, [mode, mapScriptLoaded]);
115
+
116
+ useEffect(() => {
117
+ // click events for UI mode
118
+ if(mode !== 'ui') return;
119
+
120
+ // bind events
121
+ const echartsCompInstance = echartsCompRef?.current?.getEchartsInstance();
122
+ if (!echartsCompInstance) {
123
+ return _.noop;
124
+ }
125
+ echartsCompInstance?.on("selectchanged", (param: any) => {
126
+ const option: any = echartsCompInstance?.getOption();
127
+ //log.log("chart select change", param);
128
+ // trigger click event listener
129
+
130
+ document.dispatchEvent(new CustomEvent("clickEvent", {
131
+ bubbles: true,
132
+ detail: {
133
+ action: param.fromAction,
134
+ data: getSelectedPoints(param, option)
135
+ }
136
+ }));
137
+
138
+ if (param.fromAction === "select") {
139
+ comp.dispatch(changeChildAction("selectedPoints", getSelectedPoints(param, option), false));
140
+ onUIEvent("select");
141
+ } else if (param.fromAction === "unselect") {
142
+ comp.dispatch(changeChildAction("selectedPoints", getSelectedPoints(param, option), false));
143
+ onUIEvent("unselect");
144
+ }
145
+
146
+ triggerClickEvent(
147
+ comp.dispatch,
148
+ changeChildAction("lastInteractionData", getSelectedPoints(param, option), false)
149
+ );
150
+ });
151
+ // unbind
152
+ return () => {
153
+ echartsCompInstance?.off("selectchanged");
154
+ document.removeEventListener('clickEvent', clickEventCallback)
155
+ };
156
+ }, [mode, onUIEvent]);
157
+
158
+ const echartsConfigChildren = _.omit(comp.children, echartsConfigOmitChildren);
159
+ const option = useMemo(() => {
160
+ return getEchartsConfig(
161
+ childrenToProps(echartsConfigChildren) as ToViewReturn<typeof echartsConfigChildren>,
162
+ chartSize
163
+ );
164
+ }, [chartSize, ...Object.values(echartsConfigChildren)]);
165
+
166
+ const isMapScriptLoaded = useMemo(() => {
167
+ return mapScriptLoaded || window?.google;
168
+ }, [mapScriptLoaded])
169
+
170
+ const loadGoogleMapData = () => {
171
+ const echartsCompInstance = echartsCompRef?.current?.getEchartsInstance();
172
+ if (!echartsCompInstance) {
173
+ return _.noop;
174
+ }
175
+
176
+ comp.children.mapInstance.dispatch(changeValueAction(echartsCompInstance))
177
+ onMapEvent('mapReady')
178
+ }
179
+
180
+ const handleOnMapScriptLoad = () => {
181
+ setMapScriptLoaded(true);
182
+ setTimeout(() => {
183
+ loadGoogleMapData();
184
+ })
185
+ }
186
+
187
+ useEffect(() => {
188
+ if( mode !== 'map') {
189
+ comp.children.mapInstance.dispatch(changeValueAction(null, false))
190
+ return;
191
+ }
192
+
193
+ if(comp.children.mapInstance.value) return;
194
+
195
+ const gMapScript = loadGoogleMapsScript(apiKey);
196
+ if(isMapScriptLoaded) {
197
+ handleOnMapScriptLoad();
198
+ return;
199
+ }
200
+ gMapScript.addEventListener('load', handleOnMapScriptLoad);
201
+ return () => {
202
+ gMapScript.removeEventListener('load', handleOnMapScriptLoad);
203
+ }
204
+ }, [mode, apiKey, option])
205
+
206
+ useEffect(() => {
207
+ if(mode !== 'map') return;
208
+ onMapEvent('centerPositionChange');
209
+ }, [mode, mapCenterPosition.lat, mapCenterPosition.lng])
210
+
211
+ useEffect(() => {
212
+ if(mode !== 'map') return;
213
+ onMapEvent('zoomLevelChange');
214
+ }, [mode, mapZoomlevel])
215
+
216
+ return (
217
+ <ReactResizeDetector
218
+ onResize={(w, h) => {
219
+ if (w && h) {
220
+ setChartSize({ w: w, h: h });
221
+ }
222
+ if (!firstResize.current) {
223
+ // ignore the first resize, which will impact the loading animation
224
+ echartsCompRef.current?.getEchartsInstance().resize();
225
+ } else {
226
+ firstResize.current = false;
227
+ }
228
+ }}
229
+ >
230
+ {(mode !== 'map' || (mode === 'map' && isMapScriptLoaded)) && (
231
+ <ReactECharts
232
+ ref={(e) => (echartsCompRef.current = e)}
233
+ style={{ height: "100%" }}
234
+ notMerge
235
+ lazyUpdate
236
+ opts={{ locale: getEchartsLocale() }}
237
+ option={option}
238
+ theme={mode !== 'map' ? themeConfig : undefined}
239
+ mode={mode}
240
+ />
241
+ )}
242
+ </ReactResizeDetector>
243
+ );
244
+ });
245
+
246
+ function getYAxisFormatContextValue(
247
+ data: Array<JSONObject>,
248
+ yAxisType: EchartsAxisType,
249
+ yAxisName?: string
250
+ ) {
251
+ const dataSample = yAxisName && data.length > 0 && data[0][yAxisName];
252
+ let contextValue = dataSample;
253
+ if (yAxisType === "time") {
254
+ // to timestamp
255
+ const time =
256
+ typeof dataSample === "number" || typeof dataSample === "string"
257
+ ? new Date(dataSample).getTime()
258
+ : null;
259
+ if (time) contextValue = time;
260
+ }
261
+ return contextValue;
262
+ }
263
+
264
+ ChartTmpComp = class extends ChartTmpComp {
265
+ private lastYAxisFormatContextVal?: JSONValue;
266
+ private lastColorContext?: JSONObject;
267
+
268
+ updateContext(comp: this) {
269
+ // the context value of axis format
270
+ let resultComp = comp;
271
+ const data = comp.children.data.getView();
272
+ const sampleSeries = comp.children.series.getView().find((s) => !s.getView().hide);
273
+ const yAxisContextValue = getYAxisFormatContextValue(
274
+ data,
275
+ comp.children.yConfig.children.yAxisType.getView(),
276
+ sampleSeries?.children.columnName.getView()
277
+ );
278
+ if (yAxisContextValue !== comp.lastYAxisFormatContextVal) {
279
+ comp.lastYAxisFormatContextVal = yAxisContextValue;
280
+ resultComp = comp.setChild(
281
+ "yConfig",
282
+ comp.children.yConfig.reduce(
283
+ wrapChildAction(
284
+ "formatter",
285
+ AxisFormatterComp.changeContextDataAction({ value: yAxisContextValue })
286
+ )
287
+ )
288
+ );
289
+ }
290
+ // item color context
291
+ const colorContextVal = {
292
+ seriesName: sampleSeries?.children.seriesName.getView(),
293
+ value: yAxisContextValue,
294
+ };
295
+ if (
296
+ comp.children.chartConfig.children.comp.children.hasOwnProperty("itemColor") &&
297
+ !_.isEqual(colorContextVal, comp.lastColorContext)
298
+ ) {
299
+ comp.lastColorContext = colorContextVal;
300
+ resultComp = resultComp.setChild(
301
+ "chartConfig",
302
+ comp.children.chartConfig.reduce(
303
+ wrapChildAction(
304
+ "comp",
305
+ wrapChildAction("itemColor", ItemColorComp.changeContextDataAction(colorContextVal))
306
+ )
307
+ )
308
+ );
309
+ }
310
+ return resultComp;
311
+ }
312
+
313
+ override reduce(action: CompAction): this {
314
+ const comp = super.reduce(action);
315
+ if (action.type === CompActionTypes.UPDATE_NODES_V2) {
316
+ const newData = comp.children.data.getView();
317
+ // data changes
318
+ if (comp.children.data !== this.children.data) {
319
+ setTimeout(() => {
320
+ // update x-axis value
321
+ const keys = getDataKeys(newData);
322
+ if (keys.length > 0 && !keys.includes(comp.children.xAxisKey.getView())) {
323
+ comp.children.xAxisKey.dispatch(changeValueAction(keys[0] || ""));
324
+ }
325
+ // pass to child series comp
326
+ comp.children.series.dispatchDataChanged(newData);
327
+ }, 0);
328
+ }
329
+ return this.updateContext(comp);
330
+ }
331
+ return comp;
332
+ }
333
+
334
+ override autoHeight(): boolean {
335
+ return false;
336
+ }
337
+ };
338
+
339
+ let ChartComp = withExposingConfigs(ChartTmpComp, [
340
+ depsConfig({
341
+ name: "selectedPoints",
342
+ desc: trans("chart.selectedPointsDesc"),
343
+ depKeys: ["selectedPoints"],
344
+ func: (input) => {
345
+ return input.selectedPoints;
346
+ },
347
+ }),
348
+ depsConfig({
349
+ name: "lastInteractionData",
350
+ desc: trans("chart.lastInteractionDataDesc"),
351
+ depKeys: ["lastInteractionData"],
352
+ func: (input) => {
353
+ return input.lastInteractionData;
354
+ },
355
+ }),
356
+ depsConfig({
357
+ name: "data",
358
+ desc: trans("chart.dataDesc"),
359
+ depKeys: ["data", "mode"],
360
+ func: (input) => {
361
+ if (input.mode === "ui") {
362
+ return input.data;
363
+ } else {
364
+ // no data in json mode
365
+ return [];
366
+ }
367
+ },
368
+ }),
369
+ new NameConfig("title", trans("chart.titleDesc")),
370
+ ]);
371
+
372
+ ChartComp = withMethodExposing(ChartComp, [
373
+ {
374
+ method: {
375
+ name: "getMapInstance",
376
+ },
377
+ execute: (comp) => {
378
+ return new Promise(resolve => {
379
+ let intervalCount = 0;
380
+ const mapInstanceInterval = setInterval(() => {
381
+ const instance = comp.children.mapInstance.getView();
382
+ const mapInstance = instance?.getModel()?.getComponent("gmap")?.getGoogleMap()
383
+ if(mapInstance || intervalCount === 10) {
384
+ clearInterval(mapInstanceInterval)
385
+ resolve(mapInstance)
386
+ }
387
+ intervalCount++;
388
+ }, 1000);
389
+ })
390
+ }
391
+ },
392
+ {
393
+ method: {
394
+ name: "getMapZoomLevel",
395
+ },
396
+ execute: (comp) => {
397
+ return comp.children.mapZoomLevel.getView();
398
+ }
399
+ },
400
+ {
401
+ method: {
402
+ name: "getMapCenterPosition",
403
+ },
404
+ execute: (comp) => {
405
+ return Promise.resolve({
406
+ lng: comp.children.mapCenterLng.getView(),
407
+ lat: comp.children.mapCenterLat.getView(),
408
+ });
409
+ }
410
+ },
411
+ {
412
+ method: {
413
+ name: "onClick",
414
+ params: [
415
+ {
416
+ name: "callback",
417
+ type: "function",
418
+ },
419
+ ],
420
+ },
421
+ execute: (comp, params) => {
422
+ clickEventCallback = params[0];
423
+ document.addEventListener('clickEvent', clickEventCallback);
424
+ }
425
+ },
426
+ ])
427
+
428
+ export const ChartCompWithDefault = withDefault(ChartComp, {
429
+ xAxisKey: "date",
430
+ series: [
431
+ {
432
+ dataIndex: genRandomKey(),
433
+ seriesName: trans("chart.spending"),
434
+ columnName: "spending",
435
+ },
436
+ {
437
+ dataIndex: genRandomKey(),
438
+ seriesName: trans("chart.budget"),
439
+ columnName: "budget",
440
+ },
441
+ ],
442
+ });
@@ -0,0 +1,51 @@
1
+ import {
2
+ BoolControl,
3
+ dropdownControl,
4
+ MultiCompBuilder,
5
+ showLabelPropertyView,
6
+ } from "lowcoder-sdk";
7
+ import { BarSeriesOption } from "echarts";
8
+ import { trans } from "i18n/comps";
9
+
10
+ const BarTypeOptions = [
11
+ {
12
+ label: trans("chart.basicBar"),
13
+ value: "basicBar",
14
+ },
15
+ {
16
+ label: trans("chart.stackedBar"),
17
+ value: "stackedBar",
18
+ },
19
+ ] as const;
20
+
21
+ export const BarChartConfig = (function () {
22
+ return new MultiCompBuilder(
23
+ {
24
+ showLabel: BoolControl,
25
+ type: dropdownControl(BarTypeOptions, "basicBar"),
26
+ },
27
+ (props): BarSeriesOption => {
28
+ const config: BarSeriesOption = {
29
+ type: "bar",
30
+ label: {
31
+ show: props.showLabel,
32
+ position: "top",
33
+ },
34
+ };
35
+ if (props.type === "stackedBar") {
36
+ config.stack = "stackValue";
37
+ }
38
+ return config;
39
+ }
40
+ )
41
+ .setPropertyViewFn((children) => (
42
+ <>
43
+ {showLabelPropertyView(children)}
44
+ {children.type.propertyView({
45
+ label: trans("chart.barType"),
46
+ radioButton: true,
47
+ })}
48
+ </>
49
+ ))
50
+ .build();
51
+ })();