diff --git a/package-lock.json b/package-lock.json index 9d63f8f..bd67fc8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "@tanstack/react-query-persist-client": "^5.90.22", "@tanstack/react-table": "^8.21.3", "idb-keyval": "^6.2.2", - "jotai": "^2.17.0", + "jotai": "^2.17.1", "react": "^19.2.4", "react-dom": "^19.2.4", "react-fontpicker-ts": "^1.3.0", @@ -30,7 +30,7 @@ }, "devDependencies": { "@types/node": "^25.2.0", - "@types/react": "^19.2.10", + "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.3", "@vitest/coverage-v8": "^4.0.18", @@ -1846,9 +1846,9 @@ } }, "node_modules/@types/react": { - "version": "19.2.10", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.10.tgz", - "integrity": "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==", + "version": "19.2.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.11.tgz", + "integrity": "sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==", "devOptional": true, "dependencies": { "csstype": "^3.2.2" @@ -2936,9 +2936,9 @@ "dev": true }, "node_modules/jotai": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.17.0.tgz", - "integrity": "sha512-DBPT7Vx7E7R/ZJL7Uq7yUA9+LLR0IRiRM+Bw5ugVwv8L8++RjlXVXZ2//ccucypc5lcyuHOW09rYcW77RurduQ==", + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.17.1.tgz", + "integrity": "sha512-TFNZZDa/0ewCLQyRC/Sq9crtixNj/Xdf/wmj9631xxMuKToVJZDbqcHIYN0OboH+7kh6P6tpIK7uKWClj86PKw==", "engines": { "node": ">=12.20.0" }, diff --git a/package.json b/package.json index dfb036c..9baf5df 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "@tanstack/react-query-persist-client": "^5.90.22", "@tanstack/react-table": "^8.21.3", "idb-keyval": "^6.2.2", - "jotai": "^2.17.0", + "jotai": "^2.17.1", "react": "^19.2.4", "react-dom": "^19.2.4", "react-fontpicker-ts": "^1.3.0", @@ -32,7 +32,7 @@ }, "devDependencies": { "@types/node": "^25.2.0", - "@types/react": "^19.2.10", + "@types/react": "^19.2.11", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.3", "@vitest/coverage-v8": "^4.0.18", diff --git a/src/pages/homepage/components/SettingsButton/ThemingCard.tsx b/src/pages/homepage/components/SettingsButton/ThemingCard.tsx index 31045a6..deccbcb 100644 --- a/src/pages/homepage/components/SettingsButton/ThemingCard.tsx +++ b/src/pages/homepage/components/SettingsButton/ThemingCard.tsx @@ -85,7 +85,7 @@ function ThemingCard({ wolEnabled }: { wolEnabled: number }) { > - Current theme: + Current: (null); const [colorId, setColorId] = useState(''); 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(); const [customFontEnabled, setCustomFontEnabled] = useState(false); const re = /(?:\.([^.]+))?$/; @@ -146,13 +151,17 @@ export function ThemeEditor({ }); 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 || ''); setColorValue(colorValue || ''); closeBackgroundPicker(); openPicker(); - setDesignerTheme(designerTheme); }; - const randomColor = (withAlpha?: boolean) => { const letters = '0123456789ABCDEF'; let color = '#'; @@ -181,7 +190,16 @@ export function ThemeEditor({ setFont(designerTheme.themeFont); } }, [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 ( <> @@ -325,7 +343,7 @@ export function ThemeEditor({ setColorValue(e); setDesignerTheme({ ...designerTheme, - backgroundColor: e, + [colorId]: e, }); }} format={'hexa'} @@ -347,53 +365,168 @@ export function ThemeEditor({ mb={'1.5rem'} /> )} - setColorValue(e.target.value)} - /> - - - + + + + + + - + closePicker(); + }} + > + + + )} @@ -710,14 +843,22 @@ export function ThemeEditor({ gap={0} key={key} > - + { @@ -745,245 +886,234 @@ export function ThemeEditor({ [key]: defaultTheme[key as keyof Theme], }); }} + pos={'absolute'} + right={0} > - {key === 'name' && ( - - {defaultTheme[key as keyof Theme]} - → - {designerTheme[key as keyof Theme]} - - )} - {key.includes('Shadow') && ( - - {defaultTheme[key as keyof Theme] === 0 ? ( - Off - ) : ( - On - )} - → - {designerTheme[key as keyof Theme] === 0 ? ( - Off - ) : ( - On - )} - - )} - {key.includes('Font') && ( - - - {defaultTheme[key as keyof Theme] || - `Default (${currentUser.defaultFont})`} - - → - - {designerTheme[key as keyof Theme] || - `Default (${currentUser.defaultFont})`} - - - )} - {key === 'backgroundImage' && ( - - - → - - - )} - {key.includes('Color') && ( - - - { - navigator.clipboard.writeText( - defaultTheme[key as keyof Theme] as string, - ); - notifications.show({ - title: ( - - Copied{' '} - { - ThemeProperties[ - key as keyof typeof ThemeProperties - ] - } - - ), - message: ( - - { - defaultTheme[ - key as keyof Theme - ] as string - } - - ), - autoClose: true, - withCloseButton: true, - icon: , - }); - }} - color={ - defaultTheme[key as keyof Theme] as string - } + + {key === 'name' && ( + <> + {defaultTheme[key as keyof Theme]} + → + {designerTheme[key as keyof Theme]} + + )} + {key.includes('Shadow') && ( + <> + {defaultTheme[key as keyof Theme] === 0 ? ( + Off + ) : ( + On + )} + → + {designerTheme[key as keyof Theme] === 0 ? ( + Off + ) : ( + On + )} + + )} + {key.includes('Font') && ( + <> + - - → - - { - navigator.clipboard.writeText( - defaultTheme[key as keyof Theme] as string, - ); - notifications.show({ - title: ( - - Copied{' '} - { - ThemeProperties[ - key as keyof typeof ThemeProperties - ] - } - - ), - message: ( - - { - designerTheme[ - key as keyof Theme - ] as string - } - - ), - autoClose: true, - withCloseButton: true, - icon: , - }); - }} - color={ - designerTheme[key as keyof Theme] as string - } + > + {defaultTheme[key as keyof Theme] || + `Default (${currentUser.defaultFont})`} + + → + + {designerTheme[key as keyof Theme] || + `Default (${currentUser.defaultFont})`} + + + )} + {key === 'backgroundImage' && ( + <> + - - - )} + → + + + )} + {key.includes('Color') && ( + <> + + { + navigator.clipboard.writeText( + defaultTheme[ + key as keyof Theme + ] as string, + ); + notifications.show({ + title: ( + + Copied{' '} + { + ThemeProperties[ + key as keyof typeof ThemeProperties + ] + } + + ), + message: ( + + { + defaultTheme[ + key as keyof Theme + ] as string + } + + ), + autoClose: true, + withCloseButton: true, + icon: , + }); + }} + color={ + defaultTheme[key as keyof Theme] as string + } + style={{ + cursor: 'pointer', + }} + styles={{ + alphaOverlay: { + borderRadius: '0px', + }, + colorOverlay: { + borderRadius: '0px', + }, + shadowOverlay: { + borderRadius: '0px', + }, + childrenOverlay: { + borderRadius: '0px', + }, + }} + /> + + → + + { + navigator.clipboard.writeText( + defaultTheme[ + key as keyof Theme + ] as string, + ); + notifications.show({ + title: ( + + Copied{' '} + { + ThemeProperties[ + key as keyof typeof ThemeProperties + ] + } + + ), + message: ( + + { + designerTheme[ + key as keyof Theme + ] as string + } + + ), + autoClose: true, + withCloseButton: true, + icon: , + }); + }} + color={ + designerTheme[key as keyof Theme] as string + } + style={{ + cursor: 'pointer', + }} + styles={{ + alphaOverlay: { + borderRadius: '0px', + }, + colorOverlay: { + borderRadius: '0px', + }, + shadowOverlay: { + borderRadius: '0px', + }, + childrenOverlay: { + borderRadius: '0px', + }, + }} + /> + + + )} + ) ); diff --git a/src/styles/Select.module.css b/src/styles/Select.module.css index 87b0824..f865222 100644 --- a/src/styles/Select.module.css +++ b/src/styles/Select.module.css @@ -18,6 +18,24 @@ z-index: 1; 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 { border-color: var(--mantine-color-border-0) !important; background-color: var(--mantine-color-background-0) !important; diff --git a/src/styles/TextInput.module.css b/src/styles/TextInput.module.css index 92961d0..bff8a54 100644 --- a/src/styles/TextInput.module.css +++ b/src/styles/TextInput.module.css @@ -49,8 +49,8 @@ border-radius: 4px; .input { width: 100%; - background-color: transparent; border: none; + background-color: transparent; color: var(--mantine-color-primary-0); 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%; + } + } + } +} \ No newline at end of file