Files
Homarr/src/components/Settings/Customization/Theme/ShadeSelector.tsx

102 lines
2.7 KiB
TypeScript
Raw Normal View History

import {
ColorSwatch,
2022-12-06 21:22:37 +01:00
Grid,
Group,
2022-12-06 21:22:37 +01:00
MantineTheme,
Popover,
2022-12-06 21:22:37 +01:00
Stack,
Text,
useMantineTheme,
} from '@mantine/core';
2022-12-04 17:36:30 +01:00
import { useDisclosure } from '@mantine/hooks';
2022-12-06 21:22:37 +01:00
import { useTranslation } from 'next-i18next';
import { useState } from 'react';
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
import { useColorTheme } from '../../../../tools/color';
2022-12-04 17:36:30 +01:00
interface ShadeSelectorProps {
defaultValue: MantineTheme['primaryShade'] | undefined;
}
export function ShadeSelector({ defaultValue }: ShadeSelectorProps) {
2022-08-24 18:38:28 +02:00
const { t } = useTranslation('settings/customization/shade-selector');
2022-12-04 17:36:30 +01:00
const [shade, setShade] = useState(defaultValue);
const [popoverOpened, popover] = useDisclosure(false);
const { primaryColor, setPrimaryShade } = useColorTheme();
2022-12-04 17:36:30 +01:00
const { name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig);
const theme = useMantineTheme();
const primaryShades = theme.colors[primaryColor].map((s, i) => ({
swatch: theme.colors[primaryColor][i],
shade: i as MantineTheme['primaryShade'],
}));
2022-12-04 17:36:30 +01:00
if (shade === undefined || !configName) return null;
const handleSelection = (shade: MantineTheme['primaryShade']) => {
setPrimaryShade(shade);
2022-12-04 17:36:30 +01:00
setShade(shade);
updateConfig(configName, (prev) => ({
...prev,
settings: {
2022-12-04 17:36:30 +01:00
...prev.settings,
customization: {
...prev.settings.customization,
colors: {
...prev.settings.customization.colors,
shade,
},
},
},
2022-12-04 17:36:30 +01:00
}));
};
const primarySwatches = primaryShades.map(({ swatch, shade }) => (
<Grid.Col span={1} key={Number(shade)}>
<ColorSwatch
component="button"
type="button"
2022-12-04 17:36:30 +01:00
onClick={() => handleSelection(shade)}
color={swatch}
size={22}
style={{ cursor: 'pointer' }}
/>
</Grid.Col>
));
return (
<Group>
<Popover
width={350}
withinPortal
2022-12-04 17:36:30 +01:00
opened={popoverOpened}
onClose={popover.close}
position="left"
withArrow
>
<Popover.Target>
<ColorSwatch
component="button"
type="button"
2022-12-04 17:36:30 +01:00
color={theme.colors[primaryColor][Number(shade)]}
onClick={popover.toggle}
size={22}
style={{ display: 'block', cursor: 'pointer' }}
/>
</Popover.Target>
<Popover.Dropdown>
<Stack spacing="xs">
<Grid gutter="lg" columns={10}>
{primarySwatches}
</Grid>
</Stack>
</Popover.Dropdown>
</Popover>
2022-08-22 09:50:54 +02:00
<Text>{t('label')}</Text>
</Group>
);
}