@goldenpine/react-form-builder2 0.20.3-build.3 → 0.20.3-build.30

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.
@@ -19,7 +19,7 @@ var _fileSaver = require("file-saver");
19
19
  var _react = _interopRequireDefault(require("react"));
20
20
  var _reactSelect = _interopRequireDefault(require("react-select"));
21
21
  var _reactSignatureCanvas = _interopRequireDefault(require("react-signature-canvas"));
22
- var _reactBootstrapSlider = _interopRequireDefault(require("react-bootstrap-slider"));
22
+ var _reactBootstrapSlider = _interopRequireDefault(require("@goldenpine/react-bootstrap-slider"));
23
23
  var _starRating = _interopRequireDefault(require("./star-rating"));
24
24
  var _datePicker = _interopRequireDefault(require("./date-picker"));
25
25
  var _componentHeader = _interopRequireDefault(require("./component-header"));
@@ -30,6 +30,17 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
30
30
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
31
31
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } /* eslint-disable quote-props */ // eslint-disable-next-line max-classes-per-file
32
32
  var FormElements = {};
33
+
34
+ // Helper function to format placeholder with asterisk if the field is required and label is hidden.
35
+ // The function checks if the field has a required label, if the label is hidden, and if the placeholder is not empty.
36
+ // If all conditions are met, it appends an asterisk to the placeholder.
37
+ function formatPlaceholder(placeholder, hasRequiredLabel, labelHidden) {
38
+ var result = placeholder || '';
39
+ if (hasRequiredLabel && labelHidden && result.trim() !== '' && !result.endsWith('*')) {
40
+ result += ' *';
41
+ }
42
+ return result;
43
+ }
33
44
  var Header = /*#__PURE__*/function (_React$Component) {
34
45
  function Header() {
35
46
  (0, _classCallCheck2["default"])(this, Header);
@@ -86,7 +97,7 @@ var Paragraph = /*#__PURE__*/function (_React$Component2) {
86
97
  return /*#__PURE__*/_react["default"].createElement("div", {
87
98
  style: _objectSpread({}, this.props.style),
88
99
  className: baseClasses
89
- }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("p", {
100
+ }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
90
101
  className: classNames,
91
102
  dangerouslySetInnerHTML: {
92
103
  __html: _myxss["default"].process(this.props.data.content)
@@ -163,6 +174,9 @@ var TextInput = /*#__PURE__*/function (_React$Component5) {
163
174
  props.type = 'text';
164
175
  props.className = 'form-control';
165
176
  props.name = this.props.data.field_name;
177
+ var labelHidden = this.props.data.labelHidden || false;
178
+ var hasRequiredLabel = this.props.data.hasOwnProperty('required') && this.props.data.required === true && !this.props.read_only;
179
+ props.placeholder = formatPlaceholder(this.props.data.placeholder, hasRequiredLabel, labelHidden);
166
180
  if (this.props.mutable) {
167
181
  props.defaultValue = this.props.defaultValue;
168
182
  props.ref = this.inputField;
@@ -178,8 +192,12 @@ var TextInput = /*#__PURE__*/function (_React$Component5) {
178
192
  style: _objectSpread({}, this.props.style),
179
193
  className: baseClasses
180
194
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
181
- className: "form-group"
182
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement("input", props)));
195
+ className: "mb-3"
196
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
197
+ className: ["form-label",
198
+ // In app, it's leveraged to identify element labels. Additionally removed !important of its specificity in scss to make it work with labelHidden.
199
+ this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
200
+ })), /*#__PURE__*/_react["default"].createElement("input", props)));
183
201
  }
184
202
  }]);
185
203
  }(_react["default"].Component);
@@ -199,6 +217,9 @@ var EmailInput = /*#__PURE__*/function (_React$Component6) {
199
217
  props.type = 'text';
200
218
  props.className = 'form-control';
201
219
  props.name = this.props.data.field_name;
220
+ var labelHidden = this.props.data.labelHidden || false;
221
+ var hasRequiredLabel = this.props.data.hasOwnProperty('required') && this.props.data.required === true && !this.props.read_only;
222
+ props.placeholder = formatPlaceholder(this.props.data.placeholder, hasRequiredLabel, labelHidden);
202
223
  if (this.props.mutable) {
203
224
  props.defaultValue = this.props.defaultValue;
204
225
  props.ref = this.inputField;
@@ -214,8 +235,10 @@ var EmailInput = /*#__PURE__*/function (_React$Component6) {
214
235
  style: _objectSpread({}, this.props.style),
215
236
  className: baseClasses
216
237
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
217
- className: "form-group"
218
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement("input", props)));
238
+ className: "mb-3"
239
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
240
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
241
+ })), /*#__PURE__*/_react["default"].createElement("input", props)));
219
242
  }
