Bug fixes and style updates to theme builder

This commit is contained in:
Sean Edmunds
2026-02-04 14:25:53 -06:00
parent 471ae99333
commit aa9fdd5be0
7 changed files with 485 additions and 296 deletions

16
package-lock.json generated
View File

@@ -20,7 +20,7 @@
"@tanstack/react-query-persist-client": "^5.90.22", "@tanstack/react-query-persist-client": "^5.90.22",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"idb-keyval": "^6.2.2", "idb-keyval": "^6.2.2",
"jotai": "^2.17.0", "jotai": "^2.17.1",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"react-fontpicker-ts": "^1.3.0", "react-fontpicker-ts": "^1.3.0",
@@ -30,7 +30,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^25.2.0", "@types/node": "^25.2.0",
"@types/react": "^19.2.10", "@types/react": "^19.2.11",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.3", "@vitejs/plugin-react": "^5.1.3",
"@vitest/coverage-v8": "^4.0.18", "@vitest/coverage-v8": "^4.0.18",
@@ -1846,9 +1846,9 @@
} }
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.2.10", "version": "19.2.11",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.10.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.11.tgz",
"integrity": "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==", "integrity": "sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==",
"devOptional": true, "devOptional": true,
"dependencies": { "dependencies": {
"csstype": "^3.2.2" "csstype": "^3.2.2"
@@ -2936,9 +2936,9 @@
"dev": true "dev": true
}, },
"node_modules/jotai": { "node_modules/jotai": {
"version": "2.17.0", "version": "2.17.1",
"resolved": "https://registry.npmjs.org/jotai/-/jotai-2.17.0.tgz", "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.17.1.tgz",
"integrity": "sha512-DBPT7Vx7E7R/ZJL7Uq7yUA9+LLR0IRiRM+Bw5ugVwv8L8++RjlXVXZ2//ccucypc5lcyuHOW09rYcW77RurduQ==", "integrity": "sha512-TFNZZDa/0ewCLQyRC/Sq9crtixNj/Xdf/wmj9631xxMuKToVJZDbqcHIYN0OboH+7kh6P6tpIK7uKWClj86PKw==",
"engines": { "engines": {
"node": ">=12.20.0" "node": ">=12.20.0"
}, },

View File

@@ -22,7 +22,7 @@
"@tanstack/react-query-persist-client": "^5.90.22", "@tanstack/react-query-persist-client": "^5.90.22",
"@tanstack/react-table": "^8.21.3", "@tanstack/react-table": "^8.21.3",
"idb-keyval": "^6.2.2", "idb-keyval": "^6.2.2",
"jotai": "^2.17.0", "jotai": "^2.17.1",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"react-fontpicker-ts": "^1.3.0", "react-fontpicker-ts": "^1.3.0",
@@ -32,7 +32,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^25.2.0", "@types/node": "^25.2.0",
"@types/react": "^19.2.10", "@types/react": "^19.2.11",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.3", "@vitejs/plugin-react": "^5.1.3",
"@vitest/coverage-v8": "^4.0.18", "@vitest/coverage-v8": "^4.0.18",

View File

@@ -85,7 +85,7 @@ function ThemingCard({ wolEnabled }: { wolEnabled: number }) {
> >
<Stack gap={0} h={'fit-content'} w={'73%'}> <Stack gap={0} h={'fit-content'} w={'73%'}>
<Text className={textClasses.currentTheme} classNames={textClasses}> <Text className={textClasses.currentTheme} classNames={textClasses}>
Current theme: Current:
</Text> </Text>
<Text <Text
w={'100%'} w={'100%'}
@@ -204,7 +204,7 @@ function ThemingCard({ wolEnabled }: { wolEnabled: number }) {
wrapper: selectClasses.menuSelectWrapper, wrapper: selectClasses.menuSelectWrapper,
root: selectClasses.menuSelectRoot, root: selectClasses.menuSelectRoot,
input: selectClasses.menuSelectInput, input: selectClasses.menuSelectInput,
label: selectClasses.menuSelectLabel, label: selectClasses.menuSelectLabelNoOverflow,
options: selectClasses.menuSelectOptions, options: selectClasses.menuSelectOptions,
option: selectClasses.menuSelectOption, option: selectClasses.menuSelectOption,
}} }}

View File

