Skip to content

Instantly share code, notes, and snippets.

@nimone
Created June 29, 2023 09:33
Show Gist options
  • Save nimone/9204ed6e9d725c0eef003011c9113698 to your computer and use it in GitHub Desktop.
Save nimone/9204ed6e9d725c0eef003011c9113698 to your computer and use it in GitHub Desktop.
Retractable Sidebar Component purely in ReactJS and TailwindCSS
import { MoreVertical, ChevronLast, ChevronFirst } from "lucide-react"
import { useContext, createContext, useState } from "react"
const SidebarContext = createContext()
export default function Sidebar({ children }) {
const [expanded, setExpanded] = useState(true)
return (
<aside className="h-screen">
<nav className="h-full flex flex-col bg-white border-r shadow-sm">
<div className="p-4 pb-2 flex justify-between items-center">
<img
src="https://img.logoipsum.com/243.svg"
className={`overflow-hidden transition-all ${
expanded ? "w-32" : "w-0"
}`}
alt=""
/>
<button
onClick={() => setExpanded((curr) => !curr)}
className="p-1.5 rounded-lg bg-gray-50 hover:bg-gray-100"
>
{expanded ? <ChevronFirst /> : <ChevronLast />}
</button>
</div>
<SidebarContext.Provider value={{ expanded }}>
<ul className="flex-1 px-3">{children}</ul>
</SidebarContext.Provider>
<div className="border-t flex p-3">
<img
src="https://ui-avatars.com/api/?background=c7d2fe&color=3730a3&bold=true"
alt=""
className="w-10 h-10 rounded-md"
/>
<div
className={`
flex justify-between items-center
overflow-hidden transition-all ${expanded ? "w-52 ml-3" : "w-0"}
`}
>
<div className="leading-4">
<h4 className="font-semibold">John Doe</h4>
<span className="text-xs text-gray-600">johndoe@gmail.com</span>
</div>
<MoreVertical size={20} />
</div>
</div>
</nav>
</aside>
)
}
export function SidebarItem({ icon, text, active, alert }) {
const { expanded } = useContext(SidebarContext)
return (
<li
className={`
relative flex items-center py-2 px-3 my-1
font-medium rounded-md cursor-pointer
transition-colors group
${
active
? "bg-gradient-to-tr from-indigo-200 to-indigo-100 text-indigo-800"
: "hover:bg-indigo-50 text-gray-600"
}
`}
>
{icon}
<span
className={`overflow-hidden transition-all ${
expanded ? "w-52 ml-3" : "w-0"
}`}
>
{text}
</span>
{alert && (
<div
className={`absolute right-2 w-2 h-2 rounded bg-indigo-400 ${
expanded ? "" : "top-2"
}`}
/>
)}
{!expanded && (
<div
className={`
absolute left-full rounded-md px-2 py-1 ml-6
bg-indigo-100 text-indigo-800 text-sm
invisible opacity-20 -translate-x-3 transition-all
group-hover:visible group-hover:opacity-100 group-hover:translate-x-0
`}
>
{text}
</div>
)}
</li>
)
}
@DavOlufuwa
Copy link

2024-02-03.01-34-56.mp4
what could be the problem here ?

Add a "h-0" to the "w-0" on the other side of the ternary of the span element in the SidebarItem

        <span
          className={`overflow-hidden transition-all ${
            expanded ? "w-52 ml-3" : "w-0 h-0"
          }`}
        >
          {text}
        </span> ```

@Siajey
Copy link

Siajey commented Mar 17, 2024

Sidebar.mp4

hi friends i just worked on this Sidebar and i fixed the problems - i will leave a Preview video of it - u can use the code and save time `//SiaJey
import { MoreVertical, ChevronLast, ChevronFirst } from 'lucide-react'
import { useContext, createContext, useState } from 'react'

const SidebarContext = createContext()

export default function Sidebar({ children }) {
const [expanded, setExpanded] = useState(true)

return (




<img
src='https://img.logoipsum.com/243.svg'
className={overflow-hidden transition-all ${ expanded ? 'w-32 opacity-90' : 'w-0' }}
alt=''
/>
<button
onClick={() => setExpanded((curr) => !curr)}
className='rounded-lg bg-gray-50 hover:bg-gray-100'
>
{expanded ? : }

    <SidebarContext.Provider value={{ expanded }}>
      <div>
        <ul
          className={` rounded-lg transition-all ${
            expanded ? 'bg-[#333333] opacity-90' : 'w-[40px]'
          }`}
        >
          {children}
        </ul>
      </div>
    </SidebarContext.Provider>

    <div className='flex p-3 bg-[#FFE328] rounded-lg'>
      <img
        src='https://ui-avatars.com/api/?background=c7d2fe&color=3730a3&bold=true'
        alt=''
        className='w-10 h-10 rounded-md'
      />
      <div
        className={`
          flex justify-between items-center
          overflow-hidden transition-all ${expanded ? 'w-52 ml-3' : 'w-0'}
      `}
      >
        <div className='leading-4'>
          <h4 className='font-semibold'>John Doe</h4>
          <span className='text-xs text-gray-600'>johndoe@gmail.com</span>
        </div>
        <MoreVertical size={20} />
      </div>
    </div>
  </nav>
</aside>

)
}

