@saltcorn/builder 0.6.0-alpha.0 → 0.6.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,253 @@
1
+ <style>
2
+ .boxmodel-container {
3
+ display: inline-flex;
4
+ flex-direction: column;
5
+ flex-flow: column wrap;
6
+ font-family: "Consolas", "Monaco", monospace;
7
+ font-size: 12px;
8
+ position: relative;
9
+ }
10
+ .boxmodel-container .boxmodel-info {
11
+ font-size: 10px;
12
+ font-family: Verdana;
13
+ font-style: normal;
14
+ text-align: left;
15
+ line-height: 14px;
16
+ margin: 2px 0 0 0;
17
+ padding: 0px;
18
+ margin-top: 2px;
19
+ }
20
+ .boxmodel-container div:not(.flex-row) {
21
+ box-sizing: border-box;
22
+ display: flex;
23
+ flex-direction: row;
24
+ align-items: center;
25
+ align-content: space-between;
26
+ padding: 0;
27
+ margin: 0;
28
+ }
29
+ .boxmodel-container span.boxmodel-text {
30
+ font-size: 8.5px;
31
+ font-family: Verdana, Geneva, sans-serif;
32
+ display: inline-block;
33
+ user-select: none;
34
+ }
35
+ .boxmodel-container span.boxmodel-text.boxmodel-header {
36
+ position: absolute;
37
+ top: 2px;
38
+ left: 2px;
39
+ color: #777;
40
+ }
41
+ .boxmodel-container .boxmodel-margin {
42
+ background: #ffffff;
43
+ border: 1px dashed #aaa;
44
+ position: relative;
45
+ }
46
+ .boxmodel-container .boxmodel-border {
47
+ background: #ddd;
48
+ border: 2px solid #aaa;
49
+ position: relative;
50
+ }
51
+ .boxmodel-container .boxmodel-padding {
52
+ background: #eee;
53
+ border: 1px dashed #aaa;
54
+ position: relative;
55
+ }
56
+ .boxmodel-container .boxmodel-content {
57
+ background: #fff;
58
+ height: 30px;
59
+ margin: 0;
60
+ border: 1px solid #aaa;
61
+ position: relative;
62
+ font-family: Verdana, Geneva, sans-serif;
63
+ font-size: 10px;
64
+ }
65
+ .boxmodel-container .flex-row {
66
+ text-align: center;
67
+ }
68
+ .boxmodel-container .boxmodel-input-direction-top,
69
+ .boxmodel-container .boxmodel-input-direction-bottom {
70
+ display: block;
71
+ padding: 0;
72
+ margin: 0;
73
+ line-height: 0;
74
+ }
75
+ .boxmodel-container .boxmodel-input-direction-right,
76
+ .boxmodel-container .boxmodel-input-direction-left {
77
+ position: relative;
78
+ }
79
+ .boxmodel-container input,
80
+ .boxmodel-container input:focus,
81
+ .boxmodel-container input:active {
82
+ background: transparent;
83
+ color: black;
84
+ font-size: 9px;
85
+ font-family: Verdana, Geneva, sans-serif;
86
+ box-shadow: none;
87
+ border: 1px solid transparent;
88
+ outline: none;
89
+ user-select: none;
90
+ margin: 0px;
91
+ padding: 1px;
92
+ text-align: center;
93
+ }
94
+ .boxmodel-chrome-skin .boxmodel-container .boxmodel-margin {
95
+ background: #f9cc9d;
96
+ border: 1px dashed #222;
97
+ }
98
+ .boxmodel-chrome-skin .boxmodel-container .boxmodel-border {
99
+ background: #ffeebc;
100
+ border: 1px solid #000;
101
+ }
102
+ .boxmodel-chrome-skin .boxmodel-container .boxmodel-padding {
103
+ background: #c3deb7;
104
+ border: 1px dashed #808080;
105
+ }
106
+ .boxmodel-chrome-skin .boxmodel-container .boxmodel-content {
107
+ background: #a0c5e8;
108
+ border: 1px solid #808080;
109
+ }
110
+ .boxmodel-chrome-skin .boxmodel-container .boxmodel-text {
111
+ color: black;
112
+ }
113
+ .boxmodel-chrome-skin .boxmodel-container .boxmodel-text.boxmodel-header {
114
+ color: black;
115
+ }
116
+ </style>
117
+
118
+ <div class="boxmodel-container boxmodel-chrome-skin">
119
+ <div class="boxmodel-container">
120
+ <div class="boxmodel-margin">
121
+ <span class="boxmodel-text boxmodel-header">Margin</span
122
+ ><span class="boxmodel-input-container boxmodel-input-direction-left"
123
+ ><input
124
+ disabled
125
+ type="text"
126
+ autocomplete="off"
127
+ name="boxmodel-ex-1_left_margin"
128
+ size="3"
129
+ /></span>
130
+ <div class="flex-row">
131
+ <span class="boxmodel-input-container boxmodel-input-direction-top"
132
+ ><input
133
+ disabled
134
+ type="text"
135
+ autocomplete="off"
136
+ name="boxmodel-ex-1_top_margin"
137
+ size="3"
138
+ /></span>
139
+ <div class="boxmodel-border">
140
+ <span class="boxmodel-text boxmodel-header">Border</span
141
+ ><span class="boxmodel-input-container boxmodel-input-direction-left"
142
+ ><input
143
+ disabled
144
+ type="text"
145
+ autocomplete="off"
146
+ name="boxmodel-ex-1_left_border"
147
+ size="3"
148
+ /></span>
149
+ <div class="flex-row">
150
+ <span class="boxmodel-input-container boxmodel-input-direction-top"
151
+ ><input
152
+ disabled
153
+ type="text"
154
+ autocomplete="off"
155
+ name="boxmodel-ex-1_top_border"
156
+ size="3"
157
+ /></span>
158
+ <div class="boxmodel-padding">
159
+ <span class="boxmodel-text boxmodel-header">Padding</span
160
+ ><span
161
+ class="boxmodel-input-container boxmodel-input-direction-left"
162
+ ><input
163
+ disabled
164
+ type="text"
165
+ autocomplete="off"
166
+ name="boxmodel-ex-1_left_padding"
167
+ size="3"
168
+ class=""
169
+ /></span>
170
+ <div class="flex-row">
171
+ <span
172
+ class="boxmodel-input-container boxmodel-input-direction-top"
173
+ ><input
174
+ disabled
175
+ type="text"
176
+ autocomplete="off"
177
+ name="boxmodel-ex-1_top_padding"
178
+ size="3"
179
+ /></span>
180
+ <div class="boxmodel-content">
181
+ <input
182
+ disabled
183
+ type="text"
184
+ autocomplete="off"
185
+ name="boxmodel-ex-1_width"
186
+ size="3"
187
+ />x<input
188
+ disabled
189
+ type="text"
190
+ autocomplete="off"
191
+ name="boxmodel-ex-1_height"
192
+ size="3"
193
+ />
194
+ </div>
195
+ <span
196
+ class="boxmodel-input-container boxmodel-input-direction-bottom"
197
+ ><input
198
+ disabled
199
+ type="text"
200
+ autocomplete="off"
201
+ name="boxmodel-ex-1_bottom_padding"
202
+ size="3"
203
+ /></span>
204
+ </div>
205
+ <span
206
+ class="boxmodel-input-container boxmodel-input-direction-right"
207
+ ><input
208
+ disabled
209
+ type="text"
210
+ autocomplete="off"
211
+ name="boxmodel-ex-1_right_padding"
212
+ size="3"
213
+ /></span>
214
+ </div>
215
+ <span
216
+ class="boxmodel-input-container boxmodel-input-direction-bottom"
217
+ ><input
218
+ disabled
219
+ type="text"
220
+ autocomplete="off"
221
+ name="boxmodel-ex-1_bottom_border"
222
+ size="3"
223
+ /></span>
224
+ </div>
225
+ <span class="boxmodel-input-container boxmodel-input-direction-right"
226
+ ><input
227
+ disabled
228
+ type="text"
229
+ autocomplete="off"
230
+ name="boxmodel-ex-1_right_border"
231
+ size="3"
232
+ /></span>
233
+ </div>
234
+ <span class="boxmodel-input-container boxmodel-input-direction-bottom"
235
+ ><input
236
+ disabled
237
+ type="text"
238
+ autocomplete="off"
239
+ name="boxmodel-ex-1_bottom_margin"
240
+ size="3"
241
+ /></span>
242
+ </div>
243
+ <span class="boxmodel-input-container boxmodel-input-direction-right"
244
+ ><input
245
+ disabled
246
+ type="text"
247
+ autocomplete="off"
248
+ name="boxmodel-ex-1_right_margin"
249
+ size="3"
250
+ /></span>
251
+ </div>
252
+ </div>
253
+ </div>
@@ -279,13 +279,14 @@ export const fetchViewPreview = (args = {}) => (changes = {}) => {
279
279
  });
