UNPKG

react-unique-dynamic-form

Version:

A reusable React library with Form, useForm hook, and Bootstrap-styled Modal component

1,393 lines (1,355 loc) 44.2 kB
import React, { useState, useCallback } from 'react'; import PropTypes from 'prop-types'; 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; } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: false }), e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: true, configurable: true, writable: true }) : e[r] = t, e; } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: true, configurable: true } }), Object.defineProperty(t, "prototype", { writable: false }), e && _setPrototypeOf(t, e); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function () { return !!t; })(); } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } 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 = true, o = false; 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 = true, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } 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."); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 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; } function _objectSpread2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(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; } function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } function _regeneratorRuntime() { _regeneratorRuntime = function () { return r; }; var t, r = {}, e = Object.prototype, n = e.hasOwnProperty, o = "function" == typeof Symbol ? Symbol : {}, i = o.iterator || "@@iterator", a = o.asyncIterator || "@@asyncIterator", u = o.toStringTag || "@@toStringTag"; function c(t, r, e, n) { return Object.defineProperty(t, r, { value: e, enumerable: !n, configurable: !n, writable: !n }); } try { c({}, ""); } catch (t) { c = function (t, r, e) { return t[r] = e; }; } function h(r, e, n, o) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype); return c(a, "_invoke", function (r, e, n) { var o = 1; return function (i, a) { if (3 === o) throw Error("Generator is already running"); if (4 === o) { if ("throw" === i) throw a; return { value: t, done: true }; } for (n.method = i, n.arg = a;;) { var u = n.delegate; if (u) { var c = d(u, n); if (c) { if (c === f) continue; return c; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (1 === o) throw o = 4, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = 3; var h = s(r, e, n); if ("normal" === h.type) { if (o = n.done ? 4 : 2, h.arg === f) continue; return { value: h.arg, done: n.done }; } "throw" === h.type && (o = 4, n.method = "throw", n.arg = h.arg); } }; }(r, n, new Context(o || [])), true), a; } function s(t, r, e) { try { return { type: "normal", arg: t.call(r, e) }; } catch (t) { return { type: "throw", arg: t }; } } r.wrap = h; var f = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var l = {}; c(l, i, function () { return this; }); var p = Object.getPrototypeOf, y = p && p(p(x([]))); y && y !== e && n.call(y, i) && (l = y); var v = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(l); function g(t) { ["next", "throw", "return"].forEach(function (r) { c(t, r, function (t) { return this._invoke(r, t); }); }); } function AsyncIterator(t, r) { function e(o, i, a, u) { var c = s(t[o], t, i); if ("throw" !== c.type) { var h = c.arg, f = h.value; return f && "object" == typeof f && n.call(f, "__await") ? r.resolve(f.__await).then(function (t) { e("next", t, a, u); }, function (t) { e("throw", t, a, u); }) : r.resolve(f).then(function (t) { h.value = t, a(h); }, function (t) { return e("throw", t, a, u); }); } u(c.arg); } var o; c(this, "_invoke", function (t, n) { function i() { return new r(function (r, o) { e(t, n, r, o); }); } return o = o ? o.then(i, i) : i(); }, true); } function d(r, e) { var n = e.method, o = r.i[n]; if (o === t) return e.delegate = null, "throw" === n && r.i.return && (e.method = "return", e.arg = t, d(r, e), "throw" === e.method) || "return" !== n && (e.method = "throw", e.arg = new TypeError("The iterator does not provide a '" + n + "' method")), f; var i = s(o, r.i, e.arg); if ("throw" === i.type) return e.method = "throw", e.arg = i.arg, e.delegate = null, f; var a = i.arg; return a ? a.done ? (e[r.r] = a.value, e.next = r.n, "return" !== e.method && (e.method = "next", e.arg = t), e.delegate = null, f) : a : (e.method = "throw", e.arg = new TypeError("iterator result is not an object"), e.delegate = null, f); } function w(t) { this.tryEntries.push(t); } function m(r) { var e = r[4] || {}; e.type = "normal", e.arg = t, r[4] = e; } function Context(t) { this.tryEntries = [[-1]], t.forEach(w, this), this.reset(true); } function x(r) { if (null != r) { var e = r[i]; if (e) return e.call(r); if ("function" == typeof r.next) return r; if (!isNaN(r.length)) { var o = -1, a = function e() { for (; ++o < r.length;) if (n.call(r, o)) return e.value = r[o], e.done = false, e; return e.value = t, e.done = true, e; }; return a.next = a; } } throw new TypeError(typeof r + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, c(v, "constructor", GeneratorFunctionPrototype), c(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = c(GeneratorFunctionPrototype, u, "GeneratorFunction"), r.isGeneratorFunction = function (t) { var r = "function" == typeof t && t.constructor; return !!r && (r === GeneratorFunction || "GeneratorFunction" === (r.displayName || r.name)); }, r.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, c(t, u, "GeneratorFunction")), t.prototype = Object.create(v), t; }, r.awrap = function (t) { return { __await: t }; }, g(AsyncIterator.prototype), c(AsyncIterator.prototype, a, function () { return this; }), r.AsyncIterator = AsyncIterator, r.async = function (t, e, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(h(t, e, n, o), i); return r.isGeneratorFunction(e) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, g(v), c(v, u, "Generator"), c(v, i, function () { return this; }), c(v, "toString", function () { return "[object Generator]"; }), r.keys = function (t) { var r = Object(t), e = []; for (var n in r) e.unshift(n); return function t() { for (; e.length;) if ((n = e.pop()) in r) return t.value = n, t.done = false, t; return t.done = true, t; }; }, r.values = x, Context.prototype = { constructor: Context, reset: function (r) { if (this.prev = this.next = 0, this.sent = this._sent = t, this.done = false, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(m), !r) for (var e in this) "t" === e.charAt(0) && n.call(this, e) && !isNaN(+e.slice(1)) && (this[e] = t); }, stop: function () { this.done = true; var t = this.tryEntries[0][4]; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function (r) { if (this.done) throw r; var e = this; function n(t) { a.type = "throw", a.arg = r, e.next = t; } for (var o = e.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i[4], u = this.prev, c = i[1], h = i[2]; if (-1 === i[0]) return n("end"), false; if (!c && !h) throw Error("try statement without catch or finally"); if (null != i[0] && i[0] <= u) { if (u < c) return this.method = "next", this.arg = t, n(c), true; if (u < h) return n(h), false; } } }, abrupt: function (t, r) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var n = this.tryEntries[e]; if (n[0] > -1 && n[0] <= this.prev && this.prev < n[2]) { var o = n; break; } } o && ("break" === t || "continue" === t) && o[0] <= r && r <= o[2] && (o = null); var i = o ? o[4] : {}; return i.type = t, i.arg = r, o ? (this.method = "next", this.next = o[2], f) : this.complete(i); }, complete: function (t, r) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && r && (this.next = r), f; }, finish: function (t) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var e = this.tryEntries[r]; if (e[2] === t) return this.complete(e[4], e[3]), m(e), f; } }, catch: function (t) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var e = this.tryEntries[r]; if (e[0] === t) { var n = e[4]; if ("throw" === n.type) { var o = n.arg; m(e); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function (r, e, n) { return this.delegate = { i: x(r), r: e, n: n }, "next" === this.method && (this.arg = t), f; } }, r; } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return (String )(t); } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 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; } } var useForm = function useForm() { var initialValues = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var validate = arguments.length > 1 ? arguments[1] : undefined; var _useState = useState(initialValues || {}), _useState2 = _slicedToArray(_useState, 2), values = _useState2[0], setValues = _useState2[1]; var _useState3 = useState({}), _useState4 = _slicedToArray(_useState3, 2), errors = _useState4[0], setErrors = _useState4[1]; var _useState5 = useState(false), _useState6 = _slicedToArray(_useState5, 2), isSubmitting = _useState6[0], setIsSubmitting = _useState6[1]; var handleChange = useCallback(function (event) { var _event$target = event.target, name = _event$target.name, value = _event$target.value; setValues(function (prev) { var newValues = _objectSpread2(_objectSpread2({}, prev), {}, _defineProperty({}, name, value)); return newValues; }); }, []); var handleSubmit = useCallback(function (onSubmit) { return /*#__PURE__*/function () { var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(event) { var validationErrors; return _regeneratorRuntime().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (event && typeof event.preventDefault === 'function') { event.preventDefault(); } else { console.error('useForm: Invalid event object:', event); } setIsSubmitting(true); validationErrors = validate ? validate(values) : {}; setErrors(validationErrors); if (!(Object.keys(validationErrors).length === 0)) { _context.next = 13; break; } _context.prev = 5; _context.next = 8; return onSubmit(values); case 8: _context.next = 13; break; case 10: _context.prev = 10; _context.t0 = _context["catch"](5); setErrors({ submit: _context.t0.message }); case 13: setIsSubmitting(false); case 14: case "end": return _context.stop(); } }, _callee, null, [[5, 10]]); })); return function (_x) { return _ref.apply(this, arguments); }; }(); }, [values, validate]); var resetForm = useCallback(function () { setValues(initialValues || {}); setErrors({}); setIsSubmitting(false); }, [initialValues]); return { values: values, errors: errors, isSubmitting: isSubmitting, handleChange: handleChange, handleSubmit: handleSubmit, resetForm: resetForm }; }; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var classnames = {exports: {}}; /*! Copyright (c) 2018 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ (function (module) { /* global define */ (function () { var hasOwn = {}.hasOwnProperty; function classNames () { var classes = ''; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; if (arg) { classes = appendClass(classes, parseValue(arg)); } } return classes; } function parseValue (arg) { if (typeof arg === 'string' || typeof arg === 'number') { return arg; } if (typeof arg !== 'object') { return ''; } if (Array.isArray(arg)) { return classNames.apply(null, arg); } if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) { return arg.toString(); } var classes = ''; for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes = appendClass(classes, key); } } return classes; } function appendClass (value, newClass) { if (!newClass) { return value; } if (value) { return value + ' ' + newClass; } return value + newClass; } if (module.exports) { classNames.default = classNames; module.exports = classNames; } else { window.classNames = classNames; } }()); } (classnames)); var classnamesExports = classnames.exports; var classNames = /*@__PURE__*/getDefaultExportFromCjs(classnamesExports); // Define styles as a JavaScript object var styles$1 = { customForm: { maxWidth: '500px', margin: '2rem auto', padding: '2rem', backgroundColor: '#ffffff', borderRadius: '12px', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)' }, fieldGroup: { marginBottom: '1.5rem' }, formField: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: '1rem', marginBottom: '1rem' }, nestedField: { marginLeft: '2rem', marginBottom: '0.5rem' }, label: { fontSize: '1rem', fontWeight: 500, color: '#333', flex: '0 0 120px' }, input: { flex: 1, padding: '0.75rem', border: '1px solid #ccc', borderRadius: '8px', fontSize: '1rem' }, checkbox: { appearance: 'none', width: '1.25rem', height: '1.25rem', border: '2px solid #ccc', borderRadius: '4px', marginRight: '0.5rem', verticalAlign: 'middle', cursor: 'pointer' }, checkboxChecked: { backgroundColor: '#007bff', backgroundSize: 'cover', borderColor: '#007bff' }, radio: { appearance: 'none', width: '1.25rem', height: '1.25rem', border: '2px solid #ccc', borderRadius: '50%', marginRight: '0.5rem', verticalAlign: 'middle', cursor: 'pointer' }, radioChecked: { backgroundColor: '#007bff', backgroundSize: 'cover', borderColor: '#007bff' }, checkboxContainer: { display: 'flex', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }, radioContainer: { display: 'flex', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }, containerLabel: { display: 'flex', alignItems: 'center', fontWeight: 400, cursor: 'pointer', margin: 0 }, formButtons: { display: 'flex', gap: '1rem', justifyContent: 'center', marginTop: '1rem' }, button: { backgroundColor: '#007bff', border: 'none', borderRadius: '8px', color: '#fff', cursor: 'pointer', fontSize: '1rem', padding: '0.75rem 2rem' }, resetButton: { backgroundColor: '#6c757d' }, buttonDisabled: { backgroundColor: '#ccc', cursor: 'not-allowed' }, fieldError: { color: '#dc3545', fontSize: '0.875rem', marginLeft: '120px', flex: 1 }, formError: { color: '#dc3545', fontSize: '0.875rem', marginTop: '0.5rem', textAlign: 'center' }, formErrorBoundary: { color: '#dc3545', padding: '1rem', border: '1px solid #dc3545', borderRadius: '8px', backgroundColor: '#fff5f5', textAlign: 'center' }, formErrorBoundaryH2: { fontSize: '1.2rem', marginBottom: '0.5rem' }, formErrorBoundaryP: { fontSize: '0.875rem', margin: '0.25rem 0' } }; // Error Boundary Component var FormErrorBoundary = /*#__PURE__*/function (_React$Component) { function FormErrorBoundary() { var _this; _classCallCheck(this, FormErrorBoundary); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, FormErrorBoundary, [].concat(args)); _defineProperty(_this, "state", { hasError: false, error: null }); return _this; } _inherits(FormErrorBoundary, _React$Component); return _createClass(FormErrorBoundary, [{ key: "componentDidCatch", value: function componentDidCatch(error, errorInfo) { console.error("Error in Form component:", error, errorInfo); } }, { key: "render", value: function render() { if (this.state.hasError) { var _this$state$error; return /*#__PURE__*/React.createElement("div", { style: styles$1.formErrorBoundary }, /*#__PURE__*/React.createElement("h2", { style: styles$1.formErrorBoundaryH2 }, "Something went wrong in the Form."), /*#__PURE__*/React.createElement("p", { style: styles$1.formErrorBoundaryP }, ((_this$state$error = this.state.error) === null || _this$state$error === void 0 ? void 0 : _this$state$error.message) || "Unknown error"), /*#__PURE__*/React.createElement("p", { style: styles$1.formErrorBoundaryP }, "Please check your initialValues structure or contact support.")); } return this.props.children; } }], [{ key: "getDerivedStateFromError", value: function getDerivedStateFromError(error) { return { hasError: true, error: error }; } }]); }(React.Component); // Utility to flatten nested objects and arrays into a single-level object with dot-notation keys var _flattenObject$1 = function flattenObject(obj) { var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var result = {}; Object.keys(obj).forEach(function (key) { var value = obj[key]; var newKey = prefix ? "".concat(prefix, ".").concat(key) : key; if (Array.isArray(value)) { var hasObjects = value.some(function (item) { return item && _typeof(item) === 'object' && !Array.isArray(item); }); var hasStrings = value.some(function (item) { return typeof item === 'string'; }); if (hasObjects) { value.forEach(function (item, index) { if (item && _typeof(item) === 'object' && !Array.isArray(item)) { Object.assign(result, _flattenObject$1(item, "".concat(newKey, "[").concat(index, "]"))); } }); } if (hasStrings) { var stringOptions = value.filter(function (item) { return typeof item === 'string'; }); if (stringOptions.length > 0) { result[newKey] = stringOptions; } } } else if (value && _typeof(value) === 'object' && !('value' in value)) { Object.assign(result, _flattenObject$1(value, newKey)); } else { result[newKey] = value; } }); return result; }; // Utility to group flattened keys by their top-level key (for nested fields only) var groupFields = function groupFields(flattenedObj) { var grouped = {}; var flatFields = []; Object.keys(flattenedObj).forEach(function (key) { if (key.includes('.') || key.includes('[')) { var _key$split = key.split(/\[|\./), _key$split2 = _slicedToArray(_key$split, 1), group = _key$split2[0]; grouped[group] = grouped[group] || []; grouped[group].push(key); } else { flatFields.push(key); } }); return { flatFields: flatFields, groupedFields: grouped }; }; // Utility to extract the actual value and optional flag from a field var getFieldConfig = function getFieldConfig(field) { if (field && _typeof(field) === 'object' && 'value' in field) { return { value: field.value, optional: !!field.optional }; } return { value: field, optional: false }; }; // Utility to generate a display label from a key (e.g., "study.degree" → "Study Degree") var generateLabel = function generateLabel(key) { return key.split(/\[|\./).filter(function (part) { return !part.match(/^\d+\]$/); }).map(function (part) { return part.charAt(0).toUpperCase() + part.slice(1); }).join(' '); }; // Default validation function var defaultValidate = function defaultValidate(values, initialValuesFlat) { var errors = {}; var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; var phoneRegex = /^\d{10}$/; Object.keys(initialValuesFlat).forEach(function (key) { var _getFieldConfig = getFieldConfig(initialValuesFlat[key]), value = _getFieldConfig.value, optional = _getFieldConfig.optional; var fieldValue = values[key]; // Skip optional fields if empty if (optional && (!fieldValue || fieldValue.trim() === '')) { return; } // Required string fields if (typeof value === 'string' && (!fieldValue || !fieldValue.trim())) { errors[key] = "".concat(generateLabel(key), " is required"); } // Email validation if (key === 'email' && fieldValue && !emailRegex.test(fieldValue)) { errors[key] = 'Invalid email format'; } // Phone validation if (key === 'phone' && fieldValue && !phoneRegex.test(fieldValue)) { errors[key] = 'Phone number must be exactly 10 digits'; } // Array (e.g., gender) validation if (Array.isArray(value) && !fieldValue) { errors[key] = "Please select a ".concat(generateLabel(key).toLowerCase(), " option"); } }); return errors; }; var Form = function Form(_ref) { var initialValues = _ref.initialValues, validate = _ref.validate, onSubmit = _ref.onSubmit, className = _ref.className, customStyles = _ref.customStyles, children = _ref.children, _ref$reset = _ref.reset, reset = _ref$reset === void 0 ? true : _ref$reset; var initialValuesFlat = _flattenObject$1(initialValues); var formInitialValues = {}; Object.keys(initialValuesFlat).forEach(function (key) { var _getFieldConfig2 = getFieldConfig(initialValuesFlat[key]), value = _getFieldConfig2.value; formInitialValues[key] = value; }); var _useForm = useForm(formInitialValues, function (values) { return validate ? validate(values) : defaultValidate(values, initialValuesFlat); }), values = _useForm.values, errors = _useForm.errors, isSubmitting = _useForm.isSubmitting, handleChange = _useForm.handleChange, handleSubmit = _useForm.handleSubmit, resetForm = _useForm.resetForm; if (children) { return /*#__PURE__*/React.createElement("form", { onSubmit: handleSubmit(onSubmit), className: classNames('custom-form', className, customStyles), style: styles$1.customForm }, children({ values: values || {}, errors: errors, handleChange: handleChange, isSubmitting: isSubmitting, resetForm: resetForm }), errors.submit && /*#__PURE__*/React.createElement("div", { style: styles$1.formError }, errors.submit)); } var _groupFields = groupFields(initialValuesFlat), flatFields = _groupFields.flatFields, groupedFields = _groupFields.groupedFields; var renderField = function renderField(key) { var isNested = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var group = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; var _getFieldConfig3 = getFieldConfig(initialValuesFlat[key]), value = _getFieldConfig3.value; var fieldType = _typeof(value); var isArray = Array.isArray(value); var label = isNested ? generateLabel(key.replace("".concat(group, "."), '')) : generateLabel(key); if (fieldType === 'string' && !isArray) { return /*#__PURE__*/React.createElement("div", { key: key, style: _objectSpread2(_objectSpread2({}, styles$1.formField), isNested ? styles$1.nestedField : {}) }, /*#__PURE__*/React.createElement("label", { htmlFor: key, style: styles$1.label }, label, ":"), /*#__PURE__*/React.createElement("input", { id: key, name: key, value: values[key] || '', onChange: handleChange, placeholder: "Enter ".concat(label.toLowerCase()), style: styles$1.input }), errors[key] && /*#__PURE__*/React.createElement("span", { style: styles$1.fieldError }, errors[key])); } if (fieldType === 'boolean') { return /*#__PURE__*/React.createElement("div", { key: key, style: _objectSpread2(_objectSpread2({}, styles$1.formField), isNested ? styles$1.nestedField : {}) }, /*#__PURE__*/React.createElement("label", { style: styles$1.label }, label, ":"), /*#__PURE__*/React.createElement("div", { style: styles$1.checkboxContainer }, /*#__PURE__*/React.createElement("label", { style: styles$1.containerLabel }, /*#__PURE__*/React.createElement("input", { type: "checkbox", name: key, checked: values[key] || false, onChange: function onChange(e) { var syntheticEvent = { target: { name: e.target.name, value: e.target.checked } }; handleChange(syntheticEvent); }, style: values[key] ? _objectSpread2(_objectSpread2({}, styles$1.checkbox), styles$1.checkboxChecked) : styles$1.checkbox }), values[key] ? 'Yes' : 'No'))); } if (isArray) { return /*#__PURE__*/React.createElement("div", { key: key, style: _objectSpread2(_objectSpread2({}, styles$1.formField), isNested ? styles$1.nestedField : {}) }, /*#__PURE__*/React.createElement("label", { style: styles$1.label }, isNested && group === key ? 'Options' : label, ":"), /*#__PURE__*/React.createElement("div", { style: styles$1.radioContainer }, value.map(function (option) { return /*#__PURE__*/React.createElement("label", { key: String(option), style: styles$1.containerLabel }, /*#__PURE__*/React.createElement("input", { type: "radio", name: key, value: option, checked: values[key] === option, onChange: handleChange, style: values[key] === option ? _objectSpread2(_objectSpread2({}, styles$1.radio), styles$1.radioChecked) : styles$1.radio }), typeof option === 'string' ? option.charAt(0).toUpperCase() + option.slice(1) : String(option)); })), errors[key] && /*#__PURE__*/React.createElement("span", { style: styles$1.fieldError }, errors[key])); } return null; }; return /*#__PURE__*/React.createElement(FormErrorBoundary, null, /*#__PURE__*/React.createElement("form", { onSubmit: handleSubmit(onSubmit), className: classNames('custom-form', className, customStyles), style: styles$1.customForm }, flatFields.map(function (key) { return renderField(key); }), Object.keys(groupedFields).map(function (group) { return /*#__PURE__*/React.createElement("div", { key: group, style: styles$1.fieldGroup }, /*#__PURE__*/React.createElement("div", { style: styles$1.formField }, /*#__PURE__*/React.createElement("label", { style: styles$1.label }, generateLabel(group), ":")), groupedFields[group].map(function (key) { return renderField(key, true, group); })); }), /*#__PURE__*/React.createElement("div", { style: styles$1.formButtons }, /*#__PURE__*/React.createElement("button", { type: "submit", disabled: isSubmitting, style: isSubmitting ? _objectSpread2(_objectSpread2({}, styles$1.button), styles$1.buttonDisabled) : styles$1.button }, isSubmitting ? 'Submitting...' : 'Submit'), reset && /*#__PURE__*/React.createElement("button", { type: "button", onClick: resetForm, disabled: isSubmitting, style: isSubmitting ? _objectSpread2(_objectSpread2(_objectSpread2({}, styles$1.button), styles$1.resetButton), styles$1.buttonDisabled) : _objectSpread2(_objectSpread2({}, styles$1.button), styles$1.resetButton) }, "Reset")), errors.submit && /*#__PURE__*/React.createElement("div", { style: styles$1.formError }, errors.submit))); }; Form.propTypes = { initialValues: PropTypes.object.isRequired, validate: PropTypes.func, onSubmit: PropTypes.func.isRequired, className: PropTypes.string, customStyles: PropTypes.string, children: PropTypes.func, reset: PropTypes.bool }; Form.defaultProps = { reset: true }; var styles = { modal: { position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', zIndex: 1050 }, modalDialog: { maxWidth: '500px', width: '90%', backgroundColor: '#fff', borderRadius: '12px', boxShadow: '0 8px 30px rgba(0, 0, 0, 0.2)', position: 'relative' }, modalContent: { padding: '1rem' }, modalHeader: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '0.5rem', borderBottom: '1px solid #dee2e6', backgroundColor: '#f8f9fa' }, modalTitle: { fontSize: '1.5rem', fontWeight: 600, margin: 0 }, closeButton: { background: 'none', border: 'none', fontSize: '1.5rem', cursor: 'pointer', color: '#333', padding: '0.5rem' }, modalBody: { padding: '1rem', maxHeight: '60vh', overflowY: 'auto' }, modalFooter: { display: 'flex', justifyContent: 'flex-end', gap: '0.5rem', padding: '1rem', borderTop: '1px solid #dee2e6' }, btn: { padding: '0.5rem 1rem', borderRadius: '8px', border: 'none', cursor: 'pointer', fontSize: '1rem', color: '#fff' }, btnPrimary: { backgroundColor: '#007bff' }, btnSecondary: { backgroundColor: '#6c757d' }, modalBackdrop: { position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', zIndex: 1040 }, message: { fontSize: '1.25rem', color: '#333', marginBottom: '1rem' }, defaultMessage: { fontSize: '1rem', color: '#6c757d', fontStyle: 'italic' }, dataList: { fontSize: '1rem', color: '#333', marginBottom: '1rem' }, dataItem: { marginBottom: '0.5rem' }, dataKey: { fontWeight: 600, marginRight: '0.5rem' }, dataValue: {}, table: { width: '100%', borderCollapse: 'collapse', border: '1px solid #dee2e6' }, tableHeader: { backgroundColor: '#f8f9fa', fontWeight: 600 }, tableCell: { padding: '0.75rem', border: '1px solid #dee2e6' } }; var _flattenObject = function flattenObject(obj) { var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var result = []; Object.entries(obj).forEach(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; var newKey = prefix ? "".concat(prefix, ".").concat(key) : key; if (_typeof(value) === 'object' && value !== null && !Array.isArray(value)) { result.push.apply(result, _toConsumableArray(_flattenObject(value, newKey))); } else { result.push({ key: newKey, value: value.toString() }); } }); return result; }; var ModalWrapper = function ModalWrapper(_ref3) { var title = _ref3.title, message = _ref3.message, data = _ref3.data, table = _ref3.table, consoleLog = _ref3.console, show = _ref3.show, onClose = _ref3.onClose, onConfirm = _ref3.onConfirm, className = _ref3.className, style = _ref3.style, modalDialogClassName = _ref3.modalDialogClassName, modalDialogStyle = _ref3.modalDialogStyle; React.useEffect(function () { if (show) { document.body.classList.add('unique-modal-open'); document.body.style.overflow = 'hidden'; } else { document.body.classList.remove('unique-modal-open'); document.body.style.overflow = ''; } return function () { document.body.classList.remove('unique-modal-open'); document.body.style.overflow = ''; }; }, [show]); React.useEffect(function () { if (consoleLog && data) { console.log('ModalWrapper data:', data); } }, [consoleLog, data]); if (!show) return null; var hasTitle = title && title.trim(); var hasMessage = message && message.trim(); var hasData = data && Object.keys(data).length > 0; var isEmpty = !hasTitle && !hasMessage && !hasData; var renderData = function renderData() { if (!hasData) return null; var flattened = _flattenObject(data); if (table) { return /*#__PURE__*/React.createElement("div", { style: { overflowX: 'auto' } }, /*#__PURE__*/React.createElement("table", { style: styles.table }, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", { style: styles.tableHeader }, /*#__PURE__*/React.createElement("th", { style: styles.tableCell }, "Field"), /*#__PURE__*/React.createElement("th", { style: styles.tableCell }, "Value"))), /*#__PURE__*/React.createElement("tbody", null, flattened.map(function (_ref4) { var key = _ref4.key, value = _ref4.value; return /*#__PURE__*/React.createElement("tr", { key: key }, /*#__PURE__*/React.createElement("td", { style: styles.tableCell }, key), /*#__PURE__*/React.createElement("td", { style: styles.tableCell }, value)); })))); } return /*#__PURE__*/React.createElement("div", { style: styles.dataList }, flattened.map(function (_ref5) { var key = _ref5.key, value = _ref5.value; return /*#__PURE__*/React.createElement("div", { key: key, style: styles.dataItem }, /*#__PURE__*/React.createElement("span", { style: styles.dataKey }, key, ":"), /*#__PURE__*/React.createElement("span", { style: styles.dataValue }, value)); })); }; var renderContent = function renderContent() { if (isEmpty) { return /*#__PURE__*/React.createElement("p", { style: styles.defaultMessage }, "Data isn't provided"); } return /*#__PURE__*/React.createElement(React.Fragment, null, renderData(), hasMessage && /*#__PURE__*/React.createElement("p", { style: styles.message }, message)); }; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { className: classNames('unique-modal-wrapper', className), style: _objectSpread2(_objectSpread2({}, styles.modal), style), tabIndex: "-1", role: "dialog" }, /*#__PURE__*/React.createElement("div", { className: classNames('modal-dialog', modalDialogClassName), style: _objectSpread2(_objectSpread2({}, styles.modalDialog), modalDialogStyle), role: "document" }, /*#__PURE__*/React.createElement("div", { style: styles.modalContent }, hasTitle && /*#__PURE__*/React.createElement("div", { style: styles.modalHeader }, /*#__PURE__*/React.createElement("h5", { style: styles.modalTitle }, title), /*#__PURE__*/React.createElement("button", { type: "button", onClick: onClose, style: styles.closeButton, "aria-label": "Close" }, /*#__PURE__*/React.createElement("span", null, "\xD7"))), /*#__PURE__*/React.createElement("div", { style: styles.modalBody }, renderContent()), /*#__PURE__*/React.createElement("div", { style: styles.modalFooter }, /*#__PURE__*/React.createElement("button", { type: "button", onClick: onClose, style: _objectSpread2(_objectSpread2({}, styles.btn), styles.btnSecondary) }, "Close"), /*#__PURE__*/React.createElement("button", { type: "button", onClick: onConfirm, style: _objectSpread2(_objectSpread2({}, styles.btn), styles.btnPrimary) }, "Confirm"))))), /*#__PURE__*/React.createElement("div", { style: styles.modalBackdrop })); }; ModalWrapper.propTypes = { title: PropTypes.string, message: PropTypes.string, data: PropTypes.object, table: PropTypes.bool, console: PropTypes.bool, show: PropTypes.bool.isRequired, onClose: PropTypes.func.isRequired, onConfirm: PropTypes.func.isRequired, className: PropTypes.string, style: PropTypes.object, modalDialogClassName: PropTypes.string, modalDialogStyle: PropTypes.object }; ModalWrapper.defaultProps = { title: '', message: '', data: {}, table: false, console: false, className: '', style: {}, modalDialogClassName: '', modalDialogStyle: {} }; export { Form, ModalWrapper }; //# sourceMappingURL=index.js.map