diff --git a/apps/status-page/src/components/themes/theme-sidebar.tsx b/apps/status-page/src/components/themes/theme-sidebar.tsx
index 4eeffea0..bc25de24 100644
--- a/apps/status-page/src/components/themes/theme-sidebar.tsx
+++ b/apps/status-page/src/components/themes/theme-sidebar.tsx
@@ -47,6 +47,7 @@ import {
} from "@openstatus/ui/components/ui/tooltip";
import { useCopyToClipboard } from "@openstatus/ui/hooks/use-copy-to-clipboard";
import { useDebounce } from "@openstatus/ui/hooks/use-debounce";
+import { useDebounceCallback } from "@openstatus/ui/hooks/use-debounce-callback";
import { cn } from "@openstatus/ui/lib/utils";
import {
Check,
@@ -344,6 +345,17 @@ function ThemeValueSelector(props: {
}) {
const { resolvedTheme } = useTheme();
+ const handleChange = useDebounceCallback((value: string) => {
+ const mode = resolvedTheme as "light" | "dark";
+ props.setTheme({
+ ...props.theme,
+ [mode]: {
+ ...props.theme[mode],
+ [props.id]: value,
+ },
+ });
+ }, 100);
+
if (!props.isMounted || !resolvedTheme)
return ;
@@ -362,15 +374,7 @@ function ThemeValueSelector(props: {
name={props.id}
value={value}
className="sr-only"
- onChange={(e) =>
- props.setTheme({
- ...props.theme,
- [resolvedTheme as "light" | "dark"]: {
- ...props.theme[resolvedTheme as "light" | "dark"],
- [props.id]: e.target.value,
- },
- })
- }
+ onChange={(e) => handleChange(e.target.value)}
/>
);
diff --git a/packages/ui/src/hooks/use-debounce-callback.ts b/packages/ui/src/hooks/use-debounce-callback.ts
new file mode 100644
index 00000000..6b8e4ca1
--- /dev/null
+++ b/packages/ui/src/hooks/use-debounce-callback.ts
@@ -0,0 +1,29 @@
+import { useCallback, useEffect, useRef } from "react";
+
+export function useDebounceCallback(
+ callback: (...args: Args) => void,
+ delay = 500,
+) {
+ const timerRef = useRef | null>(null);
+
+ const debounced = useCallback(
+ (...args: Args) => {
+ if (timerRef.current) {
+ clearTimeout(timerRef.current);
+ }
+
+ timerRef.current = setTimeout(() => {
+ callback(...args);
+ }, delay);
+ },
+ [callback, delay],
+ );
+
+ useEffect(() => {
+ return () => {
+ if (timerRef.current) clearTimeout(timerRef.current);
+ };
+ }, []);
+
+ return debounced;
+}