@goldenpine/react-form-builder2 0.20.3-build.2 → 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.
@@ -31,14 +31,19 @@
31
31
  "description": "Description",
32
32
  "correct-answer" : "Correct Answer",
33
33
  "populate-options-from-api" : "Populate Options from API",
34
+ "minimum-number-of-selections" : "The minimum number of options a customer must select",
34
35
  "populate" : "Populate",
35
36
  "pdf" : "PDF",
36
37
  "word" : "Word",
37
38
  "excel" : "Excel",
38
39
  "ppt" : "PPT",
39
- "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",
40
45
  "place-holder-display-label-after-camera-icon" : "Upload Photo",
41
- "display-message-under-camera-icon" : "Display message under camera icon",
46
+ "display-message-under-camera-icon" : "Display message under icon",
42
47
  "place-holder-display-message-under-camera-icon" : "Select an image from your computer or device.",
43
48
  "display-label-after-photo-clear-icon" : "Display label after photo clear icon",
44
49
  "place-holder-display-label-after-photo-clear-icon" : "Clear Photo",
@@ -106,12 +111,4 @@
106
111
  "message.was-not-registered": "was not registered",
107
112
  "message.invalid-email": "field requires valid email address",
108
113
  "message.invalid-phone-number": "field requires a valid phone number"
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
114
  }
@@ -31,14 +31,19 @@
31
31
  "description": "توضیحات",
32
32
  "correct-answer": "پاسخ صحیح",
33
33
  "populate-options-from-api": "پر کردن گزینه‌ها از API",
34
+ "minimum-number-of-selections" : "حداقل تعداد گزینه‌هایی که مشتری باید انتخاب کند",
34
35
  "populate": "پر کردن",
35
36
  "pdf": "PDF",
36
37
  "word": "Word",
37
38
  "excel": "Excel",
38
39
  "ppt": "PPT",
40
+ "upload-layout" : "چیدمان بخش بارگذاری",
41
+ "upload-layout-standard" : "استاندارد",
42
+ "upload-layout-dropzone" : "رها کردن فایل",
43
+ "image-layout" : "چیدمان تصویر",
39
44
  "display-label-after-camera-icon" : "نمایش برچسب پس از آیکون دوربین",
40
45
  "place-holder-display-label-after-camera-icon" : "آپلود عکس",
41
- "display-message-under-camera-icon" : "نمایش پیام زیر آیکون دوربین",
46
+ "display-message-under-camera-icon" : "نمایش پیام زیر آیکون",
42
47
  "place-holder-display-message-under-camera-icon" : "یک تصویر را از رایانه یا دستگاه خود انتخاب کنید.",
43
48
  "display-label-after-photo-clear-icon" : "نمایش برچسب پس از آیکون حذف عکس",
44
49
  "place-holder-display-label-after-photo-clear-icon" : "حذف عکس",
@@ -106,4 +111,4 @@
106
111
  "message.was-not-registered": "ثبت نشد",
107
112
  "message.invalid-email": "فیلد نیاز به آدرس ایمیل معتبر دارد",
108
113
  "message.invalid-phone-number": "فیلد نیاز به شماره تلفن معتبر دارد"
109
- }
114
+ }
@@ -31,14 +31,19 @@
31
31
  "description": "Descrizione",
32
32
  "correct-answer" : "Risposta corretta",
33
33
  "populate-options-from-api" : "Popola opzione da API",
34
+ "minimum-number-of-selections" : "Il numero minimo di opzioni che un cliente deve selezionare",
34
35
  "populate" : "Popola",
35
36
  "pdf" : "PDF",
36
37
  "word" : "Word",
37
38
  "excel" : "Excel",
38
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",
39
44
  "display-label-after-camera-icon" : "Mostra etichetta dopo l'icona della fotocamera",
40
45
  "place-holder-display-label-after-camera-icon" : "Carica foto",
41
- "display-message-under-camera-icon" : "Mostra messaggio sotto l'icona della fotocamera",
46
+ "display-message-under-camera-icon" : "Mostra il messaggio sotto l'icona",
42
47
  "place-holder-display-message-under-camera-icon" : "Seleziona un'immagine dal tuo computer o dispositivo.",
