Skip to content

Commit

Permalink
fix: list item action props
Browse files Browse the repository at this point in the history
  • Loading branch information
ingefossland committed Nov 26, 2024
1 parent fb9ad9f commit d87fe56
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 112 deletions.
199 changes: 107 additions & 92 deletions lib/components/List/ListItem.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const meta = {
title: 'Title',
description: 'Description',
size: 'md',
href: '#',
},
} satisfies Meta<typeof ListItem>;

Expand All @@ -27,102 +26,118 @@ export const Default: Story = {
args: {},
};

export const Icon: Story = {
args: {
icon: 'teddy-bear',
},
};

export const IconAccent: Story = {
args: {
color: 'accent',
icon: 'teddy-bear',
},
};

export const Person: Story = {
args: {
avatar: {
type: 'person',
name: 'Erik Huseklepp',
},
},
};

export const Company: Story = {
args: {
avatar: {
type: 'company',
name: 'Sportsklubben Brann',
},
},
};

export const Logo: Story = {
args: {
avatar: {
type: 'company',
name: 'Politiets sikkerhetstjeneste',
imageUrl:
'https://media.licdn.com/dms/image/v2/D4D0BAQH7Yv86kmHN5g/company-logo_200_200/company-logo_200_200/0/1688735908848?e=1738195200&v=beta&t=f-Mkzd03bqzdQN4IT0h89VQ9_Jri1iJ6XphYYnjsgEo',
},
},
};

export const PeopleGroup: Story = {
args: {
avatarGroup: {
items: [
{
type: 'person',
name: 'Albert Åberg',
},
{
type: 'person',
name: 'Birger Meling',
},
{
export const MediaTypes = (args) => {
return (
<ListBase>
<ListItem {...args} />
<MetaItem>No media</MetaItem>
<ListItem {...args} icon="teddy-bear" />
<MetaItem>Icon</MetaItem>
<ListItem
{...args}
avatar={{
type: 'person',
name: 'Celine Dion',
},
],
},
},
};

export const CompanyGroup: Story = {
args: {
avatarGroup: {
items: [
{
type: 'company',
name: 'Albert Åberg',
},
{
name: 'Erik Huseklepp',
}}
/>
<MetaItem>Person</MetaItem>
<ListItem
{...args}
avatar={{
type: 'company',
name: 'Birger Meling',
},
{
name: 'Sportsklubben Brann',
}}
/>
<MetaItem>Company</MetaItem>
<ListItem
{...args}
avatar={{
type: 'company',
name: 'Celine Dion',
},
],
},
},
name: 'Politiets sikkerhetstjeneste',
imageUrl:
'https://media.licdn.com/dms/image/v2/D4D0BAQH7Yv86kmHN5g/company-logo_200_200/company-logo_200_200/0/1688735908848?e=1738195200&v=beta&t=f-Mkzd03bqzdQN4IT0h89VQ9_Jri1iJ6XphYYnjsgEo',
}}
/>
<MetaItem>Logo</MetaItem>
<ListItem
{...args}
avatarGroup={{
items: [
{
type: 'person',
name: 'Albert Åberg',
},
{
type: 'person',
name: 'Birger Meling',
},
{
type: 'person',
name: 'Celine Dion',
},
],
}}
/>
<MetaItem>People group</MetaItem>
<ListItem
{...args}
avatarGroup={{
items: [
{
type: 'company',
name: 'Albert Åberg',
},
{
type: 'company',
name: 'Birger Meling',
},
{
type: 'company',
name: 'Celine Dion',
},
],
}}
/>
<MetaItem>Company group</MetaItem>
</ListBase>
);
};

export const LongTitle: Story = {
args: {
avatar: {
type: 'company',
name: 'Direktoratet for samfunnssikkerhet og beredskap',
imageUrl:
'https://media.licdn.com/dms/image/v2/C510BAQHlQiOWI4f45w/company-logo_200_200/company-logo_200_200/0/1631389121726?e=1738195200&v=beta&t=Q1P8kOwpgLvoqHBxyrHCaYd2upNkPQVi2zSSxJzbdCA',
},
title:
'Samtykke for å reparere elektrisk utstyr hvis bruk er forbundet med særlig risiko, herunder elektromedisinsk utstyr',
description: 'Direktoratet for samfunnssikkerhet og beredskap',
},
export const ActionProps = (args) => {
return (
<ListBase>
<ListItem {...args} linkIcon="chevron-right" />
<MetaItem>Link icon, emphasising that this will take you somewhere</MetaItem>
<ListItem {...args} linkIcon="chevron-right" linkText="Åpne" />
<MetaItem>Link icon + link text, emphasising that this will take you somewhere</MetaItem>
<ListItem {...args} collapsible badge={{ label: 'Admin' }} />
<MetaItem>Collapsible item with badge</MetaItem>
<ListItem {...args} collapsible expanded />
<MetaItem>Collapsible and expanded item</MetaItem>
<ListItem
{...args}
linkIcon="chevron-right"
menu={{
items: [
{ label: 'Innstillinger', icon: 'cog' },
{ label: 'Aktivitetslogg', icon: 'clock-dashed' },
],
}}
/>
<MetaItem>List item with context menu and linkIcon</MetaItem>
</ListBase>
);
};

export const Colors = (args) => {
return (
<ListBase>
<ListItem {...args} />
<MetaItem>Default</MetaItem>
<ListItem {...args} color="accent" />
<MetaItem>Accent</MetaItem>
</ListBase>
);
};

export const Sizes = (args) => {
Expand Down
24 changes: 16 additions & 8 deletions lib/components/List/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ElementType, ReactNode } from 'react';
import type { AvatarGroupProps, AvatarProps } from '../Avatar';
import type { BadgeProps } from '../Badge';
import type { IconName } from '../Icon';
import type { ContextMenuProps } from '../ContextMenu';
import { ListItemBase, type ListItemColor, type ListItemSize } from './ListItemBase';
import { ListItemLabel } from './ListItemLabel';
import { ListItemMedia } from './ListItemMedia';
Expand All @@ -26,44 +27,51 @@ export interface ListItemProps {
selected?: boolean;
/** Item is disabled, should disable mouse events */
disabled?: boolean;
/** Display an icon indicating behaviour */
linkIcon?: IconName;
/** Size of list item */
size?: ListItemSize;
/** Title */
title?: string;
/** Optional description */
description?: string;
/** Optional badge */
badge?: BadgeProps;
/** Use children to create a custom label, overriding title and description */
children?: ReactNode;
/** List item icon */
icon?: IconName;
/** List item avatar */
avatar?: AvatarProps;
/** List item avatarGroup */
avatarGroup?: AvatarGroupProps;
children?: ReactNode;
/** Optional text indicating behaviour */
linkText?: string;
/** Optional icon indicating behaviour */
linkIcon?: IconName;
/** Optional badge */
badge?: BadgeProps;
/** Optional context menu */
menu?: ContextMenuProps;
/** Custom action overrides linkText, linkIcon, badge and menu */
action?: ReactNode;
/** Child items */
items?: ListItemProps[];
className?: string;
}

export const ListItem = ({
as = 'a',
color,
children,
selected,
disabled,
size = 'sm',
icon,
avatar,
avatarGroup,
badge,
title,
description,
children,
...rest
}: ListItemProps) => {
return (
<ListItemBase as={as} size={size} badge={badge} color={color} selected={selected} {...rest}>
<ListItemBase as={as} size={size} color={color} selected={selected} {...rest}>
<ListItemMedia color={color} size={size} icon={icon} avatar={avatar} avatarGroup={avatarGroup} />
<ListItemLabel title={title} description={description} size={size}>
{children}
Expand Down
49 changes: 49 additions & 0 deletions lib/components/List/ListItemAction.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Fragment, useState } from 'react';

import { ListItemBase, ListItemAction } from './';

const meta = {
title: 'List/ListItemAction',
component: ListItemAction,
tags: ['autodocs'],
parameters: {},
args: {},
} satisfies Meta<typeof ListItem>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Icon: Story = {
args: {
linkIcon: 'chevron-right',
},
};

export const TextAndIcon: Story = {
args: {
linkText: '2 dager siden',
linkIcon: 'chevron-right',
},
};

export const BadgeAndIcon: Story = {
args: {
badge: {
label: 'Admin',
},
linkIcon: 'chevron-down',
},
};

export const ContextMenu: Story = {
args: {
menu: {
items: [
{
label: 'Slett alle',
},
],
},
},
};
30 changes: 30 additions & 0 deletions lib/components/List/ListItemAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { ReactNode } from 'react';
import { Badge, type BadgeProps } from '../Badge';
import { ContextMenu, type ContextMenuProps } from '../ContextMenu';
import { Icon, type IconName } from '../Icon';
import styles from './listItemAction.module.css';

interface ListItemActionProps {
badge?: BadgeProps;
menu?: ContextMenuProps;
linkText?: string;
linkIcon?: IconName;
children?: ReactNode;
}

export const ListItemAction = ({ linkText, linkIcon, menu, badge, children }: ListItemActionProps) => {
return (
<div className={styles.action}>
{children ? (
children
) : (
<>
{badge && <Badge {...badge} />}
{menu && <ContextMenu {...menu} />}
{linkText && <span className={styles.linkText}>{linkText}</span>}
{linkIcon && <Icon name={linkIcon} className={styles.linkIcon} />}
</>
)}
</div>
);
};
Loading

0 comments on commit d87fe56

Please sign in to comment.