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'),