Files
36-character-flower/src/lib/utils.ts
2026-05-22 17:58:52 +08:00

104 lines
2.7 KiB
TypeScript

import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
import { FULLSCREEN_CHANGE_EVENTS } from '@/constants'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
type FullscreenCapableElement = HTMLElement & {
mozRequestFullScreen?: () => Promise<void> | void
msRequestFullscreen?: () => Promise<void> | void
webkitRequestFullscreen?: () => Promise<void> | void
}
type FullscreenCapableDocument = Document & {
mozCancelFullScreen?: () => Promise<void> | void
mozFullScreenElement?: Element | null
msExitFullscreen?: () => Promise<void> | void
msFullscreenElement?: Element | null
webkitExitFullscreen?: () => Promise<void> | void
webkitFullscreenElement?: Element | null
}
export function isDesktopFullscreen() {
if (typeof document === 'undefined') {
return false
}
const fullscreenDocument = document as FullscreenCapableDocument
return Boolean(
document.fullscreenElement ||
fullscreenDocument.webkitFullscreenElement ||
fullscreenDocument.mozFullScreenElement ||
fullscreenDocument.msFullscreenElement,
)
}
export async function exitDesktopFullscreen() {
if (typeof document === 'undefined') {
return false
}
const fullscreenDocument = document as FullscreenCapableDocument
await Promise.resolve(
document.exitFullscreen?.() ??
fullscreenDocument.webkitExitFullscreen?.() ??
fullscreenDocument.mozCancelFullScreen?.() ??
fullscreenDocument.msExitFullscreen?.(),
)
return !isDesktopFullscreen()
}
export function subscribeDesktopFullscreenChange(listener: () => void) {
if (typeof document === 'undefined') {
return () => {}
}
for (const eventName of FULLSCREEN_CHANGE_EVENTS) {
document.addEventListener(eventName, listener)
}
return () => {
for (const eventName of FULLSCREEN_CHANGE_EVENTS) {
document.removeEventListener(eventName, listener)
}
}
}
export async function requestDesktopFullscreen(
target: HTMLElement = document.documentElement,
) {
if (typeof window === 'undefined' || typeof document === 'undefined') {
return false
}
if (isDesktopFullscreen()) {
return true
}
const fullscreenTarget = target as FullscreenCapableElement
await Promise.resolve(
fullscreenTarget.requestFullscreen?.() ??
fullscreenTarget.webkitRequestFullscreen?.() ??
fullscreenTarget.mozRequestFullScreen?.() ??
fullscreenTarget.msRequestFullscreen?.(),
)
return isDesktopFullscreen()
}
export async function toggleDesktopFullscreen(
target: HTMLElement = document.documentElement,
) {
if (isDesktopFullscreen()) {
return exitDesktopFullscreen()
}
return requestDesktopFullscreen(target)
}