280
280
  };
281
281
 
282
- export const SelectUnits = ({ vert, ...props }) => (
282
+ export const SelectUnits = ({ vert, autoable, ...props }) => (
283
283
  <select {...props}>
284
284
  <option>px</option>
285
285
  <option>%</option>
286
286
  <option>{vert ? "vh" : "vw"}</option>
287
287
  <option>em</option>
288
288
  <option>rem</option>
289
+ {autoable && <option>auto</option>}
289
290
  </select>
290
291
  );
291
292
 
@@ -309,6 +310,19 @@ export const parseStyles = (styles) =>
309
310
  }),
310
311
  {}
311
312
  );
313
+
314
+ export const reactifyStyles = (styles) => {
315
+ const toCamel = (s) => {
316
+ return s.replace(/([-][a-z])/gi, ($1) => {
317
+ return $1.toUpperCase().replace("-", "");
318
+ });
319
+ };
320
+ const reactified = {};
321
+ Object.keys(styles).forEach((k) => {
322
+ reactified[toCamel(k)] = styles[k];
323
+ });
324
+ return reactified;
325
+ };
312
326
  const isCheckbox = (f) =>
313
327
  f && f.type && (f.type === "Bool" || f.type.name === "Bool");
314
328
  export const setInitialConfig = (setProp, fieldview, fields) => {
@@ -320,6 +334,24 @@ export const setInitialConfig = (setProp, fieldview, fields) => {
320
334
  });