220
243
  }]);
221
244
  }(_react["default"].Component);
@@ -235,6 +258,15 @@ var PhoneNumber = /*#__PURE__*/function (_React$Component7) {
235
258
  props.type = 'tel';
236
259
  props.className = 'form-control';
237
260
  props.name = this.props.data.field_name;
261
+ var labelHidden = this.props.data.labelHidden || false;
262
+ var hasRequiredLabel = this.props.data.hasOwnProperty('required') && this.props.data.required === true && !this.props.read_only;
263
+ var placeholder; // For phone number input, if placeholder is not set, we will set a default placeholder with an asterisk if it's required, to give users a hint about the expected format and the requirement. The default placeholder is "+12345678900" which is in E.164 format without spaces or dashes, as it's the most widely accepted format for international phone numbers and works well with the pattern validation we have in place. Merchants can customize this placeholder or even disable it by leaving it blank in the form builder.
264
+ if (this.props.data.placeholder !== undefined && this.props.data.placeholder !== null) {
265
+ placeholder = this.props.data.placeholder;
266
+ } else {
267
+ placeholder = '+12345678900';
268
+ }
269
+ props.placeholder = formatPlaceholder(placeholder, hasRequiredLabel, labelHidden);
238
270
  if (this.props.mutable) {
239
271
  props.defaultValue = this.props.defaultValue;
240
272
  props.ref = this.inputField;
@@ -250,8 +282,10 @@ var PhoneNumber = /*#__PURE__*/function (_React$Component7) {
250
282
  style: _objectSpread({}, this.props.style),
251
283
  className: baseClasses
252
284
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
253
- className: "form-group"
254
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement("input", props)));
285
+ className: "mb-3"
286
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
287
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
288
+ })), /*#__PURE__*/_react["default"].createElement("input", props)));
255
289
  }
256
290
  }]);
257
291
  }(_react["default"].Component);
@@ -271,6 +305,9 @@ var NumberInput = /*#__PURE__*/function (_React$Component8) {
271
305
  props.type = 'number';
272
306
  props.className = 'form-control';
273
307
  props.name = this.props.data.field_name;
308
+ var labelHidden = this.props.data.labelHidden || false;
309
+ var hasRequiredLabel = this.props.data.hasOwnProperty('required') && this.props.data.required === true && !this.props.read_only;
310
+ props.placeholder = formatPlaceholder(this.props.data.placeholder, hasRequiredLabel, labelHidden);
274
311
  if (this.props.mutable) {
275
312
  props.defaultValue = this.props.defaultValue;
276
313
  props.ref = this.inputField;
@@ -286,8 +323,10 @@ var NumberInput = /*#__PURE__*/function (_React$Component8) {
286
323
  style: _objectSpread({}, this.props.style),
287
324
  className: baseClasses
288
325
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
289
- className: "form-group"
290
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement("input", props)));
326
+ className: "mb-3"
327
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
328
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
329
+ })), /*#__PURE__*/_react["default"].createElement("input", props)));
291
330
  }
292
331
  }]);
293
332
  }(_react["default"].Component);
@@ -306,6 +345,9 @@ var TextArea = /*#__PURE__*/function (_React$Component9) {
306
345
  var props = {};
307
346
  props.className = 'form-control';
308
347
  props.name = this.props.data.field_name;
348
+ var labelHidden = this.props.data.labelHidden || false;
349
+ var hasRequiredLabel = this.props.data.hasOwnProperty('required') && this.props.data.required === true && !this.props.read_only;
350
+ props.placeholder = formatPlaceholder(this.props.data.placeholder, hasRequiredLabel, labelHidden);
309
351
  if (this.props.read_only) {
310
352
  props.disabled = 'disabled';
311
353
  }
@@ -321,8 +363,10 @@ var TextArea = /*#__PURE__*/function (_React$Component9) {
321
363
  style: _objectSpread({}, this.props.style),
322
364
  className: baseClasses
323
365
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
324
- className: "form-group"
325
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement("textarea", props)));
366
+ className: "mb-3"
367
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
368
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
369
+ })), /*#__PURE__*/_react["default"].createElement("textarea", props)));
326
370
  }
327
371
  }]);
328
372
  }(_react["default"].Component);
