UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

983 lines (982 loc) 40.7 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.clearedData = void 0; exports.default = Provider; require("core-js/modules/web.dom-collections.iterator.js"); var _react = _interopRequireWildcard(require("react")); var _jsonPointer = _interopRequireDefault(require("../../utils/json-pointer")); var _utils = require("../../utils"); var _helpers = require("../../../../shared/helpers"); var _Provider = _interopRequireDefault(require("../../Field/Provider")); var _useUpdateEffect = _interopRequireDefault(require("../../../../shared/helpers/useUpdateEffect")); var _isAsync = require("../../../../shared/helpers/isAsync"); var _useSharedState = require("../../../../shared/helpers/useSharedState"); var _Context = _interopRequireDefault(require("../../../../shared/Context")); var _useTranslation = _interopRequireDefault(require("../../hooks/useTranslation")); var _Context2 = _interopRequireDefault(require("../Context")); var _structuredClone = _interopRequireDefault(require("@ungap/structured-clone")); const _excluded = ["id", "globalStatusId", "defaultData", "emptyData", "data", "schema", "onChange", "onPathChange", "onSubmit", "onSubmitRequest", "onSubmitComplete", "onCommit", "onClear", "scrollTopOnSubmit", "minimumAsyncBehaviorTime", "asyncSubmitTimeout", "sessionStorageId", "ajvInstance", "transformIn", "transformOut", "filterSubmitData", "countryCode", "locale", "translations", "required", "errorMessages", "isolate", "children"]; function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } 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 _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) { _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 _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } 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 || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } const useLayoutEffect = typeof window === 'undefined' ? _react.default.useEffect : _react.default.useLayoutEffect; const isArrayJsonPointer = /^\/\d+(\/|$)/; function Provider(props) { var _sharedAttachments$da; const [, forceUpdate] = (0, _react.useReducer)(() => ({}), {}); const { id, globalStatusId = 'main', defaultData, emptyData, data, schema, onChange, onPathChange, onSubmit, onSubmitRequest, onSubmitComplete, onCommit, onClear, scrollTopOnSubmit, minimumAsyncBehaviorTime, asyncSubmitTimeout, sessionStorageId, ajvInstance, transformIn, transformOut, filterSubmitData, countryCode, locale, translations, required, errorMessages, isolate, children } = props, rest = _objectWithoutProperties(props, _excluded); if (data !== undefined && sessionStorageId !== undefined) { throw new Error('Use "defaultData" instead of "data" when using sessionStorageId'); } const { hasContext } = (0, _react.useContext)(_Context2.default) || {}; if (hasContext && !isolate) { throw new Error('DataContext (Form.Handler) cannot be nested'); } const formElementRef = (0, _react.useRef)(null); const { locale: sharedLocale } = (0, _react.useContext)(_Context.default) || {}; const translation = (0, _useTranslation.default)().Field; const ajvRef = (0, _react.useRef)((0, _utils.makeAjvInstance)(ajvInstance)); const mountedFieldsRef = (0, _react.useRef)(new Map()); const snapshotsRef = (0, _react.useRef)(new Map()); const existingFieldsRef = (0, _react.useRef)(new Map()); const hasVisibleErrorRef = (0, _react.useRef)(new Map()); const errorsRef = (0, _react.useRef)(); const addSetShowAllErrorsRef = (0, _react.useRef)([]); const showAllErrorsRef = (0, _react.useRef)(false); const setShowAllErrors = (0, _react.useCallback)(showAllErrors => { showAllErrorsRef.current = showAllErrors ? Date.now() : showAllErrors; forceUpdate(); addSetShowAllErrorsRef.current.forEach(fn => fn === null || fn === void 0 ? void 0 : fn(showAllErrors)); }, []); const revealError = (0, _react.useCallback)((path, hasError) => { if (hasError) { hasVisibleErrorRef.current.set(path, hasError); } else { hasVisibleErrorRef.current.delete(path); } forceUpdate(); }, []); const submitStateRef = (0, _react.useRef)({}); const setSubmitState = (0, _react.useCallback)(state => { submitStateRef.current = _objectSpread(_objectSpread({}, submitStateRef.current), state); forceUpdate(); }, []); const formStateRef = (0, _react.useRef)(); const keepPending = (0, _react.useRef)(false); const setFormState = (0, _react.useCallback)(function (formState) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (typeof (options === null || options === void 0 ? void 0 : options.keepPending) === 'boolean') { keepPending.current = options === null || options === void 0 ? void 0 : options.keepPending; } formStateRef.current = formState; forceUpdate(); }, []); const fieldErrorRef = (0, _react.useRef)({}); const fieldStateRef = (0, _react.useRef)({}); const initialData = (0, _react.useMemo)(() => { if (sessionStorageId && typeof window !== 'undefined') { var _window$sessionStorag; const sessionDataJSON = (_window$sessionStorag = window.sessionStorage) === null || _window$sessionStorag === void 0 ? void 0 : _window$sessionStorag.getItem(sessionStorageId); if (sessionDataJSON) { return JSON.parse(sessionDataJSON); } } return data !== null && data !== void 0 ? data : defaultData; }, []); const internalDataRef = (0, _react.useRef)(initialData); const isEmptyDataRef = (0, _react.useRef)(false); const ajvValidatorRef = (0, _react.useRef)(); const executeAjvValidator = (0, _react.useCallback)(() => { var _ajvValidatorRef$curr; if (!ajvValidatorRef.current) { return; } if (!((_ajvValidatorRef$curr = ajvValidatorRef.current) !== null && _ajvValidatorRef$curr !== void 0 && _ajvValidatorRef$curr.call(ajvValidatorRef, internalDataRef.current))) { errorsRef.current = (0, _utils.ajvErrorsToFormErrors)(ajvValidatorRef.current.errors, internalDataRef.current); } else { errorsRef.current = undefined; } }, []); const validateData = (0, _react.useCallback)(() => { if (!ajvValidatorRef.current) { return; } executeAjvValidator(); forceUpdate(); }, [executeAjvValidator]); const checkFieldStateFor = (0, _react.useCallback)((path, state) => { var _errorsRef$current; return Boolean(state === 'error' ? ((_errorsRef$current = errorsRef.current) === null || _errorsRef$current === void 0 ? void 0 : _errorsRef$current[path]) instanceof Error || fieldErrorRef.current[path] instanceof Error : fieldStateRef.current[path] === state); }, []); const hasFieldState = (0, _react.useCallback)(state => { return Array.from(mountedFieldsRef.current.entries()).some(_ref => { let [path, item] = _ref; return item.isMounted && checkFieldStateFor(path, state); }); }, [checkFieldStateFor]); const hasFieldError = (0, _react.useCallback)(path => { return Array.from(mountedFieldsRef.current.entries()).some(_ref2 => { let [p, item] = _ref2; return item.isMounted && p === path && checkFieldStateFor(path, 'error'); }); }, [checkFieldStateFor]); const hasErrors = (0, _react.useCallback)(() => { return hasFieldState('error'); }, [hasFieldState]); const setFieldError = (0, _react.useCallback)((path, error) => { fieldErrorRef.current[path] = error; }, []); const setFieldState = (0, _react.useCallback)((path, fieldState) => { if (fieldState !== fieldStateRef.current[path]) { fieldStateRef.current[path] = fieldState; forceUpdate(); } }, []); const getDataPathHandlerParameters = (0, _react.useCallback)(function (path) { var _fieldInternalsRef$cu; let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : internalDataRef.current; const value = _jsonPointer.default.has(data, path) ? _jsonPointer.default.get(data, path) : undefined; const { value: displayValue } = fieldDisplayValueRef.current[path] || {}; const props = (_fieldInternalsRef$cu = fieldInternalsRef.current[path]) === null || _fieldInternalsRef$cu === void 0 ? void 0 : _fieldInternalsRef$cu.props; const label = props === null || props === void 0 ? void 0 : props.label; const error = fieldErrorRef.current[path]; return { path, value, displayValue, label, props, data: internalDataRef.current, error, internal: { error } }; }, []); const mutateDataHandler = (0, _react.useCallback)(function (data, handler) { let { remove = false, mutate = true, fireHandlerWhen = null } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; const freshData = {}; const mutateEntry = (path, result) => { if (remove) { if (result === false) { data = (0, _structuredClone.default)(data); _jsonPointer.default.remove(data, path); } } else { if (typeof result !== 'undefined') { if (mutate) { data = (0, _structuredClone.default)(data); _jsonPointer.default.set(data, path, result); } else { _jsonPointer.default.set(freshData, path, result); } } } }; if (typeof handler === 'function') { Object.keys(fieldInternalsRef.current).forEach(path => { const exists = _jsonPointer.default.has(data, path); if (exists) { const { type } = fieldDisplayValueRef.current[path] || {}; if ((fireHandlerWhen === null || fireHandlerWhen === void 0 ? void 0 : fireHandlerWhen({ type })) !== false) { const result = handler(getDataPathHandlerParameters(path, data)); mutateEntry(path, result); } } }); if (!mutate) { return freshData; } return data; } else if (handler) { const runFilter = _ref3 => { let { path, condition } = _ref3; const exists = _jsonPointer.default.has(data, path); if (exists) { const result = typeof condition === 'function' ? condition(getDataPathHandlerParameters(path, data)) : condition; mutateEntry(path, result); } }; const wildcardPaths = []; Object.entries(handler).forEach(_ref4 => { let [path, condition] = _ref4; if (path.includes('*')) { const parts = path.split(/\/\*/g); const exists = _jsonPointer.default.has(data, parts[0]); if (exists) { const traverse = (subData, subPath, idx) => { if (idx === parts.length - 1) { wildcardPaths.push({ path: subPath, condition }); return; } const list = _jsonPointer.default.get(subData, subPath); if (Array.isArray(list)) { list.forEach((_, i) => { traverse(list[i], `${subPath}/${i}${parts[idx + 1]}`, idx + 1); }); } }; traverse(data, parts[0], 0); } } else { runFilter({ path, condition }); } }); wildcardPaths.forEach(runFilter); return data; } return data; }, [getDataPathHandlerParameters]); const visibleDataHandler = (0, _react.useCallback)(function () { let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : internalDataRef.current; let { keepPaths, removePaths } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; const visibleData = {}; mountedFieldsRef.current.forEach((item, path) => { if (item && item.isVisible !== false && (item.isPreMounted !== false || item.wasStepChange === true) && (removePaths ? !removePaths.includes(path) : true) && _jsonPointer.default.has(data, path)) { _jsonPointer.default.set(visibleData, path, _jsonPointer.default.get(data, path)); } }); if (keepPaths) { keepPaths.forEach(path => { if (_jsonPointer.default.has(data, path)) { _jsonPointer.default.set(visibleData, path, _jsonPointer.default.get(data, path)); } }); } return visibleData; }, []); const filterDataHandler = (0, _react.useCallback)((data, filter) => { if (filter) { return mutateDataHandler(data, filter, { remove: true }); } return data; }, [mutateDataHandler]); const filterData = (0, _react.useCallback)(function (filter) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : internalDataRef.current; return filterDataHandler(data, filter); }, [filterDataHandler]); const fieldDisplayValueRef = (0, _react.useRef)({}); const fieldConnectionsRef = (0, _react.useRef)({}); const setFieldConnection = (0, _react.useCallback)((path, connections) => { fieldConnectionsRef.current[path] = connections; }, []); const fieldInternalsRef = (0, _react.useRef)({}); const setFieldInternals = (0, _react.useCallback)((path, props, id) => { fieldInternalsRef.current[path] = Object.assign(fieldInternalsRef.current[path] || {}, { props, id }); }, []); const valueInternalsRef = (0, _react.useRef)({}); const setValueInternals = (0, _react.useCallback)((path, props) => { valueInternalsRef.current[path] = Object.assign(valueInternalsRef.current[path] || {}, { props }); }, []); const hasFieldWithAsyncValidator = (0, _react.useCallback)(() => { for (const path in fieldInternalsRef.current) { var _mountedFieldsRef$cur; if ((_mountedFieldsRef$cur = mountedFieldsRef.current.get(path)) !== null && _mountedFieldsRef$cur !== void 0 && _mountedFieldsRef$cur.isMounted) { var _fieldInternalsRef$cu2; const props = (_fieldInternalsRef$cu2 = fieldInternalsRef.current[path]) === null || _fieldInternalsRef$cu2 === void 0 ? void 0 : _fieldInternalsRef$cu2.props; if ((0, _isAsync.isAsync)(props === null || props === void 0 ? void 0 : props.onChangeValidator) || (0, _isAsync.isAsync)(props === null || props === void 0 ? void 0 : props.onBlurValidator)) { return true; } } } return false; }, []); const sharedData = (0, _useSharedState.useSharedState)(id); const sharedAttachments = (0, _useSharedState.useSharedState)((0, _useSharedState.createReferenceKey)(id, 'attachments')); const sharedDataContext = (0, _useSharedState.useSharedState)((0, _useSharedState.createReferenceKey)(id, 'data-context')); const setSharedData = sharedData.set; const extendSharedData = sharedData.extend; const extendAttachment = sharedAttachments.extend; const rerenderUseDataHook = (_sharedAttachments$da = sharedAttachments.data) === null || _sharedAttachments$da === void 0 ? void 0 : _sharedAttachments$da.rerenderUseDataHook; const cacheRef = (0, _react.useRef)({ data, schema, shared: sharedData.data, hasUsedInitialData: false }); const internalData = (0, _react.useMemo)(() => { if (id && initialData && !sharedData.data) { sharedData.update(initialData); } if (id && initialData && sharedData.data && cacheRef.current.shared === sharedData.data && internalDataRef.current === initialData && typeof internalDataRef.current === 'object') { return _objectSpread(_objectSpread({}, internalDataRef.current), sharedData.data || {}); } if (id && !initialData && !internalDataRef.current && sharedData.data && cacheRef.current.shared === sharedData.data) { return sharedData.data; } if (id && sharedData.data && cacheRef.current.shared !== sharedData.data && sharedData.data !== internalDataRef.current && typeof internalDataRef.current === 'object') { cacheRef.current.shared = sharedData.data; if (isEmptyDataRef.current) { return Array.isArray(internalDataRef.current) ? [] : clearedData; } return _objectSpread(_objectSpread({}, internalDataRef.current), sharedData.data || {}); } if (data !== cacheRef.current.data) { cacheRef.current.data = data; return data; } return internalDataRef.current; }, [id, initialData, sharedData, data]); internalDataRef.current = props.path && _jsonPointer.default.has(internalData, props.path) ? _jsonPointer.default.get(internalData, props.path) : internalData; const clearData = (0, _react.useCallback)(() => { var _ref5, _requestAnimationFram; isEmptyDataRef.current = true; internalDataRef.current = (_ref5 = typeof emptyData === 'function' ? emptyData(internalDataRef.current) : emptyData) !== null && _ref5 !== void 0 ? _ref5 : Array.isArray(internalDataRef.current) ? [] : clearedData; if (id) { setSharedData(internalDataRef.current); } forceUpdate(); onClear === null || onClear === void 0 ? void 0 : onClear(); (_requestAnimationFram = requestAnimationFrame) === null || _requestAnimationFram === void 0 ? void 0 : _requestAnimationFram(() => { isEmptyDataRef.current = false; }); }, [emptyData, id, onClear, setSharedData]); (0, _react.useMemo)(() => { executeAjvValidator(); }, [internalDataRef.current]); const storeInSession = (0, _react.useMemo)(() => { return (0, _helpers.debounce)(() => { var _window$sessionStorag2; (_window$sessionStorag2 = window.sessionStorage) === null || _window$sessionStorag2 === void 0 ? void 0 : _window$sessionStorag2.setItem(sessionStorageId, JSON.stringify(internalDataRef.current)); }, process.env.NODE_ENV === 'test' ? 1 : 800); }, [sessionStorageId]); const setData = (0, _react.useCallback)(function (newData) { let preventUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (transformIn) { newData = mutateDataHandler(newData, transformIn); } internalDataRef.current = newData; if (id) { extendSharedData(newData, { preventSyncOfSameInstance: true }); if (filterSubmitData) { rerenderUseDataHook === null || rerenderUseDataHook === void 0 ? void 0 : rerenderUseDataHook(); } } if (sessionStorageId && typeof window !== 'undefined') { storeInSession(); } if (!preventUpdate) { forceUpdate(); } }, [extendSharedData, filterSubmitData, id, mutateDataHandler, rerenderUseDataHook, sessionStorageId, storeInSession, transformIn]); const updateDataValue = (0, _react.useCallback)(function (path, value) { var _internalDataRef$curr; let { preventUpdate } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (!path) { return; } const givenData = path === '/' ? value : (_internalDataRef$curr = internalDataRef.current) !== null && _internalDataRef$curr !== void 0 ? _internalDataRef$curr : path.match(isArrayJsonPointer) ? [] : {}; let newData = null; try { newData = (0, _structuredClone.default)(givenData); } catch (e) { newData = givenData; } if (path !== '/') { _jsonPointer.default.set(newData, path, value); } setData(newData, preventUpdate); }, [setData]); const handlePathChangeUnvalidated = (0, _react.useCallback)(async (path, value) => { if (!path) { return null; } updateDataValue(path, value); if ((0, _isAsync.isAsync)(onPathChange)) { await (onPathChange === null || onPathChange === void 0 ? void 0 : onPathChange(path, value)); } else { onPathChange === null || onPathChange === void 0 ? void 0 : onPathChange(path, value); } for (const itm of fieldEventListenersRef.current) { if (itm.type === 'onPathChange' && itm.path === path) { const { callback } = itm; if ((0, _isAsync.isAsync)(callback)) { await callback({ value }); } else { callback({ value }); } } } }, [onPathChange, updateDataValue]); const handlePathChange = (0, _react.useCallback)(async function (path) { let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '_undefined_'; if (!path) { return null; } if (value !== '_undefined_') { handlePathChangeUnvalidated(path, value); } showAllErrorsRef.current = false; validateData(); const data = internalDataRef.current; const options = { filterData }; const transformedData = transformOut ? mutateDataHandler(data, transformOut) : data; for (const cb of changeHandlerStackRef.current) { if ((0, _isAsync.isAsync)(onChange)) { await cb(transformedData, options); } else { cb(transformedData, options); } } if ((0, _isAsync.isAsync)(onChange)) { return await onChange(transformedData, options); } return onChange === null || onChange === void 0 ? void 0 : onChange(transformedData, options); }, [filterData, handlePathChangeUnvalidated, mutateDataHandler, onChange, transformOut, validateData]); const changeHandlerStackRef = (0, _react.useRef)([]); const addOnChangeHandler = (0, _react.useCallback)(callback => { const exists = changeHandlerStackRef.current.some(cb => { return callback === cb; }); if (!exists) { changeHandlerStackRef.current.push(callback); } }, []); const setMountedFieldState = (0, _react.useCallback)((path, state) => { mountedFieldsRef.current.set(path, _objectSpread(_objectSpread({}, mountedFieldsRef.current.get(path)), state)); for (const itm of fieldEventListenersRef.current) { if (itm.type === 'onMount' && itm.path === path) { const { callback } = itm; callback(); } } }, []); const scrollToTop = (0, _react.useCallback)(() => { if (typeof window !== 'undefined') { var _window, _window$scrollTo; (_window = window) === null || _window === void 0 ? void 0 : (_window$scrollTo = _window.scrollTo) === null || _window$scrollTo === void 0 ? void 0 : _window$scrollTo.call(_window, { top: 0, behavior: 'smooth' }); } }, []); const handleSubmitCall = (0, _react.useCallback)(async args => { const { onSubmit, enableAsyncBehavior, skipFieldValidation, skipErrorCheck } = args; setSubmitState({ error: undefined, customStatus: undefined }); const asyncBehaviorIsEnabled = (skipErrorCheck ? true : !hasErrors() || hasFieldState('pending')) && (enableAsyncBehavior || hasFieldWithAsyncValidator()); if (asyncBehaviorIsEnabled) { setFormState('pending'); } if (!skipFieldValidation) { for (const item of fieldEventListenersRef.current) { var _mountedFieldsRef$cur2; const { path, type, callback } = item; if (type === 'onSubmitCall' && (_mountedFieldsRef$cur2 = mountedFieldsRef.current.get(path)) !== null && _mountedFieldsRef$cur2 !== void 0 && _mountedFieldsRef$cur2.isMounted) { if (asyncBehaviorIsEnabled) { await callback(); } else { callback(); } } } } let result; if (!(skipErrorCheck ? false : hasErrors()) && !hasFieldState('pending') && (skipFieldValidation ? true : !hasFieldState('error'))) { var _result2, _result4, _result5, _result6, _result7; let submitResult; try { if (isolate) { submitResult = await (onCommit === null || onCommit === void 0 ? void 0 : onCommit(internalDataRef.current, { clearData })); } else { submitResult = await onSubmit(); } if (submitResult instanceof Error) { throw submitResult; } } catch (error) { submitResult = { error }; } result = submitResult; if (asyncBehaviorIsEnabled) { var _result; if ((_result = result) !== null && _result !== void 0 && _result.error) { setFormState('abort'); } else if (keepPending.current !== true) { setFormState('complete'); } } if ((_result2 = result) !== null && _result2 !== void 0 && _result2['status']) { var _result3; setFormState((_result3 = result) === null || _result3 === void 0 ? void 0 : _result3['status']); } if ((_result4 = result) !== null && _result4 !== void 0 && _result4.error || (_result5 = result) !== null && _result5 !== void 0 && _result5.warning || (_result6 = result) !== null && _result6 !== void 0 && _result6.info || (_result7 = result) !== null && _result7 !== void 0 && _result7.customStatus) { setSubmitState(result); } } else { if (asyncBehaviorIsEnabled) { await new Promise(resolve => window.requestAnimationFrame(resolve)); setFormState(undefined); if (!skipFieldValidation) { onSubmitContinueRef.current = () => { window.requestAnimationFrame(() => { handleSubmitCall(_objectSpread(_objectSpread({}, args), {}, { skipFieldValidation: true })); }); }; } } setShowAllErrors(true); onSubmitRequest === null || onSubmitRequest === void 0 ? void 0 : onSubmitRequest({ getErrors: () => Object.keys(fieldErrorRef.current).map(path => { return getDataPathHandlerParameters(path); }).filter(_ref6 => { let { error } = _ref6; return error; }) }); for (const itm of fieldEventListenersRef.current) { if (itm.type === 'onSubmitRequest') { itm.callback(); } } } return result; }, [clearData, getDataPathHandlerParameters, hasErrors, hasFieldState, hasFieldWithAsyncValidator, isolate, onCommit, onSubmitRequest, setFormState, setShowAllErrors, setSubmitState]); const getSubmitData = (0, _react.useCallback)(() => { const data = internalDataRef.current; const mutatedData = transformOut ? mutateDataHandler(data, transformOut) : data; const filteredData = filterSubmitData ? filterDataHandler(mutatedData, filterSubmitData) : mutatedData; return filteredData; }, [filterDataHandler, filterSubmitData, mutateDataHandler, transformOut]); const getSubmitParams = (0, _react.useCallback)(() => { const reduceToVisibleFields = (data, options) => { return visibleDataHandler(transformOut ? mutateDataHandler(data, transformOut) : data, options); }; const transformData = (data, handler) => { return mutateDataHandler(data, handler, { mutate: false, fireHandlerWhen: _ref7 => { let { type } = _ref7; return type === 'field'; } }); }; const formElement = formElementRef.current; const params = { filterData, reduceToVisibleFields, transformData, resetForm: () => { var _formElement$reset; formElement === null || formElement === void 0 ? void 0 : (_formElement$reset = formElement.reset) === null || _formElement$reset === void 0 ? void 0 : _formElement$reset.call(formElement); if (typeof window !== 'undefined') { if (sessionStorageId) { window.sessionStorage.removeItem(sessionStorageId); } } forceUpdate(); }, clearData }; return params; }, [clearData, filterData, mutateDataHandler, sessionStorageId, transformOut, visibleDataHandler]); const handleSubmit = (0, _react.useCallback)(async () => { return await handleSubmitCall({ enableAsyncBehavior: (0, _isAsync.isAsync)(onSubmit), onSubmit: async () => { let stop = false; const preventSubmit = () => stop = true; for (const item of fieldEventListenersRef.current) { const { type, callback } = item; if (type === 'onSubmit') { callback({ preventSubmit }); } } if (stop) { return; } const data = getSubmitData(); const options = getSubmitParams(); let result = undefined; if ((0, _isAsync.isAsync)(onSubmit)) { result = await onSubmit(data, options); } else { result = onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(data, options); } const completeResult = await (onSubmitComplete === null || onSubmitComplete === void 0 ? void 0 : onSubmitComplete(data, result)); if (completeResult) { result = Object.keys(result).length > 0 ? _objectSpread(_objectSpread({}, result), completeResult) : completeResult; } if (scrollTopOnSubmit) { scrollToTop(); } return result; } }); }, [getSubmitData, getSubmitParams, handleSubmitCall, onSubmit, onSubmitComplete, scrollToTop, scrollTopOnSubmit]); const fieldEventListenersRef = (0, _react.useRef)([]); const setFieldEventListener = (0, _react.useCallback)(function (path, type, callback) { let { remove = false } = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; fieldEventListenersRef.current = fieldEventListenersRef.current.filter(_ref8 => { let { path: p, type: t, callback: c } = _ref8; return !(p === path && t === type && c === callback); }); if (!remove) { fieldEventListenersRef.current.push({ path, type, callback }); } }, []); const onSubmitContinueRef = (0, _react.useRef)(null); if (!hasFieldState('pending')) { var _onSubmitContinueRef$; (_onSubmitContinueRef$ = onSubmitContinueRef.current) === null || _onSubmitContinueRef$ === void 0 ? void 0 : _onSubmitContinueRef$.call(onSubmitContinueRef); onSubmitContinueRef.current = null; } (0, _react.useEffect)(() => { if (schema) { var _ajvRef$current; ajvValidatorRef.current = (_ajvRef$current = ajvRef.current) === null || _ajvRef$current === void 0 ? void 0 : _ajvRef$current.compile(schema); } validateData(); }, [schema, validateData]); (0, _useUpdateEffect.default)(() => { if (schema && schema !== cacheRef.current.schema) { var _ajvRef$current2; cacheRef.current.schema = schema; ajvValidatorRef.current = (_ajvRef$current2 = ajvRef.current) === null || _ajvRef$current2 === void 0 ? void 0 : _ajvRef$current2.compile(schema); validateData(); forceUpdate(); } }, [schema, validateData, forceUpdate]); const onTimeout = (0, _react.useCallback)(() => { setFormState(undefined); setSubmitState({ info: undefined, warning: undefined, error: undefined, customStatus: undefined }); }, [setFormState, setSubmitState]); useLayoutEffect(() => { if (id) { if (initialData && !sharedData.data) { extendSharedData(initialData, { preventSyncOfSameInstance: true }); } } }, [id, initialData, extendSharedData, sharedData.data]); useLayoutEffect(() => { if (id) { extendAttachment({ visibleDataHandler, filterDataHandler, hasErrors, hasFieldError, setShowAllErrors, setSubmitState, clearData, setData, updateDataValue, fieldConnectionsRef, internalDataRef }, { preventSyncOfSameInstance: true }); if (filterSubmitData) { rerenderUseDataHook === null || rerenderUseDataHook === void 0 ? void 0 : rerenderUseDataHook(); } } }, [clearData, extendAttachment, filterDataHandler, filterSubmitData, hasErrors, hasFieldError, id, rerenderUseDataHook, setData, setShowAllErrors, setSubmitState, updateDataValue, visibleDataHandler]); const { bufferedFormState: formState } = useFormStatusBuffer({ formState: formStateRef.current, waitFor: hasFieldState('pending'), minimumAsyncBehaviorTime, asyncSubmitTimeout, onTimeout }); const submitState = submitStateRef.current; const disabled = typeof (rest === null || rest === void 0 ? void 0 : rest['disabled']) === 'boolean' ? rest === null || rest === void 0 ? void 0 : rest['disabled'] : formState === 'pending' === true ? true : undefined; const contextErrorMessages = (errorMessages === null || errorMessages === void 0 ? void 0 : errorMessages[locale !== null && locale !== void 0 ? locale : sharedLocale]) || errorMessages; const getSourceValue = (0, _react.useCallback)(value => { const data = internalDataRef.current; if (String(value).startsWith('/') && _jsonPointer.default.has(data, String(value))) { return _jsonPointer.default.get(data, String(value)); } return value; }, []); const contextValue = _objectSpread({ handlePathChange, handlePathChangeUnvalidated, handleSubmit, setMountedFieldState, handleSubmitCall, setFormState, setSubmitState, setShowAllErrors, revealError, setFieldEventListener, setFieldState, setFieldError, setFieldConnection, setFieldInternals, setValueInternals, hasErrors, hasFieldError, hasFieldState, validateData, updateDataValue, setData, clearData, visibleDataHandler, filterDataHandler, getSubmitData, getSubmitParams, addOnChangeHandler, scrollToTop, schema, disabled, required, formState, submitState, contextErrorMessages, hasContext: true, errors: errorsRef.current, showAllErrors: showAllErrorsRef.current, hasVisibleError: hasVisibleErrorRef.current.size > 0, addSetShowAllErrorsRef, fieldConnectionsRef, fieldDisplayValueRef, fieldInternalsRef, valueInternalsRef, mountedFieldsRef, snapshotsRef, existingFieldsRef, formElementRef, isEmptyDataRef, fieldErrorRef, ajvInstance: ajvRef.current, countryCode: countryCode ? getSourceValue(countryCode) : undefined, id, data: internalDataRef.current, internalDataRef, props }, rest); if (id) { sharedDataContext.set(contextValue); } return _react.default.createElement(_Context2.default.Provider, { value: contextValue }, _react.default.createElement(_Provider.default, { FormStatus: globalStatusId ? { globalStatus: { id: globalStatusId, title: translation.errorSummaryTitle, show: Boolean(showAllErrorsRef.current) } } : undefined, formElement: disabled ? { disabled: true } : undefined, locale: locale ? locale : undefined, translations: translations ? translations : undefined }, children)); } function useFormStatusBuffer(props) { const { formState, waitFor, minimumAsyncBehaviorTime, asyncSubmitTimeout, onTimeout } = props || {}; const [, forceUpdate] = (0, _react.useReducer)(() => ({}), {}); const stateRef = (0, _react.useRef)(); const nowRef = (0, _react.useRef)(null); const timeoutRef = (0, _react.useRef)({}); const setState = (0, _react.useCallback)(state => { stateRef.current = state; forceUpdate(); }, [forceUpdate]); const clear = (0, _react.useCallback)(() => { for (const key in timeoutRef.current) { clearTimeout(timeoutRef.current[key]); } }, []); const hadCompleteRef = (0, _react.useRef)(false); const activeElementRef = (0, _react.useRef)(null); (0, _react.useEffect)(() => { const isTest = process.env.NODE_ENV === 'test'; const minimum = minimumAsyncBehaviorTime !== null && minimumAsyncBehaviorTime !== void 0 ? minimumAsyncBehaviorTime : isTest ? 1 : 1000; if (stateRef.current && formState === 'error') { clear(); setState(undefined); return; } if (formState === 'abort') { clear(); setState('abort'); timeoutRef.current.reset = setTimeout(() => { nowRef.current = 0; setState(undefined); }, minimum); return; } if (formState === 'complete') { hadCompleteRef.current = true; } if (formState === 'pending' && stateRef.current !== 'pending') { activeElementRef.current = document.activeElement; clear(); nowRef.current = Date.now(); hadCompleteRef.current = false; setState('pending'); } else if (stateRef.current === 'pending') { const offset = Math.max(Date.now() - nowRef.current); const delay = isTest ? minimum : Math.max(minimum - offset, 0); if (!waitFor) { timeoutRef.current.complete = setTimeout(() => { if (hadCompleteRef.current) { setState('complete'); } window.requestAnimationFrame(() => { var _activeElementRef$cur, _activeElementRef$cur2; (_activeElementRef$cur = activeElementRef.current) === null || _activeElementRef$cur === void 0 ? void 0 : (_activeElementRef$cur2 = _activeElementRef$cur.focus) === null || _activeElementRef$cur2 === void 0 ? void 0 : _activeElementRef$cur2.call(_activeElementRef$cur); }); }, delay); timeoutRef.current.reset = setTimeout(() => { nowRef.current = 0; setState(undefined); clear(); }, delay + minimum); } } if (stateRef.current === 'pending') { timeoutRef.current.timeout = setTimeout(() => { clear(); setState(undefined); onTimeout === null || onTimeout === void 0 ? void 0 : onTimeout(); }, asyncSubmitTimeout !== null && asyncSubmitTimeout !== void 0 ? asyncSubmitTimeout : 30000); } return clear; }, [clear, minimumAsyncBehaviorTime, formState, setState, waitFor, asyncSubmitTimeout, onTimeout]); return { bufferedFormState: stateRef.current }; } const clearedData = exports.clearedData = Object.freeze({}); //# sourceMappingURL=Provider.js.map