@goldenpine/react-form-builder2 0.20.3-build.20 → 0.20.3-build.21

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.
@@ -824,53 +824,103 @@ var Camera = /*#__PURE__*/function (_React$Component17) {
824
824
  sourceDataURL = "data:image/png;base64,".concat(this.props.defaultValue);
825
825
  }
826
826
  }
827
- return /*#__PURE__*/_react["default"].createElement("div", {
828
- style: _objectSpread({}, this.props.style),
829
- className: baseClasses
830
- }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
831
- className: "mb-3"
832
- }, /*#__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", {
833
- style: imageStyle,
834
- src: sourceDataURL
835
- // {...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.
836
- })) : /*#__PURE__*/_react["default"].createElement("div", {
837
- className: "image-upload-container"
838
- }, /*#__PURE__*/_react["default"].createElement("div", {
839
- style: fileInputStyle
840
- }, /*#__PURE__*/_react["default"].createElement("input", {
841
- name: name,
842
- type: "file",
843
- accept: "image/*"
844
- //capture="camera" // With this property, users on most mobiles can only take photo but no options to pick up a photo from gallery
845
- ,
846
- className: "image-upload visually-hidden",
847
- onChange: this.displayImage,
848
- "data-clearlabel": this.props.data.label_after_photo_clear_icon,
849
- disabled: this.props.read_only,
850
- id: name
851
- }), /*#__PURE__*/_react["default"].createElement("div", {
852
- className: "image-upload-control",
853
- style: {
854
- position: 'relative'
855
- }
856
- }, /*#__PURE__*/_react["default"].createElement("label", {
857
- className: "btn btn-outline-secondary",
858
- htmlFor: name
859
- }, /*#__PURE__*/_react["default"].createElement("i", {
860
- className: "fas fa-camera"
861
- }), " ", 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", {
862
- onLoad: function onLoad() {
863
- return URL.revokeObjectURL(_this13.state.previewImg);
864
- },
865
- src: this.state.previewImg,
866
- height: "100",
867
- className: "image-upload-preview"
868
- }), /*#__PURE__*/_react["default"].createElement("br", null), /*#__PURE__*/_react["default"].createElement("div", {
869
- className: "btn btn-image-clear",
870
- onClick: this.clearImage
871
- }, /*#__PURE__*/_react["default"].createElement("i", {
872
- className: "fas fa-times"
873
- }), " ", this.props.data.label_after_photo_clear_icon)))));
827
+ if (this.props.data.upload_layout === "standard") {
828
+ return /*#__PURE__*/_react["default"].createElement("div", {
829
+ style: _objectSpread({}, this.props.style),
830
+ className: baseClasses
831
+ }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
832
+ className: "mb-3"
833
+ }, /*#__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", {
834
+ style: imageStyle,
835
+ src: sourceDataURL
836
+ // {...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.
837
+ })) : /*#__PURE__*/_react["default"].createElement("div", {
838
+ className: "image-upload-container"
839
+ }, /*#__PURE__*/_react["default"].createElement("div", {
840
+ style: fileInputStyle
841
+ }, /*#__PURE__*/_react["default"].createElement("input", {
842
+ name: name,
843
+ type: "file",
844
+ accept: "image/*"
845
+ //capture="camera" // With this property, users on most mobiles can only take photo but no options to pick up a photo from gallery
846
+ ,
847
+ className: "image-upload visually-hidden",
848
+ onChange: this.displayImage,
849
+ "data-clearlabel": this.props.data.label_after_photo_clear_icon,
850
+ disabled: this.props.read_only,
851
+ id: name
852
+ }), /*#__PURE__*/_react["default"].createElement("div", {
853
+ className: "image-upload-control",
854
+ style: {
855
+ position: 'relative'
856
+ }
857
+ }, /*#__PURE__*/_react["default"].createElement("label", {
858
+ className: "btn btn-outline-secondary",
859
+ htmlFor: name
860
+ }, /*#__PURE__*/_react["default"].createElement("i", {
861
+ className: "fas fa-camera"
862
+ }), " ", 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", {
863
+ onLoad: function onLoad() {
864
+ return URL.revokeObjectURL(_this13.state.previewImg);
865
+ },
866
+ src: this.state.previewImg,
867
+ height: "100",
868
+ className: "image-upload-preview"
869
+ }), /*#__PURE__*/_react["default"].createElement("br", null), /*#__PURE__*/_react["default"].createElement("div", {
870
+ className: "btn btn-image-clear",
871
+ onClick: this.clearImage
872
+ }, /*#__PURE__*/_react["default"].createElement("i", {
873
+ className: "fas fa-times"
874
+ }), " ", this.props.data.label_after_photo_clear_icon)))));
875
+ } else {
876
+ return /*#__PURE__*/_react["default"].createElement("div", {
877
+ style: _objectSpread({}, this.props.style),
878
+ className: baseClasses
879
+ }, /*#__PURE__*/_react["default"].createElement(_componentHeader["default"], this.props), /*#__PURE__*/_react["default"].createElement("div", {
880
+ className: "mb-3"
881
+ }, /*#__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", {
882
+ style: imageStyle,
883
+ src: sourceDataURL
884
+ })) : /*#__PURE__*/_react["default"].createElement("div", {
885
+ className: "image-upload-container"
886
+ }, /*#__PURE__*/_react["default"].createElement("div", {
887
+ style: fileInputStyle,
888
+ className: "upload-card"
889
+ }, /*#__PURE__*/_react["default"].createElement("input", {
890
+ name: name,
891
+ type: "file",
892
+ accept: "image/*",
893
+ capture: "camera",
894
+ className: "visually-hidden",
895
+ onChange: this.displayImage,
896
+ id: name,
897
+ disabled: this.props.read_only
898
+ }), /*#__PURE__*/_react["default"].createElement("label", {
899
+ htmlFor: name,
900
+ className: "upload-card-content"
901
+ }, /*#__PURE__*/_react["default"].createElement("i", {
902
+ className: "fas fa-cloud-upload-alt upload-icon"
903
+ }), /*#__PURE__*/_react["default"].createElement("span", {
904
+ className: "upload-text"
905
+ }, this.props.data.message_under_camera_icon), /*#__PURE__*/_react["default"].createElement("div", {
906
+ className: "btn-browse"
907
+ }, this.props.data.label_after_camera_icon))), this.state.img && /*#__PURE__*/_react["default"].createElement("div", {
908
+ className: "preview-container"
909
+ }, /*#__PURE__*/_react["default"].createElement("img", {
910
+ onLoad: function onLoad() {
911
+ return URL.revokeObjectURL(_this13.state.previewImg);
912
+ },
913
+ src: this.state.previewImg,
914
+ className: "image-upload-preview",
915
+ alt: "Preview",
916
+ height: "100"
917
+ }), /*#__PURE__*/_react["default"].createElement("button", {
918
+ className: "btn btn-image-clear",
919
+ onClick: this.clearImage
920
+ }, /*#__PURE__*/_react["default"].createElement("i", {
921
+ className: "fas fa-times"
922
+ }), " Remove Photo")))));
923
+ }
874
924
  }