@@ -341,6 +385,7 @@ var Dropdown = /*#__PURE__*/function (_React$Component0) {
341
385
  var props = {};
342
386
  props.className = 'form-control';
343
387
  props.name = this.props.data.field_name;
388
+ var labelHidden = this.props.data.labelHidden || false;
344
389
  if (this.props.mutable) {
345
390
  props.defaultValue = this.props.defaultValue;
346
391
  props.ref = this.inputField;
@@ -356,8 +401,10 @@ var Dropdown = /*#__PURE__*/function (_React$Component0) {
356
401
  style: _objectSpread({}, this.props.style),
357
402
  className: baseClasses
358
403
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
359
- className: "form-group"
360
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement("select", props, this.props.data.options.map(function (option) {
404
+ className: "mb-3"
405
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
406
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
407
+ })), /*#__PURE__*/_react["default"].createElement("select", props, this.props.data.options.map(function (option) {
361
408
  var this_key = "preview_".concat(option.key);
362
409
  return /*#__PURE__*/_react["default"].createElement("option", {
363
410
  value: option.value,
@@ -397,6 +444,7 @@ var Signature = /*#__PURE__*/function (_React$Component1) {
397
444
  var props = {};
398
445
  props.type = 'hidden';
399
446
  props.name = this.props.data.field_name;
447
+ var labelHidden = this.props.data.labelHidden || false;
400
448
  if (this.props.mutable) {
401
449
  props.defaultValue = defaultValue;
402
450
  props.ref = this.inputField;
@@ -421,8 +469,10 @@ var Signature = /*#__PURE__*/function (_React$Component1) {
421
469
  style: _objectSpread({}, this.props.style),
422
470
  className: baseClasses
423
471
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
424
- className: "form-group"
425
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), this.props.read_only === true || !!sourceDataURL ? /*#__PURE__*/_react["default"].createElement("img", {
472
+ className: "mb-3"
473
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
474
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
475
+ })), this.props.read_only === true || !!sourceDataURL ? /*#__PURE__*/_react["default"].createElement("img", {
426
476
  src: sourceDataURL
427
477
  }) : /*#__PURE__*/_react["default"].createElement(_reactSignatureCanvas["default"], pad_props), canClear && /*#__PURE__*/_react["default"].createElement("i", {
428
478
  className: "fas fa-times clear-signature",
@@ -481,6 +531,7 @@ var Tags = /*#__PURE__*/function (_React$Component10) {
481
531
  props.isMulti = true;
482
532
  props.name = this.props.data.field_name;
483
533
  props.onChange = this.handleChange;
534
+ var labelHidden = this.props.data.labelHidden || false;
484
535
  props.options = options;
485
536
  if (!this.props.mutable) {
486
537
  props.value = options[0].text;
@@ -498,8 +549,10 @@ var Tags = /*#__PURE__*/function (_React$Component10) {
498
549
  style: _objectSpread({}, this.props.style),
499
550
  className: baseClasses
500
551
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
501
- className: "form-group"
502
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement(_reactSelect["default"], props)));
552
+ className: "mb-3"
553
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
554
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
555
+ })), /*#__PURE__*/_react["default"].createElement(_reactSelect["default"], props)));
503
556
  }
504
557
  }]);
505
558
  }(_react["default"].Component);
@@ -517,9 +570,10 @@ var Checkboxes = /*#__PURE__*/function (_React$Component11) {
517
570
  value: function render() {
518
571
  var _this0 = this;
519
572
  var self = this;
520
- var classNames = 'custom-control custom-checkbox';
573
+ var labelHidden = this.props.data.labelHidden || false;
574
+ var classNames = 'form-check';
521
575
  if (this.props.data.inline) {
522
- classNames += ' option-inline';
576
+ classNames += ' form-check-inline';
523
577
  }
524
578
  var baseClasses = 'SortableItem rfb-item';
525
579
  if (this.props.data.pageBreakBefore) {
@@ -529,8 +583,10 @@ var Checkboxes = /*#__PURE__*/function (_React$Component11) {
529
583
  style: _objectSpread({}, this.props.style),
530
584
  className: baseClasses
531
585
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
532
- className: "form-group"
533
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), this.props.data.options.map(function (option) {
586
+ className: "mb-3"
587
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
588
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
589
+ })), this.props.data.options.map(function (option) {
534
590
  var this_key = "preview_".concat(option.key);
535
591
  var props = {};
536
592
  props.name = "option_".concat(option.key);
@@ -547,14 +603,15 @@ var Checkboxes = /*#__PURE__*/function (_React$Component11) {
547
603
  key: this_key
548
604
  }, /*#__PURE__*/_react["default"].createElement("input", (0, _extends2["default"])({
549
605
  id: "fid_".concat(this_key),
550
- className: "custom-control-input",
606
+ className: "form-check-input",
551
607
  ref: function ref(c) {
552
608
  if (c && self.props.mutable) {
553
609
  self.options["child_ref_".concat(option.key)] = c;
554
610
  }
555
- }
611
+ },
612
+ "data-required-checks": _this0.props.data.checkbox_required_checks ? _this0.props.data.checkbox_required_checks : '1'
556
613
  }, props)), /*#__PURE__*/_react["default"].createElement("label", {
557
- className: "custom-control-label",
614
+ className: "form-check-label",
558
615
  htmlFor: "fid_".concat(this_key)
559
616
  }, option.text));
560
617
  })));
