Font support on themes
This commit is contained in:
@@ -24,6 +24,7 @@ import 'react-fontpicker-ts/dist/index.css';
|
||||
import '@gfazioli/mantine-text-animate/styles.css';
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import { Homepage, Settings } from 'pages';
|
||||
import FontPicker from 'react-fontpicker-ts';
|
||||
import type { Theme, ThemePlaylist } from 'types';
|
||||
|
||||
function App() {
|
||||
@@ -55,7 +56,7 @@ function App() {
|
||||
search: colorsTuple(theme.searchColor),
|
||||
},
|
||||
white: theme?.backgroundColor,
|
||||
fontFamily: `${personalData?.[0]?.defaultFont},Helvetica Neue,Roboto,system-ui,sans-serif`,
|
||||
fontFamily: `${theme?.themeFont || personalData?.[0]?.defaultFont},system-ui,sans-serif`,
|
||||
autoContrast: true,
|
||||
});
|
||||
const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides);
|
||||
@@ -139,6 +140,9 @@ function App() {
|
||||
<>
|
||||
{theme && (
|
||||
<MantineProvider theme={mantineTheme}>
|
||||
{theme.themeFont && (
|
||||
<FontPicker loaderOnly loadFonts={theme.themeFont} autoLoad />
|
||||
)}
|
||||
<Notifications />
|
||||
<Loading loaded={loaded} />
|
||||
<RouterProvider router={router} />
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
} from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { useCommonHooks } from 'hooks';
|
||||
import { useRef, useState } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import FontPicker from 'react-fontpicker-ts';
|
||||
import { FaShuffle } from 'react-icons/fa6';
|
||||
import { FiImage, FiSave, FiShuffle, FiX } from 'react-icons/fi';
|
||||
import {
|
||||
@@ -64,13 +65,27 @@ export function ThemeEditor({
|
||||
const viewportRef = useRef<HTMLDivElement>(null);
|
||||
const [colorId, setColorId] = useState<string>('');
|
||||
const [colorValue, setColorValue] = useState('#000000');
|
||||
|
||||
const [font, setFont] = useState<Theme['themeFont']>();
|
||||
const re = /(?:\.([^.]+))?$/;
|
||||
const [backgroundPicker, { open: openBackgroundPicker, close: closeBackgroundPicker }] =
|
||||
useDisclosure(false);
|
||||
const filtered = backgroundList.filter((item: string) =>
|
||||
item.toLowerCase().includes(query.toLowerCase()),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (font) {
|
||||
setSelectedTheme({
|
||||
...selectedTheme,
|
||||
themeFont: font,
|
||||
});
|
||||
} else {
|
||||
setSelectedTheme({
|
||||
...selectedTheme,
|
||||
themeFont: null,
|
||||
});
|
||||
}
|
||||
}, [font]);
|
||||
const items = filtered.map((item: string, index: number) => {
|
||||
return (
|
||||
<UnstyledButton
|
||||
@@ -516,6 +531,23 @@ export function ThemeEditor({
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Group w={'100%'} justify='center'>
|
||||
<FontPicker
|
||||
style={{ width: '75%' }}
|
||||
autoLoad
|
||||
defaultValue={
|
||||
selectedTheme.themeFont === null ? 'Jost' : selectedTheme.themeFont
|
||||
}
|
||||
value={(font: string) => setFont(font)}
|
||||
/>
|
||||
<ActionIcon
|
||||
onClick={() => {
|
||||
setFont(null);
|
||||
}}
|
||||
>
|
||||
<FiX />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
</Stack>
|
||||
{JSON.stringify(defaultTheme) !== JSON.stringify(selectedTheme) && (
|
||||
<>
|
||||
@@ -609,6 +641,16 @@ export function ThemeEditor({
|
||||
)}
|
||||
</Group>
|
||||
)}
|
||||
{key.includes('Font') && (
|
||||
<Group w={'100%'} justify='center'>
|
||||
<Text>
|
||||
{defaultTheme[key as keyof Theme] ||
|
||||
'Default (Jost)'}
|
||||
</Text>
|
||||
<Text>→</Text>
|
||||
<Text>{designerTheme[key as keyof Theme]}</Text>
|
||||
</Group>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -31,6 +31,7 @@ export function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
|
||||
'--mantine-color-border-0': selectedTheme?.borderColor,
|
||||
'--mantine-color-search-0': selectedTheme?.searchColor,
|
||||
transition: 'all 0.2s ease',
|
||||
fontFamily: selectedTheme.themeFont ?? undefined,
|
||||
}}
|
||||
align='center'
|
||||
gap={0}
|
||||
@@ -45,6 +46,7 @@ export function ThemeModalContent({ selectedTheme }: { selectedTheme: Theme }) {
|
||||
color: selectedTheme?.primaryColor,
|
||||
borderBottom: `thin solid ${selectedTheme?.borderColor}`,
|
||||
backgroundColor: `color-mix(in srgb, ${selectedTheme?.searchColor}, transparent 50%)`,
|
||||
fontFamily: selectedTheme.themeFont ?? undefined,
|
||||
},
|
||||
}}
|
||||
data={[
|
||||
|
||||
@@ -73,6 +73,7 @@ export function Themes() {
|
||||
randomEnabled: 1,
|
||||
textShadowsEnabled: 0,
|
||||
appShadowsEnabled: 0,
|
||||
themeFont: null,
|
||||
});
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -97,7 +98,6 @@ export function Themes() {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, [debouncedSearch]);
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<ThemeModal
|
||||
|
||||
@@ -10,6 +10,7 @@ export interface Theme {
|
||||
randomEnabled: number;
|
||||
textShadowsEnabled: number;
|
||||
appShadowsEnabled: number;
|
||||
themeFont?: string | null;
|
||||
}
|
||||
|
||||
export interface ThemePlaylist {
|
||||
|
||||
Reference in New Issue
Block a user