@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
131 lines (130 loc) • 4.13 kB
JavaScript
"use client";
import React, { useCallback, useContext, useMemo, useRef } from 'react';
import SectionContext from "./SectionContext.js";
import DataContext from "../../DataContext/Context.js";
import Provider from "../../DataContext/Provider/Provider.js";
import FieldPropsProvider from "../../Field/Provider/index.js";
import SectionContainerProvider from "./containers/SectionContainerProvider.js";
import ViewContainer from "./ViewContainer/index.js";
import EditContainer from "./EditContainer/index.js";
import Toolbar from "./Toolbar/index.js";
import { cleanPath } from "../../hooks/usePath.js";
import { useIsomorphicLayoutEffect as useLayoutEffect } from "../../../../shared/helpers/useIsomorphicLayoutEffect.js";
import withComponentMarkers from "../../../../shared/helpers/withComponentMarkers.js";
import { jsx as _jsx } from "react/jsx-runtime";
function SectionComponent(props) {
const {
path,
overwriteProps,
translations,
required,
data,
defaultData,
validateInitially,
containerMode = 'auto',
disableEditing = false,
onChange,
errorPrioritization = ['contextSchema'],
schema,
children
} = props;
if (path && !path.startsWith?.('/')) {
throw new Error(`path="${path}" must start with a slash`);
}
const {
hasContext,
addOnChangeHandler,
registerSectionSchema
} = useContext(DataContext);
const {
path: nestedPath,
props: nestedProps
} = useContext(SectionContext) || {};
const isRootRelativePath = path?.startsWith('//');
const resolvedPath = useMemo(() => {
if (!path) {
return path;
}
if (isRootRelativePath) {
return path.substring(1) || '/';
}
return path;
}, [isRootRelativePath, path]);
const identifier = useMemo(() => {
if (!resolvedPath) {
return nestedPath || '';
}
const nestedPrefix = !isRootRelativePath && nestedPath && nestedPath !== '/' ? nestedPath : '';
const combinedPath = cleanPath(`${nestedPrefix}${resolvedPath}`);
return combinedPath || '/';
}, [isRootRelativePath, nestedPath, resolvedPath]);
const handleChange = useCallback((...args) => onChange?.(...args), [onChange]);
addOnChangeHandler?.(handleChange);
const resolvedSchema = useMemo(() => {
if (!schema) {
return undefined;
}
if (typeof schema === 'function') {
try {
return schema(props);
} catch (_) {
return undefined;
}
}
return schema;
}, [schema]);
const sectionSchemaIdRef = useRef(Symbol('Form.Section.schema'));
useLayoutEffect(() => {
if (!registerSectionSchema || !resolvedSchema) {
return undefined;
}
const normalizedIdentifier = identifier || '/';
return registerSectionSchema({
id: sectionSchemaIdRef.current,
path: normalizedIdentifier,
schema: resolvedSchema
});
}, [identifier, registerSectionSchema, resolvedSchema]);
const fieldProps = required ? {
required: true
} : undefined;
if (!hasContext) {
return _jsx(Provider, {
data: data,
defaultData: defaultData,
children: _jsx(SectionComponent, {
...props
})
});
}
const sectionProps = props;
return _jsx(SectionContext, {
value: {
path: identifier,
errorPrioritization,
props: sectionProps
},
children: _jsx(SectionContainerProvider, {
validateInitially: validateInitially,
containerMode: containerMode,
disableEditing: disableEditing,
children: _jsx(FieldPropsProvider, {
overwriteProps: {
...overwriteProps,
...(resolvedPath ? nestedProps?.overwriteProps?.[resolvedPath.startsWith('/') ? resolvedPath.substring(1) : resolvedPath] : undefined)
},
translations: translations,
...fieldProps,
children: children
})
})
});
}
SectionComponent.Toolbar = Toolbar;
SectionComponent.ViewContainer = ViewContainer;
SectionComponent.EditContainer = EditContainer;
withComponentMarkers(SectionComponent, {
_supportsSpacingProps: undefined
});
export default SectionComponent;
//# sourceMappingURL=Section.js.map