devextreme-react
Version:
DevExtreme React UI and Visualization Components
46 lines (44 loc) • 2.34 kB
JavaScript
/*!
* devextreme-react
* Version: 24.2.6
* Build date: Mon Mar 17 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file in the root of the project for details.
*
* https://github.com/DevExpress/devextreme-react
*/
import * as React from 'react';
import { useContext, useLayoutEffect, useState, useMemo, } from 'react';
import { createPortal } from 'react-dom';
import { getOptionInfo, } from './configuration/react/element';
import { useOptionScanning } from './use-option-scanning';
import { NestedOptionContext, TemplateRenderingContext } from './contexts';
import { hasExpectedChildren } from './helpers';
const NestedOption = function NestedOption(props) {
const { children } = props;
const { elementDescriptor, ...restProps } = props;
const { isTemplateRendering } = useContext(TemplateRenderingContext);
if (!elementDescriptor || typeof document === 'undefined' || isTemplateRendering) {
return null;
}
const usesNamedTemplate = elementDescriptor.TemplateProps?.some((prop) => props[prop.tmplOption] && typeof props[prop.tmplOption] === 'string');
const { parentExpectedChildren, onChildOptionsReady: triggerParentOptionsReady, getOptionComponentKey, treeUpdateToken, } = useContext(NestedOptionContext);
const [optionComponentKey] = useState(getOptionComponentKey());
const optionElement = getOptionInfo(elementDescriptor, restProps, parentExpectedChildren);
const mainContainer = useMemo(() => document.createElement('div'), []);
const renderChildren = hasExpectedChildren(elementDescriptor) || usesNamedTemplate;
const getHasTemplate = renderChildren
? () => !!mainContainer.childNodes.length
: () => !!children;
const [config, context,] = useOptionScanning(optionElement, getHasTemplate, treeUpdateToken, 'option');
useLayoutEffect(() => {
triggerParentOptionsReady(config, optionElement.descriptor, treeUpdateToken, optionComponentKey);
}, [treeUpdateToken]);
return renderChildren ? React.createElement(React.Fragment, {}, createPortal(React.createElement(NestedOptionContext.Provider, {
value: context,
}, children), mainContainer)) : null;
};
export default NestedOption;