Skip to content

Commit

Permalink
feat: refactor ListGroup component
Browse files Browse the repository at this point in the history
  • Loading branch information
bacali95 committed Mar 18, 2022
1 parent 1a7c0c5 commit 0f18211
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 119 deletions.
55 changes: 0 additions & 55 deletions src/components/ListGroup.tsx

This file was deleted.

1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './Carousel';
export * from './dropdown/Dropdown';
export * from './DarkThemeToggle';
export * from './form-controls';
export * from './list-group/ListGroup';
export * from './Navbar';
export * from './Sidebar';
export * from './Spinner';
Expand Down
23 changes: 23 additions & 0 deletions src/components/list-group/ListGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FC } from 'react';
import classNames from 'classnames';

import { ListGroupItem } from './ListGroupItem';

export type ListGroupProps = {
className?: string;
};

const ListGroupComponent: FC<ListGroupProps> = ({ children, className }) => (
<div
className={classNames(
'list-none rounded-lg border border-gray-200 bg-white text-sm font-medium text-gray-900 dark:border-gray-600 dark:bg-gray-700 dark:text-white',
className,
)}
>
{children}
</div>
);

ListGroupItem.displayName = 'ListGroup.Item';

export const ListGroup = Object.assign(ListGroupComponent, { Item: ListGroupItem });
41 changes: 41 additions & 0 deletions src/components/list-group/ListGroupItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ComponentProps, FC, PropsWithChildren } from 'react';
import classNames from 'classnames';

export type ListGroupItemProps = {
className?: string;
href?: string;
icon?: FC<ComponentProps<'svg'>>;
active?: boolean;
onClick?: () => void;
disabled?: boolean;
};

export const ListGroupItem: FC<ListGroupItemProps> = ({ children, className, href, onClick, active, icon: Icon }) => {
const Wrapper = ({ children, className }: PropsWithChildren<{ className?: string }>) =>
!href ? (
<button className={classNames('text-left', className)} onClick={onClick} type="button">
{children}
</button>
) : (
<a className={className} href={href}>
{children}
</a>
);

return (
<Wrapper
className={classNames(
'flex w-full cursor-pointer border-b border-gray-200 py-2 px-4 first:rounded-t-lg last:rounded-b-lg last:border-b-0 dark:border-gray-600',
{
'bg-blue-700 text-white dark:bg-gray-800': active,
'hover:bg-gray-100 hover:text-blue-700 focus:text-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-700 dark:border-gray-600 dark:hover:bg-gray-600 dark:hover:bg-gray-600 dark:hover:text-white dark:hover:text-white dark:focus:text-white dark:focus:ring-gray-500':
!active,
},
className,
)}
>
{Icon && <Icon className="mr-2 h-4 w-4 fill-current" />}
{children}
</Wrapper>
);
};
108 changes: 44 additions & 64 deletions src/pages/ListGroupPage.tsx
Original file line number Diff line number Diff line change
@@ -1,84 +1,64 @@
import { FC } from 'react';
import { ListGroup, ListGroupItem } from '../components/ListGroup';
import { CodeExample, DemoPage } from './DemoPage';
import { HiCloudDownload, HiInbox, HiOutlineAdjustments, HiUserCircle } from 'react-icons/hi';

const ListGroupPage: FC = () => {
const defaultItems: ListGroupItem[] = [
{
title: 'Profile',
},
{
title: 'Settings',
},
{
title: 'Messages',
},
{
title: 'Download',
},
];

const itemsWithLinks: ListGroupItem[] = [
{
title: 'Profile',
link: '#/list-group',
active: true,
},
{
title: 'Settings',
link: '#/list-group',
},
{
title: 'Messages',
link: '#/list-group',
},
{
title: 'Download',
link: '#/list-group',
},
];

const itemsWithIcons: ListGroupItem[] = [
{
title: 'Profile',
icon: HiUserCircle,
onClick: () => alert('profile'),
},
{
title: 'Settings',
icon: HiOutlineAdjustments,
},
{
title: 'Messages',
icon: HiInbox,
},
{
title: 'Download',
icon: HiCloudDownload,
},
];
import { ListGroup } from '../components';
import { CodeExample, DemoPage } from './DemoPage';

const ListGroupPage: FC = () => {
const examples: CodeExample[] = [
{
title: 'Default list',
code: <ListGroup items={defaultItems} />,
code: (
<ListGroup className="w-48">
<ListGroup.Item>Profile</ListGroup.Item>
<ListGroup.Item>Settings</ListGroup.Item>
<ListGroup.Item>Messages</ListGroup.Item>
<ListGroup.Item>Download</ListGroup.Item>
</ListGroup>
),
},
{
title: 'List group with links',
code: <ListGroup items={itemsWithLinks} />,
code: (
<ListGroup className="w-48">
<ListGroup.Item active href="#/list-group">
Profile
</ListGroup.Item>
<ListGroup.Item href="#/list-group">Settings</ListGroup.Item>
<ListGroup.Item href="#/list-group">Messages</ListGroup.Item>
<ListGroup.Item href="#/list-group">Download</ListGroup.Item>
</ListGroup>
),
},
{
title: 'List group with buttons',
code: <ListGroup items={itemsWithLinks} />,
},
{
title: 'List group with icons',
code: <ListGroup items={itemsWithIcons} />,
code: (
<ListGroup className="w-48">
<ListGroup.Item active onClick={() => alert('Profile clicked!')}>
Profile
</ListGroup.Item>
<ListGroup.Item>Settings</ListGroup.Item>
<ListGroup.Item>Messages</ListGroup.Item>
<ListGroup.Item>Download</ListGroup.Item>
</ListGroup>
),
codeStringifierOptions: {
functionValue: (fn) => (fn.name === 'onClick' ? fn : fn.name),
},
},
{
title: 'List group with icons',
code: (
<ListGroup className="w-48">
<ListGroup.Item active icon={HiUserCircle}>
Profile
</ListGroup.Item>
<ListGroup.Item icon={HiOutlineAdjustments}>Settings</ListGroup.Item>
<ListGroup.Item icon={HiInbox}>Messages</ListGroup.Item>
<ListGroup.Item icon={HiCloudDownload}>Download</ListGroup.Item>
</ListGroup>
),
},
];

return <DemoPage examples={examples} />;
Expand Down

0 comments on commit 0f18211

Please sign in to comment.