@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
87 lines (86 loc) • 3.14 kB
JavaScript
'use client';
import { Device, useIsomorphicLayoutEffect, useSyncRef, useStylesheet } from '@ui5/webcomponents-react-base';
import { clsx } from 'clsx';
import { forwardRef, useContext, useEffect, useState } from 'react';
import { SplitterLayoutContext } from '../../internal/SplitterLayoutContext.js';
import { classNames, styleData } from './SplitterElement.module.css.js';
import { jsx as _jsx } from "react/jsx-runtime";
/**
* The `SplitterElement` holds the component of the content area. Allowed size values are of the type css property width or
* height according to the orientation of the `SplitterLayout`. If `size` isn't passed to the element, the width or
* height of the content area will be calculated automatically according to the size of the given `SplitterLayout`.
* The `minSize` defines the minimum width or height of the area and is set to 0 when no minimum size is given, so the
* content can be completely collapsed.
*/
const SplitterElement = /*#__PURE__*/forwardRef((props, ref) => {
const {
children,
style,
className,
minSize = 0,
size = 'auto',
resizable: _0,
...rest
} = props;
const [componentRef, splitterElementRef] = useSyncRef(ref);
const {
vertical,
reset
} = useContext(SplitterLayoutContext);
const safariStyles = Device.isSafari() ? {
width: 'min-content',
flex: '1 1 auto'
} : {};
const _size = typeof size === 'number' ? `${size}px` : size;
const [flexBasisApplied, setFlexBasisApplied] = useState(false);
const [observedFlex, setObservedFlex] = useState(null);
const flexStyles = reset ? undefined : _size !== 'auto' ? {
flex: `0 1 ${_size}`
} : observedFlex ?? {
flex: '1 0 min-content',
...safariStyles
};
useStylesheet(styleData, SplitterElement.displayName);
useEffect(() => {
if (_size !== 'auto') return;
const elementObserver = new ResizeObserver(([element]) => {
if (element.target.getBoundingClientRect().width !== 0 && !flexBasisApplied) {
const resetSafariStyles = Device.isSafari() ? {
width: 'unset'
} : {};
setObservedFlex({
flex: `0 0 ${element.target.getBoundingClientRect()[vertical ? 'height' : 'width']}px`,
...resetSafariStyles
});
setFlexBasisApplied(true);
}
});
if (splitterElementRef.current) {
elementObserver.observe(splitterElementRef.current);
}
return () => {
elementObserver.disconnect();
};
}, [_size, flexBasisApplied, splitterElementRef, vertical]);
useIsomorphicLayoutEffect(() => {
if (reset) {
setObservedFlex(null);
setFlexBasisApplied(false);
}
}, [reset]);
return /*#__PURE__*/_jsx("div", {
ref: componentRef,
className: clsx(classNames.splitterElement, className),
style: {
minHeight: vertical && minSize ? `${minSize}px` : undefined,
minWidth: !vertical && minSize ? `${minSize}px` : undefined,
...flexStyles,
...style
},
...rest,
"data-min-size": minSize,
children: children
});
});
SplitterElement.displayName = 'SplitterElement';
export { SplitterElement };