Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
components.layout.sidebar.Sidebar.tsx Maven / Gradle / Ivy
import LoadingIcon from 'components/common/LoadingIcon';
import LayoutContextProvider, {
ExpandAction, ExpandEnable, ExpandState, LayoutProps, SidebarKind, SidebarState
} from 'contexts/LayoutContext';
import { nextBannerState, useLayoutContext } from 'hooks/layout';
import useKeyboardShortcut, { keyboardCodeToChar } from 'hooks/shortcut';
import { useLocalTypeState } from 'hooks/state';
import { useTranslator } from 'hooks/translator';
import { useEffect, useRef, useState } from 'react';
import { DivProps } from 'types/react';
import ExpandIcon from '@mui/icons-material/ChevronLeft';
import { Box, useMediaQuery, useTheme } from '@mui/material';
const SidebarLayoutSidebar = (): JSX.Element => {
const [sidebarState, setSidebarState] = useSidebarState()
return (
)
}
const SidebarContent = (): JSX.Element => {
const { props: { side, transitionTime } } = useLayoutContext()
const bannerSx = useBannerSx()
return (
)
}
const SidebarBanner = ({}: DivProps): JSX.Element => {
const { props: {sidebarBanner} } = useLayoutContext()
return <>{sidebarBanner}>
}
const SidebarBody = ({}: DivProps): JSX.Element => {
const config = useLayoutContext()
const { sidebarState, props: {side, sidebarBody, sidebarBodyFooter}, props: {transitionTime, expandedWidth}} = config
const ref = useRef()
const [height, setHeight] = useState("0px")
useEffect(() => {
// @ts-ignore
setHeight(ref?.current?.clientHeight)
}, [])
return (
)
}
export const BannerSlidingExpander = (): JSX.Element => {
const {bannerState, props: { transitionTime }} = useLayoutContext()
const getMargin = () => {
switch(bannerState) {
case "expanded":
return {
marginTop: "-36px",
}
case "collapsed":
case 'none':
return {
marginTop: "-10px",
"&:hover": {
transition: "margin 0.1s linear",
marginTop: "0px"
}
}
}
}
return (
)
}
export const BannerExpander = (): JSX.Element => {
const { bannerProps: {shortcut, enabled}, bannerState, setBannerState, props: { transitionTime, side } } = useLayoutContext()
const { t } = useTranslator()
const handleClick = () => {
setBannerState(state => nextBannerState(state, enabled))
}
const rotate = bannerState == "none" || bannerState == "collapsed"
return
}
const SidebarSlidingExpander = (): JSX.Element => {
const {sidebarState, props: { transitionTime, side }} = useLayoutContext()
const getMarginSx = () => {
switch(sidebarState.expandState) {
case "collapsed":
case "expanded":
return {
marginLeft: side == "left" ? "-36px" : "0px",
}
case 'none':
return {
marginLeft: side == "left" ? "-10px" : "-25px",
"&:hover": {
transition: "margin 0.1s linear",
marginLeft: side == "left" ? "0px" : "-36px"
}
}
}
}
return (
)
}
const SidebarExpander = (): JSX.Element => {
const { sidebarProps: {shortcut, enabled}, sidebarState, setSidebarState, props: { transitionTime, side } } = useLayoutContext()
const { t } = useTranslator()
const expandAction = nextSidebarAction(sidebarState, enabled)
const handleClick = () => {
setSidebarState(state => updateSidebarState(state, enabled, expandAction))
}
const rotate = side == "left" && expandAction == "expand" || side == "right" && expandAction == "collapse"
return
}
const useSidebarState = () : [SidebarState, LayoutProps['setSidebarState']]=> {
// @ts-ignore
const sm = useMediaQuery(theme => theme?.breakpoints?.up('sm'));
// @ts-ignore
const lg = useMediaQuery(theme => theme?.breakpoints?.up('lg'));
const { name, sidebarProps: { shortcut, enabled} } = useLayoutContext()
const location = `${name}.sidebar`
const {value: sidebarState, setValue: setSidebarState} = useLocalTypeState(location, createSidebarExpand(sm, lg, enabled))
if (shortcut){
useKeyboardShortcut(
() => {
setSidebarState(state => ({...state, expandState: "none"})) },
{code: shortcut, ctrlKey: true, altKey: true}
)
useKeyboardShortcut(
() => { setSidebarState(state => updateSidebarState(state, enabled, nextSidebarAction(state, enabled))) },
{code: shortcut, ctrlKey: true}
)
}
const initialRender = useRef(false)
useEffect(() => {
if (initialRender.current)
setSidebarState(createSidebarExpand(sm, lg, enabled))
initialRender.current = true
}, [sm, lg])
return [sidebarState, setSidebarState]
}
const useBannerSx = () => {
const theme = useTheme()
const { bannerState, bannerProps, props: { transitionTime, withBanner } } = useLayoutContext()
//@ts-ignore
const bannerSx = theme.components?.banner
const bannerColor = bannerSx?.backgroundColor || bannerSx?.background
const bannerHeight = withBanner ? parseInt(bannerProps.height) + (bannerState != "expanded" ? 20 : 0) + 'px' : "0px"
if (withBanner)
return {
margin: 0,
height: bannerHeight,
transition: `all ${transitionTime} ease`,
marginBottom: bannerState != "expanded" ? "5px" : "0px",
boxShadow: bannerState == "expanded" ? bannerProps.shadow : undefined,
background: bannerState == "expanded" ? bannerColor : undefined,
}
else return {}
}
function nextSidebarAction(state: SidebarState, enabled: ExpandEnable): ExpandAction {
if ((Number(enabled.collapsed) + Number(enabled.expanded) + Number(enabled.none) <= 1))
return "none"
switch (state.expandState) {
case 'expanded': return 'collapse'
case enabled.expanded && 'collapsed': return "expand"
case 'collapsed': return "collapse"
case 'none': return 'expand'
default: return "none"
}
}
function updateSidebarState(state: SidebarState, enabled: ExpandEnable, action: ExpandAction): SidebarState {
if ((Number(enabled.collapsed) + Number(enabled.expanded) + Number(enabled.none) <= 1))
return state
if (state.kind == "sliding"){
switch (true) {
case state.expandState == "expanded" && action == "collapse":
return { ...state, expandState: "none"}
case state.expandState == "none" && action == "expand":
return { ...state, expandState: "expanded"}
default:
console.error("Attempting to perform action %o on sidebarState %o", action, JSON.stringify(state))
return state
}
} else {
switch (true) {
case state.expandState == "expanded" && action == "collapse":
return { ...state, expandState: enabled.collapsed ? "collapsed" : "none"}
case state.expandState == "collapsed" && action == "collapse" :
return enabled.none ? { ...state, expandState: "none"} : state
case state.expandState == "collapsed" && action == "expand" :
return enabled.expanded ? { ...state, expandState: "expanded"} : state
case state.expandState == "none" && action == "expand":
return { ...state, expandState: enabled.collapsed ? "collapsed" : "expanded"}
default:
console.error("Attempting to perform action %o on sidebarState %o", action, JSON.stringify(state))
return state
}
}
}
function createSidebarExpand ( sm: boolean, lg: boolean, enabled: ExpandEnable) : SidebarState {
switch (true) {
case enabled.expanded && lg : return { kind: "permanent", expandState: "expanded" }
case enabled.collapsed && sm: return { kind: "permanent", expandState: "collapsed" }
default: return { kind: "permanent", expandState: "none"}
//default: return { kind: "sliding", expandState: "none"}
}
}
function getSidebarWidth(config: LayoutProps): string {
switch (config.sidebarState.expandState) {
case "collapsed":
return config.props.collapsedWidth
case "expanded":
return config.props.expandedWidth
default:
return "0px"
}
}
export default SidebarLayoutSidebar