xxf_react 0.3.6 → 0.3.7
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/dist/foundation/LayoutSize.d.ts +5 -0
- package/dist/foundation/LayoutSize.d.ts.map +1 -0
- package/dist/foundation/LayoutSize.js +1 -0
- package/dist/layout/index.d.ts +6 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +5 -0
- package/dist/layout/resize/core/ResizeObserverHook.d.ts +41 -0
- package/dist/layout/resize/core/ResizeObserverHook.d.ts.map +1 -0
- package/dist/layout/resize/core/ResizeObserverHook.js +57 -0
- package/dist/layout/resize/core/SizedLayoutContext.d.ts +23 -0
- package/dist/layout/resize/core/SizedLayoutContext.d.ts.map +1 -0
- package/dist/layout/resize/core/SizedLayoutContext.js +23 -0
- package/dist/layout/resize/core/SizedLayoutProps.d.ts +19 -0
- package/dist/layout/resize/core/SizedLayoutProps.d.ts.map +1 -0
- package/dist/layout/resize/core/SizedLayoutProps.js +1 -0
- package/dist/layout/resize/impl/SizedContainer.d.ts +45 -0
- package/dist/layout/resize/impl/SizedContainer.d.ts.map +1 -0
- package/dist/layout/resize/impl/SizedContainer.js +65 -0
- package/dist/layout/resize/impl/SizedLayout.d.ts +45 -0
- package/dist/layout/resize/impl/SizedLayout.d.ts.map +1 -0
- package/dist/layout/resize/impl/SizedLayout.js +65 -0
- package/dist/utils/index.d.ts +4 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -1
- package/package.json +8 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutSize.d.ts","sourceRoot":"","sources":["../../src/foundation/LayoutSize.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './resize/core/SizedLayoutProps';
|
|
2
|
+
export * from './resize/core/SizedLayoutContext';
|
|
3
|
+
export * from './resize/core/ResizeObserverHook';
|
|
4
|
+
export * from './resize/impl/SizedContainer';
|
|
5
|
+
export * from './resize/impl/SizedLayout';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,8BAA8B,CAAA;AAC5C,cAAc,2BAA2B,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
import { LayoutSize } from "../../../foundation/LayoutSize";
|
|
3
|
+
interface UseResizeObserverOptions {
|
|
4
|
+
/** 防抖延迟,默认 0(不防抖) */
|
|
5
|
+
debounce?: number;
|
|
6
|
+
/** 初始尺寸 */
|
|
7
|
+
initialSize?: LayoutSize;
|
|
8
|
+
}
|
|
9
|
+
interface UseResizeObserverReturn<T extends HTMLElement> {
|
|
10
|
+
/** 绑定到容器元素的 ref */
|
|
11
|
+
containerRef: RefObject<T | null>;
|
|
12
|
+
/** 容器宽度 */
|
|
13
|
+
containerWidth: number;
|
|
14
|
+
/** 容器高度 */
|
|
15
|
+
containerHeight: number;
|
|
16
|
+
/** 是否已获取到尺寸 */
|
|
17
|
+
isContainerReady: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 基于 ResizeObserver 监听容器尺寸变化
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const { containerRef, containerWidth, containerHeight, isContainerReady } = useResizeObserver();
|
|
25
|
+
*
|
|
26
|
+
* return (
|
|
27
|
+
* <div ref={containerRef}>
|
|
28
|
+
* {isContainerReady && <Chart width={containerWidth} height={containerHeight} />}
|
|
29
|
+
* </div>
|
|
30
|
+
* );
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* // 带防抖
|
|
36
|
+
* const { containerRef, containerHeight } = useResizeObserver({ debounce: 100 });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function useResizeObserver<T extends HTMLElement = HTMLDivElement>(options?: UseResizeObserverOptions): UseResizeObserverReturn<T>;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=ResizeObserverHook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResizeObserverHook.d.ts","sourceRoot":"","sources":["../../../../src/layout/resize/core/ResizeObserverHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,SAAS,EAAC,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAC,UAAU,EAAC,MAAM,gCAAgC,CAAC;AAG1D,UAAU,wBAAwB;IAC9B,qBAAqB;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW;IACX,WAAW,CAAC,EAAE,UAAU,CAAC;CAC5B;AAED,UAAU,uBAAuB,CAAC,CAAC,SAAS,WAAW;IACnD,mBAAmB;IACnB,YAAY,EAAE,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAClC,WAAW;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW;IACX,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe;IACf,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,WAAW,GAAG,cAAc,EACpE,OAAO,GAAE,wBAA6B,GACvC,uBAAuB,CAAC,CAAC,CAAC,CAqC5B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export * from './ScrollToCenter';
|
|
2
2
|
export * from './Reload';
|
|
3
|
-
export * from '
|
|
3
|
+
export * from '../layout/resize/core/ResizeObserverHook';
|
|
4
|
+
export * from '../layout/resize/core/SizedLayoutContext';
|
|
5
|
+
export * from '../layout/resize/impl/SizedLayout';
|
|
6
|
+
export * from '../layout/resize/impl/SizedContainer';
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,0CAA0C,CAAA;AACxD,cAAc,0CAA0C,CAAA;AACxD,cAAc,mCAAmC,CAAA;AACjD,cAAc,sCAAsC,CAAA"}
|
package/dist/utils/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
export * from './ScrollToCenter';
|
|
3
3
|
export * from './Reload';
|
|
4
|
-
export * from '
|
|
4
|
+
export * from '../layout/resize/core/ResizeObserverHook';
|
|
5
|
+
export * from '../layout/resize/core/SizedLayoutContext';
|
|
6
|
+
export * from '../layout/resize/impl/SizedLayout';
|
|
7
|
+
export * from '../layout/resize/impl/SizedContainer';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xxf_react",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -45,9 +45,15 @@
|
|
|
45
45
|
"./foundation": {
|
|
46
46
|
"types": "./dist/foundation/index.d.ts",
|
|
47
47
|
"import": "./dist/foundation/index.js"
|
|
48
|
+
},
|
|
49
|
+
"./layout": {
|
|
50
|
+
"types": "./dist/layout/index.d.ts",
|
|
51
|
+
"import": "./dist/layout/index.js"
|
|
48
52
|
}
|
|
49
53
|
},
|
|
50
|
-
"files": [
|
|
54
|
+
"files": [
|
|
55
|
+
"dist"
|
|
56
|
+
],
|
|
51
57
|
"scripts": {
|
|
52
58
|
"build": "tsc"
|
|
53
59
|
},
|