@insticc/genericform 2.1.3 → 2.1.5

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,12 @@ 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,
269
+ _ref$overrideErrors = _ref.overrideErrors,
270
+ overrideErrors = _ref$overrideErrors === void 0 ? {} : _ref$overrideErrors;
259
271
  var _useState = (0, _react.useState)([]),
260
272
  _useState2 = _slicedToArray(_useState, 2),
261
273
  sortedFields = _useState2[0],
@@ -271,9 +283,18 @@ var GenericForm = function GenericForm(_ref) {
271
283
  setErrors = _useState6[1];
272
284
  var _useState7 = (0, _react.useState)(false),
273
285
  _useState8 = _slicedToArray(_useState7, 2),
274
- isSubmitting = _useState8[0],
286
+ isSubmittingInternal = _useState8[0],
275
287
  setIsSubmitting = _useState8[1];
276
288
  var prevFieldValuesRef = (0, _react.useRef)({});
289
+ (0, _react.useEffect)(function () {
290
+ setIsSubmitting(isSubmitting);
291
+ }, [isSubmitting]);
292
+ (0, _react.useEffect)(function () {
293
+ handleErrors && handleErrors(errors);
294
+ }, [errors]);
295
+ (0, _react.useEffect)(function () {
296
+ setErrors(overrideErrors);
297
+ }, [overrideErrors]);
277
298
 
278
299
  // ── Sync fields ─────────────────────────────────────────────────────────────
279
300
  (0, _react.useEffect)(function () {
@@ -545,7 +566,7 @@ var GenericForm = function GenericForm(_ref) {
545
566
 
546
567
  // #region RenderField
547
568
  var renderField = (0, _react.useCallback)(function (field) {
548
- var _internalFormData$fie2;
569
+ var _internalFormData$fie2, _field$showStrength;
549
570
  var isHidden = typeof field.hide === 'function' ? field.hide(internalFormData, field) : field.hide;
550
571
  if (isHidden) return null;
551
572
  var error = errors[field.name];
@@ -588,15 +609,20 @@ var GenericForm = function GenericForm(_ref) {
588
609
  case 'string':
589
610
  case 'text':
590
611
  case 'email':
591
- case 'password':
592
612
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CustomInput["default"], _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, cp), sp), fp), {}, {
593
613
  value: value,
594
614
  type: field.type === 'email' ? 'email' : field.type === 'password' ? 'password' : 'text',
595
- placeholder: field.placeholder,
596
615
  onChange: fieldHandler(field),
597
- inputStyle: field.inputStyle,
598
616
  className: field.className
599
617
  }), field.name);
618
+ case 'password':
619
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CustomPasswordInput["default"], _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, cp), sp), fp), {}, {
620
+ value: value,
621
+ onChange: fieldHandler(field),
622
+ className: field.className,
623
+ showStrength: (_field$showStrength = field.showStrength) !== null && _field$showStrength !== void 0 ? _field$showStrength : false,
624
+ matchValue: field.matchField ? internalFormData[field.matchField] : undefined
625
+ }), field.name);
600
626
  case 'int':
601
627
  case 'number':
602
628
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CustomNumberInput["default"], _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, cp), sp), fp), {}, {
@@ -790,7 +816,9 @@ var GenericForm = function GenericForm(_ref) {
790
816
  var renderGroupSection = function renderGroupSection(g, fieldList) {
791
817
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
792
818
  className: "ufg-fields",
793
- style: fieldsStyle,
819
+ style: enableModal ? _objectSpread({
820
+ gap: "1em"
821
+ }, fieldsStyle) : fieldsStyle,
794
822
  children: [g !== 'ungrouped' && /*#__PURE__*/(0, _jsxRuntime.jsx)("h2", {
795
823
  children: g
796
824
  }), renderFields(fieldList)]
@@ -887,7 +915,9 @@ var GenericForm = function GenericForm(_ref) {
887
915
  var hasErrors = Object.values(errors).some(Boolean);
888
916
  var actionsBar = /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
889
917
  className: "ufg-actions",
890
- style: actionsDivStyle,
918
+ style: enableModal ? _objectSpread({
919
+ justifyContent: "center"
920
+ }, actionsDivStyle) : actionsDivStyle,
891
921
  children: [customActions.map(function (action, idx) {
892
922
  return (0, _CustomAction["default"])(_objectSpread(_objectSpread({}, action), {}, {
893
923
  name: "".concat(action.name, " ").concat(idx),
@@ -897,9 +927,9 @@ var GenericForm = function GenericForm(_ref) {
897
927
  }), showSubmit && haveSaveButton && /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
898
928
  type: "submit",
899
929
  className: "ufg-button ".concat(submitButton.className || 'ufg-button-primary'),
900
- disabled: isSubmitting || hasErrors,
930
+ disabled: isSubmittingInternal || hasErrors,
901
931
  style: _objectSpread(_objectSpread({}, actionsStyle), submitButton.style),
902
- children: isSubmitting ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
932
+ children: isSubmittingInternal ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
903
933
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_semanticUiReact.Icon, {
904
934
  name: "spinner",
905
935
  loading: true
@@ -920,14 +950,20 @@ var GenericForm = function GenericForm(_ref) {
920
950
  // #region Form JSX
921
951
  var formJSX = disableFormTag ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
922
952
  className: "ufg-form",
923
- style: formStyle || {
953
+ style: enableModal ? _objectSpread({
954
+ padding: "2em",
955
+ gap: "3em"
956
+ }, formStyle) : formStyle || {
924
957
  margin: 'auto'
925
958
  },
926
959
  onSubmit: onFormSubmit,
927
960
  children: [buildContent(), actionsBar]
928
961
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)("form", {
929
962
  className: "ufg-form",
930
- style: formStyle || {
963
+ style: enableModal ? _objectSpread({
964
+ padding: "2em",
965
+ gap: "3em"
966
+ }, formStyle) : formStyle || {
931
967
  margin: 'auto'
932
968
  },
933
969
  onSubmit: onFormSubmit,
@@ -940,7 +976,7 @@ var GenericForm = function GenericForm(_ref) {
940
976
  size: modalSize,
941
977
  style: containerStyle,
942
978
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Modal.Header, {
943
- closeButton: true,
979
+ closeButton: !!onCancel,
944
980
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactBootstrap.Modal.Title, {
945
981
  style: titleStyle,
946
982
  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.5",
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": {