Skip to content

Commit

Permalink
feat: add SidebarHeader component
Browse files Browse the repository at this point in the history
  • Loading branch information
karrui committed May 10, 2023
1 parent 779c2c1 commit ab29cd5
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 2 deletions.
3 changes: 3 additions & 0 deletions react/src/Sidebar/Sidebar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { getMobileViewParameters } from '~/utils/storybook'

import { Sidebar, SidebarProps } from './Sidebar'
import { SidebarContainer } from './SidebarContainer'
import { SidebarHeader } from './SidebarHeader'
import { SidebarItem } from './SidebarItem'
import { SidebarList } from './SidebarList'

Expand All @@ -26,6 +27,7 @@ const meta = {
} satisfies Meta<typeof Sidebar>

const DEFAULT_ITEMS: SidebarProps['items'] = [
{ type: 'header', children: 'Header' },
{
children: 'Inbox',
icon: BxMailSend,
Expand Down Expand Up @@ -103,6 +105,7 @@ export const OnlyCaretToggle = {
export const NoNest = {
render: () => (
<SidebarContainer>
<SidebarHeader>Header</SidebarHeader>
<SidebarItem isActive icon={BxStar}>
Item 1
</SidebarItem>
Expand Down
14 changes: 12 additions & 2 deletions react/src/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemo } from 'react'
import { type ThemingProps } from '@chakra-ui/react'

import { SidebarContainer } from './SidebarContainer'
import { SidebarHeader, type SidebarHeaderProps } from './SidebarHeader'
import { SidebarItem, type SidebarItemProps } from './SidebarItem'
import { SidebarList, type SidebarListProps } from './SidebarList'
import type { BaseSidebarItemProps } from './types'
Expand All @@ -13,13 +14,16 @@ interface GeneratedBase
props?: any
}
interface GeneratedItem extends GeneratedBase, SidebarItemProps {}
interface GeneratedHeader extends SidebarHeaderProps {
type: 'header'
}
interface GeneratedList
extends Omit<GeneratedBase, 'children'>,
SidebarListProps {
subItems: (GeneratedList | GeneratedItem)[]
subItems: (GeneratedList | GeneratedItem | GeneratedHeader)[]
}

type GeneratedSidebarItem = GeneratedList | GeneratedItem
type GeneratedSidebarItem = GeneratedList | GeneratedItem | GeneratedHeader

export interface SidebarProps extends ThemingProps<'Sidebar'> {
items: GeneratedSidebarItem[]
Expand All @@ -28,6 +32,9 @@ export interface SidebarProps extends ThemingProps<'Sidebar'> {
const isNestableItem = (item: GeneratedSidebarItem): item is GeneratedList => {
return 'subItems' in item
}
const isHeaderItem = (item: GeneratedSidebarItem): item is GeneratedHeader => {
return 'type' in item && item.type === 'header'
}

// Generate recursive sidebar items if nested
export const generateSidebarItems = (
Expand All @@ -42,6 +49,9 @@ export const generateSidebarItems = (
</SidebarList>
)
}
if (isHeaderItem(item)) {
return <SidebarHeader key={index} {...item} />
}

const { props, ...rest } = item
return <SidebarItem key={index} {...rest} {...props} />
Expand Down
23 changes: 23 additions & 0 deletions react/src/Sidebar/SidebarHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Box, chakra, forwardRef, Icon } from '@chakra-ui/react'

import { useSidebarStyles } from './SidebarContext'
import type { BaseSidebarItemProps } from './types'

export type SidebarHeaderProps = BaseSidebarItemProps

export const SidebarHeader = forwardRef<SidebarHeaderProps, 'li'>(
({ children, icon, iconProps, ...props }, ref): JSX.Element => {
const styles = useSidebarStyles()

return (
<chakra.li listStyleType="none">
<Box as="h2" __css={styles.header} ref={ref} {...props}>
{icon ? <Icon as={icon} __css={styles.icon} {...iconProps} /> : null}
{children}
</Box>
</chakra.li>
)
},
)

SidebarHeader.displayName = 'SidebarHeader'
1 change: 1 addition & 0 deletions react/src/Sidebar/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './Sidebar'
export * from './SidebarContainer'
export * from './SidebarContext'
export * from './SidebarHeader'
export * from './SidebarItem'
export * from './SidebarList'
export * from './types'
7 changes: 7 additions & 0 deletions react/src/theme/components/Sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { layerStyles } from '../layerStyles'
const parts = anatomy('sidebar').parts(
'item',
'list',
'header',
'label',
'nest',
'section',
Expand All @@ -18,6 +19,12 @@ const { definePartsStyle, defineMultiStyleConfig } =
createMultiStyleConfigHelpers(parts.keys)

const baseStyle = definePartsStyle({
header: {
textStyle: 'subhead-3',
px: '1rem',
pt: '1rem',
pb: '0.75rem',
},
section: {
display: 'flex',
flexDirection: 'column',
Expand Down

0 comments on commit ab29cd5

Please sign in to comment.