All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hooks.layout.ts Maven / Gradle / Ivy

import {
    defaultSidebarLayoutProps, ExpandEnable, ExpandState, LayoutContext, LayoutProps,
    PartialLayoutProps
} from 'contexts/LayoutContext';
import merge from 'deepmerge';
import useKeyboardShortcut from 'hooks/shortcut';
import { useContext, useEffect, useRef } from 'react';
import Types from 'types/types';
import { prune } from 'utils/prune';

import { useMediaQuery, useTheme } from '@mui/material';

import { useLocalTypeState } from './state';

export const useLayoutContext = () => useContext(LayoutContext)
 
export const useBannerState = (withBanner?: boolean, shortcut?: KeyboardEvent['code']): [LayoutProps['bannerState'], LayoutProps['setBannerState']] => {
  if (!withBanner)
    return ['none', defaultSidebarLayoutProps.setBannerState]
  else {
    // @ts-ignore
    const bannerTrigger                    = useMediaQuery(theme => theme?.breakpoints?.up('md'));
    const { name, bannerProps: {enabled} } = useLayoutContext()
    const location                         = `${name}.banner`
    const defaultBannerState               = () => withBanner ? enabled.expanded && "expanded" || enabled.collapsed && "collapsed" || "none" : "none"

    const {value: bannerState, setValue: setBannerState} = useLocalTypeState(location, defaultBannerState())

    if (shortcut){
      useKeyboardShortcut(
        (e) => { setBannerState("none") }, 
        {code: shortcut, ctrlKey: true, altKey: true}
      )

      useKeyboardShortcut(
        (e) => { setBannerState(state => nextBannerState(state, enabled)) }, 
        {code: shortcut, ctrlKey: true}
      )
    }

    const initialRender = useRef(false)
    useEffect(() => {
      if (initialRender.current){
        if (withBanner) {
          if (bannerTrigger) 
            setBannerState("expanded")
          else 
            setBannerState("collapsed")
        }
      } 
      initialRender.current = true
      
    }, [bannerTrigger])
 
    return [bannerState, setBannerState]
  }
}

export function nextBannerState(state: ExpandState, enabled: ExpandEnable): ExpandState {
  switch (state) {
    case enabled.none      && "expanded":  return "none"
    case enabled.collapsed && "expanded":  return "collapsed"
    case enabled.expanded  && "collapsed": return "expanded"
    case enabled.none      && "collapsed": return "none"
    case enabled.expanded  && "none":      return "expanded"
    case enabled.collapsed && "none":      return "collapsed"
    default: return state
  }
}

export const useLayoutConfig = (layoutProps: PartialLayoutProps, reset?: boolean) => {
  const ctx     = useLayoutContext()  
  const theme   = useTheme()

  if (reset) {

    const defaultBannerConfig: PartialLayoutProps = {
      bannerProps: {
        // @ts-ignore
        height: theme.components?.banner?.height
      },
    }

    return joinAll([defaultSidebarLayoutProps, defaultBannerConfig, layoutProps])
  } else {
    return joinAll([ctx, layoutProps])
  }
}

function joinAll(configs: PartialLayoutProps[]): LayoutProps {
  return Types.as(
    merge.all(
      configs.map((config, index) => index == 0 ? config : prune(config, {undefined: true}))
    )
  )
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy