mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
Share reduced motion media query hook (#3287)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
renderer surface. Keeping the state machine and its presentation variants together avoids
|
||||
scattering tightly coupled update behavior across multiple files. */
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { usePrefersReducedMotion } from '@/hooks/usePrefersReducedMotion'
|
||||
import { useAppStore } from '../store'
|
||||
import { Card } from './ui/card'
|
||||
import { Button } from './ui/button'
|
||||
@@ -197,14 +198,7 @@ export function UpdateCard() {
|
||||
}, [status.state])
|
||||
|
||||
// ── Prefers-reduced-motion ──────────────────────────────────────────
|
||||
const [prefersReducedMotion, setPrefersReducedMotion] = useState(false)
|
||||
useEffect(() => {
|
||||
const mq = window.matchMedia('(prefers-reduced-motion: reduce)')
|
||||
setPrefersReducedMotion(mq.matches)
|
||||
const handler = (e: MediaQueryListEvent) => setPrefersReducedMotion(e.matches)
|
||||
mq.addEventListener('change', handler)
|
||||
return () => mq.removeEventListener('change', handler)
|
||||
}, [])
|
||||
const prefersReducedMotion = usePrefersReducedMotion()
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { FeatureWallOpenSourceTelemetry } from '../../../../shared/telemetry-events'
|
||||
|
||||
const REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)'
|
||||
export { usePrefersReducedMotion } from '@/hooks/usePrefersReducedMotion'
|
||||
|
||||
export function getFeatureWallOpenSource(
|
||||
modalData: Record<string, unknown>
|
||||
@@ -11,27 +9,3 @@ export function getFeatureWallOpenSource(
|
||||
? source
|
||||
: 'unknown'
|
||||
}
|
||||
|
||||
export function usePrefersReducedMotion(): boolean {
|
||||
const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => {
|
||||
if (typeof window === 'undefined' || !window.matchMedia) {
|
||||
return false
|
||||
}
|
||||
return window.matchMedia(REDUCED_MOTION_QUERY).matches
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined' || !window.matchMedia) {
|
||||
return
|
||||
}
|
||||
const media = window.matchMedia(REDUCED_MOTION_QUERY)
|
||||
setPrefersReducedMotion(media.matches)
|
||||
const onChange = (event: MediaQueryListEvent): void => {
|
||||
setPrefersReducedMotion(event.matches)
|
||||
}
|
||||
media.addEventListener('change', onChange)
|
||||
return () => media.removeEventListener('change', onChange)
|
||||
}, [])
|
||||
|
||||
return prefersReducedMotion
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useId, useRef, useState } from 'react'
|
||||
import { usePrefersReducedMotion } from '@/hooks/usePrefersReducedMotion'
|
||||
import { usePetUrl } from './usePetUrl'
|
||||
import type { DetectedSpriteCacheEntry } from './pet-blob-cache'
|
||||
import type { CustomPet } from '../../../../shared/types'
|
||||
@@ -176,25 +177,6 @@ function useDocumentVisible(): boolean {
|
||||
return visible
|
||||
}
|
||||
|
||||
function usePrefersReducedMotion(): boolean {
|
||||
const [reduced, setReduced] = useState(() => {
|
||||
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
||||
return false
|
||||
}
|
||||
return window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||
})
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
||||
return
|
||||
}
|
||||
const mq = window.matchMedia('(prefers-reduced-motion: reduce)')
|
||||
const onChange = (event: MediaQueryListEvent): void => setReduced(event.matches)
|
||||
mq.addEventListener('change', onChange)
|
||||
return () => mq.removeEventListener('change', onChange)
|
||||
}, [])
|
||||
return reduced
|
||||
}
|
||||
|
||||
// Why: keep a default for the cached helpers below; the live size now comes
|
||||
// from the store so the user can resize from the status-bar menu.
|
||||
const SIZE = 180
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
const REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)'
|
||||
|
||||
function readPrefersReducedMotion(): boolean {
|
||||
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
||||
return false
|
||||
}
|
||||
return window.matchMedia(REDUCED_MOTION_QUERY).matches
|
||||
}
|
||||
|
||||
export function usePrefersReducedMotion(): boolean {
|
||||
const [prefersReducedMotion, setPrefersReducedMotion] = useState(readPrefersReducedMotion)
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
||||
return
|
||||
}
|
||||
const media = window.matchMedia(REDUCED_MOTION_QUERY)
|
||||
setPrefersReducedMotion(media.matches)
|
||||
const onChange = (event: MediaQueryListEvent): void => {
|
||||
setPrefersReducedMotion(event.matches)
|
||||
}
|
||||
media.addEventListener('change', onChange)
|
||||
return () => media.removeEventListener('change', onChange)
|
||||
}, [])
|
||||
|
||||
return prefersReducedMotion
|
||||
}
|
||||
Reference in New Issue
Block a user