165 lines
3.8 KiB
TypeScript
165 lines
3.8 KiB
TypeScript
import {
|
|
type ComboboxItem,
|
|
Group,
|
|
MultiSelect,
|
|
Select,
|
|
Slider,
|
|
Stack,
|
|
Text,
|
|
} from '@mantine/core';
|
|
import { useCommonHooks } from 'hooks';
|
|
import { multiSelectClasses, selectClasses, sliderClasses, stackClasses } from 'styles';
|
|
|
|
function SettingsCard({
|
|
categories,
|
|
sectionTitle,
|
|
filter,
|
|
setFilter,
|
|
sort,
|
|
setSort,
|
|
density,
|
|
setDensity,
|
|
scale,
|
|
setScale,
|
|
}: {
|
|
categories: ComboboxItem[];
|
|
sectionTitle: string;
|
|
filter: any;
|
|
setFilter: any;
|
|
sort: any;
|
|
setSort: any;
|
|
density: any;
|
|
setDensity: any;
|
|
scale: any;
|
|
setScale: any;
|
|
}) {
|
|
const { theme } = useCommonHooks();
|
|
return (
|
|
<Stack
|
|
gap={0}
|
|
justify='space-between'
|
|
className={stackClasses.menuStack}
|
|
classNames={stackClasses}
|
|
pos={'relative'}
|
|
>
|
|
<Text
|
|
style={{
|
|
fontSize: '.75rem',
|
|
paddingLeft: '.5rem',
|
|
paddingRight: '.5rem',
|
|
paddingTop: '.125rem',
|
|
paddingBottom: '.125rem',
|
|
borderRadius: 8,
|
|
position: 'absolute',
|
|
left: -12,
|
|
top: -8,
|
|
backgroundColor: 'var(--mantine-color-primary-0)',
|
|
color: 'var(--mantine-color-background-0)',
|
|
boxShadow: '2px -2px var(--mantine-color-border-0)',
|
|
}}
|
|
>
|
|
{sectionTitle}
|
|
</Text>
|
|
<Group w={'100%'} justify='center'>
|
|
<Stack w={scale !== undefined ? '60%' : '90%'} align='center'>
|
|
<Text fz={'.875rem'} mt={'1rem'}>
|
|
Density
|
|
</Text>
|
|
<Slider
|
|
className={sliderClasses.default}
|
|
classNames={sliderClasses}
|
|
value={density}
|
|
onChange={(value) => setDensity(value)}
|
|
min={1}
|
|
max={16}
|
|
marks={[{ value: 6, label: 'Default' }]}
|
|
onDoubleClick={() => setDensity(6)}
|
|
/>
|
|
</Stack>
|
|
{scale !== undefined && (
|
|
<Stack w={'33%'} align='center'>
|
|
<Text fz={'.875rem'} mt={'1rem'}>
|
|
Scale
|
|
</Text>
|
|
<Slider
|
|
className={sliderClasses.default}
|
|
classNames={sliderClasses}
|
|
value={scale}
|
|
onChange={(value) => setScale(value)}
|
|
step={0.1}
|
|
min={0.2}
|
|
max={3}
|
|
marks={[{ value: 1, label: 'Default' }]}
|
|
onDoubleClick={() => setScale(1)}
|
|
/>
|
|
</Stack>
|
|
)}
|
|
</Group>
|
|
<Group justify='center' mb={'.25rem'} pos={'relative'}>
|
|
<MultiSelect
|
|
label='Filter'
|
|
data={
|
|
categories.toSorted((a: ComboboxItem, b: ComboboxItem) =>
|
|
a.label.localeCompare(b.label),
|
|
) ?? []
|
|
}
|
|
placeholder={
|
|
filter.length > 0
|
|
? filter.length === 1
|
|
? filter[0]
|
|
: `${filter.length} ${sectionTitle.toLocaleLowerCase()} selected`
|
|
: `No ${sectionTitle.toLocaleLowerCase()} selected`
|
|
}
|
|
defaultValue={filter}
|
|
onChange={(data: string[]) => {
|
|
setFilter(data);
|
|
}}
|
|
classNames={multiSelectClasses}
|
|
comboboxProps={{
|
|
withinPortal: false,
|
|
position: 'top',
|
|
}}
|
|
styles={
|
|
theme.textShadowsEnabled
|
|
? {
|
|
label: { boxShadow: '2px 2px var(--mantine-color-border-0)' },
|
|
}
|
|
: undefined
|
|
}
|
|
/>
|
|
<Select
|
|
label={'Sorting'}
|
|
placeholder={`Sort ${sectionTitle}...`}
|
|
value={sort}
|
|
data={['Custom', 'A>Z', 'Z>A', 'Newest', 'Oldest']}
|
|
classNames={{
|
|
wrapper: selectClasses.menuSelectWrapper,
|
|
root: selectClasses.menuSelectRoot,
|
|
input: selectClasses.menuSelectInput,
|
|
label: selectClasses.menuSelectLabel,
|
|
options: selectClasses.menuSelectOptions,
|
|
option: selectClasses.menuSelectOption,
|
|
}}
|
|
comboboxProps={{
|
|
withinPortal: false,
|
|
position: 'top',
|
|
}}
|
|
onChange={(_value, option: ComboboxItem) => {
|
|
setSort(option.value);
|
|
}}
|
|
labelProps={{ top: 8 }}
|
|
styles={
|
|
theme.textShadowsEnabled
|
|
? {
|
|
label: { boxShadow: '2px 2px var(--mantine-color-border-0)' },
|
|
}
|
|
: undefined
|
|
}
|
|
/>
|
|
</Group>
|
|
</Stack>
|
|
);
|
|
}
|
|
|
|
export default SettingsCard;
|