Files
supabase/apps/studio/components/ui/DebouncedComponent.tsx
Gildas Garcia 86a3f8b03d chore: upgrade to react-19 (#45886)
- Most changes are related to either types or `useRef` usages (it now
requires an initial value).
- also updated `vaul` to its latest version and haven't noticed any
change ([design-system
demo](https://design-system-git-react-19-supabase.vercel.app/design-system/docs/components/drawer))

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Upgraded workspace to React 19.

* **Bug Fixes**
* Improved null-safety and ref handling across editors, UI components,
shortcuts, and markdown/image rendering to reduce runtime errors.
* Safer event/timeout/interval cleanup and more robust command/context
handling.

* **Chores**
  * Bumped vaul dependency versions.

* **Documentation**
* Type and TypeScript accuracy improvements for clearer developer
feedback.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45886)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-15 16:04:41 +02:00

45 lines
1.0 KiB
TypeScript

import { useEffect, useRef, useState } from 'react'
interface DebouncedComponentProps {
value: any
delay?: number
fallback?: React.ReactNode
children: React.ReactNode
}
export function DebouncedComponent({
value,
delay = 500,
fallback = <div className="text-sm">Loading...</div>,
children,
}: DebouncedComponentProps) {
const [shouldRender, setShouldRender] = useState(false)
const timeoutRef = useRef<NodeJS.Timeout>(null)
const prevValueRef = useRef(value)
const isInitialMount = useRef(true)
useEffect(() => {
if (isInitialMount.current || prevValueRef.current !== value) {
setShouldRender(false)
prevValueRef.current = value
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
timeoutRef.current = setTimeout(() => {
setShouldRender(true)
isInitialMount.current = false
}, delay)
}
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
}
}, [value, delay])
return shouldRender ? children : fallback
}