@@ -575,9 +632,10 @@ var RadioButtons = /*#__PURE__*/function (_React$Component12) {
575
632
  value: function render() {
576
633
  var _this10 = this;
577
634
  var self = this;
578
- var classNames = 'custom-control custom-radio';
635
+ var labelHidden = this.props.data.labelHidden || false;
636
+ var classNames = 'form-check';
579
637
  if (this.props.data.inline) {
580
- classNames += ' option-inline';
638
+ classNames += ' form-check-inline';
581
639
  }
582
640
  var baseClasses = 'SortableItem rfb-item';
583
641
  if (this.props.data.pageBreakBefore) {
@@ -587,8 +645,10 @@ var RadioButtons = /*#__PURE__*/function (_React$Component12) {
587
645
  style: _objectSpread({}, this.props.style),
588
646
  className: baseClasses
589
647
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
590
- className: "form-group"
591
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), this.props.data.options.map(function (option) {
648
+ className: "mb-3"
649
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
650
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
651
+ })), this.props.data.options.map(function (option) {
592
652
  var this_key = "preview_".concat(option.key);
593
653
  var props = {};
594
654
  props.name = self.props.data.field_name;
@@ -605,14 +665,14 @@ var RadioButtons = /*#__PURE__*/function (_React$Component12) {
605
665
  key: this_key
606
666
  }, /*#__PURE__*/_react["default"].createElement("input", (0, _extends2["default"])({
607
667
  id: "fid_".concat(this_key),
608
- className: "custom-control-input",
668
+ className: "form-check-input",
609
669
  ref: function ref(c) {
610
670
  if (c && self.props.mutable) {
611
671
  self.options["child_ref_".concat(option.key)] = c;
612
672
  }
613
673
  }
614
674
  }, props)), /*#__PURE__*/_react["default"].createElement("label", {
615
- className: "custom-control-label",
675
+ className: "form-check-label",
616
676
  htmlFor: "fid_".concat(this_key)
617
677
  }, option.text));
618
678
  })));
@@ -640,8 +700,11 @@ var Image = /*#__PURE__*/function (_React$Component13) {
640
700
  className: baseClasses
641
701
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), this.props.data.src && /*#__PURE__*/_react["default"].createElement("img", {
642
702
  src: this.props.data.src,
643
- width: this.props.data.width,
644
- height: this.props.data.height
703
+ style: {
704
+ height: this.props.data.height,
705
+ width: this.props.data.width,
706
+ display: 'inline'
707
+ }
645
708
  }), !this.props.data.src && /*#__PURE__*/_react["default"].createElement("div", {
646
709
  className: "no-image"
647
710
  }, "No Image"));
@@ -662,6 +725,7 @@ var Rating = /*#__PURE__*/function (_React$Component14) {
662
725
  value: function render() {
663
726
  var props = {};
664
727
  props.name = this.props.data.field_name;
728
+ var labelHidden = this.props.data.labelHidden || false;
665
729
  props.ratingAmount = 5;
666
730
  if (this.props.mutable) {
667
731
  props.rating = this.props.defaultValue !== undefined ? parseFloat(this.props.defaultValue, 10) : 0;
@@ -677,8 +741,10 @@ var Rating = /*#__PURE__*/function (_React$Component14) {
677
741
  style: _objectSpread({}, this.props.style),
678
742
  className: baseClasses
679
743
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
680
- className: "form-group"
681
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement(_starRating["default"], props)));
744
+ className: "mb-3"
745
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
746
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
747
+ })), /*#__PURE__*/_react["default"].createElement(_starRating["default"], props)));
682
748
  }
683
749
  }]);
684
750
  }(_react["default"].Component);
@@ -699,7 +765,7 @@ var HyperLink = /*#__PURE__*/function (_React$Component15) {
699
765
  style: _objectSpread({}, this.props.style),
700
766
  className: baseClasses
701
767
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
702
- className: "form-group"
768
+ className: "mb-3"
703
769
  }, /*#__PURE__*/_react["default"].createElement("label", {
704
770
  className: 'form-label'
705
771
  }, /*#__PURE__*/_react["default"].createElement("a", {
@@ -729,7 +795,7 @@ var Download = /*#__PURE__*/function (_React$Component16) {
729
795
  style: _objectSpread({}, this.props.style),
730
796
  className: baseClasses
731
797
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
732
- className: "form-group"
798
+ className: "mb-3"
733
799
  }, /*#__PURE__*/_react["default"].createElement("a", {
734
800
  href: "".concat(this.props.download_path, "?id=").concat(this.props.data.file_path)
735
801
  }, this.props.data.content)));
@@ -780,16 +846,33 @@ var Camera = /*#__PURE__*/function (_React$Component17) {
780
846
  }
781
847
  return imgProps;
782
848
  }