875
925
  }]);
876
926
  }(_react["default"].Component);
@@ -10,6 +10,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
10
10
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
11
11
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
12
12
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
13
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
14
  var _react = _interopRequireDefault(require("react"));
14
15
  var _reactTextareaAutosize = _interopRequireDefault(require("react-textarea-autosize"));
15
16
  var _draftJs = require("draft-js");
@@ -34,6 +35,17 @@ var FormElementsEdit = exports["default"] = /*#__PURE__*/function (_React$Compon
34
35
  var _this;
35
36
  (0, _classCallCheck2["default"])(this, FormElementsEdit);
36
37
  _this = _callSuper(this, FormElementsEdit, [props]);
38
+ // Instead of using editElementProp for the camera layout change, we have a separate handler to immediately update the element on change without waiting for blur, as it's a radio button and we want the change to be reflected immediately in the UI.
39
+ (0, _defineProperty2["default"])(_this, "handleUploadLayoutChange", function (e) {
40
+ var this_element = _this.state.element;
41
+ this_element["upload_layout"] = e.target["value"];
42
+ _this.setState({
43
+ element: this_element,
44
+ dirty: true
45
+ }, function () {
46
+ _this.updateElement();
47
+ });
48
+ });
37
49
  _this.state = {
38
50
  element: _this.props.element,
39
51
  data: _this.props.data,
@@ -348,53 +360,45 @@ var FormElementsEdit = exports["default"] = /*#__PURE__*/function (_React$Compon
348
360
  defaultValue: this.props.element.src,
349
361
  onBlur: this.updateElement.bind(this),
350
362
  onChange: this.editElementProp.bind(this, 'src', 'value')
351
- }))), canHaveImageSize && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
363
+ }))), this.state.element.element === 'Camera' && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
352
364
  className: "mb-3"