321
335
  });
322
336
  };
337
+
338
+ const ColorInput = ({ value, onChange }) =>
339
+ value ? (
340
+ <input
341
+ type="color"
342
+ value={value}
343
+ className="form-control"
344
+ onChange={(e) => e.target && onChange(e.target.value)}
345
+ />
346
+ ) : (
347
+ <button
348
+ className="btn btn-sm btn-outline-secondary"
349
+ onClick={() => onChange("#000000")}
350
+ >
351
+ <small>Set color</small>
352
+ </button>
353
+ );
354
+
323
355
  export const ConfigForm = ({
324
356
  fields,
325
357
  configuration,
@@ -365,18 +397,26 @@ export const ConfigField = ({
365
397
  setProp,
366
398
  onChange,
367
399
  props,
400
+ isStyle,
368
401
  }) => {
369
402
  const myOnChange = (v) => {
370
403
  setProp((prop) => {
371
404
  if (configuration) {
372
405
  if (!prop.configuration) prop.configuration = {};
373
406
  prop.configuration[field.name] = v;
407
+ } else if (isStyle) {
408
+ if (!prop.style) prop.style = {};
409
+ prop.style[field.name] = v;
374
410
  } else prop[field.name] = v;
375
411
  });
376
412
  onChange && onChange(field.name, v);
377
413
  };
378
414
  const value = or_if_undef(
379
- configuration ? configuration[field.name] : props[field.name],
415
+ configuration
416
+ ? configuration[field.name]
417
+ : isStyle
418
+ ? props.style[field.name]
419
+ : props[field.name],
380
420
  field.default
381
421
  );
382
422
  if (field.input_type === "fromtype") field.input_type = null;
@@ -412,14 +452,7 @@ export const ConfigField = ({
412
452
  onChange={(e) => e.target && myOnChange(e.target.value)}
413
453
  />
414
454
  ),
415
- Color: () => (
416
- <input
417
- type="color"
418
- value={value}
419
- className="form-control"
420
- onChange={(e) => e.target && myOnChange(e.target.value)}
421
- />
422
- ),
455
+ Color: () => <ColorInput value={value} onChange={(c) => myOnChange(c)} />,
423
456
  Bool: () => (
424
457
  <div className="form-check">
425
458
  <input
@@ -478,38 +511,74 @@ export const ConfigField = ({
478
511
  ))}
479
512
  </div>
480
513
  ),
481
- DimUnits: () => (
482
- <Fragment>
483
- <input
484
- type="number"
485
- value={value}
486
- step="1"
487
- min="0"
488
- max="9999"
489
- className="w-50 form-control-sm d-inline dimunit"
490
- onChange={(e) => myOnChange(e.target.value)}
491
- />
492
- <SelectUnits
493
- value={or_if_undef(
494
- configuration
495
- ? configuration[field.name + "Unit"]
496
- : props[field.name + "Unit"],
497
- "px"
514
+ DimUnits: () => {
515
+ let styleVal, styleDim;
516
+ if (isStyle && value === "auto") {
517
+ styleVal = "";
518
+ styleDim = "auto";
519
+ } else if (isStyle && value && typeof value === "string") {
520
+ const matches = value.match(/^([0-9]+\.?[0-9]*)(.*)/);
521
+ if (matches) {
522
+ styleVal = matches[1];
523
+ styleDim = matches[2];
524
+ }
525
+ }
526
+ return (
527
+ <Fragment>
528
+ {styleDim !== "auto" && (
529
+ <input
530
+ type="number"
531
+ value={(isStyle ? styleVal : value) || ""}
532
+ step="1"
533
+ min="0"
534
+ max="9999"
535
+ className="w-50 form-control-sm d-inline dimunit"
536
+ disabled={field.autoable && styleDim === "auto"}
537
+ onChange={(e) =>
538
+ myOnChange(
539
+ isStyle
540
+ ? `${e.target.value}${styleDim || "px"}`
541
+ : e.target.value
542
+ )
543
+ }
544
+ />
498
545
  )}
499
- className="w-50 form-control-sm d-inline dimunit"
500
- vert={true}
501
- onChange={(e) => {
502
- if (!e.target) return;
503
- const target_value = e.target.value;
504
- setProp((prop) => {
505
- if (configuration)
506
- prop.configuration[field.name + "Unit"] = target_value;
507
- else prop[field.name + "Unit"] = target_value;
508
- });
509
- }}
510
- />
511
- </Fragment>
512
- ),
546
+ <SelectUnits
547
+ value={or_if_undef(
548
+ configuration
549
+ ? configuration[field.name + "Unit"]
550
+ : isStyle
551
+ ? styleDim
552
+ : props[field.name + "Unit"],
553
+ "px"
554
+ )}
555
+ autoable={field.autoable}
556
+ className={`w-${
557
+ styleDim === "auto" ? 100 : 50
558
+ } form-control-sm d-inline dimunit`}
559
+ vert={true}
560
+ onChange={(e) => {
561
+ if (!e.target) return;
562
+ const target_value = e.target.value;
563
+ setProp((prop) => {
564
+ const myStyleVal =
565
+ target_value === "auto" && field.autoable && isStyle
566
+ ? ""
567
+ : styleVal;
568
+ if (configuration)
569
+ prop.configuration[field.name + "Unit"] = target_value;
570
+ else if (isStyle) {
571
+ prop.style[field.name] = `${or_if_undef(
572
+ myStyleVal,
573
+ 0
574
+ )}${target_value}`;
575
+ } else prop[field.name + "Unit"] = target_value;
576
+ });
577
+ }}
578
+ />
579
+ </Fragment>
580
+ );
581
+ },
513
582
  };
514
583
  const f = dispatch[field.input_type || field.type.name || field.type];
515
584
  return f ? f() : null;
@@ -546,7 +615,7 @@ export const SettingsSectionHeaderRow = ({ title }) => (
546
615
  </tr>
547
616
  );
548
617
 
549
- export const SettingsRow = ({ field, node, setProp, onChange }) => {
618
+ export const SettingsRow = ({ field, node, setProp, onChange, isStyle }) => {
550
619
  const fullWidth = ["String", "Bool", "textarea"].includes(field.type);
551
620
  const needLabel = field.type !== "Bool";
552
621
  const inner = field.canBeFormula ? (
@@ -568,6 +637,7 @@ export const SettingsRow = ({ field, node, setProp, onChange }) => {
568
637
  props={node}
569
638
  setProp={setProp}
570
639
  onChange={onChange}
640
+ isStyle={isStyle}
571
641
  />
572
642
  );
573
643
  return (
@@ -737,3 +807,17 @@ export const ButtonOrLinkSettingsRows = ({
737
807
  : []),
738
808
  ];
739
809
  };
810
+ export const bstyleopt = (style) => ({
811
+ value: style,
812
+ title: style,
813
+ label: (
814
+ <div
815
+ style={{
816
+ borderLeftStyle: style,
817
+ borderTopStyle: style,
818
+ height: "15px",
819
+ width: "6px",
820
+ }}
821
+ ></div>
822
+ ),
823
+ });
@@ -136,12 +136,6 @@ export const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
136
136
  <Element
137
137
  key={ix}
138
138
  canvas
139
- borderWidth={segment.borderWidth}
140
- borderStyle={segment.borderStyle}
141
- borderRadius={segment.borderRadius}
142
- borderDirection={segment.borderDirection}
143
- borderColor={segment.borderColor}
144
- borderRadiusUnit={segment.borderRadiusUnit}
145
139
  gradStartColor={segment.gradStartColor}
146
140
  gradEndColor={segment.gradEndColor}
147
141
  gradDirection={segment.gradDirection}
@@ -161,7 +155,14 @@ export const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
161
155
  widthUnit={segment.widthUnit || "px"}
162
156
  vAlign={segment.vAlign}
163
157
  hAlign={segment.hAlign}
164
- block={typeof segment.block === "undefined" ? true : segment.block}
158
+ display={
159
+ segment.display ||
160
+ (segment.block === true
161
+ ? "block"
162
+ : segment.block === false
163
+ ? "inline-block"
164
+ : "block")
165
+ }
165
166
  fullPageWidth={
166
167
  typeof segment.fullPageWidth === "undefined"
167
168
  ? false
@@ -170,6 +171,7 @@ export const layoutToNodes = (layout, query, actions, parent = "ROOT") => {
170
171
  bgFileId={segment.bgFileId}
171
172
  imageSize={segment.imageSize || "contain"}
172
173
  bgType={segment.bgType || "None"}
174
+ style={segment.style || {}}
173
175
  bgColor={segment.bgColor || "#ffffff"}
174
176
  setTextColor={!!segment.setTextColor}
175
177
  textColor={segment.textColor || "#000000"}
@@ -282,12 +284,6 @@ export const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
282
284
  return {
283
285
  contents: get_nodes(node),
284
286
  type: "container",
285
- borderWidth: node.props.borderWidth,
286
- borderStyle: node.props.borderStyle,
287
- borderColor: node.props.borderColor,
288
- borderRadius: node.props.borderRadius,
289
- borderDirection: node.props.borderDirection,
290
- borderRadiusUnit: node.props.borderRadiusUnit,
291
287
  customCSS: node.props.customCSS,
292
288
  customClass: node.props.customClass,
293
289
  minHeight: node.props.minHeight,
@@ -303,7 +299,7 @@ export const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
303
299
  margin: node.props.margin,
304
300
  padding: node.props.padding,
305
301
  overflow: node.props.overflow,
306
- block: node.props.block || false,
302
+ display: node.props.display,
307
303
  fullPageWidth: node.props.fullPageWidth || false,
308
304
  bgFileId: node.props.bgFileId,
309
305
  bgType: node.props.bgType,
@@ -321,6 +317,7 @@ export const craftToSaltcorn = (nodes, startFrom = "ROOT") => {
321
317
  gradEndColor: node.props.gradEndColor,
322
318
  gradDirection: node.props.gradDirection,
323
319
  rotate: node.props.rotate,
320
+ style: node.props.style,
324
321
  };
325
322
  else return get_nodes(node);
326
323
  }