849
+
850
+ /*
851
+ Originally Image/File upload elments don't count the heights of all visible controls which is layered on top of <input>,
852
+ which makes the element possibly overlaps on the next element on a narrow screen.
853
+ It's caused by "position: absolue" of .image-upload-control.
854
+ The fix is to add inline style "position: relative" to the container div of .image-upload-control, and use <label> tag
855
+ and "for"/"id" to trigger to the file input dialog.
856
+ */
783
857
  }, {
784
858
  key: "render",
785
859
  value: function render() {
786
860
  var _this13 = this;
787
861
  var imageStyle = {
788
- objectFit: 'scale-down',
789
- objectPosition: this.props.data.center ? 'center' : 'left'
862
+ // 2025/11/11
863
+ // 'scale-down' looks to keep the original size of image on form-builder-generator.
864
+ // and sometimes the image is too small. Supposeing admin want to show the image in bigger size,
865
+ // so adjust it "contain" to make it bigger if possible.
866
+ // "contain" is supposed to "Preserves the aspect ratio, and fits the image inside the container, without cutting"
867
+ objectFit: 'contain',
868
+ objectPosition: this.props.data.center ? 'center' : 'left',
869
+ // Move width and height from element style to inline style of image, to make it work the same way as 'Image' element.
870
+ width: this.props.data.width,
871
+ height: this.props.data.height
790
872
  };
791
873
  var baseClasses = 'SortableItem rfb-item';
792
874
  var name = this.props.data.field_name;
875
+ var labelHidden = this.props.data.labelHidden || false;
793
876
  var fileInputStyle = this.state.img ? {
794
877
  display: 'none'
795
878
  } : null;
@@ -804,46 +887,105 @@ var Camera = /*#__PURE__*/function (_React$Component17) {
804
887
  sourceDataURL = "data:image/png;base64,".concat(this.props.defaultValue);
805
888
  }
806
889
  }
807
- return /*#__PURE__*/_react["default"].createElement("div", {
808
- style: _objectSpread({}, this.props.style),
809
- className: baseClasses
810
- }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
811
- className: "form-group"
812
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), this.props.read_only === true && this.props.defaultValue && this.props.defaultValue.length > 0 ? /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("img", (0, _extends2["default"])({
813
- style: imageStyle,
814
- src: sourceDataURL
815
- }, this.getImageSizeProps(this.props.data)))) : /*#__PURE__*/_react["default"].createElement("div", {
816
- className: "image-upload-container"
817
- }, /*#__PURE__*/_react["default"].createElement("div", {
818
- style: fileInputStyle
819
- }, /*#__PURE__*/_react["default"].createElement("input", {
820
- name: name,
821
- type: "file",
822
- accept: "image/*",
823
- capture: "camera",
824
- className: "image-upload",
825
- onChange: this.displayImage,
826
- "data-clearlabel": this.props.data.label_after_photo_clear_icon,
827
- disabled: this.props.read_only
828
- }), /*#__PURE__*/_react["default"].createElement("div", {
829
- className: "image-upload-control"
830
- }, /*#__PURE__*/_react["default"].createElement("div", {
831
- className: "btn btn-default"
832
- }, /*#__PURE__*/_react["default"].createElement("i", {
833
- className: "fas fa-camera"
834
- }), " ", this.props.data.label_after_camera_icon), /*#__PURE__*/_react["default"].createElement("p", null, this.props.data.message_under_camera_icon))), this.state.img && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("img", {
835
- onLoad: function onLoad() {
836
- return URL.revokeObjectURL(_this13.state.previewImg);
837
- },
838
- src: this.state.previewImg,
839
- height: "100",
840
- className: "image-upload-preview"
841
- }), /*#__PURE__*/_react["default"].createElement("br", null), /*#__PURE__*/_react["default"].createElement("div", {
842
- className: "btn btn-image-clear",
843
- onClick: this.clearImage
844
- }, /*#__PURE__*/_react["default"].createElement("i", {
845
- className: "fas fa-times"
846
- }), " ", this.props.data.label_after_photo_clear_icon)))));
890
+ if (this.props.data.upload_layout !== "dropzone") {
891
+ return /*#__PURE__*/_react["default"].createElement("div", {
892
+ style: _objectSpread({}, this.props.style),
893
+ className: baseClasses
894
+ }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
895
+ className: "mb-3"
896
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
897
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
898
+ })), this.props.read_only === true && this.props.defaultValue && this.props.defaultValue.length > 0 ? /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("img", {
899
+ style: imageStyle,
900
+ src: sourceDataURL
901
+ // {...this.getImageSizeProps(this.props.data)} // move width and height from element style to inline style of image, to make it work the same way as 'Image' element.
902
+ })) : /*#__PURE__*/_react["default"].createElement("div", {
903
+ className: "image-upload-container"
904
+ }, /*#__PURE__*/_react["default"].createElement("div", {
905
+ style: fileInputStyle
906
+ }, /*#__PURE__*/_react["default"].createElement("input", {
907
+ name: name,
908
+ type: "file",
909
+ accept: "image/*"
910
+ //capture="camera" // With this property, users on most mobiles can only take photo but no options to pick up a photo from gallery
911
+ ,
912
+ className: "image-upload visually-hidden",
913
+ onChange: this.displayImage,
914
+ "data-clearlabel": this.props.data.label_after_photo_clear_icon,
915
+ disabled: this.props.read_only,
916
+ id: name
917
+ }), /*#__PURE__*/_react["default"].createElement("div", {
918
+ className: "image-upload-control",
919
+ style: {
920
+ position: 'relative'
921
+ }
922
+ }, /*#__PURE__*/_react["default"].createElement("label", {
923
+ className: "btn btn-outline-secondary",
924
+ htmlFor: name
925
+ }, /*#__PURE__*/_react["default"].createElement("i", {
926
+ className: "fas fa-camera"
927
+ }), " ", this.props.data.label_after_camera_icon), /*#__PURE__*/_react["default"].createElement("div", null, this.props.data.message_under_camera_icon))), this.state.img && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("img", {
928
+ onLoad: function onLoad() {
929
+ return URL.revokeObjectURL(_this13.state.previewImg);
930
+ },
931
+ src: this.state.previewImg,
932
+ height: "100",
933
+ className: "image-upload-preview"
934
+ }), /*#__PURE__*/_react["default"].createElement("button", {
935
+ className: "btn btn-image-clear",
936
+ onClick: this.clearImage
937
+ }, /*#__PURE__*/_react["default"].createElement("i", {
938
+ className: "fas fa-times"
939
+ }), " ", this.props.data.label_after_photo_clear_icon)))));
940
+ } else {
941
+ return /*#__PURE__*/_react["default"].createElement("div", {
942
+ style: _objectSpread({}, this.props.style),
943
+ className: baseClasses
944
+ }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
945
+ className: "mb-3"
946
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
947
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
948
+ })), this.props.read_only === true && this.props.defaultValue && this.props.defaultValue.length > 0 ? /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("img", {
949
+ style: imageStyle,
950
+ src: sourceDataURL
951
+ })) : /*#__PURE__*/_react["default"].createElement("div", {
952
+ className: "image-upload-container"
953
+ }, /*#__PURE__*/_react["default"].createElement("div", {
954
+ style: fileInputStyle,
955
+ className: "upload-card"
956
+ }, /*#__PURE__*/_react["default"].createElement("input", {
957
+ name: name,
958
+ type: "file",
959
+ accept: "image/*",
960
+ className: "visually-hidden",
961
+ onChange: this.displayImage,
962
+ "data-clearlabel": this.props.data.label_after_photo_clear_icon,
963
+ disabled: this.props.read_only,
964
+ id: name
965
+ }), /*#__PURE__*/_react["default"].createElement("label", {
966
+ htmlFor: name,
967
+ className: "upload-card-content"
968
+ }, /*#__PURE__*/_react["default"].createElement("i", {
969
+ className: "fas fa-cloud-upload-alt upload-icon"
970
+ }), /*#__PURE__*/_react["default"].createElement("span", {
971
+ className: "upload-text"
972
+ }, this.props.data.message_under_camera_icon), /*#__PURE__*/_react["default"].createElement("div", {
973
+ className: "btn-browse"
974
+ }, this.props.data.label_after_camera_icon))), this.state.img && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("img", {
975
+ onLoad: function onLoad() {
976
+ return URL.revokeObjectURL(_this13.state.previewImg);
977
+ },
978
+ src: this.state.previewImg,
979
+ className: "image-upload-preview",
980
+ alt: "Preview",
981
+ height: "100"
982
+ }), /*#__PURE__*/_react["default"].createElement("button", {
983
+ className: "btn btn-image-clear",
984
+ onClick: this.clearImage
985
+ }, /*#__PURE__*/_react["default"].createElement("i", {
986
+ className: "fas fa-times"
987
+ }), " ", this.props.data.label_after_photo_clear_icon)))));
988
+ }
847
989
  }
