@saltcorn/builder 1.1.0-beta.0 → 1.1.0-beta.2
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/dist/builder_bundle.js +1 -1
- package/dist/builder_bundle.js.LICENSE.txt +96 -0
- package/package.json +2 -2
- package/src/components/Builder.js +4 -5
- package/src/components/Library.js +5 -0
- package/src/components/RenderNode.js +1 -1
- package/src/components/elements/Clone.js +57 -0
- package/src/components/elements/Container.js +65 -6
- package/src/components/elements/utils.js +46 -48
- package/src/components/storage.js +2 -0
- package/webpack.config.js +7 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*
|
|
2
|
+
object-assign
|
|
3
|
+
(c) Sindre Sorhus
|
|
4
|
+
@license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/*!
|
|
8
|
+
Copyright (c) 2017 Jed Watson.
|
|
9
|
+
Licensed under the MIT License (MIT), see
|
|
10
|
+
http://jedwatson.github.io/classnames
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/*!
|
|
14
|
+
* Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com
|
|
15
|
+
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/*! *****************************************************************************
|
|
19
|
+
Copyright (c) Microsoft Corporation.
|
|
20
|
+
|
|
21
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
22
|
+
purpose with or without fee is hereby granted.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
25
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
26
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
27
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
28
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
29
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
30
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
31
|
+
***************************************************************************** */
|
|
32
|
+
|
|
33
|
+
/*! *****************************************************************************
|
|
34
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
35
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
36
|
+
this file except in compliance with the License. You may obtain a copy of the
|
|
37
|
+
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
38
|
+
|
|
39
|
+
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
40
|
+
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
41
|
+
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
42
|
+
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
43
|
+
|
|
44
|
+
See the Apache Version 2.0 License for specific language governing permissions
|
|
45
|
+
and limitations under the License.
|
|
46
|
+
***************************************************************************** */
|
|
47
|
+
|
|
48
|
+
/*!*
|
|
49
|
+
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
|
|
50
|
+
* For licensing, see LICENSE.md.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @license
|
|
55
|
+
* Lodash <https://lodash.com/>
|
|
56
|
+
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
57
|
+
* Released under MIT license <https://lodash.com/license>
|
|
58
|
+
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
59
|
+
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/** @license React v0.19.1
|
|
63
|
+
* scheduler.production.min.js
|
|
64
|
+
*
|
|
65
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
66
|
+
*
|
|
67
|
+
* This source code is licensed under the MIT license found in the
|
|
68
|
+
* LICENSE file in the root directory of this source tree.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
/** @license React v16.13.1
|
|
72
|
+
* react-dom.production.min.js
|
|
73
|
+
*
|
|
74
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
75
|
+
*
|
|
76
|
+
* This source code is licensed under the MIT license found in the
|
|
77
|
+
* LICENSE file in the root directory of this source tree.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/** @license React v16.13.1
|
|
81
|
+
* react-is.production.min.js
|
|
82
|
+
*
|
|
83
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
84
|
+
*
|
|
85
|
+
* This source code is licensed under the MIT license found in the
|
|
86
|
+
* LICENSE file in the root directory of this source tree.
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/** @license React v16.13.1
|
|
90
|
+
* react.production.min.js
|
|
91
|
+
*
|
|
92
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
93
|
+
*
|
|
94
|
+
* This source code is licensed under the MIT license found in the
|
|
95
|
+
* LICENSE file in the root directory of this source tree.
|
|
96
|
+
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/builder",
|
|
3
|
-
"version": "1.1.0-beta.
|
|
3
|
+
"version": "1.1.0-beta.2",
|
|
4
4
|
"description": "Drag and drop view builder for Saltcorn, open-source no-code platform",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"homepage": "https://saltcorn.com",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@babel/preset-react": "7.24.7",
|
|
21
21
|
"@craftjs/core": "0.1.0-beta.20",
|
|
22
22
|
"@craftjs/utils": "0.1.0-beta.20",
|
|
23
|
-
"@saltcorn/common-code": "1.1.0-beta.
|
|
23
|
+
"@saltcorn/common-code": "1.1.0-beta.2",
|
|
24
24
|
"saltcorn-craft-layers-noeye": "0.1.0-beta.22",
|
|
25
25
|
"@fonticonpicker/react-fonticonpicker": "1.2.0",
|
|
26
26
|
"@fortawesome/fontawesome-svg-core": "1.2.34",
|
|
@@ -60,15 +60,13 @@ import {
|
|
|
60
60
|
faCaretSquareLeft,
|
|
61
61
|
faCaretSquareRight,
|
|
62
62
|
} from "@fortawesome/free-regular-svg-icons";
|
|
63
|
-
import {
|
|
64
|
-
Accordion,
|
|
65
|
-
ErrorBoundary,
|
|
66
|
-
recursivelyCloneToElems,
|
|
67
|
-
} from "./elements/utils";
|
|
63
|
+
import { Accordion, ErrorBoundary } from "./elements/utils";
|
|
68
64
|
import { InitNewElement, Library } from "./Library";
|
|
69
65
|
import { RenderNode } from "./RenderNode";
|
|
70
66
|
import { ListColumn } from "./elements/ListColumn";
|
|
71
67
|
import { ListColumns } from "./elements/ListColumns";
|
|
68
|
+
import { recursivelyCloneToElems } from "./elements/Clone";
|
|
69
|
+
|
|
72
70
|
const { Provider } = optionsCtx;
|
|
73
71
|
|
|
74
72
|
/**
|
|
@@ -208,6 +206,7 @@ const SettingsPanel = () => {
|
|
|
208
206
|
sibIx + 1
|
|
209
207
|
);
|
|
210
208
|
};
|
|
209
|
+
|
|
211
210
|
return (
|
|
212
211
|
<div className="settings-panel card mt-1">
|
|
213
212
|
<div className="card-header px-2 py-1">
|
|
@@ -142,6 +142,11 @@ const InitNewElement = ({ nodekeys, savingState, setSavingState }) => {
|
|
|
142
142
|
}
|
|
143
143
|
});
|
|
144
144
|
};
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
window.addEventListener("beforeunload", () => doSave(query));
|
|
147
|
+
window.addEventListener("blur", () => doSave(query));
|
|
148
|
+
window.addEventListener("pagehide", () => doSave(query));
|
|
149
|
+
}, []);
|
|
145
150
|
const throttledSave = useThrottle(() => {
|
|
146
151
|
doSave(query);
|
|
147
152
|
});
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
faArrowUp,
|
|
18
18
|
faArrowsAlt,
|
|
19
19
|
} from "@fortawesome/free-solid-svg-icons";
|
|
20
|
-
import { recursivelyCloneToElems } from "./elements/
|
|
20
|
+
import { recursivelyCloneToElems } from "./elements/Clone";
|
|
21
21
|
/*
|
|
22
22
|
Contains code copied from craft.js landing page example
|
|
23
23
|
Copyright (c) 2020 Previnash Wong Sze Chuan
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React, { Fragment, useState, useEffect } from "react";
|
|
2
|
+
import { ListColumn } from "./ListColumn";
|
|
3
|
+
import { Columns, ntimes } from "./Columns";
|
|
4
|
+
import { rand_ident } from "./utils";
|
|
5
|
+
import { Element } from "@craftjs/core";
|
|
6
|
+
|
|
7
|
+
export const recursivelyCloneToElems = (query) => (nodeId, ix) => {
|
|
8
|
+
const { data } = query.node(nodeId).get();
|
|
9
|
+
const { type, props, nodes } = data;
|
|
10
|
+
const newProps = { ...props };
|
|
11
|
+
if (newProps.rndid) {
|
|
12
|
+
newProps.rndid = rand_ident();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// console.log("cloning", data.displayName, data.linkedNodes["listcol"]);
|
|
16
|
+
|
|
17
|
+
const children = (nodes || []).map(recursivelyCloneToElems(query));
|
|
18
|
+
if (data.displayName === "Columns") {
|
|
19
|
+
const cols = ntimes(data.props.ncols, (ix) =>
|
|
20
|
+
recursivelyCloneToElems(query)(data.linkedNodes["Col" + ix])
|
|
21
|
+
);
|
|
22
|
+
return React.createElement(Columns, {
|
|
23
|
+
...newProps,
|
|
24
|
+
...(typeof ix !== "undefined" ? { key: ix } : {}),
|
|
25
|
+
contents: cols,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (data.displayName === "ListColumn") {
|
|
30
|
+
const col = recursivelyCloneToElems(query)(data.linkedNodes["listcol"]);
|
|
31
|
+
|
|
32
|
+
return React.createElement(ListColumn, {
|
|
33
|
+
...newProps,
|
|
34
|
+
contents: col,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (data.isCanvas)
|
|
39
|
+
return React.createElement(
|
|
40
|
+
Element,
|
|
41
|
+
{
|
|
42
|
+
...newProps,
|
|
43
|
+
canvas: true,
|
|
44
|
+
is: type,
|
|
45
|
+
...(typeof ix !== "undefined" ? { key: ix } : {}),
|
|
46
|
+
},
|
|
47
|
+
children
|
|
48
|
+
);
|
|
49
|
+
return React.createElement(
|
|
50
|
+
type,
|
|
51
|
+
{
|
|
52
|
+
...newProps,
|
|
53
|
+
...(typeof ix !== "undefined" ? { key: ix } : {}),
|
|
54
|
+
},
|
|
55
|
+
children
|
|
56
|
+
);
|
|
57
|
+
};
|
|
@@ -108,6 +108,7 @@ const Container = ({
|
|
|
108
108
|
rotate,
|
|
109
109
|
style,
|
|
110
110
|
htmlElement,
|
|
111
|
+
transform,
|
|
111
112
|
}) => {
|
|
112
113
|
const {
|
|
113
114
|
selected,
|
|
@@ -125,7 +126,7 @@ const Container = ({
|
|
|
125
126
|
} ${selected ? "selected-node" : ""}`,
|
|
126
127
|
style: {
|
|
127
128
|
...parseStyles(customCSS || ""),
|
|
128
|
-
...reactifyStyles(style),
|
|
129
|
+
...reactifyStyles(style, transform, rotate),
|
|
129
130
|
display,
|
|
130
131
|
//padding: padding.map((p) => p + "px").join(" "),
|
|
131
132
|
//margin: margin.map((p) => p + "px").join(" "),
|
|
@@ -166,11 +167,6 @@ const Container = ({
|
|
|
166
167
|
width: `${width}${widthUnit || "px"}`,
|
|
167
168
|
}
|
|
168
169
|
: {}),
|
|
169
|
-
...(rotate
|
|
170
|
-
? {
|
|
171
|
-
transform: `rotate(${rotate}deg)`,
|
|
172
|
-
}
|
|
173
|
-
: {}),
|
|
174
170
|
},
|
|
175
171
|
},
|
|
176
172
|
children
|
|
@@ -221,6 +217,7 @@ const ContainerSettings = () => {
|
|
|
221
217
|
rotate: node.data.props.rotate,
|
|
222
218
|
display: node.data.props.display,
|
|
223
219
|
style: node.data.props.style,
|
|
220
|
+
transform: node.data.props.transform,
|
|
224
221
|
imgResponsiveWidths: node.data.props.imgResponsiveWidths,
|
|
225
222
|
click_action: node.data.props.click_action,
|
|
226
223
|
}));
|
|
@@ -254,6 +251,7 @@ const ContainerSettings = () => {
|
|
|
254
251
|
imgResponsiveWidths,
|
|
255
252
|
click_action,
|
|
256
253
|
style,
|
|
254
|
+
transform,
|
|
257
255
|
} = node;
|
|
258
256
|
const options = useContext(optionsCtx);
|
|
259
257
|
const { uploadedFiles } = useContext(previewCtx);
|
|
@@ -265,6 +263,8 @@ const ContainerSettings = () => {
|
|
|
265
263
|
* @returns {function}
|
|
266
264
|
*/
|
|
267
265
|
const setAProp = setAPropGen(setProp);
|
|
266
|
+
//console.log("transform", transform);
|
|
267
|
+
|
|
268
268
|
return (
|
|
269
269
|
<Accordion>
|
|
270
270
|
<div accordiontitle="Box" className="w-100">
|
|
@@ -676,6 +676,65 @@ const ContainerSettings = () => {
|
|
|
676
676
|
)}
|
|
677
677
|
</tbody>
|
|
678
678
|
</table>
|
|
679
|
+
<table className="w-100" accordiontitle="Transform">
|
|
680
|
+
<tbody>
|
|
681
|
+
<SettingsRow
|
|
682
|
+
field={{
|
|
683
|
+
name: "rotate",
|
|
684
|
+
label: "Rotate°",
|
|
685
|
+
type: "Integer",
|
|
686
|
+
}}
|
|
687
|
+
node={node}
|
|
688
|
+
setProp={setProp}
|
|
689
|
+
/>
|
|
690
|
+
<SettingsRow
|
|
691
|
+
field={{ name: "skewX", label: "SkewX°", type: "Integer" }}
|
|
692
|
+
node={node}
|
|
693
|
+
setProp={setProp}
|
|
694
|
+
subProp="transform"
|
|
695
|
+
valuePostfix="deg"
|
|
696
|
+
/>
|
|
697
|
+
<SettingsRow
|
|
698
|
+
field={{ name: "skewY", label: "SkewY°", type: "Integer" }}
|
|
699
|
+
node={node}
|
|
700
|
+
setProp={setProp}
|
|
701
|
+
subProp="transform"
|
|
702
|
+
valuePostfix="deg"
|
|
703
|
+
/>
|
|
704
|
+
<SettingsRow
|
|
705
|
+
field={{ name: "scaleX", label: "ScaleX", type: "Float" }}
|
|
706
|
+
node={node}
|
|
707
|
+
setProp={setProp}
|
|
708
|
+
subProp="transform"
|
|
709
|
+
/>
|
|
710
|
+
<SettingsRow
|
|
711
|
+
field={{ name: "scaleY", label: "ScaleY", type: "Float" }}
|
|
712
|
+
node={node}
|
|
713
|
+
setProp={setProp}
|
|
714
|
+
subProp="transform"
|
|
715
|
+
/>
|
|
716
|
+
<SettingsRow
|
|
717
|
+
field={{
|
|
718
|
+
name: "translateX",
|
|
719
|
+
label: "TranslateX",
|
|
720
|
+
type: "DimUnits",
|
|
721
|
+
}}
|
|
722
|
+
node={node}
|
|
723
|
+
setProp={setProp}
|
|
724
|
+
subProp="transform"
|
|
725
|
+
/>
|
|
726
|
+
<SettingsRow
|
|
727
|
+
field={{
|
|
728
|
+
name: "translateY",
|
|
729
|
+
label: "TranslateY",
|
|
730
|
+
type: "DimUnits",
|
|
731
|
+
}}
|
|
732
|
+
node={node}
|
|
733
|
+
setProp={setProp}
|
|
734
|
+
subProp="transform"
|
|
735
|
+
/>
|
|
736
|
+
</tbody>
|
|
737
|
+
</table>
|
|
679
738
|
<table className="w-100" accordiontitle="Flex properties">
|
|
680
739
|
<tbody>
|
|
681
740
|
<SettingsSectionHeaderRow title="Flex item" />
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
} from "@fortawesome/free-solid-svg-icons";
|
|
22
22
|
import { useNode, Element } from "@craftjs/core";
|
|
23
23
|
import FontIconPicker from "@fonticonpicker/react-fonticonpicker";
|
|
24
|
-
import { Columns, ntimes } from "./Columns";
|
|
25
24
|
import Tippy from "@tippyjs/react";
|
|
26
25
|
import { RelationType } from "@saltcorn/common-code";
|
|
27
26
|
import Select from "react-select";
|
|
@@ -666,7 +665,7 @@ export const parseStyles = (styles) =>
|
|
|
666
665
|
* @param {object} styles
|
|
667
666
|
* @returns {object}
|
|
668
667
|
*/
|
|
669
|
-
export const reactifyStyles = (styles) => {
|
|
668
|
+
export const reactifyStyles = (styles, transform, rotate) => {
|
|
670
669
|
const toCamel = (s) => {
|
|
671
670
|
return s.replace(/([-][a-z])/gi, ($1) => {
|
|
672
671
|
return $1.toUpperCase().replace("-", "");
|
|
@@ -676,6 +675,17 @@ export const reactifyStyles = (styles) => {
|
|
|
676
675
|
Object.keys(styles).forEach((k) => {
|
|
677
676
|
reactified[toCamel(k)] = styles[k];
|
|
678
677
|
});
|
|
678
|
+
if (transform) {
|
|
679
|
+
reactified.transform = Object.entries(transform)
|
|
680
|
+
.filter(([k, v]) => v !== "")
|
|
681
|
+
.map(([k, v]) => `${k}(${v})`)
|
|
682
|
+
.join(" ");
|
|
683
|
+
}
|
|
684
|
+
if (rotate) {
|
|
685
|
+
if (!reactified.transform) reactified.transform = `rotate(${rotate}deg)`;
|
|
686
|
+
else reactified.transform = `${reactified.transform} rotate(${rotate}deg)`;
|
|
687
|
+
}
|
|
688
|
+
|
|
679
689
|
return reactified;
|
|
680
690
|
};
|
|
681
691
|
|
|
@@ -831,6 +841,8 @@ const ConfigField = ({
|
|
|
831
841
|
props,
|
|
832
842
|
setter,
|
|
833
843
|
isStyle,
|
|
844
|
+
subProp,
|
|
845
|
+
valuePostfix,
|
|
834
846
|
}) => {
|
|
835
847
|
/**
|
|
836
848
|
* @param {object} v
|
|
@@ -838,7 +850,8 @@ const ConfigField = ({
|
|
|
838
850
|
*/
|
|
839
851
|
const options = React.useContext(optionsCtx);
|
|
840
852
|
|
|
841
|
-
const myOnChange = (
|
|
853
|
+
const myOnChange = (v0) => {
|
|
854
|
+
const v = valuePostfix && (v0 || v0 === 0) ? v0 + valuePostfix : v0;
|
|
842
855
|
setProp((prop) => {
|
|
843
856
|
if (setter) setter(prop, field.name, v);
|
|
844
857
|
else if (configuration) {
|
|
@@ -847,18 +860,25 @@ const ConfigField = ({
|
|
|
847
860
|
} else if (isStyle) {
|
|
848
861
|
if (!prop.style) prop.style = {};
|
|
849
862
|
prop.style[field.name] = v;
|
|
863
|
+
} else if (subProp) {
|
|
864
|
+
if (!prop[subProp]) prop[subProp] = {};
|
|
865
|
+
prop[subProp][field.name] = v;
|
|
850
866
|
} else prop[field.name] = v;
|
|
851
867
|
});
|
|
852
868
|
onChange && onChange(field.name, v, setProp);
|
|
853
869
|
};
|
|
854
|
-
|
|
870
|
+
let value = or_if_undef(
|
|
855
871
|
configuration
|
|
856
872
|
? configuration[field.name]
|
|
857
873
|
: isStyle
|
|
858
874
|
? props.style[field.name]
|
|
875
|
+
: subProp
|
|
876
|
+
? props[subProp]?.[field.name]
|
|
859
877
|
: props[field.name],
|
|
860
878
|
field.default
|
|
861
879
|
);
|
|
880
|
+
if (valuePostfix)
|
|
881
|
+
value = `${value}`.replaceAll(valuePostfix || "__nosuchstring", "");
|
|
862
882
|
if (field.input_type === "fromtype") field.input_type = null;
|
|
863
883
|
if (
|
|
864
884
|
field.type &&
|
|
@@ -1064,7 +1084,7 @@ const ConfigField = ({
|
|
|
1064
1084
|
if (isStyle && value === "auto") {
|
|
1065
1085
|
styleVal = "";
|
|
1066
1086
|
styleDim = "auto";
|
|
1067
|
-
} else if (isStyle && value && typeof value === "string") {
|
|
1087
|
+
} else if ((isStyle || subProp) && value && typeof value === "string") {
|
|
1068
1088
|
const matches = value.match(/^([-]?[0-9]+\.?[0-9]*)(.*)/);
|
|
1069
1089
|
if (matches) {
|
|
1070
1090
|
styleVal = matches[1];
|
|
@@ -1076,13 +1096,13 @@ const ConfigField = ({
|
|
|
1076
1096
|
{styleDim !== "auto" && (
|
|
1077
1097
|
<input
|
|
1078
1098
|
type="number"
|
|
1079
|
-
value={(isStyle ? styleVal : value) || ""}
|
|
1099
|
+
value={(isStyle || subProp ? styleVal : value) || ""}
|
|
1080
1100
|
className={`field-${field?.name} w-50 form-control-sm d-inline dimunit`}
|
|
1081
1101
|
disabled={field.autoable && styleDim === "auto"}
|
|
1082
1102
|
onChange={(e) =>
|
|
1083
1103
|
e?.target &&
|
|
1084
1104
|
myOnChange(
|
|
1085
|
-
isStyle
|
|
1105
|
+
isStyle || subProp
|
|
1086
1106
|
? `${e.target.value}${styleDim || "px"}`
|
|
1087
1107
|
: e.target.value
|
|
1088
1108
|
)
|
|
@@ -1093,7 +1113,7 @@ const ConfigField = ({
|
|
|
1093
1113
|
value={or_if_undef(
|
|
1094
1114
|
configuration
|
|
1095
1115
|
? configuration[field.name + "Unit"]
|
|
1096
|
-
: isStyle
|
|
1116
|
+
: isStyle || subProp
|
|
1097
1117
|
? styleDim
|
|
1098
1118
|
: props[field.name + "Unit"],
|
|
1099
1119
|
"px"
|
|
@@ -1118,6 +1138,13 @@ const ConfigField = ({
|
|
|
1118
1138
|
myStyleVal,
|
|
1119
1139
|
0
|
|
1120
1140
|
)}${target_value}`;
|
|
1141
|
+
}
|
|
1142
|
+
if (subProp) {
|
|
1143
|
+
if (!prop[subProp]) prop[subProp] = {};
|
|
1144
|
+
prop[subProp][field.name] = `${or_if_undef(
|
|
1145
|
+
myStyleVal,
|
|
1146
|
+
0
|
|
1147
|
+
)}${target_value}`;
|
|
1121
1148
|
} else prop[field.name + "Unit"] = target_value;
|
|
1122
1149
|
});
|
|
1123
1150
|
}}
|
|
@@ -1214,7 +1241,15 @@ export /**
|
|
|
1214
1241
|
* @subcategory components / elements / utils
|
|
1215
1242
|
* @namespace
|
|
1216
1243
|
*/
|
|
1217
|
-
const SettingsRow = ({
|
|
1244
|
+
const SettingsRow = ({
|
|
1245
|
+
field,
|
|
1246
|
+
node,
|
|
1247
|
+
setProp,
|
|
1248
|
+
onChange,
|
|
1249
|
+
isStyle,
|
|
1250
|
+
subProp,
|
|
1251
|
+
valuePostfix,
|
|
1252
|
+
}) => {
|
|
1218
1253
|
const fullWidth = ["String", "Bool", "textarea"].includes(field.type);
|
|
1219
1254
|
const needLabel = field.type !== "Bool";
|
|
1220
1255
|
const inner = field.canBeFormula ? (
|
|
@@ -1237,6 +1272,8 @@ const SettingsRow = ({ field, node, setProp, onChange, isStyle }) => {
|
|
|
1237
1272
|
setProp={setProp}
|
|
1238
1273
|
onChange={onChange}
|
|
1239
1274
|
isStyle={isStyle}
|
|
1275
|
+
subProp={subProp}
|
|
1276
|
+
valuePostfix={valuePostfix}
|
|
1240
1277
|
/>
|
|
1241
1278
|
);
|
|
1242
1279
|
return (
|
|
@@ -1528,45 +1565,6 @@ export const bstyleopt = (style) => ({
|
|
|
1528
1565
|
export const rand_ident = () =>
|
|
1529
1566
|
Math.floor(Math.random() * 16777215).toString(16);
|
|
1530
1567
|
|
|
1531
|
-
export const recursivelyCloneToElems = (query) => (nodeId, ix) => {
|
|
1532
|
-
const { data } = query.node(nodeId).get();
|
|
1533
|
-
const { type, props, nodes } = data;
|
|
1534
|
-
const newProps = { ...props };
|
|
1535
|
-
if (newProps.rndid) {
|
|
1536
|
-
newProps.rndid = rand_ident();
|
|
1537
|
-
}
|
|
1538
|
-
const children = (nodes || []).map(recursivelyCloneToElems(query));
|
|
1539
|
-
if (data.displayName === "Columns") {
|
|
1540
|
-
const cols = ntimes(data.props.ncols, (ix) =>
|
|
1541
|
-
recursivelyCloneToElems(query)(data.linkedNodes["Col" + ix])
|
|
1542
|
-
);
|
|
1543
|
-
return React.createElement(Columns, {
|
|
1544
|
-
...newProps,
|
|
1545
|
-
...(typeof ix !== "undefined" ? { key: ix } : {}),
|
|
1546
|
-
contents: cols,
|
|
1547
|
-
});
|
|
1548
|
-
}
|
|
1549
|
-
if (data.isCanvas)
|
|
1550
|
-
return React.createElement(
|
|
1551
|
-
Element,
|
|
1552
|
-
{
|
|
1553
|
-
...newProps,
|
|
1554
|
-
canvas: true,
|
|
1555
|
-
is: type,
|
|
1556
|
-
...(typeof ix !== "undefined" ? { key: ix } : {}),
|
|
1557
|
-
},
|
|
1558
|
-
children
|
|
1559
|
-
);
|
|
1560
|
-
return React.createElement(
|
|
1561
|
-
type,
|
|
1562
|
-
{
|
|
1563
|
-
...newProps,
|
|
1564
|
-
...(typeof ix !== "undefined" ? { key: ix } : {}),
|
|
1565
|
-
},
|
|
1566
|
-
children
|
|
1567
|
-
);
|
|
1568
|
-
};
|
|
1569
|
-
|
|
1570
1568
|
export const isBlock = (block, inline, textStyle) =>
|
|
1571
1569
|
!textStyle ||
|
|
1572
1570
|
!textStyleToArray(textStyle).some((ts) => ts && ts.startsWith("h"))
|
|
@@ -246,6 +246,7 @@ const layoutToNodes = (layout, query, actions, parent = "ROOT", options) => {
|
|
|
246
246
|
imgResponsiveWidths={segment.imgResponsiveWidths}
|
|
247
247
|
bgType={segment.bgType || "None"}
|
|
248
248
|
style={segment.style || {}}
|
|
249
|
+
transform={segment.transform || {}}
|
|
249
250
|
bgColor={segment.bgColor || "#ffffff"}
|
|
250
251
|
setTextColor={!!segment.setTextColor}
|
|
251
252
|
textColor={segment.textColor || "#000000"}
|
|
@@ -541,6 +542,7 @@ const craftToSaltcorn = (nodes, startFrom = "ROOT", options) => {
|
|
|
541
542
|
click_action: node.props.click_action,
|
|
542
543
|
rotate: node.props.rotate,
|
|
543
544
|
style: node.props.style,
|
|
545
|
+
transform: node.props.transform,
|
|
544
546
|
...customProps,
|
|
545
547
|
};
|
|
546
548
|
else return get_nodes(node);
|
package/webpack.config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
|
-
|
|
2
|
+
const webpack = require('webpack')
|
|
3
3
|
module.exports = {
|
|
4
4
|
module: {
|
|
5
5
|
rules: [
|
|
@@ -18,4 +18,10 @@ module.exports = {
|
|
|
18
18
|
//libraryTarget: 'window',
|
|
19
19
|
//libraryExport: 'default'
|
|
20
20
|
},
|
|
21
|
+
plugins: [
|
|
22
|
+
// fix "process is not defined" error:
|
|
23
|
+
new webpack.ProvidePlugin({
|
|
24
|
+
process: 'process/browser',
|
|
25
|
+
}),
|
|
26
|
+
]
|
|
21
27
|
};
|