mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
docs: simplify the reference and tighten the verifier (#2736)
This commit is contained in:
1 parent
6af33c7188
commit
7375ac9d80
111 files changed
+1616
-2430
No files matched your search
@@ -1,83 +1,54 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {observeResize} from '@app/features/platform/utils/SharedResizeObserver';
|
||||
import {useEffect, useState} from 'react';
|
||||
|
||||
type Callback = (el: Element) => void;
|
||||
|
||||
function observeElement(el: Element, cb: Callback): () => void {
|
||||
if (typeof ResizeObserver === 'undefined') return () => {};
|
||||
return observeResize(el, () => cb(el));
|
||||
}
|
||||
import {type RefObject, useEffect, useState} from 'react';
|
||||
|
||||
type OverflowAxis = 'horizontal' | 'vertical' | 'both';
|
||||
|
||||
function getElementOverflowState(el: HTMLElement, axis: OverflowAxis): boolean {
|
||||
const {scrollWidth, clientWidth, scrollHeight, clientHeight} = el;
|
||||
const horizontalOverflowing = scrollWidth - clientWidth > 1;
|
||||
const verticalOverflowing = scrollHeight - clientHeight > 1;
|
||||
return axis === 'horizontal'
|
||||
? horizontalOverflowing
|
||||
: axis === 'vertical'
|
||||
? verticalOverflowing
|
||||
: horizontalOverflowing || verticalOverflowing;
|
||||
return (
|
||||
(axis !== 'vertical' && el.scrollWidth - el.clientWidth > 1) ||
|
||||
(axis !== 'horizontal' && el.scrollHeight - el.clientHeight > 1)
|
||||
);
|
||||
}
|
||||
|
||||
export function useElementOverflow(element: HTMLElement | null, axis: OverflowAxis = 'horizontal'): boolean {
|
||||
function useOverflow(target: HTMLElement | RefObject<HTMLElement | null> | null, axis: OverflowAxis): boolean {
|
||||
const [isOverflowing, setIsOverflowing] = useState(false);
|
||||
useEffect(() => {
|
||||
if (!element) {
|
||||
const element = target && 'current' in target ? target.current : target;
|
||||
const ownerWindow = element?.ownerDocument.defaultView;
|
||||
if (!element || !ownerWindow) {
|
||||
setIsOverflowing(false);
|
||||
return;
|
||||
}
|
||||
let rafId: number | null = null;
|
||||
let disposed = false;
|
||||
const checkOverflow = () => {
|
||||
rafId = null;
|
||||
const overflowing = getElementOverflowState(element, axis);
|
||||
setIsOverflowing((prev) => (prev === overflowing ? prev : overflowing));
|
||||
};
|
||||
const scheduleCheckOverflow = () => {
|
||||
if (rafId != null) return;
|
||||
rafId = requestAnimationFrame(checkOverflow);
|
||||
if (disposed || rafId != null) return;
|
||||
rafId = ownerWindow.requestAnimationFrame(checkOverflow);
|
||||
};
|
||||
scheduleCheckOverflow();
|
||||
const unobserve = observeElement(element, scheduleCheckOverflow);
|
||||
const unobserve = typeof ResizeObserver === 'undefined' ? undefined : observeResize(element, scheduleCheckOverflow);
|
||||
return () => {
|
||||
disposed = true;
|
||||
if (rafId != null) {
|
||||
cancelAnimationFrame(rafId);
|
||||
ownerWindow.cancelAnimationFrame(rafId);
|
||||
}
|
||||
unobserve();
|
||||
unobserve?.();
|
||||
};
|
||||
}, [element, axis]);
|
||||
}, [target, axis]);
|
||||
return isOverflowing;
|
||||
}
|
||||
|
||||
export function useTextOverflow(ref: React.RefObject<HTMLElement | null>, axis: OverflowAxis = 'horizontal'): boolean {
|
||||
const [isOverflowing, setIsOverflowing] = useState(false);
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
if (!el) {
|
||||
setIsOverflowing(false);
|
||||
return;
|
||||
}
|
||||
let rafId: number | null = null;
|
||||
const checkOverflow = () => {
|
||||
rafId = null;
|
||||
const overflowing = getElementOverflowState(el, axis);
|
||||
setIsOverflowing((prev) => (prev === overflowing ? prev : overflowing));
|
||||
};
|
||||
const scheduleCheckOverflow = () => {
|
||||
if (rafId != null) return;
|
||||
rafId = requestAnimationFrame(checkOverflow);
|
||||
};
|
||||
scheduleCheckOverflow();
|
||||
const unobserve = observeElement(el, scheduleCheckOverflow);
|
||||
return () => {
|
||||
if (rafId != null) {
|
||||
cancelAnimationFrame(rafId);
|
||||
}
|
||||
unobserve();
|
||||
};
|
||||
}, [ref, axis]);
|
||||
return isOverflowing;
|
||||
export function useElementOverflow(element: HTMLElement | null, axis: OverflowAxis = 'horizontal'): boolean {
|
||||
return useOverflow(element, axis);
|
||||
}
|
||||
|
||||
export function useTextOverflow(ref: RefObject<HTMLElement | null>, axis: OverflowAxis = 'horizontal'): boolean {
|
||||
return useOverflow(ref, axis);
|
||||
}
|
||||
Reference in new issue
Block a user