848
990
  }]);
849
991
  }(_react["default"].Component);
@@ -924,41 +1066,106 @@ var FileUpload = /*#__PURE__*/function (_React$Component18) {
924
1066
  value: function render() {
925
1067
  var baseClasses = 'SortableItem rfb-item';
926
1068
  var name = this.props.data.field_name;
1069
+ var labelHidden = this.props.data.labelHidden || false;
927
1070
  var fileInputStyle = this.state.fileUpload ? {
928
1071
  display: 'none'
929
1072
  } : null;
930
1073
  if (this.props.data.pageBreakBefore) {
931
1074
  baseClasses += ' alwaysbreak';
932
1075
  }
1076
+ if (this.props.data.upload_layout !== 'dropzone') {
1077
+ return /*#__PURE__*/_react["default"].createElement("div", {
1078
+ style: _objectSpread({}, this.props.style),
1079
+ className: baseClasses
1080
+ }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
1081
+ className: "mb-3"
1082
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
1083
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
1084
+ })), this.props.read_only === true && this.props.defaultValue && this.props.defaultValue.length > 0 ? /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("button", {
1085
+ className: "btn btn-outline-secondary",
1086
+ onClick: this.saveFile
1087
+ }, /*#__PURE__*/_react["default"].createElement("i", {
1088
+ className: "fas fa-download"
1089
+ }), " Download File")) : /*#__PURE__*/_react["default"].createElement("div", {
1090
+ className: "image-upload-container"
1091
+ }, /*#__PURE__*/_react["default"].createElement("div", {
1092
+ style: fileInputStyle
1093
+ }, /*#__PURE__*/_react["default"].createElement("input", {
1094
+ name: name,
1095
+ type: "file",
1096
+ accept: this.props.data.fileType || '*',
1097
+ className: "image-upload visually-hidden",
1098
+ onChange: this.displayFileUpload,
1099
+ "data-clearlabel": this.props.data.label_after_file_clear_icon,
1100
+ disabled: this.props.read_only,
1101
+ id: name
1102
+ }), /*#__PURE__*/_react["default"].createElement("div", {
1103
+ className: "image-upload-control",
1104
+ style: {
1105
+ position: 'relative'
1106
+ }
1107
+ }, /*#__PURE__*/_react["default"].createElement("label", {
1108
+ className: "btn btn-outline-secondary",
1109
+ htmlFor: name
1110
+ }, /*#__PURE__*/_react["default"].createElement("i", {
1111
+ className: "fas fa-file"
1112
+ }), " ", this.props.data.label_after_file_icon), /*#__PURE__*/_react["default"].createElement("div", null, this.props.data.message_under_file_icon))), this.state.fileUpload && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
1113
+ className: "file-upload-preview"
1114
+ }, /*#__PURE__*/_react["default"].createElement("div", {
1115
+ style: {
1116
+ display: 'inline-block',
1117
+ marginRight: '5px'
1118
+ }
1119
+ }, this.state.fileUpload.name), /*#__PURE__*/_react["default"].createElement("div", {
1120
+ style: {
1121
+ display: 'inline-block',
1122
+ marginLeft: '5px'
1123
+ }
1124
+ }, this.state.fileUpload.size.length > 6 ? " ".concat(Math.ceil(this.state.fileUpload.size / (1024 * 1024)), " mb") : " ".concat(Math.ceil(this.state.fileUpload.size / 1024), " kb"))), /*#__PURE__*/_react["default"].createElement("br", null), /*#__PURE__*/_react["default"].createElement("div", {
1125
+ className: "btn btn-file-upload-clear",
1126
+ onClick: this.clearFileUpload
1127
+ }, /*#__PURE__*/_react["default"].createElement("i", {
1128
+ className: "fas fa-times"
1129
+ }), " ", this.props.data.label_after_file_clear_icon)))));
1130
+ }
1131
+
1132
+ // non-standard layout: use "upload-card" style like Camera
933
1133
  return /*#__PURE__*/_react["default"].createElement("div", {
934
1134
  style: _objectSpread({}, this.props.style),
935
1135
  className: baseClasses
936
1136
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
937
- className: "form-group"
938
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), this.props.read_only === true && this.props.defaultValue && this.props.defaultValue.length > 0 ? /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("button", {
939
- className: "btn btn-default",
1137
+ className: "mb-3"
1138
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
1139
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
1140
+ })), this.props.read_only === true && this.props.defaultValue && this.props.defaultValue.length > 0 ? /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("button", {
1141
+ className: "btn btn-outline-secondary",
940
1142
  onClick: this.saveFile
941
1143
  }, /*#__PURE__*/_react["default"].createElement("i", {
942
1144
  className: "fas fa-download"
943
1145
  }), " Download File")) : /*#__PURE__*/_react["default"].createElement("div", {
944
1146
  className: "image-upload-container"
945
1147
  }, /*#__PURE__*/_react["default"].createElement("div", {
946
- style: fileInputStyle
1148
+ style: fileInputStyle,
1149
+ className: "upload-card"
947
1150
  }, /*#__PURE__*/_react["default"].createElement("input", {
948
1151
  name: name,
949
1152
  type: "file",
950
1153
  accept: this.props.data.fileType || '*',
951
- className: "image-upload",
1154
+ className: "visually-hidden",
952
1155
  onChange: this.displayFileUpload,
953
1156
  "data-clearlabel": this.props.data.label_after_file_clear_icon,
954
- disabled: this.props.read_only
955
- }), /*#__PURE__*/_react["default"].createElement("div", {
956
- className: "image-upload-control"
957
- }, /*#__PURE__*/_react["default"].createElement("div", {
958
- className: "btn btn-default"
1157
+ disabled: this.props.read_only,
1158
+ id: name
1159
+ }), /*#__PURE__*/_react["default"].createElement("label", {
1160
+ htmlFor: name,
1161
+ className: "upload-card-content"
959
1162
  }, /*#__PURE__*/_react["default"].createElement("i", {
960
- className: "fas fa-file"
961
- }), " ", this.props.data.label_after_file_icon), /*#__PURE__*/_react["default"].createElement("p", null, this.props.data.message_under_file_icon))), this.state.fileUpload && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
1163
+ className: "fas fa-file-upload upload-icon"
1164
+ }), /*#__PURE__*/_react["default"].createElement("span", {
1165
+ className: "upload-text"
1166
+ }, this.props.data.message_under_file_icon), /*#__PURE__*/_react["default"].createElement("div", {
1167
+ className: "btn-browse"
1168
+ }, this.props.data.label_after_file_icon))), this.state.fileUpload && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
962
1169
  className: "file-upload-preview"