365
+ }, /*#__PURE__*/_react["default"].createElement("label", {
366
+ className: "control-label bold"
367
+ }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
368
+ id: "upload-layout"
369
+ }), ":"), /*#__PURE__*/_react["default"].createElement("div", {
370
+ className: "d-flex align-items-center gap-3"
353
371
  }, /*#__PURE__*/_react["default"].createElement("div", {
354
- className: "form-check"
372
+ className: "form-check d-flex align-items-center"
355
373
  }, /*#__PURE__*/_react["default"].createElement("input", {
356
- id: "do-center",
357
374
  className: "form-check-input",
358
- type: "checkbox",
359
- checked: this_checked_center,
360
- value: true,
361
- onChange: this.editElementProp.bind(this, 'center', 'checked')
375
+ type: "radio",
376
+ name: "uploadLayout",
377
+ id: "uploadLayoutStandard",
378
+ value: "standard",
379
+ checked: this.props.element.upload_layout === "standard",
380
+ onChange: this.handleUploadLayoutChange
362
381
  }), /*#__PURE__*/_react["default"].createElement("label", {
363
- className: "form-check-label",
364
- htmlFor: "do-center"
365
- }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
366
- id: "center"
367
- }), "?"))), /*#__PURE__*/_react["default"].createElement("div", {
368
- className: "row"
369
- }, /*#__PURE__*/_react["default"].createElement("div", {
370
- className: "col-sm-3"
371
- }, /*#__PURE__*/_react["default"].createElement("label", {
372
- className: "control-label",
373
- htmlFor: "elementWidth"
382
+ className: "form-check-label ms-2",
383
+ htmlFor: "uploadLayoutStandard"
374
384
  }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
375
- id: "width"
376
- }), ":"), /*#__PURE__*/_react["default"].createElement("input", {
377
- id: "elementWidth",
378
- type: "text",
379
- className: "form-control",
380
- defaultValue: this.props.element.width,
381
- onBlur: this.updateElement.bind(this),
382
- onChange: this.editElementProp.bind(this, 'width', 'value')
383
- })), /*#__PURE__*/_react["default"].createElement("div", {
384
- className: "col-sm-3"
385
- }, /*#__PURE__*/_react["default"].createElement("label", {
386
- className: "control-label",
387
- htmlFor: "elementHeight"
385
+ id: "upload-layout-standard"
386
+ }))), /*#__PURE__*/_react["default"].createElement("div", {
387
+ className: "form-check d-flex align-items-center"
388
+ }, /*#__PURE__*/_react["default"].createElement("input", {
389
+ className: "form-check-input",
390
+ type: "radio",
391
+ name: "uploadLayout",
392
+ id: "uploadLayoutDropZone",
393
+ value: "dropzone",
394
+ checked: this.props.element.upload_layout === "dropzone",
395
+ onChange: this.handleUploadLayoutChange
396
+ }), /*#__PURE__*/_react["default"].createElement("label", {
397
+ className: "form-check-label ms-2",
398
+ htmlFor: "uploadLayoutDropZone"
388
399
  }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
389
- id: "height"
390
- }), ":"), /*#__PURE__*/_react["default"].createElement("input", {
391
- id: "elementHeight",
392
- type: "text",
393
- className: "form-control",
394
- defaultValue: this.props.element.height,
395
- onBlur: this.updateElement.bind(this),
396
- onChange: this.editElementProp.bind(this, 'height', 'value')
397
- })))), this.state.element.element === 'Camera' && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
400
+ id: "upload-layout-dropzone"
401
+ }))))), /*#__PURE__*/_react["default"].createElement("div", {
398
402
  className: "mb-3"
399
403
  }, /*#__PURE__*/_react["default"].createElement("label", {
400
404
  className: "control-label",
@@ -436,7 +440,59 @@ var FormElementsEdit = exports["default"] = /*#__PURE__*/function (_React$Compon
436
440
  defaultValue: this.props.element.label_after_photo_clear_icon,
437
441
  onBlur: this.updateElement.bind(this),
438
442
  onChange: this.editElementProp.bind(this, 'label_after_photo_clear_icon', 'value')
439
- }))), this.state.element.element === 'FileUpload' && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
443
+ }))), canHaveImageSize && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
444
+ className: "mb-3"
445
+ }, /*#__PURE__*/_react["default"].createElement("label", {
446
+ className: "control-label bold"
447
+ }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
448
+ id: "image-layout"
449
+ }), ":"), /*#__PURE__*/_react["default"].createElement("div", {
450
+ className: "form-check"
451
+ }, /*#__PURE__*/_react["default"].createElement("input", {
452
+ id: "do-center",
453
+ className: "form-check-input",
454
+ type: "checkbox",
455
+ checked: this_checked_center,
456
+ value: true,
457
+ onChange: this.editElementProp.bind(this, 'center', 'checked')
458
+ }), /*#__PURE__*/_react["default"].createElement("label", {
459
+ className: "form-check-label",
460
+ htmlFor: "do-center"
461
+ }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
462
+ id: "center"
463
+ }), "?"))), /*#__PURE__*/_react["default"].createElement("div", {
464
+ className: "row mb-3"
465
+ }, /*#__PURE__*/_react["default"].createElement("div", {
466
+ className: "col-sm-3"
467
+ }, /*#__PURE__*/_react["default"].createElement("label", {
468
+ className: "control-label",
469
+ htmlFor: "elementWidth"
470
+ }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
471
+ id: "width"
472
+ }), ":"), /*#__PURE__*/_react["default"].createElement("input", {
473
+ id: "elementWidth",
474
+ type: "text",
475
+ className: "form-control",
476
+ defaultValue: this.props.element.width,
477
+ onBlur: this.updateElement.bind(this),
478
+ onChange: this.editElementProp.bind(this, 'width', 'value')
479
+ })), /*#__PURE__*/_react["default"].createElement("div", {
480
+ className: "col-sm-3"
481
+ }, /*#__PURE__*/_react["default"].createElement("label", {
482
+ className: "control-label",
483
+ htmlFor: "elementHeight"
484
+ }, /*#__PURE__*/_react["default"].createElement(_IntlMessages["default"], {
485
+ id: "height"
486
+ }), ":"), /*#__PURE__*/_react["default"].createElement("input", {
487
+ id: "elementHeight",
488
+ type: "text",
489
+ className: "form-control",
490
+ defaultValue: this.props.element.height,
491
+ onBlur: this.updateElement.bind(this),
492
+ onChange: this.editElementProp.bind(this, 'height', 'value')
493
+ })), /*#__PURE__*/_react["default"].createElement("small", {
494
+ className: "form-text text-muted"
495
+ }, "Use ", /*#__PURE__*/_react["default"].createElement("code", null, "px"), " or ", /*#__PURE__*/_react["default"].createElement("code", null, "%"), " (e.g. 200px, 100%)."))), this.state.element.element === 'FileUpload' && /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("div", {
440
496
  className: "mb-3"
441
497
  }, /*#__PURE__*/_react["default"].createElement("label", {
442
498
  className: "control-label",
@@ -37,9 +37,13 @@
37
37
  "word" : "Word",
38
38
  "excel" : "Excel",
39
39
  "ppt" : "PPT",
40
- "display-label-after-camera-icon" : "Display label after camera icon",
40
+ "upload-layout" : "Upload Area Layout",
41
+ "upload-layout-standard" : "Standard",
42
+ "upload-layout-dropzone" : "Dropzone",
43
+ "image-layout" : "Image Layout",
44
+ "display-label-after-camera-icon" : "Display label on button",
41
45
  "place-holder-display-label-after-camera-icon" : "Upload Photo",
42
- "display-message-under-camera-icon" : "Display message under camera icon",
46
+ "display-message-under-camera-icon" : "Display message under icon",
43
47
  "place-holder-display-message-under-camera-icon" : "Select an image from your computer or device.",
44
48
  "display-label-after-photo-clear-icon" : "Display label after photo clear icon",
45
49
  "place-holder-display-label-after-photo-clear-icon" : "Clear Photo",
@@ -107,12 +111,4 @@
107
111
  "message.was-not-registered": "was not registered",
108
112
  "message.invalid-email": "field requires valid email address",
109
113
  "message.invalid-phone-number": "field requires a valid phone number"
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
114
  }
@@ -37,9 +37,13 @@
37
37
  "word": "Word",
38
38
  "excel": "Excel",
39
39
  "ppt": "PPT",
40
+ "upload-layout" : "چیدمان بخش بارگذاری",
41
+ "upload-layout-standard" : "استاندارد",
42
+ "upload-layout-dropzone" : "رها کردن فایل",
43
+ "image-layout" : "چیدمان تصویر",
40
44
  "display-label-after-camera-icon" : "نمایش برچسب پس از آیکون دوربین",
41
45
  "place-holder-display-label-after-camera-icon" : "آپلود عکس",
42
- "display-message-under-camera-icon" : "نمایش پیام زیر آیکون دوربین",
46
+ "display-message-under-camera-icon" : "نمایش پیام زیر آیکون",
43
47
  "place-holder-display-message-under-camera-icon" : "یک تصویر را از رایانه یا دستگاه خود انتخاب کنید.",
44
48
  "display-label-after-photo-clear-icon" : "نمایش برچسب پس از آیکون حذف عکس",
45
49
  "place-holder-display-label-after-photo-clear-icon" : "حذف عکس",
@@ -107,4 +111,4 @@
107
111
  "message.was-not-registered": "ثبت نشد",
108
112
  "message.invalid-email": "فیلد نیاز به آدرس ایمیل معتبر دارد",
109
113
  "message.invalid-phone-number": "فیلد نیاز به شماره تلفن معتبر دارد"
110
- }
114
+ }
@@ -37,9 +37,13 @@
37
37
  "word" : "Word",
