@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
152 lines (151 loc) • 6.63 kB
JavaScript
;
"use client";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useData;
exports.useDataReturn = useDataReturn;
var _react = require("react");
var _index = _interopRequireDefault(require("../../utils/json-pointer/index.js"));
var _useSharedState = require("../../../../shared/helpers/useSharedState.js");
var _useMountEffect = _interopRequireDefault(require("../../../../shared/helpers/useMountEffect.js"));
var _Context = _interopRequireDefault(require("../../DataContext/Context.js"));
var _structuredClone = require("../../../../shared/helpers/structuredClone.js");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function useData(id = undefined, initialData = undefined) {
const sharedDataRef = (0, _react.useRef)(null);
const sharedAttachmentsRef = (0, _react.useRef)(null);
sharedDataRef.current = (0, _useSharedState.useSharedState)(id, initialData);
sharedAttachmentsRef.current = id ? (0, _useSharedState.createSharedState)((0, _useSharedState.createReferenceKey)(id, 'attachments')) : null;
const dataContext = (0, _react.useContext)(_Context.default);
const subscribeContextData = (0, _react.useCallback)(callback => {
if (!id && dataContext?.subscribeDataValue) {
return dataContext.subscribeDataValue('/', callback);
}
return () => undefined;
}, [dataContext, id]);
const getContextDataSnapshot = (0, _react.useCallback)(() => {
if (!id && dataContext?.getDataValue) {
return dataContext.getDataValue('/');
}
return undefined;
}, [dataContext, id]);
const contextData = (0, _react.useSyncExternalStore)(subscribeContextData, getContextDataSnapshot, getContextDataSnapshot);
return useDataReturn({
id,
initialData,
sharedDataRef,
sharedAttachmentsRef,
dataContext,
contextData,
errorMessage: 'useData needs to run inside DataContext (Form.Handler) or have a valid id'
});
}
function useDataReturn({
id,
initialData,
sharedDataRef,
sharedAttachmentsRef,
dataContext,
dataContextRef,
contextData,
errorMessage
}) {
const fallbackDataContextRef = (0, _react.useRef)(dataContext);
fallbackDataContextRef.current = dataContext;
const getDataContext = (0, _react.useCallback)(() => {
var _dataContextRef$curre;
return (_dataContextRef$curre = dataContextRef?.current) !== null && _dataContextRef$curre !== void 0 ? _dataContextRef$curre : fallbackDataContextRef.current;
}, [dataContextRef]);
const contextDataDependency = id ? undefined : dataContext;
if (!id && !getDataContext().hasContext) {
throw new Error(errorMessage);
}
const getCurrentData = (0, _react.useCallback)(() => {
var _dataContext$getDataV;
if (id) {
return sharedDataRef.current?.get?.();
}
const dataContext = getDataContext();
return (_dataContext$getDataV = dataContext?.getDataValue?.('/')) !== null && _dataContext$getDataV !== void 0 ? _dataContext$getDataV : dataContext?.data;
}, [getDataContext, id, sharedDataRef]);
const getExistingData = (0, _react.useCallback)(() => {
var _ref, _ref2, _ref3;
const liveStoreData = id ? sharedDataRef.current?.get?.() : null;
const liveContextData = !id ? getCurrentData() : null;
const dataContext = getDataContext();
return (0, _structuredClone.structuredClone)((_ref = (_ref2 = (_ref3 = liveStoreData !== null && liveStoreData !== void 0 ? liveStoreData : liveContextData) !== null && _ref3 !== void 0 ? _ref3 : dataContext?.data) !== null && _ref2 !== void 0 ? _ref2 : sharedAttachmentsRef.current?.data?.internalDataRef?.current) !== null && _ref !== void 0 ? _ref : {});
}, [getDataContext, getCurrentData, id, sharedAttachmentsRef, sharedDataRef]);
const set = (0, _react.useCallback)(newData => {
if (id) {
sharedDataRef.current?.set(newData);
} else {
getDataContext().setData?.(newData);
}
}, [getDataContext, id, sharedDataRef]);
const update = (0, _react.useCallback)((path, value = undefined) => {
const existingData = getExistingData();
const existingValue = _index.default.has(existingData, path) ? _index.default.get(existingData, path) : undefined;
const newValue = typeof value === 'function' ? value(existingValue) : value;
if (newValue !== existingValue) {
_index.default.set(existingData, path, newValue);
if (id) {
sharedDataRef.current?.extend(existingData);
} else {
getDataContext().updateDataValue?.(path, newValue);
}
}
}, [getDataContext, getExistingData, id, sharedDataRef]);
const remove = (0, _react.useCallback)(path => {
const existingData = getExistingData();
if (_index.default.has(existingData, path)) {
_index.default.remove(existingData, path);
if (id) {
sharedDataRef.current?.set(existingData);
} else {
getDataContext().setData?.(existingData);
}
}
}, [getDataContext, getExistingData, id, sharedDataRef]);
const reduceToVisibleFields = (0, _react.useCallback)((data, options = {}) => {
if (id) {
return sharedAttachmentsRef.current.data?.visibleDataHandler?.(data, options);
}
return getDataContext()?.visibleDataHandler?.(data, options);
}, [contextDataDependency, getDataContext, id, sharedAttachmentsRef]);
const filterData = (0, _react.useCallback)((filter, data = getCurrentData()) => {
if (id) {
return sharedAttachmentsRef.current.data?.filterDataHandler?.(data, filter);
}
return getDataContext()?.filterDataHandler?.(data, filter);
}, [contextDataDependency, getCurrentData, getDataContext, id, sharedAttachmentsRef]);
const getValue = (0, _react.useCallback)(path => {
const dataContext = getDataContext();
if (!id && dataContext?.getDataValue) {
return dataContext.getDataValue(path);
}
const data = getCurrentData();
if (_index.default.has(data, path)) {
return _index.default.get(data, path);
}
return undefined;
}, [getCurrentData, getDataContext, id]);
(0, _useMountEffect.default)(() => {
if (id && !sharedDataRef.current?.hadInitialData && initialData) {
sharedDataRef.current?.extend(initialData, {
forceSync: true
});
}
});
const data = id ? sharedDataRef.current?.data : contextData !== null && contextData !== void 0 ? contextData : getCurrentData();
return (0, _react.useMemo)(() => ({
data,
remove,
update,
set,
getValue,
reduceToVisibleFields,
filterData
}), [data, remove, update, set, getValue, reduceToVisibleFields, filterData]);
}
//# sourceMappingURL=useData.js.map