@kwiz/fluentui
Version:
KWIZ common controls for FluentUI
94 lines • 4.24 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { makeStyles, mergeClasses, Portal, tokens } from '@fluentui/react-components';
import { getScrollParent, isFunction, isNotEmptyArray, isNotEmptyString, isNullOrUndefined } from '@kwiz/common';
import React, { useEffect, useState } from 'react';
import { useElementSize, useRefWithState } from '../helpers';
import { useKWIZFluentContext } from '../helpers/context-internal';
import { KnownClassNames, mixins, useCommonStyles } from '../styles/styles';
const useStyles = makeStyles({
main: mixins.main,
clickable: mixins.clickable,
left: Object.assign(Object.assign({}, mixins.float), { float: "left", marginRight: tokens.spacingHorizontalXXL }),
right: Object.assign(Object.assign({}, mixins.float), { float: "right", marginLeft: tokens.spacingHorizontalXXL }),
sticky: Object.assign(Object.assign({}, mixins.box), { position: "sticky", top: 0, overflow: "auto", height: "fit-content", maxHeight: "fit-content" }),
selfCentered: {
alignSelf: "center"
}
});
export const Section = React.forwardRef((props, ref) => {
const ctx = useKWIZFluentContext();
const commonStyles = useCommonStyles();
const cssNames = useStyles();
let css = [KnownClassNames.section];
if (props.main)
css.push(cssNames.main);
if (props.centerSelf)
css.push(cssNames.selfCentered);
if (isFunction(props.onClick))
css.push(cssNames.clickable);
if (props.left) {
css.push(cssNames.left);
css.push(KnownClassNames.left);
}
else if (props.right) {
css.push(cssNames.right);
css.push(KnownClassNames.right);
}
else if (props.sticky) {
css.push(cssNames.sticky);
}
/** need scrollparent if we are sticky */
const [scrollParent, setScrollParent] = useState(null);
const divRef = useRefWithState();
//wait for my content to finish loading, it might change scrollparent
const mySize = useElementSize(divRef.ref.current);
useEffect(() => {
//setting the forwardRef
if (!isNullOrUndefined(ref)) {
if (isFunction(ref))
ref(divRef.ref.current);
else
ref.current = divRef.ref.current;
}
}, [divRef.value]);
useEffect(() => {
if (props.sticky) {
let scrollParent = getScrollParent(divRef.ref.current ? divRef.ref.current.parentElement : null);
setScrollParent(scrollParent);
}
}, [divRef.value, mySize.height]);
const parentSize = useElementSize(scrollParent);
useEffect(() => {
if (props.sticky && divRef.ref.current) {
let maxHeight = "fit-content";
if (scrollParent) {
let height = parseFloat(getComputedStyle(scrollParent).height);
let myStyle = getComputedStyle(divRef.ref.current);
let pTop = parseFloat(myStyle.paddingTop);
let pBottom = parseFloat(myStyle.paddingBottom);
let mTop = parseFloat(myStyle.marginTop);
let mBottom = parseFloat(myStyle.marginBottom);
if (pTop > 0)
height -= pTop;
if (pBottom > 0)
height -= pBottom;
if (mTop > 0)
height -= mTop;
if (mBottom > 0)
height -= mBottom;
maxHeight = `${height}px`;
}
divRef.ref.current.style.maxHeight = maxHeight;
}
}, [props.sticky, parentSize.height, divRef.value]);
//a css class might have space and multiuple classes in it
if (isNotEmptyArray(props.css))
props.css.filter(c => isNotEmptyString(c)).forEach(c => css.push(...c.split(" ")));
if (props.fullscreen)
css.push(commonStyles.fullscreen);
const control = _jsx("div", Object.assign({ ref: divRef.set }, (props.rootProps || {}), { title: props.title, style: props.style, className: mergeClasses(...css), onClick: props.onClick, children: props.children }));
return (props.fullscreen === "portal"
? _jsx(Portal, { mountNode: ctx.mountNode, children: control })
: control);
});
//# sourceMappingURL=section.js.map