38
38
  "excel" : "Excel",
39
39
  "ppt" : "PPT",
40
+ "upload-layout" : "Layout dell'area di caricamento",
41
+ "upload-layout-standard" : "Standard",
42
+ "upload-layout-dropzone" : "Area di rilascio",
43
+ "image-layout" : "Layout dell'immagine",
40
44
  "display-label-after-camera-icon" : "Mostra etichetta dopo l'icona della fotocamera",
41
45
  "place-holder-display-label-after-camera-icon" : "Carica foto",
42
- "display-message-under-camera-icon" : "Mostra messaggio sotto l'icona della fotocamera",
46
+ "display-message-under-camera-icon" : "Mostra il messaggio sotto l'icona",
43
47
  "place-holder-display-message-under-camera-icon" : "Seleziona un'immagine dal tuo computer o dispositivo.",
44
48
  "display-label-after-photo-clear-icon" : "Mostra etichetta dopo l'icona di cancellazione della foto",
45
49
  "place-holder-display-label-after-photo-clear-icon" : "Cancella foto",
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "display-label": "Nhãn hiển thị",
3
3
  "choose-file": "Chọn tệp tin",
4
+ "choose-file-type": "Chọn loại tệp",
5
+ "select-file-type": "Chọn kiểu tập tin",
4
6
  "text-to-display": "Chữ hiển thị",
