Skip to content

Commit

Permalink
feat: SidePanel components
Browse files Browse the repository at this point in the history
  • Loading branch information
juliajforesti committed Sep 5, 2024
1 parent c670ac1 commit 50e2926
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 0 deletions.
19 changes: 19 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanel.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { composeStories } from '@storybook/react';
import { axe } from 'jest-axe';

import { render } from '../../testing';
import * as stories from './SidePanel.stories';

const { Default } = composeStories(stories);

describe('[Sidebar Default story]', () => {
it('renders without crashing', () => {
render(<Default />);
});
it('should have no a11y violations', async () => {
const { container } = render(<Default />);

const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
75 changes: 75 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanel.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import type { Meta, StoryFn } from '@storybook/react';

import {
SidePanel,
SidePanelSection,
SidePanelHeader,
SidePanelHeaderTitle,
SidePanelList,
SidePanelListItem,
} from '.';
import {
Avatar,
Box,
Icon,
IconButton,
InputBox,
SideBarItem,
SideBarItemAvatarWrapper,
SideBarItemBadge,
SideBarItemIcon,
SideBarItemMenu,
SideBarItemTitle,
} from '../..';
import { MenuTemplate, leterAvatarUrls, names } from '../SideBarV2/helpers';

export default {
title: 'Navigation/SidePanel',
component: SidePanel,
decorators: [
(Story) => (
<Box display='flex' h='90vh' w='x276'>
<Story />
</Box>
),
],
} as Meta<typeof SidePanel>;

const Template: StoryFn<typeof SidePanel> = (args) => (
<SidePanel {...args}>
<SidePanelHeader>
<SidePanelHeaderTitle>All</SidePanelHeaderTitle>
<IconButton icon='burger-menu' size='x28' title='menu' />
</SidePanelHeader>
<SidePanelSection>
<InputBox
type='text'
placeholder='Search'
addon={<Icon name='magnifier' size='x18' />}
/>
</SidePanelSection>
<Box overflowY='auto' height='full'>
<SidePanelList>
{new Array(20).fill(null).map((_, index) => (
<SidePanelListItem key={index}>
<SideBarItem href='#'>
<SideBarItemAvatarWrapper>
<Avatar
size='x20'
url={leterAvatarUrls[index % 4]}
alt='avatar'
/>
</SideBarItemAvatarWrapper>
<SideBarItemIcon icon='team' />
<SideBarItemTitle>{names[index % 10]}</SideBarItemTitle>
<SideBarItemBadge title='unread messages' children={index + 3} />
<SideBarItemMenu children={<MenuTemplate />} />
</SideBarItem>
</SidePanelListItem>
))}
</SidePanelList>
</Box>
</SidePanel>
);

export const Default = Template.bind({});
44 changes: 44 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanel.styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@use '../../styles/colors.scss';
@use '../../styles/lengths.scss';
@use '../../styles/typography.scss';

$sidepanel-color-default: colors.font(default);

%section-base {
display: flex;
justify-content: space-between;
align-items: center;
gap: lengths.padding(8);
}

.rcx-sidepanel {
display: flex;
flex-direction: column;
flex: 1 0 auto;

width: lengths.size(276);

color: $sidepanel-color-default;
border-right: lengths.border-width(default) solid colors.stroke(extra-light);

background-color: colors.surface(room);

&-section {
@extend %section-base;
padding: lengths.padding(16);
}

&-header {
@extend %section-base;
height: lengths.size(44);
padding-inline: lengths.padding(16);

&__title {
@include typography.use-font-scale(h4);
}
}

&-list {
padding-block: lengths.padding(8);
}
}
11 changes: 11 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { HTMLAttributes } from 'react';

export const SidePanel = ({
className,
...props
}: HTMLAttributes<HTMLDivElement>) => (
<div
className={['rcx-sidepanel', className].filter(Boolean).join(' ')}
{...props}
/>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Divider } from '../Divider';

export const SidePanelDivider = () => (
<Divider rcx-sidepanel--divider mbs={-2} mbe={0} />
);
16 changes: 16 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanelHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { HTMLAttributes } from 'react';

import { SidePanelDivider } from './SidePanelDivider';

export const SidePanelHeader = ({
className,
...props
}: HTMLAttributes<HTMLDivElement>) => (
<>
<div
className={['rcx-sidepanel-header', className].filter(Boolean).join(' ')}
{...props}
/>
<SidePanelDivider />
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { HTMLAttributes } from 'react';

export const SidePanelHeaderTitle = ({
className,
...props
}: HTMLAttributes<HTMLDivElement>) => (
<div
className={['rcx-sidepanel-header__title', className]
.filter(Boolean)
.join(' ')}
{...props}
/>
);
16 changes: 16 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanelList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { HTMLAttributes } from 'react';
import { forwardRef } from 'react';

export const SidePanelList = forwardRef<
HTMLDivElement,
HTMLAttributes<HTMLDivElement>
>(function SidePanelList({ className, ...props }, ref) {
return (
<div
role='list'
ref={ref}
className={['rcx-sidepanel-list', className].filter(Boolean).join(' ')}
{...props}
/>
);
});
18 changes: 18 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanelListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { HTMLAttributes } from 'react';
import { forwardRef } from 'react';

export const SidePanelListItem = forwardRef<
HTMLDivElement,
HTMLAttributes<HTMLDivElement>
>(function SidePanelListItem({ className, ...props }, ref) {
return (
<div
role='listitem'
ref={ref}
className={['rcx-sidepanel-list__item', className]
.filter(Boolean)
.join(' ')}
{...props}
/>
);
});
11 changes: 11 additions & 0 deletions packages/fuselage/src/components/SidePanel/SidePanelSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { HTMLAttributes } from 'react';

export const SidePanelSection = ({
className,
...props
}: HTMLAttributes<HTMLDivElement>) => (
<div
className={['rcx-sidepanel-section', className].filter(Boolean).join(' ')}
{...props}
/>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { HTMLAttributes } from 'react';

export const SidePanelSectionAction = ({
className,
...props
}: HTMLAttributes<HTMLDivElement>) => (
<div
className={['rcx-sidepanel-section__action', className]
.filter(Boolean)
.join(' ')}
{...props}
/>
);
8 changes: 8 additions & 0 deletions packages/fuselage/src/components/SidePanel/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export * from './SidePanel';
export * from './SidePanelSection';
export * from './SidePanelSectionAction';
export * from './SidePanelHeaderTitle';
export * from './SidePanelHeader';
export * from './SidePanelList';
export * from './SidePanelListItem';
export * from './SidePanelDivider';
1 change: 1 addition & 0 deletions packages/fuselage/src/components/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
@import './RadioButton/RadioButton.styles.scss';
@import './Select/Select.styles.scss';
@import './Sidebar/Sidebar.styles.scss';
@import './SidePanel/SidePanel.styles.scss';
@import './SideBarV2/SideBar.styles.scss';
@import './Skeleton/Skeleton.styles.scss';
@import './States/States.styles.scss';
Expand Down
1 change: 1 addition & 0 deletions packages/fuselage/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export * from './Popover';
export * from './SelectInput';
export { default as Sidebar } from './Sidebar';
export * from './Sidebar';
export * from './SidePanel';
export * from './SideBarV2';
export * from './Skeleton';
export * from './States';
Expand Down

0 comments on commit 50e2926

Please sign in to comment.