@@ -120,8 +120,8 @@ export function ThemeModal({
color: 'var(--mantine-color-primary-0)', color: 'var(--mantine-color-primary-0)',
}, },
input: { input: {
color: designerTheme.primaryColor, color: selectedTheme.primaryColor,
backgroundColor: designerTheme.backgroundColor, backgroundColor: selectedTheme.backgroundColor,
border: 'none', border: 'none',
borderBottom: '1px solid var(--mantine-color-primary-0)', borderBottom: '1px solid var(--mantine-color-primary-0)',
}, },

View File

@@ -20,9 +20,9 @@ import { notifications } from '@mantine/notifications';
import { useCommonHooks } from 'hooks'; import { useCommonHooks } from 'hooks';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import FontPicker from 'react-fontpicker-ts'; import FontPicker from 'react-fontpicker-ts';
import { FaClipboard, FaFont, FaGoogle } from 'react-icons/fa'; import { FaCheck, FaClipboard, FaFont, FaGoogle } from 'react-icons/fa';
import { FaShuffle } from 'react-icons/fa6'; import { FaShuffle } from 'react-icons/fa6';
import { FiImage, FiSave, FiShuffle, FiX } from 'react-icons/fi'; import { FiImage, FiRefreshCcw, FiSave, FiShuffle, FiX } from 'react-icons/fi';
import { import {
buttonClasses, buttonClasses,
colorSwatchClasses, colorSwatchClasses,
@@ -68,6 +68,11 @@ export function ThemeEditor({
const viewportRef = useRef<HTMLDivElement>(null); const viewportRef = useRef<HTMLDivElement>(null);
const [colorId, setColorId] = useState<string>(''); const [colorId, setColorId] = useState<string>('');
const [colorValue, setColorValue] = useState('#000000'); const [colorValue, setColorValue] = useState('#000000');
const [rgba, setRgba] = useState<{ r: number; g: number; b: number; a?: number }>({
r: 0,
g: 0,
b: 0,
});
const [font, setFont] = useState<Theme['themeFont']>(); const [font, setFont] = useState<Theme['themeFont']>();
const [customFontEnabled, setCustomFontEnabled] = useState<boolean>(false); const [customFontEnabled, setCustomFontEnabled] = useState<boolean>(false);
const re = /(?:\.([^.]+))?$/; const re = /(?:\.([^.]+))?$/;
@@ -146,13 +151,17 @@ export function ThemeEditor({
}); });
const handleSwatchClick = (colorId: string, colorValue: string) => { const handleSwatchClick = (colorId: string, colorValue: string) => {
setRgba({
r: Number.parseInt(colorValue.substring(1, 3), 16),
g: Number.parseInt(colorValue.substring(3, 5), 16),
b: Number.parseInt(colorValue.substring(5, 7), 16),
a: Number.parseInt(colorValue.substring(7, 9), 16) || undefined,
});
setColorId(colorId || ''); setColorId(colorId || '');
setColorValue(colorValue || ''); setColorValue(colorValue || '');
closeBackgroundPicker(); closeBackgroundPicker();
openPicker(); openPicker();
setDesignerTheme(designerTheme);
}; };
const randomColor = (withAlpha?: boolean) => { const randomColor = (withAlpha?: boolean) => {
const letters = '0123456789ABCDEF'; const letters = '0123456789ABCDEF';
let color = '#'; let color = '#';
@@ -181,7 +190,16 @@ export function ThemeEditor({
setFont(designerTheme.themeFont); setFont(designerTheme.themeFont);
} }
}, [selectedTheme]); }, [selectedTheme]);
useEffect(() => {
if (colorValue) {
setRgba({
r: Number.parseInt(colorValue.substring(1, 3), 16),
g: Number.parseInt(colorValue.substring(3, 5), 16),
b: Number.parseInt(colorValue.substring(5, 7), 16),
a: Number.parseInt(colorValue.substring(7, 9), 16) || undefined,
});
}
}, [colorValue]);
return ( return (
<> <>
<Group p={'2rem'} w={'100%'} justify='space-between'> <Group p={'2rem'} w={'100%'} justify='space-between'>
@@ -325,7 +343,7 @@ export function ThemeEditor({
setColorValue(e); setColorValue(e);
setDesignerTheme({ setDesignerTheme({
...designerTheme, ...designerTheme,
backgroundColor: e, [colorId]: e,
}); });
}} }}
format={'hexa'} format={'hexa'}
@@ -347,53 +365,168 @@ export function ThemeEditor({
mb={'1.5rem'} mb={'1.5rem'}
/> />
)} )}
<TextInput <Stack w={'90%'} gap={0}>
className={textInputClasses.default} <TextInput
classNames={textInputClasses} className={textInputClasses.colorSwatchInput}
w={'90%'} classNames={textInputClasses}
value={colorValue} label={'Hex Value'}
onChange={(e) => setColorValue(e.target.value)} value={colorValue}
/> onChange={(e) => setColorValue(e.target.value)}
<Group mt={'auto'} justify='center'> />
<Button <Group gap={0} w={'100%'} justify='space-between'>
c={'white'} <TextInput
onClick={() => { className={textInputClasses.colorSwatchInput}
const rc = randomColor(colorId === 'searchColor'); classNames={textInputClasses}
setColorValue(rc); label={'Red'}
setDesignerTheme({ w={'23%'}
...designerTheme, value={rgba.r}
[colorId]: rc, onChange={(e) => {
}); if (e.target.value) {
}} setRgba({
...rgba,
r: Number.parseInt(e.target.value, 10),
});
setColorValue(
`${colorValue.substring(0, 1)}${Number.parseInt(e.target.value, 10).toString(16).padStart(2, '0')}${colorValue.substring(3)}`,
);
} else {
setRgba({
...rgba,
r: 0,
});
}
}}
/>
<TextInput
className={textInputClasses.colorSwatchInput}
classNames={textInputClasses}
label={'Green'}
w={'23%'}
value={rgba.g}
onChange={(e) => {
if (e.target.value) {
setRgba({
...rgba,
g: Number.parseInt(e.target.value, 10),
});
setColorValue(
`${colorValue.substring(0, 3)}${Number.parseInt(e.target.value, 10).toString(16).padStart(2, '0')}${colorValue.substring(5)}`,
);
} else {
setRgba({
...rgba,
g: 0,
});
}
}}
/>
<TextInput
className={textInputClasses.colorSwatchInput}
classNames={textInputClasses}
label={'Blue'}
w={'23%'}
value={rgba.b}
onChange={(e) => {
if (e.target.value) {
setRgba({
...rgba,
b: Number.parseInt(e.target.value, 10),
});
setColorValue(
`${colorValue.substring(0, 5)}${Number.parseInt(e.target.value, 10).toString(16).padStart(2, '0')}${colorValue.substring(7)}`,
);
} else {
setRgba({
...rgba,
b: 0,
});
}
}}
/>
<TextInput
disabled={colorId !== 'searchColor'}
className={textInputClasses.colorSwatchInput}
classNames={textInputClasses}
label={'Alpha'}
w={'23%'}
value={rgba.a}
onChange={(e) => {
if (e.target.value) {
setRgba({
...rgba,
a: Number.parseInt(e.target.value, 10),
});
setColorValue(
`${colorValue.substring(0, 7)}${Number.parseInt(e.target.value, 10).toString(16).padStart(2, '0')}`,
);
} else {
setRgba({
...rgba,
a: 0,
});
}
}}
/>
</Group>
</Stack>
<Group mt={'auto'} justify='center' mih={'36px'} pb={'1.5rem'}>
<Tooltip
label={'Random Color'}
className={toolTipClasses.default}
classNames={toolTipClasses}
> >
<FiShuffle /> <Button
</Button> c={'white'}
<Button onClick={() => {
color={'green'} const rc = randomColor(colorId === 'searchColor');
onClick={() => { setColorValue(rc);
setDesignerTheme({ setDesignerTheme({
...designerTheme, ...designerTheme,
[colorId]: colorValue, [colorId]: rc,
}); });
}}
>
<FiShuffle />
</Button>
</Tooltip>
<Tooltip
label={'Reset Color'}
className={toolTipClasses.default}
classNames={toolTipClasses}
>
<Button
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={() => {
setColorValue(defaultTheme[colorId as keyof Theme] as string);
setDesignerTheme({
...designerTheme,
[colorId]: defaultTheme[colorId as keyof Theme],
});
}}
>
<FiRefreshCcw />
</Button>
</Tooltip>
<Tooltip
label={'Done'}
className={toolTipClasses.default}
classNames={toolTipClasses}
>
<Button
color={'green'}
onClick={() => {
setDesignerTheme({
...designerTheme,
[colorId]: colorValue,
});
closePicker(); closePicker();
}} }}
> >
<FiSave /> <FaCheck />
</Button> </Button>
<Button </Tooltip>
color={'red'}
styles={{ label: { color: 'black' } }}
onClick={() => {
closePicker();
setDesignerTheme({
...designerTheme,
[colorId]: designerTheme[colorId as keyof Theme],
});
}}
>
<FiX />
</Button>
</Group> </Group>
</Stack> </Stack>
)} )}
@@ -710,14 +843,22 @@ export function ThemeEditor({
gap={0} gap={0}
key={key} key={key}
> >
<Group w={'100%'} justify='space-between'> <Group
w={'100%'}
justify='space-between'
pos={'relative'}
>
<Text <Text
w={'100%'}
key={key} key={key}
pl={2} pl={2}
style={{ style={{
color: 'var(--mantine-color-primary-0)', color: 'var(--mantine-color-primary-0)',
backgroundColor: backgroundColor:
'var(--mantine-color-background-0)', 'var(--mantine-color-background-0)',
overflow: 'clip',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
}} }}
> >
{ {
@@ -745,245 +886,234 @@ export function ThemeEditor({
[key]: defaultTheme[key as keyof Theme], [key]: defaultTheme[key as keyof Theme],
}); });
}} }}
pos={'absolute'}
right={0}
> >
<FiX /> <FiX />
</ActionIcon> </ActionIcon>
</Tooltip> </Tooltip>
</Group> </Group>
{key === 'name' && ( <Group
<Group w={'100%'}
w={'100%'} justify={
justify='center' key.includes('Color') ? 'space-between' : 'center'
bg='var(--mantine-color-accent-0)' }
style={{ borderRadius: 8, overflow: 'clip' }} gap={key.includes('Color') ? 4 : 0}
h={48} bg='var(--mantine-color-accent-0)'
> c='var(--mantine-color-background-0)'
<Text>{defaultTheme[key as keyof Theme]}</Text> style={{ borderRadius: 8, overflow: 'clip' }}
<Text>→</Text> h={48}
<Text>{designerTheme[key as keyof Theme]}</Text> >
</Group> {key === 'name' && (
)} <>
{key.includes('Shadow') && ( <Text>{defaultTheme[key as keyof Theme]}</Text>
<Group <Text>→</Text>
w={'100%'} <Text>{designerTheme[key as keyof Theme]}</Text>
justify='center' </>
bg='var(--mantine-color-accent-0)' )}
style={{ borderRadius: 8, overflow: 'clip' }} {key.includes('Shadow') && (
h={48} <>
> {defaultTheme[key as keyof Theme] === 0 ? (
{defaultTheme[key as keyof Theme] === 0 ? ( <Text>Off</Text>
<Text>Off</Text> ) : (
) : ( <Text>On</Text>
<Text>On</Text> )}
)} <Text>→</Text>
<Text>→</Text> {designerTheme[key as keyof Theme] === 0 ? (
{designerTheme[key as keyof Theme] === 0 ? ( <Text>Off</Text>
<Text>Off</Text> ) : (
) : ( <Text>On</Text>
<Text>On</Text> )}
)} </>
</Group> )}
)} {key.includes('Font') && (
{key.includes('Font') && ( <>
<Group <Text
w={'100%'}
justify='center'
bg='var(--mantine-color-accent-0)'
h={48}
style={{ borderRadius: 8, overflow: 'clip' }}
>
<Text
style={{
fontFamily:
(defaultTheme[
key as keyof Theme
] as string) ?? undefined,
fontSize: 18,
}}
>
{defaultTheme[key as keyof Theme] ||
`Default (${currentUser.defaultFont})`}
</Text>
<Text>→</Text>
<Text
style={{
fontFamily:
designerTheme.themeFont ?? undefined,
fontSize: 18,
}}
>
{designerTheme[key as keyof Theme] ||
`Default (${currentUser.defaultFont})`}
</Text>
</Group>
)}
{key === 'backgroundImage' && (
<Group
w={'100%'}
justify='center'
gap={4}
bg='var(--mantine-color-accent-0)'
style={{ borderRadius: 8, overflow: 'clip' }}
>
<Image
w={'40%'}
src={
(
defaultTheme[key as keyof Theme] as string
).toLocaleLowerCase() === 'none'
? 'https://placehold.co/540x360?text=None'
: `../../api/backgroundImages/thumbs/${defaultTheme[key as keyof Theme] as string}`
}
/>
<Text>→</Text>
<Image
w={'40%'}
src={
(
designerTheme[key as keyof Theme] as string
).toLocaleLowerCase() === 'none'
? 'https://placehold.co/540x360?text=None'
: `../../api/backgroundImages/thumbs/${designerTheme[key as keyof Theme] as string}`
}
/>
</Group>
)}
{key.includes('Color') && (
<Group
w={'100%'}
justify='space-between'
bg='var(--mantine-color-accent-0)'
style={{ borderRadius: 8, overflow: 'clip' }}
>
<Tooltip
label='Copy color code'
classNames={toolTipClasses}
className={toolTipClasses.default}
>
<ColorSwatch
h={50}
onClick={() => {
navigator.clipboard.writeText(
defaultTheme[key as keyof Theme] as string,
);
notifications.show({
title: (
<Text
fw={600}
c={'var(--mantine-color-accent-0)'}
>
Copied{' '}
{
ThemeProperties[
key as keyof typeof ThemeProperties
]
}
</Text>
),
message: (
<Text
c={'var(--mantine-color-primary-0)'}
>
{
defaultTheme[
key as keyof Theme
] as string
}
</Text>
),
autoClose: true,
withCloseButton: true,
icon: <FaClipboard size={24} />,
});
}}
color={
defaultTheme[key as keyof Theme] as string
}
style={{ style={{
cursor: 'pointer', fontFamily:
(defaultTheme[
key as keyof Theme
] as string) ?? undefined,
fontSize: 18,
}} }}
styles={{ >
alphaOverlay: { {defaultTheme[key as keyof Theme] ||
borderRadius: '0px', `Default (${currentUser.defaultFont})`}
}, </Text>
colorOverlay: { <Text>→</Text>
borderRadius: '0px', <Text
},
shadowOverlay: {
borderRadius: '0px',
},
childrenOverlay: {
borderRadius: '0px',
},
}}
/>
</Tooltip>
<Text>→</Text>
<Tooltip
label='Copy color code'
classNames={toolTipClasses}
className={toolTipClasses.default}
>
<ColorSwatch
h={50}
onClick={() => {
navigator.clipboard.writeText(
defaultTheme[key as keyof Theme] as string,
);
notifications.show({
title: (
<Text
fw={600}
c={'var(--mantine-color-accent-0)'}
>
Copied{' '}
{
ThemeProperties[
key as keyof typeof ThemeProperties
]
}
</Text>
),
message: (
<Text
c={'var(--mantine-color-primary-0)'}
>
{
designerTheme[
key as keyof Theme
] as string
}
</Text>
),
autoClose: true,
withCloseButton: true,
icon: <FaClipboard size={24} />,
});
}}
color={
designerTheme[key as keyof Theme] as string
}
style={{ style={{
cursor: 'pointer', fontFamily:
}} designerTheme.themeFont ?? undefined,
styles={{ fontSize: 18,
alphaOverlay: {
borderRadius: '0px',
},
colorOverlay: {
borderRadius: '0px',
},
shadowOverlay: {
borderRadius: '0px',
},
childrenOverlay: {
borderRadius: '0px',
},
}} }}
>
{designerTheme[key as keyof Theme] ||
`Default (${currentUser.defaultFont})`}
</Text>
</>
)}
{key === 'backgroundImage' && (
<>
<Image
w={'40%'}
src={
(
defaultTheme[key as keyof Theme] as string
).toLocaleLowerCase() === 'none'
? 'https://placehold.co/540x360?text=None'
: `../../api/backgroundImages/thumbs/${defaultTheme[key as keyof Theme] as string}`
}
/> />
</Tooltip> <Text>→</Text>
</Group> <Image
)} w={'40%'}
src={
(
designerTheme[key as keyof Theme] as string
).toLocaleLowerCase() === 'none'
? 'https://placehold.co/540x360?text=None'
: `../../api/backgroundImages/thumbs/${designerTheme[key as keyof Theme] as string}`
}
/>
</>
)}
{key.includes('Color') && (
<>
<Tooltip
label='Copy color code'
classNames={toolTipClasses}
className={toolTipClasses.default}
>
<ColorSwatch
h={50}
onClick={() => {
navigator.clipboard.writeText(
defaultTheme[
key as keyof Theme
] as string,
);
notifications.show({
title: (
<Text
fw={600}
c={'var(--mantine-color-accent-0)'}
>
Copied{' '}
{
ThemeProperties[
key as keyof typeof ThemeProperties
]
}
</Text>
),
message: (
<Text
c={'var(--mantine-color-primary-0)'}
>
{
defaultTheme[
key as keyof Theme
] as string
}
</Text>
),
autoClose: true,
withCloseButton: true,
icon: <FaClipboard size={24} />,
});
}}
color={
defaultTheme[key as keyof Theme] as string
}
style={{
cursor: 'pointer',
}}
styles={{
alphaOverlay: {
borderRadius: '0px',
},
colorOverlay: {
borderRadius: '0px',
},
shadowOverlay: {
borderRadius: '0px',
},
childrenOverlay: {
borderRadius: '0px',
},
}}
/>
</Tooltip>
<Text>→</Text>
<Tooltip
label='Copy color code'
classNames={toolTipClasses}
className={toolTipClasses.default}
>
<ColorSwatch
h={50}
onClick={() => {
navigator.clipboard.writeText(
defaultTheme[
key as keyof Theme
] as string,
);
notifications.show({
title: (
<Text
fw={600}
c={'var(--mantine-color-accent-0)'}
>
Copied{' '}
{
ThemeProperties[
key as keyof typeof ThemeProperties
]
}
</Text>
),
message: (
<Text
c={'var(--mantine-color-primary-0)'}
>
{
designerTheme[
key as keyof Theme
] as string
}
</Text>
),
autoClose: true,
withCloseButton: true,
icon: <FaClipboard size={24} />,
});
}}
color={
designerTheme[key as keyof Theme] as string
}
style={{
cursor: 'pointer',
}}
styles={{
alphaOverlay: {
borderRadius: '0px',
},
colorOverlay: {
borderRadius: '0px',
},
shadowOverlay: {
borderRadius: '0px',
},
childrenOverlay: {
borderRadius: '0px',
},
}}
/>
</Tooltip>
</>
)}
</Group>
</Stack> </Stack>
) )
); );