5
7
  "link-to": "Liên kết tới",
6
8
  "center": "Giữa",
@@ -31,9 +33,17 @@
31
33
  "populate-options-from-api": "Lấy dữ liệu từ API",
32
34
  "minimum-number-of-selections" : "Số lượng lựa chọn tối thiểu mà khách hàng phải chọn",
33
35
  "populate": "Thực hiện",
36
+ "pdf" : "PDF",
37
+ "word" : "Word",
38
+ "excel" : "Excel",
39
+ "ppt" : "PPT",
40
+ "upload-layout" : "Bố cục khu vực tải lên",
41
+ "upload-layout-standard" : "Tiêu chuẩn",
42
+ "upload-layout-dropzone" : "Vùng thả tệp",
43
+ "image-layout" : "Bố cục hình ảnh",
34
44
  "display-label-after-camera-icon" : "Hiển thị nhãn sau biểu tượng máy ảnh",
35
45
  "place-holder-display-label-after-camera-icon" : "Tải ảnh lên",
36
- "display-message-under-camera-icon" : "Hiển thị tin nhắn dưới biểu tượng máy ảnh",
46
+ "display-message-under-camera-icon" : "Hiển thị thông báo dưới biểu tượng",
37
47
  "place-holder-display-message-under-camera-icon" : "Chọn một hình ảnh từ máy tính hoặc thiết bị của bạn.",
