New Theme Builder UI

This commit is contained in:
Sean Edmunds
2025-06-27 16:07:29 -05:00
parent f7870d10b1
commit bfe80b5844
7 changed files with 479 additions and 313 deletions

54
package-lock.json generated
View File

@@ -13,16 +13,16 @@
"@mantine/form": "^8.1.2",
"@mantine/hooks": "^8.1.2",
"@mantine/notifications": "^8.1.2",
"@tanstack/react-query": "^5.81.2",
"@tanstack/react-query-devtools": "^5.81.2",
"@tanstack/react-query-persist-client": "^5.81.2",
"@tanstack/react-query": "^5.81.4",
"@tanstack/react-query-devtools": "^5.81.4",
"@tanstack/react-query-persist-client": "^5.81.4",
"idb-keyval": "^6.2.2",
"jotai": "^2.12.5",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-router-dom": "^7.6.2",
"recharts": "^3.0.1"
"recharts": "^3.0.2"
},
"devDependencies": {
"@types/node": "^24.0.4",
@@ -1630,9 +1630,9 @@
"license": "MIT"
},
"node_modules/@tanstack/query-core": {
"version": "5.81.2",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.81.2.tgz",
"integrity": "sha512-QLYkPdrudoMATDFa3MiLEwRhNnAlzHWDf0LKaXUqJd0/+QxN8uTPi7bahRlxoAyH0UbLMBdeDbYzWALj7THOtw==",
"version": "5.81.4",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.81.4.tgz",
"integrity": "sha512-z0yBgRFTPIEYcjFFiahOwtEU3kEKpF5Rwls7UjBCsRghmhwIXyxd5U2p0yEmUfcwm85W4XZkt4dc1OWc5my3Yw==",
"license": "MIT",
"funding": {
"type": "github",
@@ -1650,12 +1650,12 @@
}
},
"node_modules/@tanstack/query-persist-client-core": {
"version": "5.81.2",
"resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.81.2.tgz",
"integrity": "sha512-FSLHr3DL+eezaKNiAexM7+KdgpXvLmUuMQhtORPIC7QuhemM6kfzcrQC5AN34zhvVh2PZXRcib2JnHKeTMjyyg==",
"version": "5.81.4",
"resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.81.4.tgz",
"integrity": "sha512-8SlCCzIPBYCOfWRPUGkzJAdPMu+7JT42J51n6rWvaLVj20mzrVX2EKTtm7QoP19LdX+prS8ndCMClrILQi7nUA==",
"license": "MIT",
"dependencies": {
"@tanstack/query-core": "5.81.2"
"@tanstack/query-core": "5.81.4"
},
"funding": {
"type": "github",
@@ -1663,12 +1663,12 @@
}
},
"node_modules/@tanstack/react-query": {
"version": "5.81.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.81.2.tgz",
"integrity": "sha512-pe8kFlTrL2zFLlcAj2kZk9UaYYHDk9/1hg9EBaoO3cxDhOZf1FRGJeziSXKrVZyxIfs7b3aoOj/bw7Lie0mDUg==",
"version": "5.81.4",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.81.4.tgz",
"integrity": "sha512-bBrf5kTNr9t5BnskvyHQGwe2LRZsgnmx1sClyRQbAHxhSJfnT6z9h27IfGpY6JtfEH5y5R9jJegTG/93zyox/A==",
"license": "MIT",
"dependencies": {
"@tanstack/query-core": "5.81.2"
"@tanstack/query-core": "5.81.4"
},
"funding": {
"type": "github",
@@ -1679,9 +1679,9 @@
}
},
"node_modules/@tanstack/react-query-devtools": {
"version": "5.81.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.81.2.tgz",
"integrity": "sha512-TX0OQ4cbgX6z2uN8c9x0QUNbyePGyUGdcgrGnV6TYEJc7KPT8PqeASuzoA5NGw1CiMGvyFAkIGA2KipvhM9d1g==",
"version": "5.81.4",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.81.4.tgz",
"integrity": "sha512-zFg7rzOmM9Q+Ym/TujWR4HD+jKwQd+N8WuWZRmHU8sjI2flyxWTWIEQvl9BFt+HiNA6leS3ODZ9SHYmEb3zduw==",
"license": "MIT",
"dependencies": {
"@tanstack/query-devtools": "5.81.2"
@@ -1691,24 +1691,24 @@
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"@tanstack/react-query": "^5.81.2",
"@tanstack/react-query": "^5.81.4",
"react": "^18 || ^19"
}
},
"node_modules/@tanstack/react-query-persist-client": {
"version": "5.81.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.81.2.tgz",
"integrity": "sha512-HUlnB7FGqN/he4AOvR0vNA06Wn4dg3rEK7EgzenWfc0gQ9Aa6thqTWgT3Q27CnKiTkzhRn2uZJKRseTP4g54LQ==",
"version": "5.81.4",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.81.4.tgz",
"integrity": "sha512-8SlkNDZmWUZLKYYm6DvYybJYrZngnERx/7W1KLUQ3IPaANM9tfmtQjBQBhr1dagyebNK1h/c69IY24dfUaNVIA==",
"license": "MIT",
"dependencies": {
"@tanstack/query-persist-client-core": "5.81.2"
"@tanstack/query-persist-client-core": "5.81.4"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"@tanstack/react-query": "^5.81.2",
"@tanstack/react-query": "^5.81.4",
"react": "^18 || ^19"
}
},
@@ -3785,9 +3785,9 @@
}
},
"node_modules/recharts": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/recharts/-/recharts-3.0.1.tgz",
"integrity": "sha512-T5PZzeqzkdQpwdd/wG/hzuhaKAFTNY/PsezVlhdg4GbME4mfcau3DEYP4VCejEsUVOpX6hQTN6FJE4z9zL0RWA==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/recharts/-/recharts-3.0.2.tgz",
"integrity": "sha512-eDc3ile9qJU9Dp/EekSthQPhAVPG48/uM47jk+PF7VBQngxeW3cwQpPHb/GHC1uqwyCRWXcIrDzuHRVrnRryoQ==",
"license": "MIT",
"dependencies": {
"@reduxjs/toolkit": "1.x.x || 2.x.x",

View File

@@ -15,16 +15,16 @@
"@mantine/form": "^8.1.2",
"@mantine/hooks": "^8.1.2",
"@mantine/notifications": "^8.1.2",
"@tanstack/react-query": "^5.81.2",
"@tanstack/react-query-devtools": "^5.81.2",
"@tanstack/react-query-persist-client": "^5.81.2",
"@tanstack/react-query": "^5.81.4",
"@tanstack/react-query-devtools": "^5.81.4",
"@tanstack/react-query-persist-client": "^5.81.4",
"idb-keyval": "^6.2.2",
"jotai": "^2.12.5",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-icons": "^5.5.0",
"react-router-dom": "^7.6.2",
"recharts": "^3.0.1"
"recharts": "^3.0.2"
},
"devDependencies": {
"@types/node": "^24.0.4",

View File

@@ -22,7 +22,7 @@ function ExampleApp({ selectedTheme }: { selectedTheme: Theme }) {
paddingTop: '1rem',
}}
>
<FiCheck style={{ color: selectedTheme.primaryColor }} height={32} width={32} />
<FiCheck style={{ color: selectedTheme?.primaryColor }} height={32} width={32} />
</Stack>
<Stack
style={{
@@ -39,7 +39,7 @@ function ExampleApp({ selectedTheme }: { selectedTheme: Theme }) {
fontWeight: 400,
fontSize: '.625rem',
fontStyle: 'normal',
color: selectedTheme.primaryColor,
color: selectedTheme?.primaryColor,
fontFamily:
'-apple-system, Jost, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif !important',
margin: 0,
@@ -52,7 +52,7 @@ function ExampleApp({ selectedTheme }: { selectedTheme: Theme }) {
fontWeight: 400,
fontSize: '.625rem',
fontStyle: 'italic',
color: selectedTheme.accentColor,
color: selectedTheme?.accentColor,
fontFamily:
'-apple-system, Jost, BlinkMacSystemFont, Helvetica Neue, Roboto, sans-serif !important',
margin: 0,

View File

@@ -1,20 +1,23 @@
import {
ActionIcon,
Button,
ColorPicker,
ColorSwatch,
Group,
Modal,
ScrollArea,
Stack,
Text,
TextInput,
Tooltip,
UnstyledButton,
} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { useCommonHooks } from 'hooks';
import { useEffect, useRef, useState } from 'react';
import { FiSave, FiX } from 'react-icons/fi';
import { modalClasses, scrollAreaClasses, textInputClasses } from 'styles';
import { FiImage, FiSave, FiX } from 'react-icons/fi';
import { modalClasses, scrollAreaClasses, textClasses, textInputClasses } from 'styles';
import type { Theme } from 'types';
import ThemeModalColorSwatches from './ThemeModalColorSwatches';
import ThemeModalContent from './ThemeModalContent';
function ThemeModal({
@@ -22,10 +25,6 @@ function ThemeModal({
handleClose,
selectedTheme,
setSelectedTheme,
colorId,
setColorId,
colorValue,
setColorValue,
openPicker,
backgroundList,
pickerOpen,
@@ -36,10 +35,6 @@ function ThemeModal({
handleClose: () => void;
selectedTheme: Theme;
setSelectedTheme: (selectedTheme: Theme) => void;
colorId: string;
setColorId: (colorId: string) => void;
colorValue: string;
setColorValue: (colorValue: string) => void;
openPicker: () => void;
backgroundList: string[];
pickerOpen: boolean;
@@ -50,10 +45,18 @@ function ThemeModal({
const viewportRef = useRef<HTMLDivElement>(null);
const [query, setQuery] = useState('');
const [hovered, setHovered] = useState(-1);
const [colorId, setColorId] = useState<string>('');
const [colorValue, setColorValue] = useState('#000000');
const [designerTheme, setDesignerTheme] = useState<Theme>({
...selectedTheme,
});
const filtered = backgroundList.filter((item: string) =>
item.toLowerCase().includes(query.toLowerCase()),
);
const [backgroundPicker, { open: openBackgroundPicker, close: closeBackgroundPicker }] =
useDisclosure(false);
const re = /(?:\.([^.]+))?$/;
const items = filtered.map((item: string, index: number) => {
return (
@@ -75,8 +78,8 @@ function ThemeModal({
alignItems: 'center',
}}
onClick={() =>
setSelectedTheme({
...selectedTheme,
setDesignerTheme({
...designerTheme,
backgroundImage: item,
})
}
@@ -116,18 +119,11 @@ function ThemeModal({
});
useEffect(() => {
if (selectedTheme) {
if (selectedTheme?.backgroundImage === 'none') {
setQuery('');
} else {
setQuery(selectedTheme?.backgroundImage || '');
}
}
setDesignerTheme(selectedTheme);
}, [selectedTheme]);
return (
<Modal.Root
size={'50%'}
size={'75%'}
className={modalClasses.editThemeModal}
classNames={modalClasses}
opened={opened}
@@ -152,7 +148,8 @@ function ThemeModal({
color: 'var(--mantine-color-primary-0)',
},
input: {
color: 'var(--mantine-color-primary-0)',
color: selectedTheme.primaryColor,
backgroundColor: selectedTheme.backgroundColor,
border: 'none',
borderBottom: '1px solid var(--mantine-color-primary-0)',
},
@@ -161,32 +158,158 @@ function ThemeModal({
</Group>
<Modal.CloseButton />
</Modal.Header>
<Modal.Body p={'2rem'}>
<ThemeModalContent selectedTheme={selectedTheme} />
<Group
w={'100%'}
h={'100%'}
gap={isMobile ? 20 : 0}
style={{ flexDirection: isMobile ? 'column' : 'row' }}
>
<Stack w={isMobile ? '100%' : '50%'}>
{pickerOpen ? (
<Group justify='center'>
<Modal.Body>
<Group p={'2rem'} w={'100%'} align='flex-start' justify='space-between'>
<Stack display={'flex'} pos={'relative'} w={'70%'}>
<ThemeModalContent selectedTheme={designerTheme} />
<Tooltip
label={'Change Primary Color'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
>
<ColorSwatch
onClick={() => {
closeBackgroundPicker();
setColorId('primaryColor');
openPicker();
setColorValue(selectedTheme.primaryColor);
}}
color={selectedTheme.primaryColor}
bd={`1px solid ${selectedTheme.primaryColor}`}
pos={'absolute'}
top={'6.25rem'}
left={'1.5rem'}
/>
</Tooltip>
<Tooltip
label={'Change Accent Color'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
>
<ColorSwatch
onClick={() => {
closeBackgroundPicker();
setColorId('accentColor');
openPicker();
setColorValue(selectedTheme.accentColor);
}}
color={selectedTheme.accentColor}
bd={`1px solid ${selectedTheme.primaryColor}`}
pos={'absolute'}
bottom={'6rem'}
left={'11rem'}
/>
</Tooltip>
<Tooltip
label={'Change Background Color'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
>
<ColorSwatch
onClick={() => {
closeBackgroundPicker();
setColorId('backgroundColor');
openPicker();
setColorValue(selectedTheme.backgroundColor);
}}
color={selectedTheme.backgroundColor}
bd={`1px solid ${selectedTheme.primaryColor}`}
pos={'absolute'}
bottom={'10rem'}
right={'3.5rem'}
/>
</Tooltip>
<Tooltip
label={'Change Border Color'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
>
<ColorSwatch
onClick={() => {
closeBackgroundPicker();
setColorId('borderColor');
openPicker();
setColorValue(selectedTheme.borderColor);
}}
color={selectedTheme.borderColor}
bd={`1px solid ${selectedTheme.primaryColor}`}
pos={'absolute'}
top={'4.5rem'}
right={'7rem'}
/>
</Tooltip>
<Tooltip
label={'Change Search Color'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
>
<ColorSwatch
onClick={() => {
closeBackgroundPicker();
setColorId('searchBackground');
openPicker();
setColorValue(selectedTheme.searchColor);
}}
color={selectedTheme.searchColor}
bd={`1px solid ${selectedTheme.primaryColor}`}
pos={'absolute'}
top={'3.25rem'}
left={'14.5rem'}
/>
</Tooltip>
<Tooltip
label={'Change Background'}
c={'var(--mantine-color-primary-0)'}
bg={'var(--mantine-color-background-0)'}
>
<ActionIcon
onClick={() => {
closePicker();
openBackgroundPicker();
}}
pos={'absolute'}
right={0}
>
<FiImage size={20} />
</ActionIcon>
</Tooltip>
</Stack>
<Stack
w={'28%'}
h={'436px'}
p={'1rem'}
style={{
borderRadius: '1rem',
backgroundColor:
'color-mix(in srgb, var(--mantine-color-primary-0) 20%, transparent)',
}}
>
{pickerOpen && (
<Stack h={'100%'} align='center' justify='space-between'>
<Text className={textClasses.sectionTitle} classNames={textClasses}>
Change {colorId}
</Text>
<ColorPicker
value={colorValue}
onChange={setColorValue}
format={colorId === 'background' ? 'hex' : 'hexa'}
onChange={(e) => {
setColorValue(e);
setDesignerTheme({
...designerTheme,
[colorId]: e,
});
}}
format={colorId === 'backgroundColor' ? 'hex' : 'hexa'}
w={'90%'}
mb={colorId === 'background' ? '1.5rem' : undefined}
mb={colorId === 'backgroundColor' ? '1.5rem' : undefined}
/>
<Group justify='center'>
<TextInput
className={textInputClasses.default}
classNames={textInputClasses}
w={'55%'}
value={colorValue}
onChange={(e) => setColorValue(e.target.value)}
/>
<TextInput
className={textInputClasses.default}
classNames={textInputClasses}
w={'90%'}
value={colorValue}
onChange={(e) => setColorValue(e.target.value)}
/>
<Group mt={'auto'} justify='center'>
<Button
color={'green'}
onClick={() => {
@@ -203,7 +326,7 @@ function ThemeModal({
accentColor: colorValue,
});
break;
case 'background':
case 'backgroundColor':
setSelectedTheme({
...selectedTheme,
backgroundColor: colorValue,
@@ -230,89 +353,112 @@ function ThemeModal({
<Button
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={closePicker}
onClick={() => {
closePicker();
setDesignerTheme({
...designerTheme,
[colorId]: selectedTheme[colorId as keyof Theme],
});
}}
>
<FiX />
</Button>
<Group w={'100%'} align='center' justify='center' />
</Group>
</Group>
) : (
<ThemeModalColorSwatches
selectedTheme={selectedTheme}
openPicker={openPicker}
setColorId={setColorId}
setColorValue={setColorValue}
/>
</Stack>
)}
</Stack>
<Stack
h={'100%'}
w={isMobile ? '100%' : '50%'}
align='center'
justify='center'
>
<Group gap={0}>
<Text mr={'.5rem'}>Search:</Text>
<TextInput
className={textInputClasses.default}
classNames={textInputClasses}
value={query.replace(/\.[^/.]+$/, '')}
rightSection={
<FiX
style={{
cursor: 'pointer',
margin: '.25rem',
{backgroundPicker && (
<Stack h={'100%'} align='center' justify='center'>
<Group gap={0}>
<TextInput
className={textInputClasses.default}
classNames={textInputClasses}
placeholder='Search'
value={query.replace(/\.[^/.]+$/, '')}
rightSection={
<FiX
style={{
cursor: 'pointer',
margin: '.25rem',
}}
onClick={() => {
setQuery('');
}}
/>
}
onChange={(event) => {
setQuery(event.currentTarget.value);
setHovered(-1);
}}
onClick={() => {
setQuery('');
onKeyDown={(event) => {
if (event.key === 'ArrowDown') {
event.preventDefault();
setHovered((current) => {
const nextIndex =
current + 1 >= filtered.length ? current : current + 1;
viewportRef.current
?.querySelectorAll('[data-list-item]')
?.[nextIndex]?.scrollIntoView({ block: 'nearest' });
return nextIndex;
});
}
if (event.key === 'ArrowUp') {
event.preventDefault();
setHovered((current) => {
const nextIndex = current - 1 < 0 ? current : current - 1;
viewportRef.current
?.querySelectorAll('[data-list-item]')
?.[nextIndex]?.scrollIntoView({ block: 'nearest' });
return nextIndex;
});
}
}}
/>
}
onChange={(event) => {
setQuery(event.currentTarget.value);
setHovered(-1);
}}
onKeyDown={(event) => {
if (event.key === 'ArrowDown') {
event.preventDefault();
setHovered((current) => {
const nextIndex =
current + 1 >= filtered.length ? current : current + 1;
viewportRef.current
?.querySelectorAll('[data-list-item]')
?.[nextIndex]?.scrollIntoView({ block: 'nearest' });
return nextIndex;
});
}
if (event.key === 'ArrowUp') {
event.preventDefault();
setHovered((current) => {
const nextIndex = current - 1 < 0 ? current : current - 1;
viewportRef.current
?.querySelectorAll('[data-list-item]')
?.[nextIndex]?.scrollIntoView({ block: 'nearest' });
return nextIndex;
});
}
}}
/>
</Group>
<ScrollArea.Autosize
viewportRef={viewportRef}
className={scrollAreaClasses.default}
classNames={scrollAreaClasses}
style={{
height: 150,
width: '90%',
borderRadius: 8,
}}
>
<Stack gap={0} align='center' display={'block'}>
{items}
</Group>
<ScrollArea.Autosize
viewportRef={viewportRef}
className={scrollAreaClasses.default}
classNames={scrollAreaClasses}
style={{
height: 325,
width: '90%',
borderRadius: 8,
}}
>
<Stack gap={0} align='center' display={'block'}>
{items}
</Stack>
</ScrollArea.Autosize>
<Group justify='center'>
<Button
color={'green'}
onClick={() => {
setSelectedTheme({
...selectedTheme,
backgroundImage: designerTheme.backgroundImage,
});
closeBackgroundPicker();
}}
>
<FiSave />
</Button>
<Button
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={() => {
closeBackgroundPicker();
setDesignerTheme({
...designerTheme,
backgroundImage: selectedTheme.backgroundImage,
});
}}
>
<FiX />
</Button>
</Group>
</Stack>
</ScrollArea.Autosize>
)}
{!pickerOpen && !backgroundPicker && <Stack />}
</Stack>
</Group>
<Group>
@@ -322,7 +468,10 @@ function ThemeModal({
<Button
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={handleClose}
onClick={() => {
closeBackgroundPicker();
handleClose();
}}
>
Cancel
</Button>

View File

@@ -1,5 +1,4 @@
import { ColorSwatch, Group, Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { colorSwatchClasses, textClasses } from 'styles';
import type { Theme } from 'types';
@@ -14,9 +13,8 @@ function ThemeModalColorSwatches({
setColorId: (colorId: string) => void;
setColorValue: (colorValue: string) => void;
}) {
const { isMobile } = useCommonHooks();
return (
<Stack h={isMobile ? '100%' : 256} justify='center'>
<Stack justify='center'>
<Group justify='space-between'>
<Text className={textClasses.label} classNames={textClasses}>
Primary Color

View File

@@ -1,4 +1,6 @@
import { Group, Stack, Text } from '@mantine/core';
import { Select, Stack, Text } from '@mantine/core';
import SearchSelectItem from 'pages/homepage/components/Search/SearchSelectItem';
import { selectClasses } from 'styles';
import type { Theme } from 'types';
import ThemeExampleApp from './ThemeExampleApp';
@@ -6,7 +8,6 @@ export default function ThemeModalContent({ selectedTheme }: { selectedTheme: Th
return (
<Stack
style={{
width: '100%',
backgroundImage:
selectedTheme?.backgroundImage.toLocaleLowerCase() !== 'none'
? `linear-gradient(${selectedTheme?.backgroundColor}33, ${selectedTheme?.backgroundColor}33), url(../../api/backgroundImages/${selectedTheme?.backgroundImage})`
@@ -22,173 +23,197 @@ export default function ThemeModalContent({ selectedTheme }: { selectedTheme: Th
backgroundPosition: 'center',
borderRadius: '10px',
border: '2px solid var(--mantine-color-primary-0)',
padding: '1rem',
}}
align='center'
>
<Group
justify='center'
style={{
color: selectedTheme.primaryColor,
paddingTop: '1rem',
<Select
disabled
w={'80%'}
classNames={selectClasses}
data={[
{
label: 'Google Search',
value: 'google',
},
]}
searchValue={'example search'}
data-active={true}
dropdownOpened={true}
autoFocus={false}
leftSection={'Google Search'}
rightSection={<div />}
renderOption={(item: any) => {
return (
<SearchSelectItem
item={item}
handleSearchHistoryItem={undefined}
searchEndpoint={undefined}
/>
);
}}
>
{selectedTheme.name}
</Group>
<Text
pl={'1.5rem'}
style={{
textDecoration: 'underline',
fontSize: '1.25rem',
fontWeight: 200,
fontStyle: 'italic',
height: '10px',
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
color: selectedTheme.primaryColor,
}}
>
Applications
</Text>
<Stack
style={{
gap: '.25rem',
backgroundSize: 'cover',
borderBottom: '0px solid',
display: 'grid',
gridColumnGap: '5px',
gridRowGap: '5px',
gridTemplateColumns: '1fr 1fr 1fr',
gridTemplateRows: '64px',
padding: '1rem',
paddingTop: 0,
justifyContent: 'center',
alignContent: 'center',
}}
>
<ThemeExampleApp selectedTheme={selectedTheme} />
<ThemeExampleApp selectedTheme={selectedTheme} />
<ThemeExampleApp selectedTheme={selectedTheme} />
</Stack>
<Text
pl={'1.5rem'}
style={{
textDecoration: 'underline',
fontSize: '1.25rem',
fontWeight: 200,
fontStyle: 'italic',
height: '10px',
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
color: selectedTheme.primaryColor,
}}
>
Bookmarks
</Text>
<Stack
style={{
display: 'flex',
flexDirection: 'row',
flexWrap: 'nowrap',
gridColumnGap: '20px',
gridRowGap: '0px',
gridTemplateColumns: '1fr 1fr 1fr 1fr 1fr',
gridTemplateRows: 'auto',
}}
>
<Stack
/>
<Stack gap={0} w={'100%'}>
<Text
pl={'1.5rem'}
style={{
width: '100%',
marginBottom: 0,
display: 'block',
lineHeight: '1.5rem',
padding: '1rem',
paddingTop: 0,
textDecoration: 'underline',
fontSize: '1.25rem',
fontWeight: 200,
fontStyle: 'italic',
height: '10px',
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
color: selectedTheme?.primaryColor,
}}
>
<Text
style={{
fontSize: '.875rem',
fontWeight: 400,
height: '10px',
width: 'auto',
color: selectedTheme.accentColor,
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
}}
>
Example Category
</Text>
<Text
style={{
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme.primaryColor,
}}
component='a'
>
{'Bookmark 1'}
</Text>
<Text
style={{
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme.primaryColor,
}}
component='a'
>
{'Bookmark 2'}
</Text>
Applications
</Text>
<Stack
style={{
gap: '.25rem',
backgroundSize: 'cover',
borderBottom: '0px solid',
display: 'grid',
gridColumnGap: '5px',
gridRowGap: '5px',
gridTemplateColumns: '1fr 1fr 1fr',
gridTemplateRows: '64px',
padding: '1rem',
paddingTop: 0,
justifyContent: 'center',
alignContent: 'center',
}}
>
<ThemeExampleApp selectedTheme={selectedTheme} />
<ThemeExampleApp selectedTheme={selectedTheme} />
<ThemeExampleApp selectedTheme={selectedTheme} />
</Stack>
</Stack>
<Stack gap={0} w={'100%'}>
<Text
pl={'1.5rem'}
style={{
textDecoration: 'underline',
fontSize: '1.25rem',
fontWeight: 200,
fontStyle: 'italic',
height: '10px',
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
color: selectedTheme?.primaryColor,
}}
>
Bookmarks
</Text>
<Stack
style={{
width: '100%',
marginBottom: 0,
display: 'block',
lineHeight: '1.5rem',
padding: '1rem',
paddingTop: 0,
display: 'flex',
flexDirection: 'row',
flexWrap: 'nowrap',
gridColumnGap: '20px',
gridRowGap: '0px',
gridTemplateColumns: '1fr 1fr 1fr 1fr 1fr',
gridTemplateRows: 'auto',
}}
>
<Text
style={{
fontSize: '.875rem',
fontWeight: 400,
height: '10px',
width: 'auto',
color: selectedTheme.accentColor,
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
}}
>
Example Category
</Text>
<Text
<Stack
style={{
width: '100%',
marginBottom: 0,
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme.primaryColor,
lineHeight: '1.5rem',
padding: '1rem',
paddingTop: 0,
}}
component='a'
>
{'Bookmark 1'}
</Text>
<Text
<Text
style={{
fontSize: '.875rem',
fontWeight: 400,
height: '10px',
width: 'auto',
color: selectedTheme?.accentColor,
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
}}
>
Example Category
</Text>
<Text
style={{
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme?.primaryColor,
}}
component='a'
>
{'Bookmark 1'}
</Text>
<Text
style={{
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme?.primaryColor,
}}
component='a'
>
{'Bookmark 2'}
</Text>
</Stack>
<Stack
style={{
width: '100%',
marginBottom: 0,
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme.primaryColor,
lineHeight: '1.5rem',
padding: '1rem',
paddingTop: 0,
}}
component='a'
>
{'Bookmark 2'}
</Text>
<Text
style={{
fontSize: '.875rem',
fontWeight: 400,
height: '10px',
width: 'auto',
color: selectedTheme?.accentColor,
textTransform: 'uppercase',
marginTop: '1.25rem',
marginBottom: '1.25rem',
}}
>
Example Category
</Text>
<Text
style={{
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme?.primaryColor,
}}
component='a'
>
{'Bookmark 1'}
</Text>
<Text
style={{
display: 'block',
fontSize: '.875rem',
lineHeight: 2,
color: selectedTheme?.primaryColor,
}}
component='a'
>
{'Bookmark 2'}
</Text>
</Stack>
</Stack>
</Stack>
</Stack>

View File

@@ -34,8 +34,6 @@ function ThemesSettings() {
backgroundModalOpened,
{ open: openBackgroundModal, close: closeBackgroundModal },
] = useDisclosure(false);
const [colorId, setColorId] = useState<string>('');
const [colorValue, setColorValue] = useState('#000000');
const [backgroundList, setBackgroundList] = useState<string[]>(['None']);
const [inUseBackgrounds, setInUseBackgrounds] = useState<string[]>([]);
const [selectedTheme, setSelectedTheme] = useState<Theme>({
@@ -144,13 +142,9 @@ function ThemesSettings() {
handleClose={handleClose}
selectedTheme={selectedTheme}
setSelectedTheme={setSelectedTheme}
setColorId={setColorId}
colorId={colorId}
setColorValue={setColorValue}
openPicker={openPicker}
backgroundList={backgroundList}
pickerOpen={pickerOpen}
colorValue={colorValue}
closePicker={closePicker}
handleSaveTheme={handleSaveTheme}
/>