UNPKG

@kwiz/fluentui

Version:

KWIZ common controls for FluentUI

94 lines 4.24 kB
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