From 78e323910401a4dc5aee8803e18f71e5f0e2eb13 Mon Sep 17 00:00:00 2001 From: devgioele Date: Tue, 19 Sep 2023 14:13:41 +0200 Subject: [PATCH] add expanded version of section list items --- .../section/SectionItem/SectionListItem.tsx | 61 ++++++++++++++----- src/components/section/theme.ts | 17 +++++- src/components/section/types.ts | 4 ++ src/examples/List.stories.tsx | 43 ++++++++++--- 4 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 src/components/section/types.ts diff --git a/src/components/section/SectionItem/SectionListItem.tsx b/src/components/section/SectionItem/SectionListItem.tsx index 50bd72c1..aa13073a 100644 --- a/src/components/section/SectionItem/SectionListItem.tsx +++ b/src/components/section/SectionItem/SectionListItem.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames' import IconKeyboardArrowRight from '@aboutbits/react-material-icons/dist/IconKeyboardArrowRight' +import IconArrowForwardIos from '@aboutbits/react-material-icons/dist/IconArrowForwardIos' import { ReactNode, forwardRef } from 'react' import { LinkComponentProps, @@ -7,6 +8,7 @@ import { useTheme, } from '../../../framework' import { ClassNameProps } from '../../types' +import { SectionListItemVariant } from '../types' export type SectionListItemProps = ClassNameProps & { children?: ReactNode @@ -28,55 +30,85 @@ export type SectionListItemButtonProps = ClassNameProps & { */ onClick: () => void children?: ReactNode + variant?: SectionListItemVariant + badge?: ReactNode } export const SectionListItemButton = forwardRef< HTMLButtonElement, SectionListItemButtonProps >(function SectionListItemButton( - { children, onClick, className, ...props }, + { + children, + onClick, + className, + variant = SectionListItemVariant.Compact, + badge, + ...props + }, ref, ) { const { section } = useTheme() + const Icon = + variant === SectionListItemVariant.Compact + ? IconKeyboardArrowRight + : IconArrowForwardIos + return ( ) }) -export type SectionListItemLinkProps = LinkComponentProps +export type SectionListItemLinkProps = LinkComponentProps & { + variant?: SectionListItemVariant + badge?: ReactNode +} export const SectionListItemLink = forwardRef< HTMLAnchorElement, SectionListItemLinkProps >(function SectionListItemLink( - { children, className, internal = true, ...props }, + { + variant = SectionListItemVariant.Compact, + badge, + children, + className, + internal = true, + ...props + }, ref, ) { const LinkComponent = useLinkComponent() const { section } = useTheme() + const Icon = + variant === SectionListItemVariant.Compact + ? IconKeyboardArrowRight + : IconArrowForwardIos + return ( {children} - +
+ {badge} + +
) }) diff --git a/src/components/section/theme.ts b/src/components/section/theme.ts index 464e1325..9b5ed222 100644 --- a/src/components/section/theme.ts +++ b/src/components/section/theme.ts @@ -2,8 +2,9 @@ import { Size } from '../types' import { SectionContentLayout } from './Section/SectionContent/types' import { SectionHeaderRowLayout } from './SectionHeader/SectionHeaderRow/types' import { SectionHeaderSpacerSize } from './SectionHeader/SectionHeaderSpacer/types' +import { SectionListItemVariant } from './types' -export default { +const className = { section: { base: '', }, @@ -30,7 +31,16 @@ export default { base: 'grid xl:grid-cols-2 xl:gap-x-11 gap-y-6 px-4 md:px-6 pt-4 md:pt-6 pb-8 md:pb-9', }, listItem: { - base: 'flex border-b border-neutral-200 last:border-0 items-center min-h-[3.5rem] bg-white px-4 md:px-6', + base: 'flex border-b border-neutral-200 last:border-0 items-center bg-white px-4 md:px-6', + variant: { + [SectionListItemVariant.Compact]: 'py-4 min-h-[1.5rem]', + [SectionListItemVariant.Expanded]: + 'py-4 min-h-[6.5rem] first:pt-6 first:min-h-[7rem] last:pb-6 last:min-h-[7rem]', + }, + icon: 'fill-current mt-auto', + rightAlignedContainer: { + base: 'flex flex-col items-end self-stretch justify-between', + }, }, listItemWithAction: { base: 'justify-between space-x-4', @@ -40,7 +50,6 @@ export default { }, listItemButton: { base: 'block w-full focus:outline-neutral-800 justify-between space-x-4 hover:bg-neutral-100 active:bg-neutral-100', - icon: 'fill-current', }, listItemLink: { base: 'block focus:outline-neutral-800 justify-between space-x-4 hover:bg-neutral-100 active:bg-neutral-100', @@ -103,3 +112,5 @@ export default { base: 'mt-4', }, } + +export default className diff --git a/src/components/section/types.ts b/src/components/section/types.ts new file mode 100644 index 00000000..bff61464 --- /dev/null +++ b/src/components/section/types.ts @@ -0,0 +1,4 @@ +export enum SectionListItemVariant { + Compact = 'COMPACT', + Expanded = 'EXPANDED', +} diff --git a/src/examples/List.stories.tsx b/src/examples/List.stories.tsx index bd7b129d..26e07a84 100644 --- a/src/examples/List.stories.tsx +++ b/src/examples/List.stories.tsx @@ -27,9 +27,11 @@ import { SelectField, Tone, Option, + SectionListItemLink, } from '../components' import { SearchField } from '../components/form/SearchField' import { useFilter } from '../components/util/useFilter' +import { SectionListItemVariant } from '../components/section/types' const meta = { component: SectionContentList, @@ -66,7 +68,15 @@ function useMockedList(numberOfTotalItems: number) { ) } -const List = ({ numberOfTotalItems = 5 }: { numberOfTotalItems?: number }) => { +const List = ({ + numberOfTotalItems = 5, + variant, + links = false, +}: { + numberOfTotalItems?: number + variant?: SectionListItemVariant + links?: boolean +}) => { const content = useMockedList(numberOfTotalItems) return (
@@ -79,14 +89,21 @@ const List = ({ numberOfTotalItems = 5 }: { numberOfTotalItems?: number }) => { /> ) : ( - {content.map((item) => ( - - {`${item.name} (${item.role} - ${item.department})`} - - ))} + {content.map((item) => + links ? ( + + {`${item.name} (${item.role} - ${item.department})`} + + ) : ( + + {`${item.name} (${item.role} - ${item.department})`} + + ), + )} )} @@ -98,6 +115,14 @@ export const SimpleList: Story = () => export const EmptySimpleList: Story = () => +export const ExpandedButtonsList: Story = () => ( + +) + +export const ExpandedLinksList: Story = () => ( + +) + /** * The following example shows how multiple section components and the in memory pagination are used to create an overview list with filters. */