List components #31
54
frontend/src/components/ListCard/ListCard.tsx
Normal file
54
frontend/src/components/ListCard/ListCard.tsx
Normal file
@ -0,0 +1,54 @@
|
||||
import type { HTMLAttributes, CSSProperties } from 'react';
|
||||
|
||||
export interface ListCardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
||||
title: string;
|
||||
onRemove?: () => void;
|
||||
}
|
||||
|
||||
const baseClasses = [
|
||||
'px-(--padding-md) py-(--padding-md)',
|
||||
'bg-sky-35 border border-sky-100 rounded-(--border-radius-md)',
|
||||
'flex items-center justify-between',
|
||||
'focus:border-primary focus:outline focus:outline-sky-35 focus:outline-(length:--border-width-lg)',
|
||||
].join(' ');
|
||||
|
||||
const iconStyles: CSSProperties = {
|
||||
width: 'var(--font-size-body-md)',
|
||||
height: 'var(--font-size-body-md)',
|
||||
};
|
||||
|
||||
function RemoveIcon({ style }: { style?: CSSProperties }) {
|
||||
return (
|
||||
<svg
|
||||
style={style}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18" />
|
||||
<line x1="6" y1="6" x2="18" y2="18" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ListCard({ title, onRemove, className = '', ...props }: ListCardProps) {
|
||||
const classes = [baseClasses, className].filter(Boolean).join(' ');
|
||||
|
||||
return (
|
||||
<div className={classes} tabIndex={0} {...props}>
|
||||
<span className="body-light-sm text-base-ink-strong">{title}</span>
|
||||
{onRemove && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onRemove}
|
||||
className="shrink-0 ml-(--spacing-sm) text-base-ink-placeholder hover:text-primary focus:outline-none cursor-pointer"
|
||||
>
|
||||
<RemoveIcon style={iconStyles} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user