38
48
  "display-label-after-photo-clear-icon" : "Hiển thị nhãn sau biểu tượng xóa ảnh",
39
49
  "place-holder-display-label-after-photo-clear-icon" : "Xóa ảnh",
@@ -67,12 +77,16 @@
67
77
  "checkboxes" : "Hộp chọn",
68
78
  "multiple-choice":"Nhiều lựa chọn",
69
79
  "text-input":"Nhập chữ",
80
+ "email-input": "Email",
81
+ "phone-input": "Số điện thoại",
70
82
  "number-input":"Nhập số",
71
- "fieldset":"bộ trường",
72
83
  "multi-line-input":"Nhập nhiều dòng",
84
+ "fieldset":"bộ trường",
73
85
  "two-columns-row":"Dòng có hai cột",
74
86
  "three-columns-row":"Dòng có ba cột",
75
87
  "four-columns-row":"Dòng có bốn cột",
88
+ "five-columns-row": "Hàng năm cột",
89
+ "six-columns-row": "Hàng sáu cột",
76
90
  "image":"Liên kết ảnh",
77
91
  "rating":"Đánh giá",
78
92
  "date":"Ngày",
@@ -81,17 +95,20 @@
81
95
  "file-attachment":"Tệp đính kèm",
82
96
  "range":"Khoảng",
83
97
  "camera":"Tải ảnh",
98
+ "file-upload": "Tải tệp lên",
84
99
  "place-holder-text": "Nội dung...",
85
100
  "place-holder-label": "Nhãn",
86
101
  "place-holder-website-link": "Đường dẫn tới website...",
87
102
  "place-holder-file-name": "Tên tệp...",
88
- "easy": "Easy",
89
- "difficult": "Difficult",
90
-
103
+ "place-holder-email": "E-Mail",
104
+ "place-holder-phone-number": "Số điện thoại",
105
+ "easy": "Dễ",
106
+ "difficult": "Khó",
91
107
  "drop-zone": "Khu vực kéo thả",
92
108
 
93
109
  "message.is-required": "không được bỏ trống",
94
110
  "message.was-answered incorrectly": "đã trả lời sai",
95
- "message.was-not-registered": "chưa đăng ký"
96
-
111
+ "message.was-not-registered": "chưa đăng ký",
112
+ "message.invalid-email": "trường này yêu cầu địa chỉ email hợp lệ",
113
+ "message.invalid-phone-number": "trường này yêu cầu số điện thoại hợp lệ"
97
114
  }
