@insticc/genericform 2.1.3 → 2.1.4

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.
@@ -72,7 +72,7 @@ var CustomFileInput = function CustomFileInput(_ref) {
72
72
  style: {
73
73
  display: 'flex',
74
74
  alignItems: 'center',
75
- gap: 8
75
+ gap: 10
76
76
  },
77
77
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
78
78
  type: "button",
@@ -89,7 +89,7 @@ var CustomFileInput = function CustomFileInput(_ref) {
89
89
  return (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.click();
90
90
  },
91
91
  children: placeholder || "Select"
92
- }), value ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
92
+ }), value && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
93
93
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
94
94
  style: {
95
95
  fontSize: '0.85rem',
@@ -112,12 +112,6 @@ var CustomFileInput = function CustomFileInput(_ref) {
112
112
  title: "Remove file",
113
113
  children: "\u2715"
114
114
  })]
115
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
116
- style: {
117
- fontSize: '0.82rem',
118
- color: '#aaa'
119
- },
120
- children: "No file selected"
121
115
  }), tooltipInline && (0, _defaults.tooltipJsx)(tooltip, tooltipStyle)]
122
116
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
123
117
  id: "form-input-".concat(name),
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = void 0;
7
+ var _propTypes = _interopRequireDefault(require("prop-types"));
8
+ var _react = require("react");
9
+ var _defaults = require("./defaults");
10
+ var _jsxRuntime = require("react/jsx-runtime");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
13
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
14
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
15
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
16
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
17
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
18
+ var EyeIcon = function EyeIcon(_ref) {
19
+ var visible = _ref.visible;
20
+ return visible ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
21
+ viewBox: "0 0 20 20",
22
+ fill: "none",
23
+ xmlns: "http://www.w3.org/2000/svg",
24
+ width: "18",
25
+ height: "18",
26
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
27
+ d: "M2 10s3-6 8-6 8 6 8 6-3 6-8 6-8-6-8-6z",
28
+ stroke: "#9CA3AF",
29
+ strokeWidth: "1.5"
30
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("circle", {
31
+ cx: "10",
32
+ cy: "10",
33
+ r: "2.5",
34
+ stroke: "#9CA3AF",
35
+ strokeWidth: "1.5"
36
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
37
+ d: "M3 3l14 14",
38
+ stroke: "#9CA3AF",
39
+ strokeWidth: "1.5",
40
+ strokeLinecap: "round"
41
+ })]
42
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
43
+ viewBox: "0 0 20 20",
44
+ fill: "none",
45
+ xmlns: "http://www.w3.org/2000/svg",
46
+ width: "18",
47
+ height: "18",
48
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
49
+ d: "M2 10s3-6 8-6 8 6 8 6-3 6-8 6-8-6-8-6z",
50
+ stroke: "#9CA3AF",
51
+ strokeWidth: "1.5"
52
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("circle", {
53
+ cx: "10",
54
+ cy: "10",
55
+ r: "2.5",
56
+ stroke: "#9CA3AF",
57
+ strokeWidth: "1.5"
58
+ })]
59
+ });
60
+ };
61
+ var getStrength = function getStrength(password) {
62
+ if (!password) return null;
63
+ var score = 0;
64
+ if (password.length >= 8) score++;
65
+ if (password.length >= 12) score++;
66
+ if (/[A-Z]/.test(password)) score++;
67
+ if (/[0-9]/.test(password)) score++;
68
+ if (/[^A-Za-z0-9]/.test(password)) score++;
69
+ if (score <= 1) return {
70
+ level: 1,
71
+ label: "Weak",
72
+ color: "#ef4444"
73
+ };
74
+ if (score <= 3) return {
75
+ level: 2,
76
+ label: "Fair",
77
+ color: "#f59e0b"
78
+ };
79
+ if (score === 4) return {
80
+ level: 3,
81
+ label: "Good",
82
+ color: "#3b82f6"
83
+ };
84
+ return {
85
+ level: 4,
86
+ label: "Strong",
87
+ color: "#22c55e"
88
+ };
89
+ };
90
+ var CustomPasswordInput = function CustomPasswordInput(_ref2) {
91
+ var _ref3;
92
+ var onChange = _ref2.onChange,
93
+ name = _ref2.name,
94
+ label = _ref2.label,
95
+ _ref2$value = _ref2.value,
96
+ value = _ref2$value === void 0 ? "" : _ref2$value,
97
+ _ref2$disabled = _ref2.disabled,
98
+ disabled = _ref2$disabled === void 0 ? false : _ref2$disabled,
99
+ _ref2$required = _ref2.required,
100
+ required = _ref2$required === void 0 ? false : _ref2$required,
101
+ placeholder = _ref2.placeholder,
102
+ error = _ref2.error,
103
+ _ref2$tooltip = _ref2.tooltip,
104
+ tooltip = _ref2$tooltip === void 0 ? "" : _ref2$tooltip,
105
+ _ref2$showHelp = _ref2.showHelp,
106
+ showHelp = _ref2$showHelp === void 0 ? false : _ref2$showHelp,
107
+ _ref2$helpText = _ref2.helpText,
108
+ helpText = _ref2$helpText === void 0 ? "" : _ref2$helpText,
109
+ className = _ref2.className,
110
+ _ref2$showStrength = _ref2.showStrength,
111
+ showStrength = _ref2$showStrength === void 0 ? false : _ref2$showStrength,
112
+ matchValue = _ref2.matchValue,
113
+ _ref2$mainDivStyle = _ref2.mainDivStyle,
114
+ mainDivStyle = _ref2$mainDivStyle === void 0 ? {} : _ref2$mainDivStyle,
115
+ _ref2$labelStyle = _ref2.labelStyle,
116
+ labelStyle = _ref2$labelStyle === void 0 ? {} : _ref2$labelStyle,
117
+ _ref2$spanStyle = _ref2.spanStyle,
118
+ spanStyle = _ref2$spanStyle === void 0 ? {} : _ref2$spanStyle,
119
+ _ref2$inputStyle = _ref2.inputStyle,
120
+ inputStyle = _ref2$inputStyle === void 0 ? {} : _ref2$inputStyle,
121
+ _ref2$tooltipStyle = _ref2.tooltipStyle,
122
+ tooltipStyle = _ref2$tooltipStyle === void 0 ? {} : _ref2$tooltipStyle;
123
+ var _useState = (0, _react.useState)(false),
124
+ _useState2 = _slicedToArray(_useState, 2),
125
+ visible = _useState2[0],
126
+ setVisible = _useState2[1];
127
+ var handleChange = (0, _react.useCallback)(function (e) {
128
+ return onChange === null || onChange === void 0 ? void 0 : onChange(name, e.target.value);
129
+ }, [onChange, name]);
130
+ var strength = showStrength ? getStrength(value) : null;
131
+ var showMatch = matchValue !== undefined && value.length > 0 && matchValue.length > 0;
132
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
133
+ className: "ufg-field-group",
134
+ id: name,
135
+ style: mainDivStyle,
136
+ children: [(0, _defaults.labelJsx)({
137
+ name: name,
138
+ labelStyle: labelStyle,
139
+ label: label,
140
+ required: required,
141
+ spanStyle: spanStyle,
142
+ showHelp: showHelp,
143
+ helpText: helpText
144
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
145
+ className: "ufg-input-wrapper",
146
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
147
+ id: "form-input-".concat(name),
148
+ type: visible ? "text" : "password",
149
+ name: name,
150
+ value: value,
151
+ placeholder: (_ref3 = placeholder !== null && placeholder !== void 0 ? placeholder : label) !== null && _ref3 !== void 0 ? _ref3 : "••••••••••",
152
+ disabled: disabled,
153
+ required: required,
154
+ autoComplete: "current-password",
155
+ className: "ufg-input ufg-input--padded".concat(error ? " error" : "").concat(className ? " ".concat(className) : ""),
156
+ style: inputStyle,
157
+ onChange: handleChange
158
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
159
+ type: "button",
160
+ className: "ufg-eye-btn",
161
+ onClick: function onClick() {
162
+ return setVisible(function (v) {
163
+ return !v;
164
+ });
165
+ },
166
+ "aria-label": visible ? "Hide password" : "Show password",
167
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(EyeIcon, {
168
+ visible: visible
169
+ })
170
+ })]
171
+ }), showStrength && value.length > 0 && strength && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
172
+ className: "ufg-strength",
173
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
174
+ className: "ufg-strength-bar",
175
+ children: [1, 2, 3, 4].map(function (i) {
176
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
177
+ className: "ufg-strength-segment",
178
+ style: {
179
+ background: i <= strength.level ? strength.color : "#e5e7eb"
180
+ }
181
+ }, i);
182
+ })
183
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
184
+ className: "ufg-strength-label",
185
+ style: {
186
+ color: strength.color
187
+ },
188
+ children: strength.label
189
+ })]
190
+ }), showMatch && /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
191
+ className: "ufg-match ".concat(value === matchValue ? "ufg-match--ok" : "ufg-match--no"),
192
+ children: value === matchValue ? "✓ Passwords match" : "✗ Passwords do not match"
193
+ }), (0, _defaults.errorJsx)(error), (0, _defaults.tooltipJsx)(tooltip, tooltipStyle)]
194
+ });
195
+ };
196
+ CustomPasswordInput.propTypes = {
197
+ onChange: _propTypes["default"].func.isRequired,
198
+ name: _propTypes["default"].string.isRequired,
199
+ label: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].object]),
200
+ value: _propTypes["default"].string,
201
+ disabled: _propTypes["default"].bool,
202
+ required: _propTypes["default"].bool,
203
+ placeholder: _propTypes["default"].string,
204
+ error: _propTypes["default"].string,
205
+ tooltip: _propTypes["default"].string,
206
+ showHelp: _propTypes["default"].bool,
207
+ helpText: _propTypes["default"].string,
208
+ className: _propTypes["default"].string,
209
+ showStrength: _propTypes["default"].bool,
210
+ matchValue: _propTypes["default"].string,
211
+ inputStyle: _propTypes["default"].object,
212
+ mainDivStyle: _propTypes["default"].object,
213
+ labelStyle: _propTypes["default"].object,
214
+ spanStyle: _propTypes["default"].object,
215
+ tooltipStyle: _propTypes["default"].object
216
+ };
217
+ var _default = exports["default"] = CustomPasswordInput;
package/build/index.js CHANGED
@@ -75,6 +75,12 @@ Object.defineProperty(exports, "CustomNumberInput", {
75
75
  return _CustomNumberInput["default"];
76
76
  }
77
77
  });
