72 lines
1.6 KiB
TypeScript
72 lines
1.6 KiB
TypeScript
import styled from "@emotion/styled"
|
|
import { cx } from "@emotion/css"
|
|
import type { Item } from "opvault.js"
|
|
import { CategoryIcon } from "./CategoryIcon"
|
|
|
|
interface ListProps {
|
|
items: Item[]
|
|
selected?: Item
|
|
onSelect(item: Item): void
|
|
}
|
|
|
|
const Container = styled.div``
|
|
const List = styled.ol`
|
|
list-style: none;
|
|
padding: 0;
|
|
`
|
|
const ItemView = styled.li`
|
|
border-radius: 5px;
|
|
display: grid;
|
|
padding: 5px 15px;
|
|
transition: background-color 0.1s;
|
|
align-items: center;
|
|
cursor: default;
|
|
grid-template-columns: 35px 1fr;
|
|
&:hover {
|
|
background-color: var(--hover-background);
|
|
}
|
|
&.selected {
|
|
background-color: var(--selected-background);
|
|
}
|
|
&.trashed {
|
|
opacity: 0.6;
|
|
}
|
|
`
|
|
const ItemTitle = styled.div`
|
|
font-weight: 600;
|
|
margin-bottom: 2px;
|
|
`
|
|
const ItemDescription = styled.div`
|
|
font-size: 95%;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
max-width: 230px;
|
|
`
|
|
const Icon = styled(CategoryIcon)`
|
|
font-size: 1.5em;
|
|
`
|
|
|
|
export const ItemList: React.FC<ListProps> = ({ items, onSelect, selected }) => (
|
|
<Container>
|
|
<List>
|
|
{items.map(item => (
|
|
<ItemView
|
|
key={item.uuid}
|
|
onClick={() => onSelect(item)}
|
|
className={cx({
|
|
selected: selected?.uuid === item.uuid,
|
|
trashed: item.isDeleted,
|
|
})}
|
|
>
|
|
<Icon fill="#FFF" category={item.category} />
|
|
<div>
|
|
<ItemTitle>{item.overview.title!}</ItemTitle>
|
|
<ItemDescription>{item.overview.ainfo}</ItemDescription>
|
|
</div>
|
|
</ItemView>
|
|
))}
|
|
</List>
|
|
</Container>
|
|
)
|