Web layout – How to create a sticky sidebar menu?

Use “react-stickynode”

import Sticky from 'react-stickynode'

const LeftPanel: React.FC<Props> = ({ data }) => {
  return (
    <>
      {/* Make sticky LeftPanel component */}
      {/* Open 170px space on top */}
      {/* Do not overlap element "id-footer" */}
      <Sticky enabled={true} top={170} bottomBoundary={'#id-footer'}>
        ...
      </Sticky>
    </>
  )
}

export default LeftPanel

Use cases

How to fix issue where sidebar overlaps footer area?

  • Add id node before Footer component
...
<div id='id-footer' />
<Footer />
...
  • Set bottomBoundary property
<Sticky enabled={true} top={170} bottomBoundary={'#id-footer'}>

...

</Sticky>

How to scroll to an element when clicking on an item from the sidebar?

Use “react-scroll”

import React from 'react'
import { Link } from 'react-scroll'

const ListItem: React.FC<Props> = ({ entry }) => {
  function handleSetActive() {
    setActiveRow(entry.id)
  }

  function handleSetInactive() {
    setInActiveRow(entry.id)
  }

  return (
    <Link
      to={`id-item-${entry.id}`}  // This menu item is linked to element "id-item-${entry.id}"
      activeClass='' // When that element position is visible onto the browser window, this menu item is styled with this class
      spy={true}
      hashSpy={true}
      smooth={true}
      offset={-180}
      isDynamic={true}
      onSetActive={handleSetActive}  // When that element is visible, this function is called
      onSetInactive={handleSetInactive}  // When that element is invisible, this function is called
    >
      <div className='flex items-center'>
        <div className='flex-1'>
          <strong className='text-grey hover:text-red cursor-pointer' id={`id-leftpanel-text-${entry.id}`}>User {entry.userName}</strong>
        </div>
        <div
          id={`id-leftpanel-arrow-${entry.id}`}
          className='invisible'
        >
          <Icon type='right-chev' />
        </div>
      </div>
    </Link>
  )
}

export default ListItem
export const setActiveRow = (id) => {
  // Text
  const elementText = document.getElementById(
    `id-leftpanel-text-${id}`
  )
  elementText?.classList.remove('text-grey')
  elementText?.classList.add('text-red')

  // Arrow
  const elementArrow = document.getElementById(
    `id-leftpanel-arrow-${id}`
  )
  elementArrow.style.visibility = 'visible'
}

export const setInActiveRow = (id) => {
  // Text
  const elementText = document.getElementById(
    `id-leftpanel-text-${id}`
  )
  elementText?.classList.remove('text-red')
  elementText?.classList.add('text-grey')

  // Arrow
  const elementArrow = document.getElementById(
    `id-leftpanel-arrow-${id}`
  )
  elementArrow.style.visibility = 'hidden'
}

Be the first to comment

Leave a Reply

Your email address will not be published.


*