78
+ Object.defineProperty(exports, "CustomPasswordInput", {
79
+ enumerable: true,
80
+ get: function get() {
81
+ return _CustomPasswordInput["default"];
82
+ }
83
+ });
78
84
  Object.defineProperty(exports, "CustomRadioGroup", {
79
85
  enumerable: true,
80
86
  get: function get() {
@@ -123,6 +129,7 @@ var _CustomLabel = _interopRequireDefault(require("./FormFields/CustomLabel"));
123
129
  var _CustomMobilePhone = _interopRequireDefault(require("./FormFields/CustomMobilePhone"));
124
130
  var _CustomMultiDropdown = _interopRequireDefault(require("./FormFields/CustomMultiDropdown"));
125
131
  var _CustomNumberInput = _interopRequireDefault(require("./FormFields/CustomNumberInput"));
132
+ var _CustomPasswordInput = _interopRequireDefault(require("./FormFields/CustomPasswordInput"));
126
133
  var _CustomRadioGroup = _interopRequireDefault(require("./FormFields/CustomRadioGroup"));
127
134
  var _CustomSearch = _interopRequireDefault(require("./FormFields/CustomSearch"));
128
135
  var _CustomSeparator = _interopRequireDefault(require("./FormFields/CustomSeparator"));
@@ -255,7 +262,10 @@ var GenericForm = function GenericForm(_ref) {
255
262
  _ref$modalSize = _ref.modalSize,
256
263
  modalSize = _ref$modalSize === void 0 ? 'lg' : _ref$modalSize,
257
264
  _ref$disableFormTag = _ref.disableFormTag,
258
- disableFormTag = _ref$disableFormTag === void 0 ? false : _ref$disableFormTag;
265
+ disableFormTag = _ref$disableFormTag === void 0 ? false : _ref$disableFormTag,
266
+ _ref$isSubmitting = _ref.isSubmitting,
267
+ isSubmitting = _ref$isSubmitting === void 0 ? false : _ref$isSubmitting,
268
+ handleErrors = _ref.handleErrors;
259
269
  var _useState = (0, _react.useState)([]),
260
270
  _useState2 = _slicedToArray(_useState, 2),
261
271
  sortedFields = _useState2[0],
@@ -271,9 +281,15 @@ var GenericForm = function GenericForm(_ref) {
271
281
  setErrors = _useState6[1];
272
282
  var _useState7 = (0, _react.useState)(false),
273
283
  _useState8 = _slicedToArray(_useState7, 2),
274
- isSubmitting = _useState8[0],
284
+ isSubmittingInternal = _useState8[0],
275
285
  setIsSubmitting = _useState8[1];
276
286
  var prevFieldValuesRef = (0, _react.useRef)({});
287
+ (0, _react.useEffect)(function () {
288
+ setIsSubmitting(isSubmitting);
289
+ }, [isSubmitting]);
290
+ (0, _react.useEffect)(function () {
291
+ handleErrors && handleErrors(errors);
292
+ }, [errors]);
277
293
 
278
294
  // ── Sync fields ─────────────────────────────────────────────────────────────
279
295
  (0, _react.useEffect)(function () {
@@ -545,7 +561,7 @@ var GenericForm = function GenericForm(_ref) {
545
561
 
546
562
  // #region RenderField
547
563
  var renderField = (0, _react.useCallback)(function (field) {
548
- var _internalFormData$fie2;
564
+ var _internalFormData$fie2, _field$showStrength;
549
565
  var isHidden = typeof field.hide === 'function' ? field.hide(internalFormData, field) : field.hide;
550
566
  if (isHidden) return null;
551
567
  var error = errors[field.name];
@@ -588,15 +604,20 @@ var GenericForm = function GenericForm(_ref) {
588
604
  case 'string':
589
605
  case 'text':
590
606
  case 'email':
591
- case 'password':
592
607
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CustomInput["default"], _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, cp), sp), fp), {}, {
593
608
  value: value,
594
609
  type: field.type === 'email' ? 'email' : field.type === 'password' ? 'password' : 'text',
595
- placeholder: field.placeholder,
596
610
  onChange: fieldHandler(field),
597
- inputStyle: field.inputStyle,
598
611
  className: field.className
599
612
  }), field.name);
613
+ case 'password':
614
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CustomPasswordInput["default"], _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, cp), sp), fp), {}, {
615
+ value: value,
616
+ onChange: fieldHandler(field),
617
+ className: field.className,
618
+ showStrength: (_field$showStrength = field.showStrength) !== null && _field$showStrength !== void 0 ? _field$showStrength : false,
619
+ matchValue: field.matchField ? internalFormData[field.matchField] : undefined
620
+ }), field.name);
600
621
  case 'int':
601
622
  case 'number':
602
623
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CustomNumberInput["default"], _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, cp), sp), fp), {}, {
@@ -790,7 +811,9 @@ var GenericForm = function GenericForm(_ref) {
790
811
  var renderGroupSection = function renderGroupSection(g, fieldList) {
791
812
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
792
813
  className: "ufg-fields",
793
- style: fieldsStyle,
814
+ style: enableModal ? _objectSpread({
815
+ gap: "1em"
816
+ }, fieldsStyle) : fieldsStyle,
794
817
  children: [g !== 'ungrouped' && /*#__PURE__*/(0, _jsxRuntime.jsx)("h2", {
795
818
  children: g
796
819
  }), renderFields(fieldList)]
@@ -887,7 +910,9 @@ var GenericForm = function GenericForm(_ref) {
887
910
  var hasErrors = Object.values(errors).some(Boolean);
888
911
  var actionsBar = /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
889
912
  className: "ufg-actions",
890
- style: actionsDivStyle,
913
+ style: enableModal ? _objectSpread({
914
+ justifyContent: "center"
915
+ }, actionsDivStyle) : actionsDivStyle,
891
916
  children: [customActions.map(function (action, idx) {
892
917
  return (0, _CustomAction["default"])(_objectSpread(_objectSpread({}, action), {}, {
893
918
  name: "".concat(action.name, " ").concat(idx),
@@ -897,9 +922,9 @@ var GenericForm = function GenericForm(_ref) {
897
922
  }), showSubmit && haveSaveButton && /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
898
923
  type: "submit",
899
924
  className: "ufg-button ".concat(submitButton.className || 'ufg-button-primary'),
900
- disabled: isSubmitting || hasErrors,
925
+ disabled: isSubmittingInternal || hasErrors,
901
926
  style: _objectSpread(_objectSpread({}, actionsStyle), submitButton.style),
902
- children: isSubmitting ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
927
+ children: isSubmittingInternal ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
903
928
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_semanticUiReact.Icon, {
904
929
  name: "spinner",
905
930
  loading: true
@@ -920,14 +945,20 @@ var GenericForm = function GenericForm(_ref) {
920
945
  // #region Form JSX
921
946
  var formJSX = disableFormTag ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
922
947
  className: "ufg-form",
923
- style: formStyle || {
948
+ style: enableModal ? _objectSpread({
949
+ padding: "2em",
950
+ gap: "3em"
951
+ }, formStyle) : formStyle || {
924
952
  margin: 'auto'
925
953
  },
926
954
  onSubmit: onFormSubmit,
927
955
  children: [buildContent(), actionsBar]
928
956
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)("form", {
929
957
  className: "ufg-form",
930
- style: formStyle || {
958
+ style: enableModal ? _objectSpread({
959
+ padding: "2em",
960
+ gap: "3em"
961
+ }, formStyle) : formStyle || {
931
962
  margin: 'auto'
932
963
  },
933
964
  onSubmit: onFormSubmit,
@@ -940,7 +971,7 @@ var GenericForm = function GenericForm(_ref) {
940
971
  size: modalSize,
941
972
  style: containerStyle,
942
973
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Header, {
943
- closeButton: true,
974
+ closeButton: !!onCancel,
944
975
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Modal.Title, {
945
976
  style: titleStyle,
946
977
  children: [titleIcon, " ", title, " "]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insticc/genericform",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "A generic form with a comprehensive set of field types, validation, and external state management",
5
5
  "main": "build/index.js",
6
6
  "scripts": {