43
48
  "display-label-after-photo-clear-icon" : "Mostra etichetta dopo l'icona di cancellazione della foto",
44
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",
@@ -29,10 +31,19 @@
29
31
  "description": "Mô tả",
30
32
  "correct-answer": "Lựa chọn đúng",
31
33
  "populate-options-from-api": "Lấy dữ liệu từ API",
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",
32
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",
33
44
  "display-label-after-camera-icon" : "Hiển thị nhãn sau biểu tượng máy ảnh",
34
45
  "place-holder-display-label-after-camera-icon" : "Tải ảnh lên",
35
- "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",
36
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.",
37
48
  "display-label-after-photo-clear-icon" : "Hiển thị nhãn sau biểu tượng xóa ảnh",
38
49
  "place-holder-display-label-after-photo-clear-icon" : "Xóa ảnh",
@@ -66,12 +77,16 @@
66
77
  "checkboxes" : "Hộp chọn",
67
78
  "multiple-choice":"Nhiều lựa chọn",
68
79
  "text-input":"Nhập chữ",
80
+ "email-input": "Email",
81
+ "phone-input": "Số điện thoại",
69
82
  "number-input":"Nhập số",
70
- "fieldset":"bộ trường",
71
83
  "multi-line-input":"Nhập nhiều dòng",
84
+ "fieldset":"bộ trường",
72
85
  "two-columns-row":"Dòng có hai cột",
73
86
  "three-columns-row":"Dòng có ba cột",
74
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",
75
90
  "image":"Liên kết ảnh",
76
91
  "rating":"Đánh giá",
77
92
  "date":"Ngày",
@@ -80,17 +95,20 @@
80
95
  "file-attachment":"Tệp đính kèm",
81
96
  "range":"Khoảng",
82
97
  "camera":"Tải ảnh",
98
+ "file-upload": "Tải tệp lên",
83
99
  "place-holder-text": "Nội dung...",
84
100
  "place-holder-label": "Nhãn",
85
101
  "place-holder-website-link": "Đường dẫn tới website...",
86
102
  "place-holder-file-name": "Tên tệp...",
87
- "easy": "Easy",
88
- "difficult": "Difficult",
89
-
103
+ "place-holder-email": "E-Mail",
104
+ "place-holder-phone-number": "Số điện thoại",
105
+ "easy": "Dễ",
106
+ "difficult": "Khó",
90
107
  "drop-zone": "Khu vực kéo thả",
91
108
 
92
109
  "message.is-required": "không được bỏ trống",
93
110
  "message.was-answered incorrectly": "đã trả lời sai",
94
- "message.was-not-registered": "chưa đăng ký"
95
-
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ệ"
96
114
  }
@@ -61,7 +61,9 @@ function isContainer(item) {
61
61
  return true;
62
62
  }
63
63
  if (data.field_name) {
64
- return data.field_name.indexOf('_col_row') > -1;
64
+ // Check if the field name indicates a container
65
+ // Fix a runtime error when dropping a fieldset inside a multi-column row - which dropping seems not supported
66
+ return data.field_name.indexOf('_col_row') > -1 || data.field_name.indexOf('fieldset') > -1;
65
67
  }
66
68
  }
67
69
  }
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,7 +494,8 @@ Preview.defaultProps = {
381
494
  files: [],
382
495
  editMode: false,
383
496
  editElement: null,
384
- className: 'col-md-9 react-form-builder-preview float-left',
497
+ // element currently being edited
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);
387
501
  }
@@ -14,7 +14,7 @@ var _react = _interopRequireWildcard(require("react"));
14
14
  var _propTypes = _interopRequireDefault(require("prop-types"));
15
15
  var _reactDnd = require("react-dnd");
16
16
  var _ItemTypes = _interopRequireDefault(require("./ItemTypes"));