963
1170
  }, /*#__PURE__*/_react["default"].createElement("div", {
964
1171
  style: {
@@ -1002,11 +1209,12 @@ var Range = /*#__PURE__*/function (_React$Component19) {
1002
1209
  value: function render() {
1003
1210
  var props = {};
1004
1211
  var name = this.props.data.field_name;
1212
+ var labelHidden = this.props.data.labelHidden || false;
1005
1213
  props.type = 'range';
1006
1214
  props.list = "tickmarks_".concat(name);
1007
- props.min = this.props.data.min_value;
1008
- props.max = this.props.data.max_value;
1009
- props.step = this.props.data.step;
1215
+ props.min = Number(this.props.data.min_value);
1216
+ props.max = Number(this.props.data.max_value);
1217
+ props.step = Number(this.props.data.step) || 1;
1010
1218
  props.value = this.state.value;
1011
1219
  props.change = this.changeValue;
1012
1220
  if (this.props.mutable) {
@@ -1051,21 +1259,26 @@ var Range = /*#__PURE__*/function (_React$Component19) {
1051
1259
  style: _objectSpread({}, this.props.style),
1052
1260
  className: baseClasses
1053
1261
  }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
1054
- className: "form-group"
1055
- }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
1262
+ className: "mb-3"
1263
+ }, /*#__PURE__*/_react["default"].createElement(_componentLabel["default"], (0, _extends2["default"])({}, this.props, {
1264
+ className: ["form-label", this.props.className, labelHidden ? "d-none" : ""].filter(Boolean).join(" ")
1265
+ })), /*#__PURE__*/_react["default"].createElement("div", {
1056
1266
  className: "range"
1057
1267
  }, /*#__PURE__*/_react["default"].createElement("div", {
1058
1268
  className: "clearfix"
1059
1269
  }, /*#__PURE__*/_react["default"].createElement("span", {
1060
- className: "float-left"
1270
+ className: "float-start"
1061
1271
  }, this.props.data.min_label), /*#__PURE__*/_react["default"].createElement("span", {
1062
- className: "float-right"
1272
+ className: "float-end"
1063
1273
  }, this.props.data.max_label)), /*#__PURE__*/_react["default"].createElement(_reactBootstrapSlider["default"], props)), /*#__PURE__*/_react["default"].createElement("div", {
1064
1274
  className: "visible_marks"
1065
1275
  }, visible_marks), /*#__PURE__*/_react["default"].createElement("input", {
1066
1276
  name: name,
1067
1277
  value: this.state.value,
1068
- type: "hidden"
1278
+ type: "hidden",
1279
+ "data-min-value": props.min,
1280
+ "data-max-value": props.max,
1281
+ "data-step": props.step
1069
1282
  }), /*#__PURE__*/_react["default"].createElement("datalist", {
1070
1283
  id: props.list
1071
1284
  }, _datalist)));