Skip to content

Commit

Permalink
wip: add sidenav component
Browse files Browse the repository at this point in the history
  • Loading branch information
bouassaba committed Oct 29, 2024
1 parent 94a35ff commit 153cab3
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './layout-drawer'
export * from './sidenav'
export * from './icons'
export * from './spinner'
export * from './section-spinner'
Expand Down
3 changes: 0 additions & 3 deletions src/components/layout-drawer/index.ts

This file was deleted.

8 changes: 4 additions & 4 deletions src/components/shell.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MouseEvent, ReactElement } from 'react'
import cx from 'classnames'
import { StorageOptions } from '../types'
import { LayoutDrawer, LayoutDrawerItem } from './layout-drawer'
import { Sidenav, SidenavItem } from './sidenav'

export type ShellProps = {
storage?: StorageOptions
Expand Down Expand Up @@ -32,10 +32,10 @@ export const Shell = ({
navigateFn,
}: ShellProps) => (
<div className={cx('flex', 'flex-row', 'items-center', 'gap-0', 'h-full')}>
<LayoutDrawer storage={storage} logo={logo} navigateFn={navigateFn}>
<Sidenav storage={storage} logo={logo} navigateFn={navigateFn}>
{items
? items.map((item, index) => (
<LayoutDrawerItem
<SidenavItem
key={index}
href={item.href}
icon={item.icon}
Expand All @@ -46,7 +46,7 @@ export const Shell = ({
/>
))
: null}
</LayoutDrawer>
</Sidenav>
<div
className={cx('flex', 'flex-col', 'items-center', 'h-full', 'w-full')}
onClick={onContentClick}
Expand Down
3 changes: 3 additions & 0 deletions src/components/sidenav/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './sidenav'
export * from './sidenav-item'
export * from './sidenav-context'
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createContext } from 'react'

export type LayoutDrawerContextType = {
export type SidenavContextType = {
isCollapsed: boolean | undefined
isTouched: boolean
}

export const LayoutDrawerContext = createContext<LayoutDrawerContextType>({
export const SidenavContext = createContext<SidenavContextType>({
isCollapsed: undefined,
isTouched: false,
})
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ReactElement, useContext, useEffect, useState } from 'react'
import { Tooltip, Link } from '@chakra-ui/react'
import cx from 'classnames'
import { LayoutDrawerContext } from './layout-drawer-context'
import { SidenavContext } from './sidenav-context'

export type DrawerItemProps = {
export type SidenavItemProps = {
icon: ReactElement
href: string
primaryText: string
Expand All @@ -12,17 +12,17 @@ export type DrawerItemProps = {
navigateFn: (href: string) => void
}

export const LayoutDrawerItem = ({
export const SidenavItem = ({
icon,
href,
primaryText,
secondaryText,
pathnameFn,
navigateFn,
}: DrawerItemProps) => {
}: SidenavItemProps) => {
const pathname = pathnameFn()
const [isActive, setIsActive] = useState<boolean>()
const { isCollapsed } = useContext(LayoutDrawerContext)
const { isCollapsed } = useContext(SidenavContext)

useEffect(() => {
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import { Link } from '@chakra-ui/react'
import cx from 'classnames'
import { StorageOptions } from '../../types'
import { IconChevronLeft, IconChevronRight } from '../icons'
import { LayoutDrawerContext } from './layout-drawer-context'
import { SidenavContext } from './sidenav-context'

export type LayoutDrawerProps = {
export type SidenavProps = {
children?: ReactNode
logo?: ReactNode
storage?: StorageOptions
homeHref?: string
navigateFn: (href: string) => void
}

export const LayoutDrawer = ({
export const Sidenav = ({
children,
storage,
logo,
homeHref,
navigateFn,
}: LayoutDrawerProps) => {
}: SidenavProps) => {
const [isCollapsed, setIsCollapsed] = useState<boolean | undefined>(undefined)
const [isTouched, setIsTouched] = useState(false)
const localStorageCollapsedKey = useMemo(
Expand Down Expand Up @@ -48,7 +48,7 @@ export const LayoutDrawer = ({
}

return (
<LayoutDrawerContext.Provider
<SidenavContext.Provider
value={{
isCollapsed,
isTouched,
Expand Down Expand Up @@ -128,6 +128,6 @@ export const LayoutDrawer = ({
{isCollapsed ? <IconChevronRight /> : <IconChevronLeft />}
</div>
</div>
</LayoutDrawerContext.Provider>
</SidenavContext.Provider>
)
}
41 changes: 39 additions & 2 deletions src/stories/components/shell.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ export const Default: Story = {
secondaryText: 'Allows assigning permissions to a group of users.',
},
{
href: '/organizations',
href: '/organization',
icon: <IconFlag />,
primaryText: 'Organizations',
secondaryText: 'Umbrellas for workspaces and users.',
},
],
children: <></>,
},
render: (args) => {
const location = useLocation()
Expand All @@ -52,7 +53,43 @@ export const Default: Story = {
{...args}
pathnameFn={() => location.pathname}
navigateFn={(href: string) => navigate(href)}
/>
>
<>
{location.pathname == '/' ? (
<p>
Lorem ipsum odor amet, consectetuer adipiscing elit. Duis nascetur
magnis morbi laoreet; montes porta. Pulvinar nunc per accumsan sed
suspendisse sit sapien. Venenatis maximus inceptos taciti
vestibulum porta sagittis quisque ipsum erat. Risus sodales
conubia leo facilisi dignissim potenti senectus. Lectus feugiat
ornare amet iaculis metus inceptos adipiscing placerat. Vestibulum
faucibus facilisis viverra magna litora. Molestie lorem leo
malesuada dictumst porta erat sagittis ullamcorper sollicitudin.
Hendrerit ante maximus tincidunt, venenatis mauris molestie.
</p>
) : null}
{location.pathname == '/group' ? (
<>
Commodo volutpat facilisis habitant; mattis ultrices mauris ex
nisi. Consequat nascetur lacus sed fames convallis pretium sit
justo. Gravida curabitur condimentum hac mi, ridiculus montes.
Eros commodo porttitor erat amet primis imperdiet. Morbi at
potenti volutpat litora viverra dapibus sapien. Fermentum sodales
nullam aliquam fusce aliquam.
</>
) : null}
{location.pathname == '/organization' ? (
<>
Dis eros primis condimentum a porttitor orci curabitur. Aluctus
arcu blandit dui facilisi interdum pretium tristique. Cras nam
congue parturient posuere tempor lectus? Felis hendrerit penatibus
semper maximus convallis tortor. Et potenti quisque ex phasellus
magnis leo netus. Hac enim ante curae odio libero feugiat metus
conubia tincidunt.
</>
) : null}
</>
</Shell>
)
},
}
66 changes: 66 additions & 0 deletions src/stories/components/sidenav.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Meta, StoryObj } from '@storybook/react'
import cx from 'classnames'
import { useLocation, useNavigate } from 'react-router-dom'
import {
IconFlag,
IconGroup,
IconWorkspaces,
Sidenav,
SidenavItem,
Logo,
} from '../../components'

const meta: Meta<typeof Sidenav> = {
title: 'Components/Sidenav',
component: Sidenav,
parameters: {
layout: 'fullscreen',
},
}

export default meta
type Story = StoryObj<typeof Sidenav>

export const Default: Story = {
args: {
storage: { prefix: 'shell', namespace: 'main' },
logo: <Logo type="koupr" size="sm" />,
},
render: (args) => {
const location = useLocation()
const navigateFn = useNavigate()

return (
<div
className={cx('flex', 'flex-row', 'items-center', 'gap-0', 'h-full')}
>
<Sidenav {...args} navigateFn={navigateFn}>
<SidenavItem
href="/"
icon={<IconWorkspaces />}
primaryText="Workspaces"
secondaryText="Isolated containers for files and folders."
pathnameFn={() => location.pathname}
navigateFn={navigateFn}
/>
<SidenavItem
href="/group"
icon={<IconGroup />}
primaryText="Groups"
secondaryText="Allows assigning permissions to a group of users."
pathnameFn={() => location.pathname}
navigateFn={navigateFn}
/>
<SidenavItem
href="/organization"
icon={<IconFlag />}
primaryText="Organizations"
secondaryText="Umbrellas for workspaces and users."
pathnameFn={() => location.pathname}
navigateFn={navigateFn}
/>
</Sidenav>
</div>
)
},
}

0 comments on commit 153cab3

Please sign in to comment.