Skip to content

Commit

Permalink
Merge pull request #147 from Dias999/feature/Storybook-Drawer
Browse files Browse the repository at this point in the history
feat: storybook - add Drawer stories / add tsdocs for drawer component
  • Loading branch information
MrMaz authored Jul 17, 2024
2 parents 30237e2 + 3b75268 commit 1739976
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/react-material-ui/__tests__/Drawer.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import '@testing-library/jest-dom';
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import Drawer from '../src/components/Drawer/Drawer';
import { Drawer } from '../src/components/Drawer/Drawer';

describe('Drawer Component', () => {
const mockItems = [
Expand Down
2 changes: 1 addition & 1 deletion packages/react-material-ui/__tests__/DrawerItem.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import '@testing-library/jest-dom';
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import DrawerItem from '../src/components/Drawer/DrawerItem';
import { DrawerItem } from '../src/components/Drawer/DrawerItem';

describe('DrawerItem Component', () => {
it('should render correctly', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import Drawer, { DrawerProps } from '../Drawer';
import { Drawer, DrawerProps } from '../Drawer';
import { useAppBarRoot } from './hooks/useAppBarRoot';

const AppBarDrawer = (props: DrawerProps) => {
Expand Down
52 changes: 47 additions & 5 deletions packages/react-material-ui/src/components/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,82 @@ import Toolbar from '@mui/material/Toolbar';
import IconButton from '@mui/material/IconButton';
import ChevronLeft from '@mui/icons-material/ChevronLeft';
import ChevronRight from '@mui/icons-material/ChevronRight';
import DrawerItem, { DrawerItemProps } from './DrawerItem';
import { DrawerItem, DrawerItemProps } from './DrawerItem';
import Image from '../Image';
import Text from '../Text';
import Box from '@mui/material/Box';
import { TextProps } from 'interfaces';
import { SxProps, Theme } from '@mui/material/styles';

/**
* Drawer component props.
*/
export type DrawerProps = {
/** Array of items to display in the drawer */
items: DrawerItemProps[];
/** ID of the currently active item */
currentId?: string;
/** Custom toggle component for the drawer */
customToggle?: (toggleDrawer: () => void, collapsed?: boolean) => ReactNode;
/** Whether the drawer is open on mobile devices */
mobileIsOpen?: boolean;
/** Callback function to handle closing the drawer on mobile devices */
onMobileClose?: () => void;
/** Logo to display in the drawer header */
logo?: string | ReactNode | ((collapsed?: boolean) => ReactNode);
/** Props for text elements inside the drawer */
textProps?: TextProps;
/** Custom styles for the drawer */
sx?: StyledDrawerProps['sx'];
/** Custom styles for drawer buttons */
buttonSx?: SxProps<Theme>;
/** Whether the drawer items should be displayed horizontally */
horizontal?: boolean;
/** Whether the drawer is collapsible */
collapsible?: boolean;
/** Icon to use for the collapsible button */
collapsibleIcon?: ReactNode | ((collapsed?: boolean) => ReactNode);
/** Color of the collapsible icon */
collapsibleIconColor?: string;
/** Background color of the collapsible icon */
collapsibleIconBgColor?: string;
/** Whether the drawer is collapsed */
collapsed?: boolean;
/** Callback function to handle changes to the collapsed state */
onCollapsedChange?: (collapsed: boolean) => void;
/** Background color of the drawer */
backgroundColor?: StyledDrawerProps['backgroundColor'];
/** Color of the drawer item icons */
iconColor?: DrawerItemProps['iconColor'];
/** Color of the active drawer item icons */
activeIconColor?: DrawerItemProps['activeIconColor'];
/** Width of the drawer when collapsed */
collapsedWidth?: StyledDrawerProps['collapsedWidth'];
/** Width of the drawer when expanded */
expandedWidth?: StyledDrawerProps['expandedWidth'];
};

const Drawer = (props: DrawerProps) => {
/**
* The Drawer component is a sidebar with navigation items.
* It supports various features such as collapsible sections,
* custom toggles, and responsive design for mobile devices.
*
* @see [Storybook - Drawer](https://storybook.rockets.tools/?path=/docs/drawer)
*
* @example
* ```tsx
* <Drawer
* items={[
* { id: 'item1', label: 'Item 1', onClick: () => console.log('Item 1 clicked') },
* { id: 'item2', label: 'Item 2', onClick: () => console.log('Item 2 clicked') },
* ]}
* currentId="item1"
* logo="logo.png"
* />
* ```
*
* @param props - Drawer component props
*/
export const Drawer = (props: DrawerProps) => {
const {
items,
currentId,
Expand Down Expand Up @@ -212,5 +256,3 @@ const Drawer = (props: DrawerProps) => {
</>
);
};

export default Drawer;
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type DrawerItemProps = {
temporary?: boolean;
} & DrawerButtonProps;

const DrawerItem = (props: DrawerItemProps) => {
export const DrawerItem = (props: DrawerItemProps) => {
const {
id,
icon,
Expand Down Expand Up @@ -76,5 +76,3 @@ const DrawerItem = (props: DrawerItemProps) => {
</DrawerButton>
);
};

export default DrawerItem;
8 changes: 2 additions & 6 deletions packages/react-material-ui/src/components/Drawer/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
import Drawer, { DrawerProps } from './Drawer';
import { DrawerItemProps, DEFAULT_DRAWER_TEXT_PROPS } from './DrawerItem';

export type { DrawerProps, DrawerItemProps };
export { DEFAULT_DRAWER_TEXT_PROPS };
export default Drawer;
export { Drawer, DrawerProps } from './Drawer';
export { DrawerItemProps, DEFAULT_DRAWER_TEXT_PROPS } from './DrawerItem';
3 changes: 1 addition & 2 deletions packages/react-material-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ export { AppBar };

export { default as Dialog } from './components/Dialog';

import Drawer, { DrawerProps, DrawerItemProps } from './components/Drawer';
export { Drawer, DrawerProps, DrawerItemProps };
export { Drawer, DrawerProps, DrawerItemProps } from './components/Drawer';

import Dropdown, { DropdownItem } from './components/Dropdown';
export { Dropdown, DropdownItem };
Expand Down
2 changes: 1 addition & 1 deletion stories/AppBar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import rockets from './assets/rockets.svg';
const Component = (args) => (
<AppBar.Root {...args}>
<AppBar.Drawer
logo={rockets}
logo={<img src={rockets} alt="rockets" width={60} height={60} />}
items={[
{
icon: <HomeIcon />,
Expand Down
160 changes: 160 additions & 0 deletions stories/Drawer.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import {
Drawer,
DrawerProps,
DrawerItemProps,
} from '@concepta/react-material-ui';
import HomeIcon from '@mui/icons-material/Home';
import SettingsIcon from '@mui/icons-material/Settings';
import LockOpenOutlined from '@mui/icons-material/LockOpenOutlined';
import LockOutlined from '@mui/icons-material/LockOutlined';
import rockets from './assets/rockets.svg';

const meta = {
component: Drawer,
tags: ['autodocs'],
args: {},
argTypes: {
items: {
description: 'Array of items to display in the drawer',
control: 'object',
},
currentId: { control: 'text' },
customToggle: { type: 'function' },
mobileIsOpen: { control: 'boolean' },
onMobileClose: { type: 'function' },
logo: { control: 'text' },
textProps: {
description: 'Props for text elements inside the drawer',
control: 'object',
},
sx: { description: 'Custom styles for the drawer', control: 'object' },
buttonSx: {
description: 'Custom styles for drawer buttons',
control: 'object',
},
horizontal: {
description: 'Whether the drawer items should be displayed horizontally',
control: 'boolean',
},
collapsibleIcon: {
description: 'Icon to use for the collapsible button',
control: 'object',
},
collapsibleIconColor: { control: 'color' },
collapsibleIconBgColor: { control: 'color' },
collapsed: { control: 'boolean' },
onCollapsedChange: { type: 'function' },
backgroundColor: { control: 'color' },
iconColor: { control: 'color' },
activeIconColor: { control: 'color' },
collapsedWidth: { control: 'range', min: 100, max: 500, step: 5 },
expandedWidth: { control: 'range', min: 100, max: 500, step: 5 },
},
} satisfies Meta<typeof Drawer>;

export default meta;

type Story = StoryObj<typeof meta>;

const items: DrawerItemProps[] = [
{
id: 'home',
text: 'Home',
icon: <HomeIcon />,
onClick: () => alert('Home clicked'),
},
{
id: 'settings',
text: 'Settings',
icon: <SettingsIcon />,
onClick: () => alert('Settings clicked'),
},
];

export const Default: Story = {
args: {
items,
logo: 'https://via.placeholder.com/80',
collapsible: true,
collapsed: false,
},
};

export const DrawerWithLogoAndItems: Story = {
args: {
logo: <img src={rockets} alt="rockets" width={60} height={60} />,
items,
},
};

/**
* Horizontal prop will display the items in a row instead of a column
*/
export const HorizontalDrawer: Story = {
args: {
items,
horizontal: true,
},
};

export const CollapsedDrawer: Story = {
args: {
items,
collapsed: true,
},
};

export const CustomStyles: Story = {
args: {
items,
backgroundColor: '#333',
iconColor: '#ff0000',
activeIconColor: '#0f0',
sx: { padding: '10px' },
},
};

export const CustomCollapsibleIcon: Story = {
args: {
items,
collapsibleIcon: (collapsed) =>
collapsed ? <LockOpenOutlined /> : <LockOutlined />,
collapsibleIconBgColor: '#333',
collapsibleIconColor: '#ee4400',
},
};

export const CustomToggleButton: Story = {
args: {
items,
customToggle: (toggleDrawer, collapsed) => (
<button onClick={toggleDrawer}>
{collapsed ? 'Expand' : 'Collapse'}
</button>
),
},
};

export const WithActiveItem: Story = {
args: {
items,
currentId: 'home',
},
};

export const WithTextProperties: Story = {
args: {
items,
textProps: { fontSize: 18, color: 'red' },
},
};

export const CustomWidths: Story = {
args: {
items,
collapsedWidth: 200,
expandedWidth: 300,
},
};

0 comments on commit 1739976

Please sign in to comment.