export function SidebarItem({ icon, text, active, alert }) {
const { expanded } = useContext(SidebarContext)

return (
<li
className={relative flex items-center py-2 px-3 my-1 font-medium rounded-md cursor-pointer transition-colors group ${ active ? 'bg-gradient-to-tr from-indigo-200 to-indigo-100 text-indigo-800' : 'hover:bg-indigo-50 text-gray-600' }}
>
{icon}
<span
className={overflow-hidden transition-all ${ expanded ? 'w-52 ml-3' : 'w-0' }}
>
{text}

{alert && (
<div
className={absolute right-2 w-2 h-2 rounded bg-indigo-400 ${ expanded ? '' : 'top-2' }}
/>
)}

  {!expanded && (
    <div
      className={`
      absolute left-full rounded-md px-2 py-1 ml-6
      bg-indigo-100 text-indigo-800 text-sm
      invisible opacity-20 -translate-x-3 transition-all
      group-hover:visible group-hover:opacity-100 group-hover:translate-x-0
  `}
    >
      {text}
    </div>
  )}
</li>

)
}

`

@Siajey
Copy link

Siajey commented Mar 17, 2024

i leave the code correctly i think there is a problem with this comment system of github that modify my code like this - soryy

@obuastella
Copy link

please can you try sending the full code again.. i am still having issues with it

@Siajey
Copy link

Siajey commented Mar 29, 2024

hi friend yes ill paste it here again

@Siajey
Copy link

Siajey commented Mar 29, 2024

import { MoreVertical, ChevronLast, ChevronFirst } from 'lucide-react'
import { useContext, createContext, useState } from 'react'

const SidebarContext = createContext()

export default function Sidebar({ children }) {
const [expanded, setExpanded] = useState(true)

return (

<img
src='https://img.logoipsum.com/243.svg'
className={overflow-hidden transition-all ${ expanded ? 'w-32 opacity-90' : 'w-0' }}
alt=''
/>
<button
onClick={() => setExpanded((curr) => !curr)}
className='rounded-lg bg-gray-50 hover:bg-gray-100'

{expanded ? : }

<SidebarContext.Provider value={{ expanded }}>
  <div>
    <ul
      className={` rounded-lg transition-all ${
        expanded ? 'bg-[#333333] opacity-90' : 'w-[40px]'
      }`}
    >
      {children}
    </ul>
  </div>
</SidebarContext.Provider>

<div className='flex p-3 bg-[#FFE328] rounded-lg'>
  <img
    src='https://ui-avatars.com/api/?background=c7d2fe&color=3730a3&bold=true'
    alt=''
    className='w-10 h-10 rounded-md'
  />
  <div
    className={`
      flex justify-between items-center
      overflow-hidden transition-all ${expanded ? 'w-52 ml-3' : 'w-0'}
  `}
  >
    <div className='leading-4'>
      <h4 className='font-semibold'>John Doe</h4>
      <span className='text-xs text-gray-600'>johndoe@gmail.com</span>
    </div>
    <MoreVertical size={20} />
  </div>
</div>

)
}

export function SidebarItem({ icon, text, active, alert }) {
const { expanded } = useContext(SidebarContext)

return (

  • {icon} {text}

    {alert && (

    )}

    {!expanded && (
    <div
    className={absolute left-full rounded-md px-2 py-1 ml-6 bg-indigo-100 text-indigo-800 text-sm invisible opacity-20 -translate-x-3 transition-all group-hover:visible group-hover:opacity-100 group-hover:translate-x-0}
    >
    {text}


    )}

  • )
    }

    @cristhianreyesp
    Copy link

    Agregen al app.jsx

    import { LayoutDashboard, Home, StickyNote, Layers, Flag, Calendar, LifeBuoy, Settings } from "lucide-react";
    import Sidebar, { SidebarItem } from "./components/Sidebar"

    function App() {

    return (
    <>



    <SidebarItem icon={} text="Home" alert />
    <SidebarItem icon={} text="Dashboard" active />
    <SidebarItem icon={} text="Projects" alert />
    <SidebarItem icon={} text="Calendar" />
    <SidebarItem icon={} text="Tasks" />
    <SidebarItem icon={} text="Reporting" />


    <SidebarItem icon={} text="Settings" />
    <SidebarItem icon={} text="Help" />


    </>
    )
    }

    export default App

    @PrathivKrishnaR
    Copy link

    PrathivKrishnaR commented May 4, 2024

    Vite.+.React.-.Opera.2024-05-04.23-58-36.mp4

    could u update the code

    @haseeb-sheikh10
    Copy link

     <SidebarContext.Provider value={{ expanded }}>
              <ul className="flex-1 px-3 overflow-y-auto">{children}</ul>
            </SidebarContext.Provider>
    

    I am making the ul overflow-y-scroll but it also start scrolling tooltip on x-axis
    what could be the problem? all other code is same

    Uploading Screenshot from 2024-05-11 13-38-05.png…

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment