Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: list item action props #88

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/components/Footer/Footer.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ const meta = {
title: 'Footer/Footer',
component: Footer,
tags: ['autodocs'],
parameters: {},
parameters: {
layout: 'fullscreen',
},
args: {
address: 'Postboks 1382 Vika, 0114 Oslo.',
address2: 'Org.nr. 991 825 827',
menu: {
items: [
{
Expand Down
9 changes: 7 additions & 2 deletions lib/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@ import { FooterAddress } from './FooterAddress';
import { FooterBase } from './FooterBase';
import { FooterLogo } from './FooterLogo';
import { FooterMenu, type FooterMenuProps } from './FooterMenu';
import styles from './footer.module.css';

export interface FooterProps {
address: string;
address2?: string;
menu: FooterMenuProps;
}

export const Footer = ({ address, menu }: FooterProps) => {
export const Footer = ({ address, address2, menu }: FooterProps) => {
return (
<FooterBase>
<FooterAddress>
<FooterLogo />
{address}
<div className={styles.address}>
<span>{address}</span>
<span>{address2}</span>
</div>
</FooterAddress>
<FooterMenu {...menu} />
</FooterBase>
Expand Down
5 changes: 5 additions & 0 deletions lib/components/Footer/footer.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.address {
display: flex;
flex-direction: column;
column-gap: 0.5rem;
}
1 change: 0 additions & 1 deletion lib/components/Footer/footerBase.module.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.footer {
width: 100%;
border-top: 1px solid;
border-color: var(--theme-border-subtle);

Expand Down
3 changes: 3 additions & 0 deletions lib/components/GlobalMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export * from './AccountMenu';
export * from './GlobalMenu';
export * from './AccountButton';
export * from './BackButton';
export * from './LogoutButton';
9 changes: 6 additions & 3 deletions lib/components/Layout/Layout.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const header: HeaderProps = {

const footer: FooterProps = {
address: 'Postboks 1382 Vika, 0114 Oslo.',
address2: 'Org.nr. 991 825 827',
menu: {
items: [
{
Expand Down Expand Up @@ -299,9 +300,11 @@ export const InboxBulkMode = (args) => {
);
})}
</ListBase>
<ActionFooter>
{bulkMode && <ActionMenu items={bulkMenu} />}
{snackbars.length > 0 && snackbars?.map((item, index) => <Snackbar key={index} {...item} />)}
<ActionFooter hidden={false}>
<>
{bulkMode && <ActionMenu items={bulkMenu} theme="global-dark" />}
{snackbars.length > 0 && snackbars?.map((item, index) => <Snackbar key={index} {...item} />)}
</>
</ActionFooter>
</Layout>
);
Expand Down
2 changes: 1 addition & 1 deletion lib/components/LayoutAction/ActionFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ReactElement } from 'react';
import styles from './actionFooter.module.css';

export interface ActionFooterProps {
hidden: boolean;
hidden?: boolean;
children?: ReactElement;
}

Expand Down
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
@@ -1,6 +1,7 @@
import type { ElementType, ReactNode } from 'react';
import type { AvatarGroupProps, AvatarProps } from '../Avatar';
import type { BadgeProps } from '../Badge';
import type { ContextMenuProps } from '../ContextMenu';
import type { IconName } from '../Icon';
import { ListItemBase, type ListItemColor, type ListItemSize } from './ListItemBase';
import { ListItemLabel } from './ListItemLabel';
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
Loading