17
- var _excluded = ["index", "id", "moveCard", "seq"];
17
+ var _excluded = ["index", "id", "moveCard", "seq", "component"];
18
18
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
19
19
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
20
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -153,20 +153,19 @@ var useDragAndDrop = function useDragAndDrop(props) {
153
153
 
154
154
  // Modern approach using a functional component wrapper instead of HOC
155
155
  var DraggableCard = function DraggableCard(props) {
156
+ // ✅ Move the default value directly into destructuring
156
157
  var index = props.index,
157
158
  id = props.id,
158
159
  moveCard = props.moveCard,
159
160
  _props$seq = props.seq,
160
161
  seq = _props$seq === void 0 ? -1 : _props$seq,
162
+ ComposedComponent = props.component,
161
163
  restProps = (0, _objectWithoutProperties2["default"])(props, _excluded);
162
164
  var _useDragAndDrop = useDragAndDrop(props),
163
165
  ref = _useDragAndDrop.ref,
164
166
  previewRef = _useDragAndDrop.previewRef,
165
167
  isDragging = _useDragAndDrop.isDragging;
166
168
  var opacity = isDragging ? 0 : 1;
167
-
168
- // Use the ComposedComponent passed in props
169
- var ComposedComponent = props.component;
170
169
  return /*#__PURE__*/_react["default"].createElement("div", {
171
170
  ref: previewRef
172
171
  }, /*#__PURE__*/_react["default"].createElement("div", {
@@ -189,9 +188,11 @@ DraggableCard.propTypes = {
189
188
  moveCard: _propTypes["default"].func.isRequired,
190
189
  seq: _propTypes["default"].number
191
190
  };
192
- DraggableCard.defaultProps = {
193
- seq: -1
194
- };
191
+
192
+ // ❌ REMOVE THIS BLOCK ENTIRELY
193
+ // DraggableCard.defaultProps = {
194
+ // seq: -1,
195
+ // };
195
196
 
196
197
  // This replaces the HOC pattern with a component that takes the component as a prop
197
198
  function createDraggableCard(ComposedComponent) {
package/lib/toolbar.js CHANGED
@@ -423,6 +423,7 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
423
423
  id: 'place-holder-label'
424
424
  }),
425
425
  field_name: 'camera_',
426
+ upload_layout: 'standard',
426
427
  label_after_camera_icon: intl.formatMessage({
427
428
  id: 'place-holder-display-label-after-camera-icon'
428
429
  }),
@@ -539,6 +540,7 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
539
540
  elementOptions.max_label = item.max_label;
540
541
  }
541
542
  if (elementKey === 'Camera') {
543
+ elementOptions.upload_layout = item.upload_layout;
542
544
  elementOptions.label_after_camera_icon = item.label_after_camera_icon;
543
545
  elementOptions.message_under_camera_icon = item.message_under_camera_icon;
544
546
  elementOptions.label_after_photo_clear_icon = item.label_after_photo_clear_icon;
@@ -588,7 +590,7 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
588
590
  grouped = _buildGroupItems.grouped,
589
591
  groupKeys = _buildGroupItems.groupKeys;
590
592
  return /*#__PURE__*/_react["default"].createElement("div", {
591
- className: "col-md-3 react-form-builder-toolbar float-right",
593
+ className: "col-md-3 react-form-builder-toolbar float-end",
592
594
  style: {
593
595
  position: this.state.isPinned ? 'fixed' : '',
594
596
  // set up the vertical boundary by top/bottom,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goldenpine/react-form-builder2",
3
- "version": "0.20.3-build.2",
3
+ "version": "0.20.3-build.21",
4
4
  "description": "A complete form builder for react.",
5
5
  "main": "lib/index.js",
6
6
  "types": "types/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "engines": {
30
30
  "node": ">=18.0.0"
31
31
  },
32
- "author": "Kiho Chang",
32
+ "author": "Golden Pine",
33
33
  "dependencies": {
34
34
  "beedle": "^0.8.1",
35
35
  "classnames": "^2.2.6",
@@ -43,7 +43,7 @@
43
43
  "immutability-helper": "^3.1.1",
44
44
  "isomorphic-fetch": "^3.0.0",
45
45
  "prop-types": "^15.7.2",
46
- "react-bootstrap-slider": "^3.0.0",
46
+ "@goldenpine/react-bootstrap-slider": "^3.0.1",
47
47
  "react-datepicker": "^8.3.0",
48
48
  "react-dnd": "^16.0.1",
49
49
  "react-dnd-html5-backend": "^16.0.1",