package/lib/preview.js CHANGED
@@ -30,7 +30,57 @@ var Preview = exports["default"] = /*#__PURE__*/function (_React$Component) {
30
30
  _this = _callSuper(this, Preview, [props]);
31
31
  (0, _defineProperty2["default"])(_this, "state", {
32
32
  data: [],
33
- answer_data: {}
33
+ answer_data: {},
34
+ // make edit form movable state
35
+ editFormPosition: {
36
+ x: 100,
37
+ y: 100
38
+ },
39
+ dragging: false,
40
+ dragOffset: null
41
+ });
42
+ // start dragging the edit form (ignore clicks on inputs/buttons)
43
+ (0, _defineProperty2["default"])(_this, "onEditFormMouseDown", function (e) {
44
+ var tag = e.target && e.target.tagName && e.target.tagName.toLowerCase();
45
+ if (['input', 'textarea', 'select', 'button', 'a', 'label'].includes(tag)) {
46
+ return;
47
+ }
48
+ if (!_this.editForm.current) return;
49
+ var rect = _this.editForm.current.getBoundingClientRect();
50
+ var offset = {
51
+ x: e.clientX - rect.left,
52
+ y: e.clientY - rect.top
53
+ };
54
+ _this.setState({
55
+ dragging: true,
56
+ dragOffset: offset
57
+ });
58
+ document.addEventListener('mousemove', _this.onEditFormDrag);
59
+ document.addEventListener('mouseup', _this.onEditFormMouseUp);
60
+ e.stopPropagation();
61
+ e.preventDefault();
62
+ });
63
+ (0, _defineProperty2["default"])(_this, "onEditFormDrag", function (e) {
64
+ if (!_this.state.dragging || !_this.state.dragOffset) return;
65
+ var x = e.clientX - _this.state.dragOffset.x;
66
+ var y = e.clientY - _this.state.dragOffset.y;
67
+ _this.setState({
68
+ editFormPosition: {
69
+ x: x,
70
+ y: y
71
+ }
72
+ });
73
+ });
74
+ (0, _defineProperty2["default"])(_this, "onEditFormMouseUp", function (e) {
75
+ if (_this.state.dragging) {
76
+ _this.setState({
77
+ dragging: false,
78
+ dragOffset: null
79
+ });
80
+ document.removeEventListener('mousemove', _this.onEditFormDrag);
81
+ document.removeEventListener('mouseup', _this.onEditFormMouseUp);
82
+ }
83
+ e.stopPropagation();
34
84
  });
35
85
  (0, _defineProperty2["default"])(_this, "editModeOff", function (e) {
36
86
  if (_this.editForm.current && !_this.editForm.current.contains(e.target)) {
@@ -48,10 +98,20 @@ var Preview = exports["default"] = /*#__PURE__*/function (_React$Component) {
48
98
  var onLoad = props.onLoad,
49
99
  onPost = props.onPost;
50
100
  _store["default"].setExternalHandler(onLoad, onPost);
101
+
102
+ // eidtForm is for Element Property Edit,
103
+ // used to detect clicks outside the edit panel and to make it draggable
51
104
  _this.editForm = /*#__PURE__*/_react["default"].createRef();
105
+ _this._editFormListenerAttached = false; // <-- track listener
52
106
  _this.state = {
53
107
  data: props.data || [],
54
- answer_data: {}
108
+ answer_data: {},
109
+ editFormPosition: {
110
+ x: 100,
111
+ y: 100
112
+ },
113
+ dragging: false,
114
+ dragOffset: null
55
115
  };
56
116
  _this.seq = 0;
57
117
  _this._onUpdate = _this._onChange.bind(_this);
@@ -83,11 +143,49 @@ var Preview = exports["default"] = /*#__PURE__*/function (_React$Component) {
83
143
  saveAlways: saveAlways
84
144
  });
85
145
  document.addEventListener('mousedown', this.editModeOff);
146
+
147
+ // attach drag start on the edit form container if present
148
+ if (this.editForm && this.editForm.current) {
149
+ this.editForm.current.addEventListener('mousedown', this.onEditFormMouseDown);
150
+ this._editFormListenerAttached = true;
151
+ }
152
+ }
153
+ }, {
154
+ key: "componentDidUpdate",
155
+ value: function componentDidUpdate(prevProps) {
156
+ // attach/detach mousedown listener when edit panel opens/closes
157
+ var wasOpen = !!prevProps.editElement;
158
+ var isOpen = !!this.props.editElement;
159
+ if (!wasOpen && isOpen) {
160
+ // always (re)attach the listener to the current DOM node when opening.
161
+ if (this.editForm && this.editForm.current) {
162
+ // defensive remove in case a stale listener flag is set
163
+ try {
164
+ this.editForm.current.removeEventListener('mousedown', this.onEditFormMouseDown);
165
+ } catch (e) {/* ignore */}
166
+ this.editForm.current.addEventListener('mousedown', this.onEditFormMouseDown);
167
+ this._editFormListenerAttached = true;
168
+ } else {
169
+ this._editFormListenerAttached = false;
170
+ }
171
+ } else if (wasOpen && !isOpen) {
172
+ // mark as detached so future opens will reattach; remove if node still exists
173
+ if (this.editForm && this.editForm.current && this._editFormListenerAttached) {
174
+ this.editForm.current.removeEventListener('mousedown', this.onEditFormMouseDown);
175
+ }
176
+ this._editFormListenerAttached = false;
177
+ }
86
178
  }
87
179
  }, {
88
180
  key: "componentWillUnmount",
89
181
  value: function componentWillUnmount() {
90
182
  document.removeEventListener('mousedown', this.editModeOff);
183
+ if (this.editForm && this.editForm.current && this._editFormListenerAttached) {
184
+ this.editForm.current.removeEventListener('mousedown', this.onEditFormMouseDown);
185
+ this._editFormListenerAttached = false;
186
+ }
187
+ document.removeEventListener('mousemove', this.onEditFormDrag);
188
+ document.removeEventListener('mouseup', this.onEditFormMouseUp);
91
189
  }
92
190
  }, {
93
191
  key: "_setValue",
@@ -359,12 +457,27 @@ var Preview = exports["default"] = /*#__PURE__*/function (_React$Component) {
359
457
  var items = data.map(function (item, index) {
360
458
  return _this6.getElement(item, index);
361
459
  });
460
+ var editFormStyle = {
461
+ position: 'fixed',
462
+ left: this.state.editFormPosition.x,
463
+ top: this.state.editFormPosition.y,
464
+ zIndex: 9999,
465
+ cursor: this.state.dragging ? 'grabbing' : 'move',
466
+ height: 'auto',
467
+ // allow height to fit content
468
+ maxHeight: '80vh',
469
+ // prevent overflow beyond viewport
470
+ overflow: 'auto',
471
+ // enable scrolling when content is taller than maxHeight
472
+ boxSizing: 'border-box' // ensure padding doesn't grow box beyond maxHeight
473
+ };
362
474
  return /*#__PURE__*/_react["default"].createElement("div", {
363
475
  className: classes
364
- }, /*#__PURE__*/_react["default"].createElement("div", {
476
+ }, this.props.editElement !== null && /*#__PURE__*/_react["default"].createElement("div", {
365
477
  className: "edit-form",
366
- ref: this.editForm
367
- }, this.props.editElement !== null && this.showEditForm()), /*#__PURE__*/_react["default"].createElement("div", {
478
+ ref: this.editForm,
479
+ style: editFormStyle
480
+ }, this.showEditForm()), /*#__PURE__*/_react["default"].createElement("div", {
368
481
  className: "Sortable"
369
482
  }, items), /*#__PURE__*/_react["default"].createElement(PlaceHolder, {
370
483
  id: "form-place-holder",
@@ -381,6 +494,7 @@ Preview.defaultProps = {
381
494
  files: [],
382
495
  editMode: false,
383
496
  editElement: null,
497
+ // element currently being edited
384
498
  className: 'col-md-9 react-form-builder-preview float-start',
385
499
  renderEditForm: function renderEditForm(props) {
386
500
  return /*#__PURE__*/_react["default"].createElement(_formDynamicEdit["default"], props);