xxf_react 0.8.3 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/dist/cache/CacheEntry.d.ts +0 -28
- package/dist/cache/CacheEntry.d.ts.map +0 -1
- package/dist/cache/CacheEntry.js +0 -1
- package/dist/cache/DiskCacheConfig.d.ts +0 -56
- package/dist/cache/DiskCacheConfig.d.ts.map +0 -1
- package/dist/cache/DiskCacheConfig.js +0 -4
- package/dist/cache/DiskLruCache.d.ts +0 -69
- package/dist/cache/DiskLruCache.d.ts.map +0 -1
- package/dist/cache/DiskLruCache.js +0 -305
- package/dist/cache/LruMetadata.d.ts +0 -28
- package/dist/cache/LruMetadata.d.ts.map +0 -1
- package/dist/cache/LruMetadata.js +0 -6
- package/dist/cache/index.d.ts +0 -5
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/index.js +0 -2
- package/dist/event-bus/EventBus.d.ts +0 -176
- package/dist/event-bus/EventBus.d.ts.map +0 -1
- package/dist/event-bus/EventBus.js +0 -278
- package/dist/event-bus/EventDemo.d.ts +0 -71
- package/dist/event-bus/EventDemo.d.ts.map +0 -1
- package/dist/event-bus/EventDemo.js +0 -76
- package/dist/event-bus/EventHooks.d.ts +0 -48
- package/dist/event-bus/EventHooks.d.ts.map +0 -1
- package/dist/event-bus/EventHooks.js +0 -73
- package/dist/event-bus/index.d.ts +0 -3
- package/dist/event-bus/index.d.ts.map +0 -1
- package/dist/event-bus/index.js +0 -2
- package/dist/fetch/Fetch.d.ts +0 -9
- package/dist/fetch/Fetch.d.ts.map +0 -1
- package/dist/fetch/Fetch.js +0 -54
- package/dist/fetch/TimeoutError.d.ts +0 -7
- package/dist/fetch/TimeoutError.d.ts.map +0 -1
- package/dist/fetch/TimeoutError.js +0 -23
- package/dist/fetch/index.d.ts +0 -3
- package/dist/fetch/index.d.ts.map +0 -1
- package/dist/fetch/index.js +0 -2
- package/dist/flow/PromiseExt.d.ts +0 -8
- package/dist/flow/PromiseExt.d.ts.map +0 -1
- package/dist/flow/PromiseExt.js +0 -50
- package/dist/flow/PromiseLifecycle.d.ts +0 -33
- package/dist/flow/PromiseLifecycle.d.ts.map +0 -1
- package/dist/flow/PromiseLifecycle.js +0 -37
- package/dist/flow/PromiseLoading.d.ts +0 -25
- package/dist/flow/PromiseLoading.d.ts.map +0 -1
- package/dist/flow/PromiseLoading.js +0 -30
- package/dist/flow/index.d.ts +0 -4
- package/dist/flow/index.d.ts.map +0 -1
- package/dist/flow/index.js +0 -3
- package/dist/foundation/Copy.d.ts +0 -8
- package/dist/foundation/Copy.d.ts.map +0 -1
- package/dist/foundation/Copy.js +0 -21
- package/dist/foundation/Debug.d.ts +0 -7
- package/dist/foundation/Debug.d.ts.map +0 -1
- package/dist/foundation/Debug.js +0 -12
- package/dist/foundation/LayoutSize.d.ts +0 -5
- package/dist/foundation/LayoutSize.d.ts.map +0 -1
- package/dist/foundation/LayoutSize.js +0 -1
- package/dist/foundation/PerformanceMonitor.d.ts +0 -13
- package/dist/foundation/PerformanceMonitor.d.ts.map +0 -1
- package/dist/foundation/PerformanceMonitor.js +0 -26
- package/dist/foundation/index.d.ts +0 -5
- package/dist/foundation/index.d.ts.map +0 -1
- package/dist/foundation/index.js +0 -4
- package/dist/http/api/ApiBuilder.d.ts +0 -251
- package/dist/http/api/ApiBuilder.d.ts.map +0 -1
- package/dist/http/api/ApiBuilder.js +0 -189
- package/dist/http/api/index.d.ts +0 -2
- package/dist/http/api/index.d.ts.map +0 -1
- package/dist/http/api/index.js +0 -1
- package/dist/http/cache/HttpCache.d.ts +0 -59
- package/dist/http/cache/HttpCache.d.ts.map +0 -1
- package/dist/http/cache/HttpCache.js +0 -215
- package/dist/http/cache/index.d.ts +0 -3
- package/dist/http/cache/index.d.ts.map +0 -1
- package/dist/http/cache/index.js +0 -2
- package/dist/http/client/ApiStream.d.ts +0 -80
- package/dist/http/client/ApiStream.d.ts.map +0 -1
- package/dist/http/client/ApiStream.js +0 -190
- package/dist/http/client/HttpClient.d.ts +0 -88
- package/dist/http/client/HttpClient.d.ts.map +0 -1
- package/dist/http/client/HttpClient.js +0 -381
- package/dist/http/client/index.d.ts +0 -3
- package/dist/http/client/index.d.ts.map +0 -1
- package/dist/http/client/index.js +0 -2
- package/dist/http/demo/api-builder.demo.d.ts +0 -102
- package/dist/http/demo/api-builder.demo.d.ts.map +0 -1
- package/dist/http/demo/api-builder.demo.js +0 -343
- package/dist/http/index.d.ts +0 -52
- package/dist/http/index.d.ts.map +0 -1
- package/dist/http/index.js +0 -61
- package/dist/http/interceptor/CacheInterceptor.d.ts +0 -112
- package/dist/http/interceptor/CacheInterceptor.d.ts.map +0 -1
- package/dist/http/interceptor/CacheInterceptor.js +0 -6
- package/dist/http/interceptor/DefaultCacheInterceptor.d.ts +0 -53
- package/dist/http/interceptor/DefaultCacheInterceptor.d.ts.map +0 -1
- package/dist/http/interceptor/DefaultCacheInterceptor.js +0 -106
- package/dist/http/interceptor/index.d.ts +0 -3
- package/dist/http/interceptor/index.d.ts.map +0 -1
- package/dist/http/interceptor/index.js +0 -2
- package/dist/http/models/ApiTypes.d.ts +0 -54
- package/dist/http/models/ApiTypes.d.ts.map +0 -1
- package/dist/http/models/ApiTypes.js +0 -4
- package/dist/http/models/CacheConfig.d.ts +0 -58
- package/dist/http/models/CacheConfig.d.ts.map +0 -1
- package/dist/http/models/CacheConfig.js +0 -4
- package/dist/http/models/CacheMode.d.ts +0 -45
- package/dist/http/models/CacheMode.d.ts.map +0 -1
- package/dist/http/models/CacheMode.js +0 -45
- package/dist/http/models/HttpClientConfig.d.ts +0 -90
- package/dist/http/models/HttpClientConfig.d.ts.map +0 -1
- package/dist/http/models/HttpClientConfig.js +0 -4
- package/dist/http/models/RequestConfig.d.ts +0 -67
- package/dist/http/models/RequestConfig.d.ts.map +0 -1
- package/dist/http/models/RequestConfig.js +0 -4
- package/dist/http/models/index.d.ts +0 -24
- package/dist/http/models/index.d.ts.map +0 -1
- package/dist/http/models/index.js +0 -16
- package/dist/http/types.d.ts +0 -13
- package/dist/http/types.d.ts.map +0 -1
- package/dist/http/types.js +0 -14
- package/dist/index.d.ts +0 -15
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -20
- package/dist/layout/button/XButton.d.ts +0 -99
- package/dist/layout/button/XButton.d.ts.map +0 -1
- package/dist/layout/button/XButton.js +0 -131
- package/dist/layout/hover/XHover.d.ts +0 -147
- package/dist/layout/hover/XHover.d.ts.map +0 -1
- package/dist/layout/hover/XHover.js +0 -128
- package/dist/layout/image/XImage.d.ts +0 -35
- package/dist/layout/image/XImage.d.ts.map +0 -1
- package/dist/layout/image/XImage.effects.d.ts +0 -16
- package/dist/layout/image/XImage.effects.d.ts.map +0 -1
- package/dist/layout/image/XImage.effects.js +0 -77
- package/dist/layout/image/XImage.js +0 -261
- package/dist/layout/image/XImage.types.d.ts +0 -130
- package/dist/layout/image/XImage.types.d.ts.map +0 -1
- package/dist/layout/image/XImage.types.js +0 -2
- package/dist/layout/image/XImageGallery.d.ts +0 -76
- package/dist/layout/image/XImageGallery.d.ts.map +0 -1
- package/dist/layout/image/XImageGallery.js +0 -94
- package/dist/layout/image/index.d.ts +0 -12
- package/dist/layout/image/index.d.ts.map +0 -1
- package/dist/layout/image/index.js +0 -4
- package/dist/layout/index.d.ts +0 -12
- package/dist/layout/index.d.ts.map +0 -1
- package/dist/layout/index.js +0 -11
- package/dist/layout/resize/core/ResizeObserverHook.d.ts +0 -41
- package/dist/layout/resize/core/ResizeObserverHook.d.ts.map +0 -1
- package/dist/layout/resize/core/ResizeObserverHook.js +0 -57
- package/dist/layout/resize/core/SizedLayoutContext.d.ts +0 -23
- package/dist/layout/resize/core/SizedLayoutContext.d.ts.map +0 -1
- package/dist/layout/resize/core/SizedLayoutContext.js +0 -23
- package/dist/layout/resize/core/SizedLayoutProps.d.ts +0 -19
- package/dist/layout/resize/core/SizedLayoutProps.d.ts.map +0 -1
- package/dist/layout/resize/core/SizedLayoutProps.js +0 -1
- package/dist/layout/resize/impl/SizedContainer.d.ts +0 -45
- package/dist/layout/resize/impl/SizedContainer.d.ts.map +0 -1
- package/dist/layout/resize/impl/SizedContainer.js +0 -65
- package/dist/layout/resize/impl/SizedLayout.d.ts +0 -45
- package/dist/layout/resize/impl/SizedLayout.d.ts.map +0 -1
- package/dist/layout/resize/impl/SizedLayout.js +0 -65
- package/dist/layout/spinner/XSpinner.d.ts +0 -43
- package/dist/layout/spinner/XSpinner.d.ts.map +0 -1
- package/dist/layout/spinner/XSpinner.js +0 -47
- package/dist/layout/virtualized/VirtualizedConfig.d.ts +0 -16
- package/dist/layout/virtualized/VirtualizedConfig.d.ts.map +0 -1
- package/dist/layout/virtualized/VirtualizedConfig.js +0 -15
- package/dist/layout/visibility/ElementVisibilityHooks.d.ts +0 -13
- package/dist/layout/visibility/ElementVisibilityHooks.d.ts.map +0 -1
- package/dist/layout/visibility/ElementVisibilityHooks.js +0 -119
- package/dist/media/components/XVideo.d.ts +0 -205
- package/dist/media/components/XVideo.d.ts.map +0 -1
- package/dist/media/components/XVideo.js +0 -297
- package/dist/media/components/XVideoBufferingIndicator.d.ts +0 -13
- package/dist/media/components/XVideoBufferingIndicator.d.ts.map +0 -1
- package/dist/media/components/XVideoBufferingIndicator.js +0 -13
- package/dist/media/components/XVideoErrorIndicator.d.ts +0 -15
- package/dist/media/components/XVideoErrorIndicator.d.ts.map +0 -1
- package/dist/media/components/XVideoErrorIndicator.js +0 -19
- package/dist/media/index.d.ts +0 -7
- package/dist/media/index.d.ts.map +0 -1
- package/dist/media/index.js +0 -7
- package/dist/media/playback-queue-store.d.ts +0 -746
- package/dist/media/playback-queue-store.d.ts.map +0 -1
- package/dist/media/playback-queue-store.js +0 -670
- package/dist/media/video-play-safe.d.ts +0 -26
- package/dist/media/video-play-safe.d.ts.map +0 -1
- package/dist/media/video-play-safe.js +0 -56
- package/dist/media/video-state.d.ts +0 -38
- package/dist/media/video-state.d.ts.map +0 -1
- package/dist/media/video-state.js +0 -125
- package/dist/models/ApiPageDataFieldDTO.d.ts +0 -9
- package/dist/models/ApiPageDataFieldDTO.d.ts.map +0 -1
- package/dist/models/ApiPageDataFieldDTO.js +0 -1
- package/dist/models/ApiResponse.d.ts +0 -29
- package/dist/models/ApiResponse.d.ts.map +0 -1
- package/dist/models/ApiResponse.js +0 -32
- package/dist/models/PaginationDTO.d.ts +0 -8
- package/dist/models/PaginationDTO.d.ts.map +0 -1
- package/dist/models/PaginationDTO.js +0 -6
- package/dist/models/index.d.ts +0 -4
- package/dist/models/index.d.ts.map +0 -1
- package/dist/models/index.js +0 -3
- package/dist/refresh/LoadMoreAsync.d.ts +0 -36
- package/dist/refresh/LoadMoreAsync.d.ts.map +0 -1
- package/dist/refresh/LoadMoreAsync.js +0 -55
- package/dist/refresh/index.d.ts +0 -2
- package/dist/refresh/index.d.ts.map +0 -1
- package/dist/refresh/index.js +0 -2
- package/dist/responsive/BrowserAdapter.d.ts +0 -26
- package/dist/responsive/BrowserAdapter.d.ts.map +0 -1
- package/dist/responsive/BrowserAdapter.js +0 -79
- package/dist/responsive/ScreenAdapter.d.ts +0 -2
- package/dist/responsive/ScreenAdapter.d.ts.map +0 -1
- package/dist/responsive/ScreenAdapter.js +0 -5
- package/dist/responsive/index.d.ts +0 -3
- package/dist/responsive/index.d.ts.map +0 -1
- package/dist/responsive/index.js +0 -3
- package/dist/sse/SSEManager.d.ts +0 -21
- package/dist/sse/SSEManager.d.ts.map +0 -1
- package/dist/sse/SSEManager.js +0 -73
- package/dist/sse/SSERegistry.d.ts +0 -20
- package/dist/sse/SSERegistry.d.ts.map +0 -1
- package/dist/sse/SSERegistry.js +0 -36
- package/dist/sse/SSEStatus.d.ts +0 -7
- package/dist/sse/SSEStatus.d.ts.map +0 -1
- package/dist/sse/SSEStatus.js +0 -7
- package/dist/sse/UseSSE.d.ts +0 -13
- package/dist/sse/UseSSE.d.ts.map +0 -1
- package/dist/sse/UseSSE.js +0 -39
- package/dist/sse/index.d.ts +0 -5
- package/dist/sse/index.d.ts.map +0 -1
- package/dist/sse/index.js +0 -5
- package/dist/utils/MIME.d.ts +0 -137
- package/dist/utils/MIME.d.ts.map +0 -1
- package/dist/utils/MIME.js +0 -192
- package/dist/utils/Reload.d.ts +0 -62
- package/dist/utils/Reload.d.ts.map +0 -1
- package/dist/utils/Reload.js +0 -66
- package/dist/utils/ScrollToCenter.d.ts +0 -72
- package/dist/utils/ScrollToCenter.d.ts.map +0 -1
- package/dist/utils/ScrollToCenter.js +0 -145
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -5
- package/dist/utils/url-placholder.d.ts +0 -14
- package/dist/utils/url-placholder.d.ts.map +0 -1
- package/dist/utils/url-placholder.js +0 -17
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect, useRef } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* 基于 ResizeObserver 监听容器尺寸变化
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```tsx
|
|
7
|
-
* const { containerRef, containerWidth, containerHeight, isContainerReady } = useResizeObserver();
|
|
8
|
-
*
|
|
9
|
-
* return (
|
|
10
|
-
* <div ref={containerRef}>
|
|
11
|
-
* {isContainerReady && <Chart width={containerWidth} height={containerHeight} />}
|
|
12
|
-
* </div>
|
|
13
|
-
* );
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```tsx
|
|
18
|
-
* // 带防抖
|
|
19
|
-
* const { containerRef, containerHeight } = useResizeObserver({ debounce: 100 });
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export function useResizeObserver(options = {}) {
|
|
23
|
-
const { debounce = 0, initialSize = { width: 0, height: 0 } } = options;
|
|
24
|
-
const containerRef = useRef(null);
|
|
25
|
-
const [size, setSize] = useState(initialSize);
|
|
26
|
-
const timeoutRef = useRef(null);
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
const element = containerRef.current;
|
|
29
|
-
if (!element)
|
|
30
|
-
return;
|
|
31
|
-
const updateSize = (entries) => {
|
|
32
|
-
var _a, _b;
|
|
33
|
-
const { width, height } = (_b = (_a = entries[0]) === null || _a === void 0 ? void 0 : _a.contentRect) !== null && _b !== void 0 ? _b : { width: 0, height: 0 };
|
|
34
|
-
if (debounce > 0) {
|
|
35
|
-
if (timeoutRef.current)
|
|
36
|
-
clearTimeout(timeoutRef.current);
|
|
37
|
-
timeoutRef.current = setTimeout(() => setSize({ width, height }), debounce);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
setSize({ width, height });
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
const observer = new ResizeObserver(updateSize);
|
|
44
|
-
observer.observe(element);
|
|
45
|
-
return () => {
|
|
46
|
-
observer.disconnect();
|
|
47
|
-
if (timeoutRef.current)
|
|
48
|
-
clearTimeout(timeoutRef.current);
|
|
49
|
-
};
|
|
50
|
-
}, [debounce]);
|
|
51
|
-
return {
|
|
52
|
-
containerRef,
|
|
53
|
-
containerWidth: size.width,
|
|
54
|
-
containerHeight: size.height,
|
|
55
|
-
isContainerReady: size.width > 0 && size.height > 0,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { LayoutSize } from "../../../foundation/LayoutSize";
|
|
2
|
-
/** Context 中的尺寸状态 */
|
|
3
|
-
export interface SizedLayoutContextValue extends LayoutSize {
|
|
4
|
-
/** 是否已获取到有效尺寸 */
|
|
5
|
-
isReady: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare const SizedLayoutContext: import("react").Context<SizedLayoutContextValue | null>;
|
|
8
|
-
/**
|
|
9
|
-
* 获取父级容器(SizedLayout 或 SizedContainer)的尺寸
|
|
10
|
-
*
|
|
11
|
-
* @throws 如果不在 SizedLayout 或 SizedContainer 内部使用会抛出错误
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```tsx
|
|
15
|
-
* function ChildComponent() {
|
|
16
|
-
* const { width, height, isReady } = useContextLayoutSize();
|
|
17
|
-
* if (!isReady) return <Loading />;
|
|
18
|
-
* return <div style={{ width, height }}>...</div>;
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare function useContextLayoutSize(): SizedLayoutContextValue;
|
|
23
|
-
//# sourceMappingURL=SizedLayoutContext.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SizedLayoutContext.d.ts","sourceRoot":"","sources":["../../../../src/layout/resize/core/SizedLayoutContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,gCAAgC,CAAC;AAG1D,qBAAqB;AACrB,MAAM,WAAW,uBAAwB,SAAQ,UAAU;IACvD,iBAAiB;IACjB,OAAO,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,kBAAkB,yDAAsD,CAAC;AAEtF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,IAAI,uBAAuB,CAM9D"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from "react";
|
|
2
|
-
export const SizedLayoutContext = createContext(null);
|
|
3
|
-
/**
|
|
4
|
-
* 获取父级容器(SizedLayout 或 SizedContainer)的尺寸
|
|
5
|
-
*
|
|
6
|
-
* @throws 如果不在 SizedLayout 或 SizedContainer 内部使用会抛出错误
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```tsx
|
|
10
|
-
* function ChildComponent() {
|
|
11
|
-
* const { width, height, isReady } = useContextLayoutSize();
|
|
12
|
-
* if (!isReady) return <Loading />;
|
|
13
|
-
* return <div style={{ width, height }}>...</div>;
|
|
14
|
-
* }
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
export function useContextLayoutSize() {
|
|
18
|
-
const context = useContext(SizedLayoutContext);
|
|
19
|
-
if (!context) {
|
|
20
|
-
throw new Error('useContextLayoutSize must be used within a SizedLayout or SizedContainer');
|
|
21
|
-
}
|
|
22
|
-
return context;
|
|
23
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { CSSProperties, ElementType, ReactNode } from "react";
|
|
2
|
-
import { LayoutSize } from "../../../foundation/LayoutSize";
|
|
3
|
-
export interface SizedLayoutProps {
|
|
4
|
-
/** 子元素 */
|
|
5
|
-
children: ReactNode;
|
|
6
|
-
/** 容器的 className */
|
|
7
|
-
className?: string;
|
|
8
|
-
/** 容器的 style */
|
|
9
|
-
style?: CSSProperties;
|
|
10
|
-
/** 自定义容器元素类型,默认 div */
|
|
11
|
-
as?: ElementType;
|
|
12
|
-
/** 防抖延迟(毫秒) */
|
|
13
|
-
debounce?: number;
|
|
14
|
-
/** 尺寸未就绪时显示的占位内容 */
|
|
15
|
-
fallback?: ReactNode;
|
|
16
|
-
/** 尺寸变化时的回调 */
|
|
17
|
-
onResize?: (size: LayoutSize) => void;
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=SizedLayoutProps.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SizedLayoutProps.d.ts","sourceRoot":"","sources":["../../../../src/layout/resize/core/SizedLayoutProps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,WAAW,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAC,UAAU,EAAC,MAAM,gCAAgC,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC7B,UAAU;IACV,QAAQ,EAAE,SAAS,CAAC;IACpB,oBAAoB;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,uBAAuB;IACvB,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,eAAe;IACf,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACzC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { SizedLayoutProps } from "../core/SizedLayoutProps";
|
|
3
|
-
/**
|
|
4
|
-
* 自动测量尺寸的容器组件(基于 react-resize-detector)
|
|
5
|
-
*
|
|
6
|
-
* 子组件通过 useContextLayoutSize() 获取容器尺寸,适用于需要根据父容器尺寸
|
|
7
|
-
* 进行布局的场景(如虚拟列表、图表、Canvas 等)。
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```tsx
|
|
11
|
-
* // 基础用法
|
|
12
|
-
* <SizedContainer className="h-full w-full">
|
|
13
|
-
* <ChartComponent />
|
|
14
|
-
* </SizedContainer>
|
|
15
|
-
*
|
|
16
|
-
* // ChartComponent 内部
|
|
17
|
-
* function ChartComponent() {
|
|
18
|
-
* const { width, height, isReady } = useContextLayoutSize();
|
|
19
|
-
* if (!isReady) return <Skeleton />;
|
|
20
|
-
* return <Chart width={width} height={height} />;
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```tsx
|
|
26
|
-
* // 带 fallback 的用法
|
|
27
|
-
* <SizedContainer fallback={<Loading />} className="h-full">
|
|
28
|
-
* <VirtualList />
|
|
29
|
-
* </SizedContainer>
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```tsx
|
|
34
|
-
* // 自定义元素类型 + 尺寸变化回调
|
|
35
|
-
* <SizedContainer
|
|
36
|
-
* as="section"
|
|
37
|
-
* debounce={100}
|
|
38
|
-
* onResize={({ width, height }) => console.log(width, height)}
|
|
39
|
-
* >
|
|
40
|
-
* <Content />
|
|
41
|
-
* </SizedContainer>
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export declare function SizedContainer({ children, className, style, as: Component, debounce, fallback, onResize, }: SizedLayoutProps): React.JSX.Element;
|
|
45
|
-
//# sourceMappingURL=SizedContainer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SizedContainer.d.ts","sourceRoot":"","sources":["../../../../src/layout/resize/impl/SizedContainer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAK1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,cAAc,CAAC,EACI,QAAQ,EACR,SAAS,EACT,KAAK,EACL,EAAE,EAAE,SAAiB,EACrB,QAAQ,EACR,QAAQ,EACR,QAAQ,GACX,EAAE,gBAAgB,qBA2BjD"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useResizeDetector } from 'react-resize-detector';
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { SizedLayoutContext } from "../core/SizedLayoutContext";
|
|
5
|
-
/**
|
|
6
|
-
* 自动测量尺寸的容器组件(基于 react-resize-detector)
|
|
7
|
-
*
|
|
8
|
-
* 子组件通过 useContextLayoutSize() 获取容器尺寸,适用于需要根据父容器尺寸
|
|
9
|
-
* 进行布局的场景(如虚拟列表、图表、Canvas 等)。
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```tsx
|
|
13
|
-
* // 基础用法
|
|
14
|
-
* <SizedContainer className="h-full w-full">
|
|
15
|
-
* <ChartComponent />
|
|
16
|
-
* </SizedContainer>
|
|
17
|
-
*
|
|
18
|
-
* // ChartComponent 内部
|
|
19
|
-
* function ChartComponent() {
|
|
20
|
-
* const { width, height, isReady } = useContextLayoutSize();
|
|
21
|
-
* if (!isReady) return <Skeleton />;
|
|
22
|
-
* return <Chart width={width} height={height} />;
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```tsx
|
|
28
|
-
* // 带 fallback 的用法
|
|
29
|
-
* <SizedContainer fallback={<Loading />} className="h-full">
|
|
30
|
-
* <VirtualList />
|
|
31
|
-
* </SizedContainer>
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```tsx
|
|
36
|
-
* // 自定义元素类型 + 尺寸变化回调
|
|
37
|
-
* <SizedContainer
|
|
38
|
-
* as="section"
|
|
39
|
-
* debounce={100}
|
|
40
|
-
* onResize={({ width, height }) => console.log(width, height)}
|
|
41
|
-
* >
|
|
42
|
-
* <Content />
|
|
43
|
-
* </SizedContainer>
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export function SizedContainer({ children, className, style, as: Component = 'div', debounce, fallback, onResize, }) {
|
|
47
|
-
const { width, height, ref } = useResizeDetector({
|
|
48
|
-
refreshMode: debounce ? 'debounce' : undefined,
|
|
49
|
-
refreshRate: debounce,
|
|
50
|
-
onResize: onResize
|
|
51
|
-
? ({ width: w, height: h }) => {
|
|
52
|
-
if (w !== null && h !== null) {
|
|
53
|
-
onResize({ width: w, height: h });
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
: undefined,
|
|
57
|
-
});
|
|
58
|
-
const size = {
|
|
59
|
-
width: width !== null && width !== void 0 ? width : 0,
|
|
60
|
-
height: height !== null && height !== void 0 ? height : 0,
|
|
61
|
-
};
|
|
62
|
-
const isReady = size.width > 0 && size.height > 0;
|
|
63
|
-
return (React.createElement(Component, { ref: ref, className: className, style: style },
|
|
64
|
-
React.createElement(SizedLayoutContext.Provider, { value: { ...size, isReady } }, fallback && !isReady ? fallback : children)));
|
|
65
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { SizedLayoutProps } from "../core/SizedLayoutProps";
|
|
3
|
-
/**
|
|
4
|
-
* 自动测量尺寸的布局容器
|
|
5
|
-
*
|
|
6
|
-
* 子组件通过 useContextLayoutSize() 获取容器尺寸,适用于需要根据父容器尺寸
|
|
7
|
-
* 进行布局的场景(如虚拟列表、图表、Canvas 等)。
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```tsx
|
|
11
|
-
* // 基础用法
|
|
12
|
-
* <SizedLayout className="h-full w-full">
|
|
13
|
-
* <ChartComponent />
|
|
14
|
-
* </SizedLayout>
|
|
15
|
-
*
|
|
16
|
-
* // ChartComponent 内部
|
|
17
|
-
* function ChartComponent() {
|
|
18
|
-
* const { width, height, isReady } = useContextLayoutSize();
|
|
19
|
-
* if (!isReady) return <Skeleton />;
|
|
20
|
-
* return <Chart width={width} height={height} />;
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```tsx
|
|
26
|
-
* // 带 fallback 的用法
|
|
27
|
-
* <SizedLayout fallback={<Loading />} className="h-full">
|
|
28
|
-
* <VirtualList />
|
|
29
|
-
* </SizedLayout>
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```tsx
|
|
34
|
-
* // 自定义元素类型 + 尺寸变化回调
|
|
35
|
-
* <SizedLayout
|
|
36
|
-
* as="section"
|
|
37
|
-
* debounce={100}
|
|
38
|
-
* onResize={({ width, height }) => console.log(width, height)}
|
|
39
|
-
* >
|
|
40
|
-
* <Content />
|
|
41
|
-
* </SizedLayout>
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export declare function SizedLayout({ children, className, style, as: Component, debounce, fallback, onResize, }: SizedLayoutProps): React.JSX.Element;
|
|
45
|
-
//# sourceMappingURL=SizedLayout.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SizedLayout.d.ts","sourceRoot":"","sources":["../../../../src/layout/resize/impl/SizedLayout.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,WAAW,CAAC,EACI,QAAQ,EACR,SAAS,EACT,KAAK,EACL,EAAE,EAAE,SAAiB,EACrB,QAAQ,EACR,QAAQ,EACR,QAAQ,GACX,EAAE,gBAAgB,qBA2B9C"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useEffect, useRef } from 'react';
|
|
3
|
-
import { useResizeObserver } from '../core/ResizeObserverHook';
|
|
4
|
-
import React from "react";
|
|
5
|
-
import { SizedLayoutContext } from "../core/SizedLayoutContext";
|
|
6
|
-
/**
|
|
7
|
-
* 自动测量尺寸的布局容器
|
|
8
|
-
*
|
|
9
|
-
* 子组件通过 useContextLayoutSize() 获取容器尺寸,适用于需要根据父容器尺寸
|
|
10
|
-
* 进行布局的场景(如虚拟列表、图表、Canvas 等)。
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* // 基础用法
|
|
15
|
-
* <SizedLayout className="h-full w-full">
|
|
16
|
-
* <ChartComponent />
|
|
17
|
-
* </SizedLayout>
|
|
18
|
-
*
|
|
19
|
-
* // ChartComponent 内部
|
|
20
|
-
* function ChartComponent() {
|
|
21
|
-
* const { width, height, isReady } = useContextLayoutSize();
|
|
22
|
-
* if (!isReady) return <Skeleton />;
|
|
23
|
-
* return <Chart width={width} height={height} />;
|
|
24
|
-
* }
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```tsx
|
|
29
|
-
* // 带 fallback 的用法
|
|
30
|
-
* <SizedLayout fallback={<Loading />} className="h-full">
|
|
31
|
-
* <VirtualList />
|
|
32
|
-
* </SizedLayout>
|
|
33
|
-
* ```
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```tsx
|
|
37
|
-
* // 自定义元素类型 + 尺寸变化回调
|
|
38
|
-
* <SizedLayout
|
|
39
|
-
* as="section"
|
|
40
|
-
* debounce={100}
|
|
41
|
-
* onResize={({ width, height }) => console.log(width, height)}
|
|
42
|
-
* >
|
|
43
|
-
* <Content />
|
|
44
|
-
* </SizedLayout>
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
export function SizedLayout({ children, className, style, as: Component = 'div', debounce, fallback, onResize, }) {
|
|
48
|
-
const { containerRef, containerWidth, containerHeight, isContainerReady } = useResizeObserver({
|
|
49
|
-
debounce,
|
|
50
|
-
});
|
|
51
|
-
const size = {
|
|
52
|
-
width: containerWidth,
|
|
53
|
-
height: containerHeight,
|
|
54
|
-
};
|
|
55
|
-
// 处理 onResize 回调
|
|
56
|
-
const onResizeRef = useRef(onResize);
|
|
57
|
-
onResizeRef.current = onResize;
|
|
58
|
-
useEffect(() => {
|
|
59
|
-
if (isContainerReady && onResizeRef.current) {
|
|
60
|
-
onResizeRef.current(size);
|
|
61
|
-
}
|
|
62
|
-
}, [containerWidth, containerHeight, isContainerReady]);
|
|
63
|
-
return (React.createElement(Component, { ref: containerRef, className: className, style: style },
|
|
64
|
-
React.createElement(SizedLayoutContext.Provider, { value: { ...size, isReady: isContainerReady } }, fallback && !isContainerReady ? fallback : children)));
|
|
65
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
/**
|
|
3
|
-
* XSpinner 组件属性
|
|
4
|
-
*/
|
|
5
|
-
export interface XSpinnerProps {
|
|
6
|
-
/**
|
|
7
|
-
* 自定义样式类名
|
|
8
|
-
* - 可覆盖默认的尺寸、颜色、动画等样式
|
|
9
|
-
* @example "w-8 h-8 border-blue-500"
|
|
10
|
-
*/
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* XSpinner - 轻量级加载指示器组件
|
|
15
|
-
*
|
|
16
|
-
* @description
|
|
17
|
-
* 使用 CSS border + rotate 动画实现的高性能 spinner:
|
|
18
|
-
* - 基于 div + Tailwind CSS,无 SVG 解析开销
|
|
19
|
-
* - 尺寸使用 `1em`,自动跟随父元素字体大小
|
|
20
|
-
* - 默认白色边框,适合深色背景
|
|
21
|
-
* - 可通过 className 完全自定义样式
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* ```tsx
|
|
25
|
-
* // 基本用法(跟随父元素字体大小)
|
|
26
|
-
* <XSpinner />
|
|
27
|
-
*
|
|
28
|
-
* // 自定义尺寸
|
|
29
|
-
* <XSpinner className="w-8 h-8" />
|
|
30
|
-
*
|
|
31
|
-
* // 自定义颜色(深色主题)
|
|
32
|
-
* <XSpinner className="border-gray-800 border-t-transparent" />
|
|
33
|
-
*
|
|
34
|
-
* // 在按钮中使用
|
|
35
|
-
* <button className="text-lg">
|
|
36
|
-
* <XSpinner /> 加载中...
|
|
37
|
-
* </button>
|
|
38
|
-
* ```
|
|
39
|
-
*
|
|
40
|
-
* @see XButton - 内置 XSpinner 作为默认加载指示器
|
|
41
|
-
*/
|
|
42
|
-
export declare const XSpinner: ({ className }?: XSpinnerProps) => React.JSX.Element;
|
|
43
|
-
//# sourceMappingURL=XSpinner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"XSpinner.d.ts","sourceRoot":"","sources":["../../../src/layout/spinner/XSpinner.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,QAAQ,GAAI,gBAAa,aAAkB,sBAoBvD,CAAC"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { cn } from "tailwind-variants";
|
|
4
|
-
/**
|
|
5
|
-
* XSpinner - 轻量级加载指示器组件
|
|
6
|
-
*
|
|
7
|
-
* @description
|
|
8
|
-
* 使用 CSS border + rotate 动画实现的高性能 spinner:
|
|
9
|
-
* - 基于 div + Tailwind CSS,无 SVG 解析开销
|
|
10
|
-
* - 尺寸使用 `1em`,自动跟随父元素字体大小
|
|
11
|
-
* - 默认白色边框,适合深色背景
|
|
12
|
-
* - 可通过 className 完全自定义样式
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```tsx
|
|
16
|
-
* // 基本用法(跟随父元素字体大小)
|
|
17
|
-
* <XSpinner />
|
|
18
|
-
*
|
|
19
|
-
* // 自定义尺寸
|
|
20
|
-
* <XSpinner className="w-8 h-8" />
|
|
21
|
-
*
|
|
22
|
-
* // 自定义颜色(深色主题)
|
|
23
|
-
* <XSpinner className="border-gray-800 border-t-transparent" />
|
|
24
|
-
*
|
|
25
|
-
* // 在按钮中使用
|
|
26
|
-
* <button className="text-lg">
|
|
27
|
-
* <XSpinner /> 加载中...
|
|
28
|
-
* </button>
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @see XButton - 内置 XSpinner 作为默认加载指示器
|
|
32
|
-
*/
|
|
33
|
-
export const XSpinner = ({ className } = {}) => (React.createElement("div", { style: {
|
|
34
|
-
// 使用内联样式确保 em 单位正确跟随 font-size
|
|
35
|
-
width: '1em',
|
|
36
|
-
height: '1em',
|
|
37
|
-
// 边框粗细也跟随字体大小
|
|
38
|
-
borderWidth: '0.125em',
|
|
39
|
-
}, className: cn(
|
|
40
|
-
// 边框样式:白色圆环,顶部透明形成缺口
|
|
41
|
-
"border-solid border-current border-t-transparent rounded-full",
|
|
42
|
-
// 动画:无限旋转
|
|
43
|
-
"animate-spin",
|
|
44
|
-
// 透明度:略微降低避免过亮
|
|
45
|
-
"opacity-80",
|
|
46
|
-
// 用户自定义类名
|
|
47
|
-
className) }));
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Virtuoso 虚拟列表配置常量
|
|
3
|
-
* overscan: 可视区域外预渲染的像素数量
|
|
4
|
-
* - 值越大,预渲染越多,滚动越流畅,但内存占用增加
|
|
5
|
-
*/
|
|
6
|
-
export declare const VirtualizedOverscan: {
|
|
7
|
-
/** 小型列表或慢速滚动场景 (200px) */
|
|
8
|
-
readonly SMALL: 200;
|
|
9
|
-
/** 中等列表或正常滚动场景 (800px) */
|
|
10
|
-
readonly MEDIUM: 800;
|
|
11
|
-
/** 大型列表或快速滚动场景 (1200px) */
|
|
12
|
-
readonly LARGE: 1200;
|
|
13
|
-
/** 超大列表或极快速滚动场景 (2000px) */
|
|
14
|
-
readonly EXTRA_LARGE: 2000;
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=VirtualizedConfig.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualizedConfig.d.ts","sourceRoot":"","sources":["../../../src/layout/virtualized/VirtualizedConfig.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,mBAAmB;IAC5B,0BAA0B;;IAE1B,0BAA0B;;IAE1B,2BAA2B;;IAE3B,4BAA4B;;CAEtB,CAAA"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Virtuoso 虚拟列表配置常量
|
|
3
|
-
* overscan: 可视区域外预渲染的像素数量
|
|
4
|
-
* - 值越大,预渲染越多,滚动越流畅,但内存占用增加
|
|
5
|
-
*/
|
|
6
|
-
export const VirtualizedOverscan = {
|
|
7
|
-
/** 小型列表或慢速滚动场景 (200px) */
|
|
8
|
-
SMALL: 200,
|
|
9
|
-
/** 中等列表或正常滚动场景 (800px) */
|
|
10
|
-
MEDIUM: 800,
|
|
11
|
-
/** 大型列表或快速滚动场景 (1200px) */
|
|
12
|
-
LARGE: 1200,
|
|
13
|
-
/** 超大列表或极快速滚动场景 (2000px) */
|
|
14
|
-
EXTRA_LARGE: 2000,
|
|
15
|
-
};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { RefObject } from 'react';
|
|
2
|
-
/**
|
|
3
|
-
* 监听元素及其所有祖先的可见性
|
|
4
|
-
* 支持检测 display: none、visibility: hidden、opacity: 0
|
|
5
|
-
* 支持 Radix UI 的 data-state 属性变化(如 Tabs.Content)
|
|
6
|
-
*
|
|
7
|
-
* @param ref - 要监听的元素 ref
|
|
8
|
-
* @param debounceMs - 防抖时间(毫秒),默认 16ms(约一帧)
|
|
9
|
-
* @param ancestor - 是否同步检查祖先元素的可见性,默认 true
|
|
10
|
-
* @returns boolean | null - null 表示还未检测到结果
|
|
11
|
-
*/
|
|
12
|
-
export declare function useElementVisibility(ref: RefObject<HTMLElement | null>, debounceMs?: number, ancestor?: boolean): boolean | null;
|
|
13
|
-
//# sourceMappingURL=ElementVisibilityHooks.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ElementVisibilityHooks.d.ts","sourceRoot":"","sources":["../../../src/layout/visibility/ElementVisibilityHooks.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA8B,SAAS,EAAC,MAAM,OAAO,CAAA;AAE5D;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAChC,GAAG,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAClC,UAAU,GAAE,MAAW,EACvB,QAAQ,GAAE,OAAc,GACzB,OAAO,GAAG,IAAI,CAyHhB"}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useState, useEffect, useRef } from 'react';
|
|
3
|
-
/**
|
|
4
|
-
* 监听元素及其所有祖先的可见性
|
|
5
|
-
* 支持检测 display: none、visibility: hidden、opacity: 0
|
|
6
|
-
* 支持 Radix UI 的 data-state 属性变化(如 Tabs.Content)
|
|
7
|
-
*
|
|
8
|
-
* @param ref - 要监听的元素 ref
|
|
9
|
-
* @param debounceMs - 防抖时间(毫秒),默认 16ms(约一帧)
|
|
10
|
-
* @param ancestor - 是否同步检查祖先元素的可见性,默认 true
|
|
11
|
-
* @returns boolean | null - null 表示还未检测到结果
|
|
12
|
-
*/
|
|
13
|
-
export function useElementVisibility(ref, debounceMs = 16, ancestor = true) {
|
|
14
|
-
const [isVisible, setIsVisible] = useState(null);
|
|
15
|
-
const lastVisibleRef = useRef(null);
|
|
16
|
-
const timerRef = useRef(null);
|
|
17
|
-
const observerRef = useRef(null);
|
|
18
|
-
const debounceMsRef = useRef(debounceMs);
|
|
19
|
-
const mountedRef = useRef(true);
|
|
20
|
-
// 保持 debounceMs 最新,但不触发 effect 重新执行
|
|
21
|
-
debounceMsRef.current = debounceMs;
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
// 重置状态(处理组件重新挂载的情况)
|
|
24
|
-
mountedRef.current = true;
|
|
25
|
-
lastVisibleRef.current = null;
|
|
26
|
-
// 检查元素及所有祖先是否可见
|
|
27
|
-
const checkVisibility = () => {
|
|
28
|
-
if (!mountedRef.current)
|
|
29
|
-
return;
|
|
30
|
-
const el = ref.current;
|
|
31
|
-
if (!el)
|
|
32
|
-
return;
|
|
33
|
-
let current = el;
|
|
34
|
-
let visible = true;
|
|
35
|
-
while (current) {
|
|
36
|
-
const style = getComputedStyle(current);
|
|
37
|
-
if (style.display === 'none' ||
|
|
38
|
-
style.visibility === 'hidden' ||
|
|
39
|
-
style.opacity === '0') {
|
|
40
|
-
visible = false;
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
// 如果不检查祖先,只检查当前元素后退出
|
|
44
|
-
if (!ancestor)
|
|
45
|
-
break;
|
|
46
|
-
current = current.parentElement;
|
|
47
|
-
}
|
|
48
|
-
// 只在值变化时更新
|
|
49
|
-
if (mountedRef.current && lastVisibleRef.current !== visible) {
|
|
50
|
-
lastVisibleRef.current = visible;
|
|
51
|
-
setIsVisible(visible);
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
// 带防抖的检查
|
|
55
|
-
const debouncedCheck = () => {
|
|
56
|
-
if (timerRef.current) {
|
|
57
|
-
clearTimeout(timerRef.current);
|
|
58
|
-
}
|
|
59
|
-
timerRef.current = setTimeout(checkVisibility, debounceMsRef.current);
|
|
60
|
-
};
|
|
61
|
-
// 设置 observer
|
|
62
|
-
const setupObserver = () => {
|
|
63
|
-
const el = ref.current;
|
|
64
|
-
if (!el)
|
|
65
|
-
return;
|
|
66
|
-
// 清理旧的 observer
|
|
67
|
-
if (observerRef.current) {
|
|
68
|
-
observerRef.current.disconnect();
|
|
69
|
-
}
|
|
70
|
-
const observer = new MutationObserver(debouncedCheck);
|
|
71
|
-
let parent = el;
|
|
72
|
-
while (parent) {
|
|
73
|
-
observer.observe(parent, {
|
|
74
|
-
attributes: true,
|
|
75
|
-
// 监听 style、class、以及 data-state(Radix UI)
|
|
76
|
-
attributeFilter: ['style', 'class', 'data-state'],
|
|
77
|
-
});
|
|
78
|
-
// 如果不检查祖先,只监听当前元素后退出
|
|
79
|
-
if (!ancestor)
|
|
80
|
-
break;
|
|
81
|
-
parent = parent.parentElement;
|
|
82
|
-
}
|
|
83
|
-
observerRef.current = observer;
|
|
84
|
-
checkVisibility(); // 初始检查
|
|
85
|
-
};
|
|
86
|
-
setupObserver();
|
|
87
|
-
// 监听 ref 变化(通过 RAF 轮询,处理 ref 延迟赋值的情况)
|
|
88
|
-
let rafId = null;
|
|
89
|
-
const checkRef = () => {
|
|
90
|
-
if (!mountedRef.current)
|
|
91
|
-
return;
|
|
92
|
-
if (ref.current && !observerRef.current) {
|
|
93
|
-
setupObserver();
|
|
94
|
-
rafId = null;
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
rafId = requestAnimationFrame(checkRef);
|
|
98
|
-
};
|
|
99
|
-
if (!ref.current) {
|
|
100
|
-
rafId = requestAnimationFrame(checkRef);
|
|
101
|
-
}
|
|
102
|
-
return () => {
|
|
103
|
-
mountedRef.current = false;
|
|
104
|
-
if (observerRef.current) {
|
|
105
|
-
observerRef.current.disconnect();
|
|
106
|
-
observerRef.current = null;
|
|
107
|
-
}
|
|
108
|
-
if (timerRef.current) {
|
|
109
|
-
clearTimeout(timerRef.current);
|
|
110
|
-
timerRef.current = null;
|
|
111
|
-
}
|
|
112
|
-
if (rafId) {
|
|
113
|
-
cancelAnimationFrame(rafId);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}, [ref, ancestor]);
|
|
117
|
-
// null 表示还未检测到结果
|
|
118
|
-
return isVisible;
|
|
119
|
-
}
|