From 9f7b46d2adfccaf8ff35be6aaab50c5e92cf884d Mon Sep 17 00:00:00 2001 From: SethBurkart123 Date: Mon, 17 Mar 2025 13:45:16 +1100 Subject: [PATCH] feat: add back react colour picker --- package.json | 4 +- src/interface/components/ColourPicker.svelte | 510 ++----------------- src/interface/components/ColourPicker.tsx | 108 ++++ vite.config.ts | 4 +- 4 files changed, 146 insertions(+), 480 deletions(-) create mode 100644 src/interface/components/ColourPicker.tsx diff --git a/package.json b/package.json index abcfdadb..08e34ad9 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "@codemirror/search": "^6.5.10", "@codemirror/state": "^6.5.2", "@codemirror/view": "^6.36.4", - "@jaames/iro": "^5.5.2", "@sveltejs/vite-plugin-svelte": "^5.0.3", "@tailwindcss/forms": "^0.5.9", "@tailwindcss/vite": "^4.0.12", @@ -86,6 +85,9 @@ "lodash": "^4.17.21", "million": "^3.1.11", "motion": "^12.4.12", + "react": "17", + "react-best-gradient-color-picker": "3.0.11", + "react-dom": "17", "rss-parser": "^3.13.0", "sortablejs": "^1.15.6", "svelte": "^5.22.6", diff --git a/src/interface/components/ColourPicker.svelte b/src/interface/components/ColourPicker.svelte index 4095fc8e..fde37b7f 100644 --- a/src/interface/components/ColourPicker.svelte +++ b/src/interface/components/ColourPicker.svelte @@ -1,93 +1,20 @@ {#if standalone} -
-
- - -
- -
- - {#if currentMode === 'gradient'} -
- -
- -
- - - {#each gradientStops as stop, i} - - {/each} -
- - -
-
- - - {gradientAngle}° -
- - {#if gradientStops.length > 2} - - {/if} -
-
- {/if} +
+
{:else} - +
{ e.key === 'Enter' && handleBackgroundClick }} - role="button" - aria-label="Close color picker" - tabindex="0" >
- -
- - -
- -
- - {#if currentMode === 'gradient'} -
- -
- -
- - - {#each gradientStops as stop, i} - - {/each} -
- - -
-
- - - {gradientAngle}° -
- - {#if gradientStops.length > 2} - - {/if} -
-
- {/if} +
{/if} diff --git a/src/interface/components/ColourPicker.tsx b/src/interface/components/ColourPicker.tsx new file mode 100644 index 00000000..46eaf224 --- /dev/null +++ b/src/interface/components/ColourPicker.tsx @@ -0,0 +1,108 @@ +import ColorPicker from "react-best-gradient-color-picker" +import { useEffect, useRef, useState } from "react" +import { settingsState } from "@/seqta/utils/listeners/SettingsState.ts" + +const defaultPresets = [ + "linear-gradient(30deg, rgba(229,209,218,1) 0%, RGBA(235,169,202,1) 46%, rgba(214,155,162,1) 100%)", + "linear-gradient(40deg, rgba(201,61,0,1) 0%, RGBA(170, 5, 58, 1) 100%)", + "linear-gradient(40deg, rgba(0, 141, 201, 0.76) 0%, rgba(8, 5, 170, 0.66) 100%)", + "linear-gradient(40deg, rgba(0, 201, 20, 0.76) 0%, rgba(4, 160, 105, 0.66) 100%)", + "linear-gradient(40deg, rgba(199, 20, 55, 0.76) 0%, rgba(95, 11, 160, 0.66) 100%)", + "linear-gradient(40deg, rgba(24, 20, 199, 0.76) 0%, rgba(23, 173, 65, 0.66) 100%)", + "radial-gradient(circle, rgba(20, 199, 178, 0.76) 32%, rgba(3, 120, 57, 0.66) 100%)", + "radial-gradient(circle, rgba(13, 15, 145, 0.76) 12%, rgba(103, 3, 120, 0.66) 100%)", + "linear-gradient(20deg, rgb(230, 21, 21) 0%, rgb(230, 109, 21) 12%, rgb(230, 34, 21) 26%, rgb(230, 21, 21) 39%, rgb(230, 84, 21) 48%, rgb(230, 34, 21) 58%, rgb(230, 96, 21) 69%, rgb(230, 34, 21) 80%, rgb(230, 71, 21) 89%, rgb(230, 21, 21) 100%)", + "rgba(114, 1, 170, 0.89)", + "rgba(93, 135, 63, 0.89)", + "rgba(4, 4, 138, 0.77)", + "rgba(21, 20, 20, 0.89)", + "linear-gradient(340deg, rgb(205, 74, 82) 18%, rgba(132, 8, 8, 0.89) 46%, rgb(204, 78, 85) 72%)", + "radial-gradient(circle, rgb(74, 205, 158) 0%, rgba(8, 72, 132, 0.89) 99%)", + "rgba(17, 94, 89, 1)", + "rgba(30, 64, 175, 0.89)", + "rgba(134, 25, 143, 1)", + "rgba(14, 165, 233, 0.9)", +] + +interface PickerProps { + customOnChange?: (color: string) => void + customState?: string + savePresets?: boolean +} + +export default function Picker({ + customOnChange, + customState, + savePresets = true, +}: PickerProps) { + const [customThemeColor, setCustomThemeColor] = useState() + const [presets, setPresets] = useState() + + const latestValuesRef = useRef({ customThemeColor, customOnChange, savePresets, presets }); + + useEffect(() => { + if (customState !== undefined && customState !== null) { + setCustomThemeColor(customState) + } else { + setCustomThemeColor(settingsState.selectedColor ?? null) + } + + if (presets === undefined) { + const savedPresets = localStorage.getItem("colorPickerPresets") + setPresets(savedPresets ? JSON.parse(savedPresets) : defaultPresets) + } + }, []) + + useEffect(() => { + latestValuesRef.current = { customThemeColor, customOnChange, savePresets, presets }; + }, [customThemeColor, customOnChange, savePresets, presets]); + + useEffect(() => { + return () => { + const { customThemeColor, customOnChange, savePresets, presets } = latestValuesRef.current; + if (!(customThemeColor && !customOnChange && savePresets && presets)) return; + + // Only proceed if presets are different (avoid unnecessary updates) + const existingIndex = presets.indexOf(customThemeColor); + let updatedPresets; + + if (existingIndex === 0) { + // No need to update if the selected color is already the first element + return; + } else if (existingIndex > -1) { + updatedPresets = [ + customThemeColor, + ...presets.slice(0, existingIndex), + ...presets.slice(existingIndex + 1), + ]; + } else { + updatedPresets = [customThemeColor, ...presets].slice(0, 18); + } + + localStorage.setItem("colorPickerPresets", JSON.stringify(updatedPresets)); + } + }, []) + + useEffect(() => { + if (customThemeColor && !customOnChange) { + settingsState.selectedColor = customThemeColor + } + }, [customThemeColor, customOnChange]) + + return ( + { + if (customOnChange) { + customOnChange(color) + setCustomThemeColor(color) + } else { + setCustomThemeColor(color) + } + }} + /> + ) +} diff --git a/vite.config.ts b/vite.config.ts index 0e408fcf..90ec170a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -25,7 +25,7 @@ const targets: BuildTarget[] = [ ] const mode = process.env.MODE || 'chrome'; // Check the environment variable to determine which build type to use. -const sourcemap = (process.env.SOURCEMAP === "true") || false; // Check whether we want sourcemaps. +//const sourcemap = (process.env.SOURCEMAP === "true") || false; // Check whether we want sourcemaps. export default defineConfig(({ command }) => ({ plugins: [ @@ -74,7 +74,7 @@ export default defineConfig(({ command }) => ({ outDir: resolve(__dirname, 'dist', mode), emptyOutDir: false, minify: false, - sourcemap: sourcemap, + //sourcemap: sourcemap, rollupOptions: { input: { settings: join(__dirname, 'src', 'interface', 'index.html'),