@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
150 lines (149 loc) • 5.68 kB
JavaScript
"use client";
import { useCallback, useContext, useMemo, useRef, useSyncExternalStore } from 'react';
import pointer from "../../utils/json-pointer/index.js";
import Context from "../Context.js";
import DataContextRefContext from "../DataContextRefContext.js";
import withComponentMarkers from "../../../../shared/helpers/withComponentMarkers.js";
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
function At(props) {
const {
path = '/',
iterate,
children
} = props;
const dataContext = useContext(Context);
const {
data: contextData,
handlePathChange: handlePathChangeDataContext,
handlePathChangeUnvalidated: handlePathChangeUnvalidatedDataContext,
updateDataValue: updateDataValueDataContext,
subscribeDataValue,
getDataValue
} = dataContext;
const subscribe = useCallback(callback => {
var _subscribeDataValue;
return (_subscribeDataValue = subscribeDataValue?.(path, callback)) !== null && _subscribeDataValue !== void 0 ? _subscribeDataValue : noop;
}, [path, subscribeDataValue]);
const getSnapshot = useCallback(() => {
if (getDataValue) {
return getDataValue(path);
}
return getValueByPath(contextData, path);
}, [contextData, getDataValue, path]);
const data = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
const internalDataRef = useRef(data);
internalDataRef.current = data;
const makeScopedPath = useCallback(changePath => joinPath(path, changePath), [path]);
const handlePathChange = useCallback((changePath, value) => {
return handlePathChangeDataContext(makeScopedPath(changePath), value);
}, [handlePathChangeDataContext, makeScopedPath]);
const handlePathChangeUnvalidated = useCallback((changePath, value, options) => {
return handlePathChangeUnvalidatedDataContext(makeScopedPath(changePath), value, options);
}, [handlePathChangeUnvalidatedDataContext, makeScopedPath]);
const updateDataValue = useCallback((changePath, value, options) => {
return updateDataValueDataContext(makeScopedPath(changePath), value, options);
}, [makeScopedPath, updateDataValueDataContext]);
const scopedSubscribeDataValue = useCallback((changePath, callback) => {
var _subscribeDataValue2;
return (_subscribeDataValue2 = subscribeDataValue?.(makeScopedPath(changePath), callback)) !== null && _subscribeDataValue2 !== void 0 ? _subscribeDataValue2 : noop;
}, [makeScopedPath, subscribeDataValue]);
const scopedGetDataValue = useCallback(changePath => {
if (getDataValue) {
return getDataValue(makeScopedPath(changePath));
}
return getValueByPath(data, changePath);
}, [data, getDataValue, makeScopedPath]);
const scopedDataContext = useMemo(() => ({
...dataContext,
data,
internalDataRef,
handlePathChange,
handlePathChangeUnvalidated,
updateDataValue,
subscribeDataValue: scopedSubscribeDataValue,
getDataValue: scopedGetDataValue
}), [data, dataContext, handlePathChange, handlePathChangeUnvalidated, internalDataRef, scopedGetDataValue, scopedSubscribeDataValue, updateDataValue]);
if (iterate) {
if (!Array.isArray(data)) {
return null;
}
return _jsx(_Fragment, {
children: data.map((element, index) => {
const itemPath = joinPath(path, `/${index}`);
const makeScopedItemPath = changePath => {
return joinPath(itemPath, changePath);
};
return _jsx(ScopedContextProvider, {
value: {
...scopedDataContext,
data: element,
internalDataRef: {
current: element
},
handlePathChange: (changePath, value) => {
return handlePathChangeDataContext(makeScopedItemPath(changePath), value);
},
handlePathChangeUnvalidated: (changePath, value, options) => {
return handlePathChangeUnvalidatedDataContext(makeScopedItemPath(changePath), value, options);
},
updateDataValue: (changePath, value, options) => {
return updateDataValueDataContext(makeScopedItemPath(changePath), value, options);
},
subscribeDataValue: (changePath, callback) => {
var _subscribeDataValue3;
return (_subscribeDataValue3 = subscribeDataValue?.(makeScopedItemPath(changePath), callback)) !== null && _subscribeDataValue3 !== void 0 ? _subscribeDataValue3 : noop;
},
getDataValue: changePath => {
if (getDataValue) {
return getDataValue(makeScopedItemPath(changePath));
}
return getValueByPath(element, changePath);
}
},
children: children
}, `element${index}`);
})
});
}
return _jsx(ScopedContextProvider, {
value: scopedDataContext,
children: children
});
}
function ScopedContextProvider({
value,
children
}) {
const dataContextRef = useRef(undefined);
dataContextRef.current = value;
return _jsx(Context, {
value: value,
children: _jsx(DataContextRefContext, {
value: dataContextRef,
children: children
})
});
}
function getValueByPath(data, path) {
if (path === '/') {
return data;
}
return data && pointer.has(data, path) ? pointer.get(data, path) : undefined;
}
function joinPath(path, changePath) {
if (!changePath || changePath === '/') {
return path;
}
if (!path || path === '/') {
return changePath;
}
return `${path}${changePath}`;
}
function noop() {
return undefined;
}
withComponentMarkers(At, {
_supportsSpacingProps: true
});
export default At;
//# sourceMappingURL=At.js.map