@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
105 lines (104 loc) • 5.78 kB
JavaScript
"use client";
import { useCallback, useContext, useMemo, useRef } from 'react';
import pointer from "../../utils/json-pointer/index.js";
import { createReferenceKey, createSharedState, useSharedState } from "../../../../shared/helpers/useSharedState.js";
import useMountEffect from "../../../../shared/helpers/useMountEffect.js";
import DataContext from "../../DataContext/Context.js";
import { structuredClone } from "../../../../shared/helpers/structuredClone.js";
export default function useData(id = undefined, initialData = undefined) {
const sharedDataRef = useRef(null);
const sharedAttachmentsRef = useRef(null);
sharedDataRef.current = useSharedState(id, initialData);
sharedAttachmentsRef.current = id ? createSharedState(createReferenceKey(id, 'attachments')) : null;
const dataContext = useContext(DataContext);
if (!id) {
var _sharedAttachmentsRef;
if (!dataContext.hasContext) {
throw new Error('useData needs to run inside DataContext (Form.Handler) or have a valid id');
}
sharedDataRef.current.data = dataContext.data;
if ((_sharedAttachmentsRef = sharedAttachmentsRef.current) !== null && _sharedAttachmentsRef !== void 0 && _sharedAttachmentsRef.data) {
sharedAttachmentsRef.current.data.filterDataHandler = dataContext.filterDataHandler;
}
}
const updateDataValue = dataContext === null || dataContext === void 0 ? void 0 : dataContext.updateDataValue;
const setData = dataContext === null || dataContext === void 0 ? void 0 : dataContext.setData;
const getExistingData = useCallback(() => {
var _ref, _ref2, _sharedAttachmentsRef2;
const liveStoreData = id ? sharedDataRef.current.get() : null;
return structuredClone((_ref = (_ref2 = liveStoreData !== null && liveStoreData !== void 0 ? liveStoreData : dataContext === null || dataContext === void 0 ? void 0 : dataContext.data) !== null && _ref2 !== void 0 ? _ref2 : (_sharedAttachmentsRef2 = sharedAttachmentsRef.current) === null || _sharedAttachmentsRef2 === void 0 || (_sharedAttachmentsRef2 = _sharedAttachmentsRef2.data) === null || _sharedAttachmentsRef2 === void 0 || (_sharedAttachmentsRef2 = _sharedAttachmentsRef2.internalDataRef) === null || _sharedAttachmentsRef2 === void 0 ? void 0 : _sharedAttachmentsRef2.current) !== null && _ref !== void 0 ? _ref : {});
}, [dataContext === null || dataContext === void 0 ? void 0 : dataContext.data, id]);
const set = useCallback(newData => {
if (id) {
sharedDataRef.current.set(newData);
} else {
setData === null || setData === void 0 || setData(newData);
}
}, [id, setData]);
const update = useCallback((path, value = undefined) => {
const existingData = getExistingData();
const existingValue = pointer.has(existingData, path) ? pointer.get(existingData, path) : undefined;
const newValue = typeof value === 'function' ? value(existingValue) : value;
if (newValue !== existingValue) {
pointer.set(existingData, path, newValue);
if (id) {
sharedDataRef.current.extend(existingData);
} else {
updateDataValue === null || updateDataValue === void 0 || updateDataValue(path, newValue);
}
}
}, [getExistingData, id, updateDataValue]);
const remove = useCallback(path => {
const existingData = getExistingData();
if (pointer.has(existingData, path)) {
pointer.remove(existingData, path);
if (id) {
sharedDataRef.current.set(existingData);
} else {
setData === null || setData === void 0 || setData(existingData);
}
}
}, [getExistingData, id, setData]);
const reduceToVisibleFields = useCallback((data, options = {}) => {
var _dataContext$visibleD;
if (id) {
var _sharedAttachmentsRef3, _sharedAttachmentsRef4;
return (_sharedAttachmentsRef3 = sharedAttachmentsRef.current.data) === null || _sharedAttachmentsRef3 === void 0 || (_sharedAttachmentsRef4 = _sharedAttachmentsRef3.visibleDataHandler) === null || _sharedAttachmentsRef4 === void 0 ? void 0 : _sharedAttachmentsRef4.call(_sharedAttachmentsRef3, data, options);
}
return dataContext === null || dataContext === void 0 || (_dataContext$visibleD = dataContext.visibleDataHandler) === null || _dataContext$visibleD === void 0 ? void 0 : _dataContext$visibleD.call(dataContext, data, options);
}, [dataContext, id]);
const filterData = useCallback((filter, data = sharedDataRef.current.data) => {
var _dataContext$filterDa;
if (id) {
var _sharedAttachmentsRef5, _sharedAttachmentsRef6;
return (_sharedAttachmentsRef5 = sharedAttachmentsRef.current.data) === null || _sharedAttachmentsRef5 === void 0 || (_sharedAttachmentsRef6 = _sharedAttachmentsRef5.filterDataHandler) === null || _sharedAttachmentsRef6 === void 0 ? void 0 : _sharedAttachmentsRef6.call(_sharedAttachmentsRef5, data, filter);
}
return dataContext === null || dataContext === void 0 || (_dataContext$filterDa = dataContext.filterDataHandler) === null || _dataContext$filterDa === void 0 ? void 0 : _dataContext$filterDa.call(dataContext, data, filter);
}, [dataContext, id]);
const getValue = useCallback(path => {
if (pointer.has(sharedDataRef.current.data, path)) {
return pointer.get(sharedDataRef.current.data, path);
}
return undefined;
}, []);
useMountEffect(() => {
if (id && !sharedDataRef.current.hadInitialData && initialData) {
sharedDataRef.current.extend(initialData, {
forceSync: true
});
}
});
const {
data
} = sharedDataRef.current;
return useMemo(() => ({
data,
remove,
update,
set,
getValue,
reduceToVisibleFields,
filterData
}), [data, remove, update, set, getValue, reduceToVisibleFields, filterData]);
}
//# sourceMappingURL=useData.js.map