Skip to content

Commit

Permalink
fix: controls (previous action) for list item (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
ingefossland authored Nov 29, 2024
1 parent 7a5fa9e commit dfac742
Show file tree
Hide file tree
Showing 15 changed files with 171 additions and 55 deletions.
10 changes: 9 additions & 1 deletion lib/components/ContextMenu/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,26 @@ export interface ContextMenuProps {
placement?: DropdownPlacement;
size?: ContextMenuSize;
groups?: MenuItemGroups;
className?: string;
}

export const ContextMenu = ({
id = 'context-menu',
placement = 'right',
size,
groups = {},
className,
items,
}: ContextMenuProps) => {
const { currentId, toggleId } = useRootContext();
return (
<ContextMenuBase size={size} placement={placement} expanded={currentId === id} onToggle={() => toggleId(id)}>
<ContextMenuBase
size={size}
placement={placement}
className={className}
expanded={currentId === id}
onToggle={() => toggleId(id)}
>
<MenuItems groups={groups} items={items} />
</ContextMenuBase>
);
Expand Down
5 changes: 4 additions & 1 deletion lib/components/ContextMenu/ContextMenuBase.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import cx from 'classnames';
import type { ReactNode } from 'react';
import { DropdownBase, IconButton } from '../';
import type { DropdownPlacement } from '../';
Expand All @@ -9,6 +10,7 @@ export interface ContextMenuBaseProps {
placement: DropdownPlacement;
expanded: boolean;
size?: ContextMenuSize;
className?: string;
onToggle?: () => void;
children?: ReactNode;
}
Expand All @@ -17,11 +19,12 @@ export const ContextMenuBase = ({
size = 'sm',
placement = 'right',
expanded = false,
className,
onToggle,
children,
}: ContextMenuBaseProps) => {
return (
<div className={styles.toggle} data-theme="neutral">
<div className={cx(styles.toggle, className)} data-theme="neutral">
<IconButton
className={styles.button}
size={size}
Expand Down
2 changes: 1 addition & 1 deletion lib/components/Dialog/DialogListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const DialogListItem = ({
{...rest}
size={size}
className={styles.item}
action={select && <DialogSelect className={styles.select} {...select} />}
controls={select && <DialogSelect className={styles.select} {...select} />}
>
<DialogBorder className={styles.border} size={size} seen={seen}>
<DialogHeaderBase size={size}>
Expand Down
43 changes: 37 additions & 6 deletions lib/components/List/ListItem.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export const MediaTypes = (args) => {
);
};

export const ActionProps = (args) => {
export const Controls = (args) => {
return (
<ListBase>
<ListItem {...args} linkIcon="chevron-right" />
Expand All @@ -124,18 +124,49 @@ export const ActionProps = (args) => {
],
}}
/>
<MetaItem>List item with context menu and linkIcon</MetaItem>
<MetaItem>List item with badge, linkIcon and context menu</MetaItem>

<ListItem
{...args}
action={
<div style={{ display: 'flex', alignItems: 'center', margin: '0.625rem' }}>
<Button icon="pencil" reverse size="sm" variant="outline">
controls={
<div style={{ position: 'absolute', right: 0, display: 'flex', alignItems: 'center', margin: '0.625rem' }}>
<Button icon="pencil" size="sm" variant="outline">
Rediger
</Button>
</div>
}
/>
<MetaItem>List item with custom action</MetaItem>
<MetaItem>List item with custom controls</MetaItem>
</ListBase>
);
};

export const Selectable = (args) => {
return (
<ListBase>
{sizes?.map((size) => {
return (
<Fragment key={size}>
<ListItem
{...args}
size={size}
select={{
checked: false,
}}
/>

<ListItem
{...args}
size={size}
select={{
checked: true,
}}
selected={true}
/>
<MetaItem>{size}</MetaItem>
</Fragment>
);
})}
</ListBase>
);
};
Expand Down
14 changes: 7 additions & 7 deletions lib/components/List/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import type { AvatarGroupProps, AvatarProps } from '../Avatar';
import type { BadgeProps } from '../Badge';
import type { ContextMenuProps } from '../ContextMenu';
import type { IconName } from '../Icon';
import { ListItemAction } from './ListItemAction';
import { ListItemBase, type ListItemBaseProps } from './ListItemBase';
import { ListItemFooter } from './ListItemFooter';
import { ListItemControls } from './ListItemControls';
import { ListItemHeader } from './ListItemHeader';
import { ListItemLabel } from './ListItemLabel';
import { ListItemMedia } from './ListItemMedia';
Expand Down Expand Up @@ -43,8 +42,6 @@ export const ListItem = ({
as = 'a',
color,
loading,
selected,
disabled,
size = 'sm',
icon,
avatar,
Expand All @@ -58,7 +55,8 @@ export const ListItem = ({
linkText,
linkIcon,
menu,
action,
select,
controls,
...rest
}: ListItemProps) => {
const applicableLinkIcon = collapsible && expanded ? 'chevron-up' : collapsible ? 'chevron-down' : linkIcon;
Expand All @@ -69,7 +67,10 @@ export const ListItem = ({
size={size}
color={color}
expanded={expanded}
action={action || (menu && <ListItemAction menu={menu}>{action}</ListItemAction>)}
select={select}
controls={
controls || <ListItemControls linkIcon={applicableLinkIcon} linkText={linkText} menu={menu} badge={badge} />
}
{...rest}
>
<ListItemHeader size={size}>
Expand All @@ -78,7 +79,6 @@ export const ListItem = ({
{children}
</ListItemLabel>
</ListItemHeader>
<ListItemFooter linkIcon={applicableLinkIcon} linkText={linkText} badge={badge} />
</ListItemBase>
);
};
12 changes: 0 additions & 12 deletions lib/components/List/ListItemAction.tsx

This file was deleted.

12 changes: 8 additions & 4 deletions lib/components/List/ListItemBase.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import cx from 'classnames';
import type { ElementType, KeyboardEvent, KeyboardEventHandler, ReactNode } from 'react';
import { ListItemSelect, type ListItemSelectProps } from './ListItemSelect';
import styles from './listItemBase.module.css';

export type ListItemColor = 'default' | 'accent';
Expand All @@ -17,11 +18,13 @@ export interface ListItemBaseProps {
hidden?: boolean;
collapsible?: boolean;
disabled?: boolean;
select?: ListItemSelectProps;
selected?: boolean;
expanded?: boolean;
onClick?: () => void;
onKeyPress?: KeyboardEventHandler;
action?: ReactNode;
controls?: ReactNode;
children?: ReactNode;
style?: React.CSSProperties;
}
Expand All @@ -36,10 +39,11 @@ export const ListItemBase = ({
active = false,
hidden = false,
shadow = 'xs',
disabled,
select,
selected,
disabled,
expanded,
action,
controls,
onClick,
onKeyPress,
style,
Expand All @@ -57,8 +61,8 @@ export const ListItemBase = ({
aria-disabled={disabled}
aria-selected={selected}
aria-expanded={expanded}
style={style}
>
{select && <ListItemSelect {...select} size={size} />}
<Component
className={cx(styles.link, className)}
data-size={size}
Expand All @@ -74,7 +78,7 @@ export const ListItemBase = ({
>
{children}
</Component>
{action}
{controls}
</article>
);
};
Original file line number Diff line number Diff line change
@@ -1,27 +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 './listItemFooter.module.css';
import styles from './listItemControls.module.css';

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

export const ListItemFooter = ({ badge, linkText, linkIcon, children }: ListItemFooterProps) => {
export const ListItemControls = ({ badge, linkText, linkIcon, menu, children }: ListItemControlsProps) => {
return (
<footer className={styles.footer}>
<div className={styles.controls} data-menu={menu && true}>
{children ? (
children
) : (
<>
{badge && <Badge {...badge} />}
{linkText && <span className={styles.linkText}>{linkText}</span>}
{linkIcon && <Icon name={linkIcon} className={styles.linkIcon} />}
{menu && <ContextMenu {...menu} className={styles.menu} />}
</>
)}
</footer>
</div>
);
};
25 changes: 25 additions & 0 deletions lib/components/List/ListItemSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import cx from 'classnames';
import type { ChangeEventHandler } from 'react';
import { CheckboxIcon } from '../Icon/';
import type { ListItemSize } from './ListItemBase';
import styles from './listItemSelect.module.css';

export type ListItemSelectProps = {
size?: ListItemSize;
checked?: boolean;
onChange?: ChangeEventHandler;
className?: string;
};

/**
* Dialog checkbox
*/

export const ListItemSelect = ({ size, checked = false, onChange, className }: ListItemSelectProps) => {
return (
<label className={cx(styles.label, className)} data-size={size}>
<input type="checkbox" checked={checked} onChange={onChange} className={styles.input} tabIndex={-1} />
<CheckboxIcon hover={true} checked={checked} className={styles.icon} />
</label>
);
};
3 changes: 2 additions & 1 deletion lib/components/List/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
export * from './ListItemBase';
export * from './ListItemHeader';
export * from './ListItemFooter';
export * from './ListItemLabel';
export * from './ListItemMedia';
export * from './ListItemControls';
export * from './ListItemSelect';
export * from './ListItem';
export * from './ListBase';
export * from './List';
7 changes: 0 additions & 7 deletions lib/components/List/listItemAction.module.css

This file was deleted.

8 changes: 7 additions & 1 deletion lib/components/List/listItemBase.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
position: relative;
width: 100%;
display: flex;
align-items: stretch;
align-items: center;
justify-content: stretch;
}

.item[aria-selected="true"] {
background-color: var(--theme-background-subtle);
outline: 2px solid;
}

/* disabled */

/* shadow */
Expand Down Expand Up @@ -67,6 +72,7 @@
/* reset link */

.link {
align-self: stretch;
padding: 0;
border: 0;
background-color: transparent;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
.footer {
.controls {
position: absolute;
right: 0;
display: flex;
align-items: center;
gap: 0.625rem;
padding: 0.625rem;
padding: 0 0.625rem;
}

.controls:empty {
display: none;
}

.linkText {
Expand Down
Loading

0 comments on commit dfac742

Please sign in to comment.