Skip to content

Commit

Permalink
More flexible section list items (#288)
Browse files Browse the repository at this point in the history
* add possibility of not showing an icon inside a section list item

* make implementation of SectionListItemButton and SectionListItemLink more similar

* work with vertical padding rather than min height
  • Loading branch information
devgioele authored Sep 19, 2023
1 parent 7d77401 commit 6f0b184
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 29 deletions.
37 changes: 22 additions & 15 deletions src/components/section/SectionItem/SectionListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,32 @@ export function SectionListItem({ className, children }: SectionListItemProps) {
)
}

function SectionListItemIcon() {
const { section } = useTheme()

return (
<IconKeyboardArrowRight
width="24"
height="24"
className={section.listItemButtonLink.icon}
/>
)
}

export type SectionListItemButtonProps = ClassNameProps & {
/**
* On click handler for the button.
*/
onClick: () => void
children?: ReactNode
withIcon?: boolean
}

export const SectionListItemButton = forwardRef<
HTMLButtonElement,
SectionListItemButtonProps
>(function SectionListItemButton(
{ children, onClick, className, ...props },
{ children, onClick, className, withIcon = true, ...props },
ref,
) {
const { section } = useTheme()
Expand All @@ -43,30 +56,28 @@ export const SectionListItemButton = forwardRef<
<button
onClick={onClick}
className={classNames(
section.listItemButton.base,
section.listItem.base,
section.listItemButtonLink.base,
className,
)}
ref={ref}
{...props}
>
{children}
<IconKeyboardArrowRight
width="24"
height="24"
className={section.listItemButton.icon}
/>
{withIcon && <SectionListItemIcon />}
</button>
)
})

export type SectionListItemLinkProps = LinkComponentProps
export type SectionListItemLinkProps = LinkComponentProps & {
withIcon?: boolean
}

export const SectionListItemLink = forwardRef<
HTMLAnchorElement,
SectionListItemLinkProps
>(function SectionListItemLink(
{ children, className, internal = true, ...props },
{ children, className, internal = true, withIcon = true, ...props },
ref,
) {
const LinkComponent = useLinkComponent()
Expand All @@ -75,20 +86,16 @@ export const SectionListItemLink = forwardRef<
return (
<LinkComponent
className={classNames(
section.listItemLink.base,
section.listItem.base,
section.listItemButtonLink.base,
className,
)}
internal={internal}
ref={ref}
{...props}
>
{children}
<IconKeyboardArrowRight
width="24"
height="24"
className={section.listItemButton.icon}
/>
{withIcon && <SectionListItemIcon />}
</LinkComponent>
)
})
Expand Down
7 changes: 2 additions & 5 deletions src/components/section/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,18 @@ 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 py-4 bg-white px-4 md:px-6',
},
listItemWithAction: {
base: 'justify-between space-x-4',
action: {
base: 'flex flex-shrink-0',
},
},
listItemButton: {
listItemButtonLink: {
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',
},
subsectionTitle: {
base: 'bg-neutral-100 px-4 md:px-6 py-1 border-b border-t first:border-t-none border-neutral-200 text-sm text-neutral-600',
},
Expand Down
39 changes: 30 additions & 9 deletions src/examples/List.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
SelectField,
Tone,
Option,
SectionListItemButtonProps,
SectionListItemLink,
} from '../components'
import { SearchField } from '../components/form/SearchField'
import { useFilter } from '../components/util/useFilter'
Expand Down Expand Up @@ -66,7 +68,13 @@ function useMockedList(numberOfTotalItems: number) {
)
}

const List = ({ numberOfTotalItems = 5 }: { numberOfTotalItems?: number }) => {
const List = ({
numberOfTotalItems = 5,
withIcon,
}: { numberOfTotalItems?: number } & Pick<
SectionListItemButtonProps,
'withIcon'
>) => {
const content = useMockedList(numberOfTotalItems)
return (
<Section>
Expand All @@ -79,14 +87,25 @@ const List = ({ numberOfTotalItems = 5 }: { numberOfTotalItems?: number }) => {
/>
) : (
<SectionContentList>
{content.map((item) => (
<SectionListItemButton
key={item.name}
onClick={action('onItemClick')}
>
{`${item.name} (${item.role} - ${item.department})`}
</SectionListItemButton>
))}
{content.map((item, index) =>
index % 2 === 0 ? (
<SectionListItemButton
key={item.name}
onClick={action('onItemClick')}
withIcon={withIcon}
>
{`Button ${item.name} (${item.role} - ${item.department})`}
</SectionListItemButton>
) : (
<SectionListItemLink
key={item.name}
href="#"
withIcon={withIcon}
>
{`Link ${item.name} (${item.role} - ${item.department})`}
</SectionListItemLink>
),
)}
</SectionContentList>
)}
</SectionContainer>
Expand All @@ -98,6 +117,8 @@ export const SimpleList: Story = () => <List />

export const EmptySimpleList: Story = () => <List numberOfTotalItems={0} />

export const ListWithoutIcon: Story = () => <List withIcon={false} />

/**
* The following example shows how multiple section components and the in memory pagination are used to create an overview list with filters.
*/
Expand Down

0 comments on commit 6f0b184

Please sign in to comment.