UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

210 lines (209 loc) 7.38 kB
"use client"; import _pushInstanceProperty from "core-js-pure/stable/instance/push.js"; import { useCallback, useContext, useMemo, useRef, useSyncExternalStore } from 'react'; import pointer from "../../utils/json-pointer/index.js"; import DataContext from "../../DataContext/Context.js"; import usePath from "../../hooks/usePath.js"; export default function useVisibility(props) { const dataContext = useContext(DataContext); const { hasFieldError, filterDataHandler, mountedFieldsRef, data: originalData, getDataValue, subscribeDataValue, setFieldEventListener } = dataContext; const { makePath, makeIteratePath } = usePath(); const propsRef = useRef(props); propsRef.current = props; const { withinIterate } = props || {}; const { pathDefined, pathUndefined, pathTruthy, pathFalsy, pathTrue, pathFalse, visibleWhen, visibleWhenNot, inferData, filterData } = props || {}; const makeLocalPath = useCallback(path => { if (withinIterate) { return makeIteratePath(path); } return makePath(path); }, [makeIteratePath, makePath, withinIterate]); const dependencyPaths = useMemo(() => { const paths = new Set(); const addPath = path => { if (path) { paths.add(makeLocalPath(path)); } }; const addVisibleWhenPath = visibleWhen => { if (visibleWhen && 'hasValue' in visibleWhen) { const path = 'itemPath' in visibleWhen ? makeIteratePath(visibleWhen.itemPath) : makePath(visibleWhen.path); paths.add(path); } }; addPath(pathDefined); addPath(pathUndefined); addPath(pathTruthy); addPath(pathFalsy); addPath(pathTrue); addPath(pathFalse); addVisibleWhenPath(visibleWhen); addVisibleWhenPath(visibleWhenNot); if (inferData || filterData) { paths.add('/'); } return Array.from(paths); }, [filterData, inferData, makeLocalPath, makeIteratePath, makePath, pathDefined, pathFalse, pathFalsy, pathTrue, pathTruthy, pathUndefined, visibleWhen, visibleWhenNot]); const fieldStateDependencyPaths = useMemo(() => { const paths = new Set(); const addVisibleWhenPath = visibleWhen => { if (visibleWhen && 'isValid' in visibleWhen) { const path = 'itemPath' in visibleWhen ? makeIteratePath(visibleWhen.itemPath) : makePath(visibleWhen.path); paths.add(path); } }; addVisibleWhenPath(visibleWhen); addVisibleWhenPath(visibleWhenNot); return Array.from(paths); }, [makeIteratePath, makePath, visibleWhen, visibleWhenNot]); const snapshotVersionRef = useRef(0); const usesDynamicCheck = !props; const subscribe = useCallback(callback => { const unsubscribers = []; const handleUpdate = () => { snapshotVersionRef.current += 1; callback(); }; const handleFieldStateUpdate = params => { if (params && 'state' in params && params.state.isFocused === true) { return undefined; } handleUpdate(); }; if (dependencyPaths.length > 0 && subscribeDataValue) { _pushInstanceProperty(unsubscribers).call(unsubscribers, ...dependencyPaths.map(path => subscribeDataValue(path, handleUpdate))); } if (fieldStateDependencyPaths.length > 0 && setFieldEventListener) { fieldStateDependencyPaths.forEach(path => { setFieldEventListener(path, 'onSetMountedFieldState', handleFieldStateUpdate); setFieldEventListener(path, 'onSetFieldError', handleFieldStateUpdate); _pushInstanceProperty(unsubscribers).call(unsubscribers, () => { setFieldEventListener(path, 'onSetMountedFieldState', handleFieldStateUpdate, { remove: true }); setFieldEventListener(path, 'onSetFieldError', handleFieldStateUpdate, { remove: true }); }); }); } else if (usesDynamicCheck && setFieldEventListener) { setFieldEventListener(undefined, 'onSetMountedFieldState', handleFieldStateUpdate); setFieldEventListener(undefined, 'onSetFieldError', handleFieldStateUpdate); _pushInstanceProperty(unsubscribers).call(unsubscribers, () => { setFieldEventListener(undefined, 'onSetMountedFieldState', handleFieldStateUpdate, { remove: true }); setFieldEventListener(undefined, 'onSetFieldError', handleFieldStateUpdate, { remove: true }); }); } return () => { unsubscribers.forEach(unsubscribe => unsubscribe()); }; }, [dependencyPaths, fieldStateDependencyPaths, setFieldEventListener, subscribeDataValue, usesDynamicCheck]); const getSnapshot = useCallback(() => snapshotVersionRef.current, []); useSyncExternalStore(subscribe, getSnapshot, getSnapshot); const check = useCallback(({ visible, visibleWhen, visibleWhenNot, pathDefined, pathUndefined, pathTruthy, pathFalsy, pathTrue, pathFalse, inferData, filterData } = propsRef.current) => { var _getDataValue; if (typeof visible === 'boolean') { return visible; } const dataFromContext = (_getDataValue = getDataValue?.('/')) !== null && _getDataValue !== void 0 ? _getDataValue : originalData; const data = filterData && filterDataHandler?.(dataFromContext, filterData) || dataFromContext; if (visibleWhen || visibleWhenNot) { if (visibleWhenNot) { visibleWhen = visibleWhenNot; } const path = 'itemPath' in visibleWhen ? makeIteratePath(visibleWhen.itemPath) : makePath(visibleWhen.path); if ('isValid' in visibleWhen) { const item = mountedFieldsRef.current.get(path); if (!item || item.isMounted !== true) { return Boolean(visibleWhenNot); } const result = (visibleWhen.validateContinuously ? true : item.isFocused !== true) && !hasFieldError(path); return visibleWhenNot ? !result : result; } if ('hasValue' in visibleWhen) { const hasPath = pointer.has(data, path); const value = hasPath ? pointer.get(data, path) : undefined; const hasValue = visibleWhen?.['hasValue']; const result = typeof hasValue === 'function' ? hasValue(value) === false : hasValue !== value; if (visibleWhenNot) { if (!result) { return false; } } else if (result) { return false; } } } const getValue = path => { if (pointer.has(data, path)) { return pointer.get(data, path); } }; if (pathDefined) { return getValue(makeLocalPath(pathDefined)) !== undefined; } if (pathUndefined) { return getValue(makeLocalPath(pathUndefined)) === undefined; } if (pathTrue && getValue(makeLocalPath(pathTrue)) !== true) { return false; } if (pathFalse && getValue(makeLocalPath(pathFalse)) !== false) { return false; } if (pathTruthy && !getValue(makeLocalPath(pathTruthy))) { return false; } if (pathFalsy && getValue(makeLocalPath(pathFalsy))) { return false; } if (inferData && !inferData(data)) { return false; } return true; }, [filterDataHandler, getDataValue, originalData, makeLocalPath, makeIteratePath, makePath, mountedFieldsRef, hasFieldError]); return { check }; } //# sourceMappingURL=useVisibility.js.map