Files
redux-scraper/app/javascript/bundles/Main/components/ListItem.tsx
2025-07-23 17:59:10 +00:00

89 lines
2.1 KiB
TypeScript

import * as React from 'react';
import Icon from './Icon';
const COMMON_LIST_ELEM_CLASSES = `
w-full p-2
text-xl font-light
border-inherit
group-focus-within:border-slate-300
`;
interface PropTypes {
value: string;
subtext?: string;
thumb?: string;
isLast: boolean;
selected: boolean;
href?: string;
style: 'item' | 'info' | 'error';
domainIcon?: string;
}
export default function ListItem({
value,
thumb,
isLast,
selected,
style,
href,
subtext,
domainIcon,
}: PropTypes) {
const groupHoverClassName = 'group-hover:text-slate-200';
const iconClassName = ['ml-2'];
const textClassName = [
COMMON_LIST_ELEM_CLASSES,
'group flex items-center justify-between',
isLast && 'rounded-b-lg',
style === 'item' && selected && 'bg-slate-700 text-slate-100',
style === 'info' && 'text-slate-500 italic',
style === 'error' && 'text-red-500',
'hover:bg-slate-600 hover:text-slate-200',
].filter(Boolean);
return (
<a
className="relative block"
onPointerUp={() => {
if (href) {
window.location.href = href;
}
}}
href={href}
>
{style === 'error' && (
<Icon type="exclamation-circle" className={iconClassName.join(' ')} />
)}
<div className={textClassName.join(' ')}>
<div className="inline-block w-8">
{thumb && (
<img
src={thumb}
alt="thumbnail"
className="inline w-full rounded-md"
/>
)}
</div>
<div className="inline-block flex-grow pl-1">{value}</div>
{subtext && (
<div
className={[
'vertical-align-middle float-right inline-block pl-1 text-sm italic',
!selected && 'text-slate-500',
selected && 'text-slate-300',
groupHoverClassName,
]
.filter(Boolean)
.join(' ')}
>
{subtext}
</div>
)}
{domainIcon && (
<img src={domainIcon} alt="domain icon" className="inline w-6" />
)}
</div>
</a>
);
}