List components #31

Open
stne3960 wants to merge 57 commits from list_item into main
Showing only changes of commit 1d5fc77fcd - Show all commits

View File

@ -0,0 +1,67 @@
import type { HTMLAttributes, CSSProperties } from 'react';
export interface ListItemProps extends HTMLAttributes<HTMLDivElement> {
title: string;
subtitle?: string;
selected?: boolean;
}
const iconStyles: CSSProperties = {
width: 'var(--font-size-body-md)',
height: 'var(--font-size-body-md)',
marginLeft: 'var(--spacing-sm)',
};
function CheckmarkIcon() {
return (
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
style={iconStyles}
>
<polyline points="20 6 9 17 4 12" />
</svg>
);
}
const baseClasses = 'w-full px-(--padding-md) py-(--padding-md) cursor-pointer flex items-center justify-between';
const defaultStateClasses = 'bg-base-canvas text-base-ink-strong hover:bg-sky-100 hover:text-primary focus:bg-sky-100 focus:text-primary focus:outline-none';
const selectedStateClasses = 'bg-base-canvas text-base-ink-placeholder';
export default function ListItem({
title,
subtitle,
selected = false,
className = '',
...props
}: ListItemProps) {
const stateClasses = selected ? selectedStateClasses : defaultStateClasses;
const classes = [baseClasses, stateClasses, className].filter(Boolean).join(' ');
return (
<div
className={classes}
tabIndex={0}
role="option"
aria-selected={selected}
{...props}
>
<div>
<div className="body-normal-md">{title}</div>
{subtitle && <div className="body-light-sm">{subtitle}</div>}
</div>
{selected && (
<div className="shrink-0">
<CheckmarkIcon />
</div>
)}
</div>
);
}