mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 20:40:15 +02:00
add VirtualMultiSelect component for filters
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
.row {
|
||||
padding: var(--theme-spacing-xs) var(--theme-spacing-sm);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--theme-radius-md);
|
||||
}
|
||||
|
||||
.row:hover {
|
||||
cursor: pointer;
|
||||
background-color: alpha(var(--theme-colors-background), 0.5);
|
||||
}
|
||||
|
||||
.row-image {
|
||||
flex-shrink: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.row-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.row.selected {
|
||||
background-color: var(--theme-colors-surface);
|
||||
}
|
||||
|
||||
.row[data-focused='true'] {
|
||||
border: 1px solid var(--theme-colors-primary);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RowComponentProps } from 'react-window-v2';
|
||||
|
||||
import styles from './multi-select-rows.module.css';
|
||||
|
||||
import { ItemImage } from '/@/renderer/components/item-image/item-image';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { VirtualMultiSelectOption } from '/@/shared/components/multi-select/virtual-multi-select';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||
|
||||
export function ArtistMultiSelectRow({
|
||||
focusedIndex,
|
||||
index,
|
||||
onToggle,
|
||||
options,
|
||||
style,
|
||||
}: RowComponentProps<{
|
||||
focusedIndex: null | number;
|
||||
onToggle: (value: string) => void;
|
||||
options: VirtualMultiSelectOption<{
|
||||
albumCount: null | number;
|
||||
imageUrl: string | undefined;
|
||||
}>[];
|
||||
value: string[];
|
||||
}>) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
onToggle(options[index].value);
|
||||
}, [onToggle, options, index]);
|
||||
|
||||
const isFocused = focusedIndex === index;
|
||||
|
||||
return (
|
||||
<Group
|
||||
className={styles.row}
|
||||
gap="sm"
|
||||
onClick={handleClick}
|
||||
style={{ ...style }}
|
||||
{...(isFocused && { 'data-focused': true })}
|
||||
>
|
||||
<ItemImage
|
||||
containerClassName={styles.rowImage}
|
||||
itemType={LibraryItem.ARTIST}
|
||||
src={options[index].imageUrl}
|
||||
type="table"
|
||||
/>
|
||||
<div className={styles.rowContent}>
|
||||
<Text isNoSelect overflow="hidden" size="sm">
|
||||
{options[index].label}
|
||||
</Text>
|
||||
<Text isMuted overflow="hidden" size="xs">
|
||||
{options[index].albumCount ? (
|
||||
<>
|
||||
{options[index].albumCount}{' '}
|
||||
{t('entity.album', { count: options[index].albumCount })}
|
||||
</>
|
||||
) : (
|
||||
<> </>
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
export function GenreMultiSelectRow({
|
||||
focusedIndex,
|
||||
index,
|
||||
onToggle,
|
||||
options,
|
||||
style,
|
||||
}: RowComponentProps<{
|
||||
focusedIndex: null | number;
|
||||
onToggle: (value: string) => void;
|
||||
options: VirtualMultiSelectOption<{ albumCount: null | number }>[];
|
||||
value: string[];
|
||||
}>) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
onToggle(options[index].value);
|
||||
}, [onToggle, options, index]);
|
||||
|
||||
const isFocused = focusedIndex === index;
|
||||
|
||||
return (
|
||||
<Group
|
||||
className={styles.row}
|
||||
gap="sm"
|
||||
onClick={handleClick}
|
||||
style={{ ...style }}
|
||||
{...(isFocused && { 'data-focused': true })}
|
||||
>
|
||||
<div className={styles.rowContent}>
|
||||
<Text isNoSelect overflow="hidden" size="sm">
|
||||
{options[index].label}
|
||||
</Text>
|
||||
<Text isMuted overflow="hidden" size="xs">
|
||||
{options[index].albumCount ? (
|
||||
<>
|
||||
{options[index].albumCount}{' '}
|
||||
{t('entity.album', { count: options[index].albumCount })}
|
||||
</>
|
||||
) : (
|
||||
<> </>
|
||||
)}
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user