UNPKG

@onehat/ui

Version:
165 lines (149 loc) 3.79 kB
import { useEffect, useState, } from 'react'; import { ScrollView, VStack, VStackNative, } from '@project-components/Gluestack'; import clsx from 'clsx'; import { HORIZONTAL, VERTICAL, } from '../../Constants/Directions.js'; import { hasWidth, hasFlex, } from '../../Functions/tailwindFunctions.js'; import Inflector from 'inflector-js'; import Header from './Header.js'; import Mask from './Mask.js'; import testProps from '../../Functions/testProps.js'; import withCollapsible from '../Hoc/withCollapsible.js'; import withComponent from '../Hoc/withComponent.js'; import UiGlobals from '../../UiGlobals.js'; import _ from 'lodash'; // Note on collapseDirections: // HORIZONTAL means the Panel collapses along the X axis. // VERTICAL means the Panel collapses along the Y axis. function Panel(props) { const { isDisabled = false, frame = false, isScrollable = false, isWindow = false, maxHeight, maxWidth, disableAutoFlex = false, // Header title = props.model ? UiGlobals.customInflect(Inflector.camel2words(Inflector.underscore(props.model))) : '', showHeader = true, header = null, onClose, isCollapsible = true, isCollapsed = false, setIsCollapsed, collapseDirection = VERTICAL, // HORIZONTAL, VERTICAL disableTitleChange = false, // Content topToolbar = null, children = null, bottomToolbar = null, footer = null, ...propsToPass } = props, self = props.self, [titleSuffix, setTitleSuffix] = useState(''), onToggleCollapse = () => { setIsCollapsed(!isCollapsed); }; if (!disableTitleChange) { const selectorSelected = props.selectorSelected, [isReady, setIsReady] = useState(disableTitleChange); useEffect(() => { let titleSuffix = ''; if (props.titleSuffix) { titleSuffix += ' ' + props.titleSuffix; } if (selectorSelected?.[0]?.displayValue) { titleSuffix += ' for ' + selectorSelected[0].displayValue; } setTitleSuffix(titleSuffix); if (!isReady) { setIsReady(true); } }, [selectorSelected, props.titleSuffix]); if (!isReady) { return null; } } let headerComponent = header; if (showHeader && title) { headerComponent = <Header title={title + titleSuffix} onClose={onClose} isCollapsible={isCollapsible} isCollapsed={isCollapsed} isWindow={isWindow} collapseDirection={collapseDirection} onToggleCollapse={onToggleCollapse} />; } let className = 'Panel'; const style = props.style || {}; if (!hasWidth(props) && !hasFlex(props) && !disableAutoFlex) { style.flex = 1; } if (maxWidth) { style.maxWidth = maxWidth; } if (maxHeight) { style.maxHeight = maxHeight; } if (isCollapsed) { if (collapseDirection === HORIZONTAL) { className += ' w-[33px]'; delete style.width; } else { className += ' h-[33px]'; delete style.height; } } // frame className += ' border-grey-300' + (isWindow ? ' rounded-lg shadow-lg ' : '') + (frame ? ' border-2' : ' border-none'); if (props.className) { className += ' ' + props.className; } return <VStackNative {...testProps(self?.reference)} className={className} style={style} > {isDisabled && <Mask />} {headerComponent} {!isCollapsed && <> {topToolbar} <VStack className={clsx( 'Panel-VSstack', 'flex-1', 'w-full', 'overflow-hidden', )} > {isScrollable ? <ScrollView className="Panel-ScrollView" contentContainerStyle={{ height: '100%', }} > {children} </ScrollView> : children} </VStack> {bottomToolbar} {footer} </>} </VStackNative>; } export default withComponent(withCollapsible(Panel));