View File

@@ -18,6 +18,24 @@
z-index: 1; z-index: 1;
top: 18px; top: 18px;
} }
.menuSelectLabelNoOverflow {
width: inherit;
position: absolute;
font-size: .75rem !important;
padding-left: .5rem;
padding-right: .5rem;
padding-top: .125rem;
padding-bottom: .125rem;
margin-left: -8px;
border-radius: 8px;
background-color: var(--mantine-color-primary-0);
color: var(--mantine-color-background-0);
z-index: 1;
top: 18px;
overflow: clip;
text-overflow: ellipsis;
white-space: nowrap;
}
.menuSelectInput { .menuSelectInput {
border-color: var(--mantine-color-border-0) !important; border-color: var(--mantine-color-border-0) !important;
background-color: var(--mantine-color-background-0) !important; background-color: var(--mantine-color-background-0) !important;

View File

@@ -49,8 +49,8 @@
border-radius: 4px; border-radius: 4px;
.input { .input {
width: 100%; width: 100%;
background-color: transparent;
border: none; border: none;
background-color: transparent;
color: var(--mantine-color-primary-0); color: var(--mantine-color-primary-0);
font-size: 1.125rem; font-size: 1.125rem;
} }
@@ -67,3 +67,44 @@
} }
} }
} }
.colorSwatchInput {
&.root {
padding-top: 0px;
.label {
position: relative;
font-size: .75rem;
padding-left: .5rem;
padding-right: .5rem;
padding-top: .125rem;
padding-bottom: .125rem;
margin-left: -8px;
margin-bottom: 8px;
border-radius: 8px;
background-color: var(--mantine-color-primary-0);
color: var(--mantine-color-background-0);
z-index: 1;
}
.wrapper {
display: flex;
margin-top: -16px;
padding-top: 8px;
border-radius: 4px;
.input {
border: none;
background-color: var(--mantine-color-background-0);
color: var(--mantine-color-primary-0);
font-size: 1.125rem;
}
.section {
color: var(--mantine-color-border-0);
padding-left: .5rem;
opacity: 1;
}
::placeholder {
color: var(--mantine-color-accent-0);
opacity: 50%;
}
}
}
}