react-public-components 1.2.4 → 1.2.6
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/README.md +5 -2
- package/dist/AnnouncementBar/index.cjs +3 -2
- package/dist/AnnouncementBar/index.css +102 -11
- package/dist/AnnouncementBar/index.css.map +1 -1
- package/dist/AnnouncementBar/index.d.ts +22 -3
- package/dist/AnnouncementBar/index.js +2 -1
- package/dist/CeilingBox/index.cjs +9 -0
- package/dist/CeilingBox/index.cjs.map +1 -0
- package/dist/CeilingBox/index.css +25 -0
- package/dist/CeilingBox/index.css.map +1 -0
- package/dist/CeilingBox/index.d.ts +28 -0
- package/dist/CeilingBox/index.js +3 -0
- package/dist/CeilingBox/index.js.map +1 -0
- package/dist/LazyLoadBox/index.cjs +18 -0
- package/dist/LazyLoadBox/index.cjs.map +1 -0
- package/dist/LazyLoadBox/index.css +57 -0
- package/dist/LazyLoadBox/index.css.map +1 -0
- package/dist/LazyLoadBox/index.d.ts +104 -0
- package/dist/LazyLoadBox/index.js +3 -0
- package/dist/LazyLoadBox/index.js.map +1 -0
- package/dist/PeriodSelect/index.cjs +22 -0
- package/dist/PeriodSelect/index.cjs.map +1 -0
- package/dist/PeriodSelect/index.css +88 -0
- package/dist/PeriodSelect/index.css.map +1 -0
- package/dist/PeriodSelect/index.d.ts +36 -0
- package/dist/PeriodSelect/index.js +3 -0
- package/dist/PeriodSelect/index.js.map +1 -0
- package/dist/chunk-5Q7THN6M.js +115 -0
- package/dist/chunk-5Q7THN6M.js.map +1 -0
- package/dist/chunk-O4EABET3.js +89 -0
- package/dist/chunk-O4EABET3.js.map +1 -0
- package/dist/chunk-QU33CY3M.cjs +83 -0
- package/dist/chunk-QU33CY3M.cjs.map +1 -0
- package/dist/chunk-RFTYEXKU.js +79 -0
- package/dist/chunk-RFTYEXKU.js.map +1 -0
- package/dist/chunk-UIU6VCEQ.cjs +117 -0
- package/dist/chunk-UIU6VCEQ.cjs.map +1 -0
- package/dist/chunk-V55FEQYU.cjs +196 -0
- package/dist/chunk-V55FEQYU.cjs.map +1 -0
- package/dist/chunk-VYPIRVL4.js +193 -0
- package/dist/chunk-VYPIRVL4.js.map +1 -0
- package/dist/chunk-ZXMFWVE4.cjs +91 -0
- package/dist/chunk-ZXMFWVE4.cjs.map +1 -0
- package/dist/index.cjs +91 -72
- package/dist/index.css +272 -11
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +18 -15
- package/dist/src/index.d.ts +7 -1
- package/package.json +3 -2
- package/dist/chunk-5YQVSOHK.js +0 -44
- package/dist/chunk-5YQVSOHK.js.map +0 -1
- package/dist/chunk-B3HZIYQQ.cjs +0 -46
- package/dist/chunk-B3HZIYQQ.cjs.map +0 -1
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// LazyLoadBox/index.tsx
|
|
7
|
+
function parseRootMargin(offset) {
|
|
8
|
+
if (typeof offset === "number") {
|
|
9
|
+
return `${offset}px 0px ${offset}px 0px`;
|
|
10
|
+
}
|
|
11
|
+
if (typeof offset === "string") {
|
|
12
|
+
return offset;
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(offset)) {
|
|
15
|
+
if (offset.length === 2) {
|
|
16
|
+
const [v, h] = offset.map((item) => typeof item === "number" ? `${item}px` : item);
|
|
17
|
+
return `${v} ${h} ${v} ${h}`;
|
|
18
|
+
}
|
|
19
|
+
if (offset.length === 4) {
|
|
20
|
+
return offset.map((item) => typeof item === "number" ? `${item}px` : item).join(" ");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return "150px 0px 150px 0px";
|
|
24
|
+
}
|
|
25
|
+
var LazyLoadBox = react.forwardRef(
|
|
26
|
+
({
|
|
27
|
+
children,
|
|
28
|
+
offset = 150,
|
|
29
|
+
height = 180,
|
|
30
|
+
width,
|
|
31
|
+
placeholder,
|
|
32
|
+
skeleton = true,
|
|
33
|
+
bordered = false,
|
|
34
|
+
once = true,
|
|
35
|
+
forceRender = false,
|
|
36
|
+
scrollContainer,
|
|
37
|
+
threshold = 0,
|
|
38
|
+
animate = true,
|
|
39
|
+
ssr = false,
|
|
40
|
+
onVisible,
|
|
41
|
+
onInViewChange,
|
|
42
|
+
className = "",
|
|
43
|
+
style
|
|
44
|
+
}, ref) => {
|
|
45
|
+
const containerRef = react.useRef(null);
|
|
46
|
+
const [isInView, setIsInView] = react.useState(Boolean(ssr || forceRender));
|
|
47
|
+
const [hasLoaded, setHasLoaded] = react.useState(Boolean(ssr || forceRender));
|
|
48
|
+
const hasLoadedRef = react.useRef(hasLoaded);
|
|
49
|
+
const onVisibleRef = react.useRef(onVisible);
|
|
50
|
+
const onInViewChangeRef = react.useRef(onInViewChange);
|
|
51
|
+
onVisibleRef.current = onVisible;
|
|
52
|
+
onInViewChangeRef.current = onInViewChange;
|
|
53
|
+
const rootMargin = parseRootMargin(offset);
|
|
54
|
+
const triggerLoad = () => {
|
|
55
|
+
var _a;
|
|
56
|
+
if (!hasLoadedRef.current) {
|
|
57
|
+
setHasLoaded(true);
|
|
58
|
+
setIsInView(true);
|
|
59
|
+
hasLoadedRef.current = true;
|
|
60
|
+
(_a = onVisibleRef.current) == null ? void 0 : _a.call(onVisibleRef);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
react.useImperativeHandle(ref, () => ({
|
|
64
|
+
load: triggerLoad,
|
|
65
|
+
reset: () => {
|
|
66
|
+
setHasLoaded(false);
|
|
67
|
+
setIsInView(false);
|
|
68
|
+
hasLoadedRef.current = false;
|
|
69
|
+
},
|
|
70
|
+
getInView: () => isInView,
|
|
71
|
+
getHasLoaded: () => hasLoadedRef.current,
|
|
72
|
+
getDOMNode: () => containerRef.current
|
|
73
|
+
}));
|
|
74
|
+
react.useEffect(() => {
|
|
75
|
+
if (forceRender && !hasLoadedRef.current) {
|
|
76
|
+
triggerLoad();
|
|
77
|
+
}
|
|
78
|
+
}, [forceRender]);
|
|
79
|
+
react.useEffect(() => {
|
|
80
|
+
if (hasLoaded && once) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const target = containerRef.current;
|
|
84
|
+
if (!target) return;
|
|
85
|
+
if (typeof window === "undefined" || !("IntersectionObserver" in window)) {
|
|
86
|
+
triggerLoad();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let rootElement = null;
|
|
90
|
+
if (typeof scrollContainer === "string") {
|
|
91
|
+
rootElement = document.querySelector(scrollContainer);
|
|
92
|
+
} else if (typeof scrollContainer === "function") {
|
|
93
|
+
rootElement = scrollContainer();
|
|
94
|
+
} else if (scrollContainer && "current" in scrollContainer) {
|
|
95
|
+
rootElement = scrollContainer.current;
|
|
96
|
+
} else if (scrollContainer instanceof HTMLElement) {
|
|
97
|
+
rootElement = scrollContainer;
|
|
98
|
+
}
|
|
99
|
+
let observer = null;
|
|
100
|
+
try {
|
|
101
|
+
observer = new IntersectionObserver(
|
|
102
|
+
(entries) => {
|
|
103
|
+
entries.forEach((entry) => {
|
|
104
|
+
var _a, _b;
|
|
105
|
+
const inView = entry.isIntersecting;
|
|
106
|
+
setIsInView(inView);
|
|
107
|
+
(_a = onInViewChangeRef.current) == null ? void 0 : _a.call(onInViewChangeRef, inView);
|
|
108
|
+
if (inView) {
|
|
109
|
+
if (!hasLoadedRef.current) {
|
|
110
|
+
setHasLoaded(true);
|
|
111
|
+
hasLoadedRef.current = true;
|
|
112
|
+
(_b = onVisibleRef.current) == null ? void 0 : _b.call(onVisibleRef);
|
|
113
|
+
}
|
|
114
|
+
if (once) {
|
|
115
|
+
observer == null ? void 0 : observer.unobserve(target);
|
|
116
|
+
observer == null ? void 0 : observer.disconnect();
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
if (!once) {
|
|
120
|
+
setHasLoaded(false);
|
|
121
|
+
hasLoadedRef.current = false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
root: rootElement,
|
|
128
|
+
rootMargin,
|
|
129
|
+
threshold
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
observer.observe(target);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
triggerLoad();
|
|
135
|
+
}
|
|
136
|
+
return () => {
|
|
137
|
+
if (observer) {
|
|
138
|
+
observer.unobserve(target);
|
|
139
|
+
observer.disconnect();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}, [rootMargin, threshold, once, hasLoaded, scrollContainer]);
|
|
143
|
+
const formattedHeight = typeof height === "number" ? `${height}px` : height;
|
|
144
|
+
const formattedWidth = typeof width === "number" ? `${width}px` : width;
|
|
145
|
+
const defaultPlaceholder = skeleton ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
className: `rpc_lazy_load_placeholder ${bordered ? "rpc_lazy_load_placeholder_bordered" : ""}`,
|
|
149
|
+
style: {
|
|
150
|
+
minHeight: formattedHeight,
|
|
151
|
+
width: formattedWidth
|
|
152
|
+
},
|
|
153
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rpc_lazy_load_skeleton" })
|
|
154
|
+
}
|
|
155
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
156
|
+
"div",
|
|
157
|
+
{
|
|
158
|
+
style: {
|
|
159
|
+
minHeight: formattedHeight,
|
|
160
|
+
width: formattedWidth
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
const shouldRenderContent = hasLoaded || (once ? hasLoaded : isInView);
|
|
165
|
+
const containerClass = [
|
|
166
|
+
"rpc_lazy_load_box",
|
|
167
|
+
shouldRenderContent ? "rpc_lazy_load_loaded" : "rpc_lazy_load_pending",
|
|
168
|
+
animate && shouldRenderContent ? "rpc_lazy_load_fade_in" : "",
|
|
169
|
+
className
|
|
170
|
+
].filter(Boolean).join(" ");
|
|
171
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
172
|
+
"div",
|
|
173
|
+
{
|
|
174
|
+
ref: containerRef,
|
|
175
|
+
className: containerClass,
|
|
176
|
+
style: {
|
|
177
|
+
minHeight: shouldRenderContent ? void 0 : formattedHeight,
|
|
178
|
+
width: formattedWidth,
|
|
179
|
+
...style
|
|
180
|
+
},
|
|
181
|
+
children: shouldRenderContent ? typeof children === "function" ? children({
|
|
182
|
+
isInView,
|
|
183
|
+
hasLoaded,
|
|
184
|
+
load: triggerLoad
|
|
185
|
+
}) : children : placeholder !== void 0 ? placeholder : defaultPlaceholder
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
LazyLoadBox.displayName = "LazyLoadBox";
|
|
191
|
+
var LazyLoadBox_default = LazyLoadBox;
|
|
192
|
+
|
|
193
|
+
exports.LazyLoadBox = LazyLoadBox;
|
|
194
|
+
exports.LazyLoadBox_default = LazyLoadBox_default;
|
|
195
|
+
//# sourceMappingURL=chunk-V55FEQYU.cjs.map
|
|
196
|
+
//# sourceMappingURL=chunk-V55FEQYU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../LazyLoadBox/index.tsx"],"names":["forwardRef","useRef","useState","useImperativeHandle","useEffect","jsx"],"mappings":"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","file":"chunk-V55FEQYU.cjs","sourcesContent":["import React, {\n\tuseState,\n\tuseEffect,\n\tuseRef,\n\tuseImperativeHandle,\n\tforwardRef,\n\tCSSProperties,\n\tReactNode,\n\tRefObject,\n} from 'react';\nimport './index.less';\n\nexport interface LazyLoadBoxRef {\n\t/** 立即强制触发加载真实内容 */\n\tload: () => void;\n\t/** 重置加载状态(仅在 once=false 或需要重新触发时可用) */\n\treset: () => void;\n\t/** 获取当前元素是否在可视/预加载区域内 */\n\tgetInView: () => boolean;\n\t/** 获取当前是否已经完成过加载 */\n\tgetHasLoaded: () => boolean;\n\t/** 获取容器原生 DOM 节点 */\n\tgetDOMNode: () => HTMLDivElement | null;\n}\n\nexport interface LazyRenderProps {\n\t/** 当前是否在视口范围内 */\n\tisInView: boolean;\n\t/** 是否已经触发过加载并完成挂载 */\n\thasLoaded: boolean;\n\t/** 重新触发加载函数 */\n\tload: () => void;\n}\n\nexport type LazyOffset = number | string | [number | string, number | string] | [number | string, number | string, number | string, number | string];\n\nexport interface LazyLoadBoxProps {\n\t/**\n\t * 子组件或 Render Props\n\t * 当为普通组件时:未进入视口时不渲染,进入视口预加载范围后挂载并触发其内部网络请求与渲染;\n\t * 当为函数时:接收 ({ isInView, hasLoaded, load }) 回传参数\n\t */\n\tchildren?: ReactNode | ((props: LazyRenderProps) => ReactNode);\n\t/**\n\t * 距离视口/滚动条多远时提前触发加载(单位 px,或标准 rootMargin 字符串/数组)\n\t * 例如:\n\t * - 纯数字:offset={200} (表示上下预加载 200px)\n\t * - 字符串:offset=\"200px 0px\"\n\t * - 数组:offset={[100, 200]} (表示上下预加载距离)\n\t * 默认:150\n\t */\n\toffset?: LazyOffset;\n\t/**\n\t * 未加载前的预估高度/最小高度,防止页面未渲染时高度坍塌导致滚动条剧烈跳动(CLS)\n\t * 默认:180\n\t */\n\theight?: number | string;\n\t/**\n\t * 预估宽度/最小宽度(可选)\n\t */\n\twidth?: number | string;\n\t/**\n\t * 未加载时显示的占位内容(如骨架屏或加载动画)\n\t * 默认提供内置的高品质流光呼吸骨架屏\n\t */\n\tplaceholder?: ReactNode;\n\t/**\n\t * 是否显示默认占位骨架屏(当 placeholder 未指定时生效)\n\t * 默认:true\n\t */\n\tskeleton?: boolean;\n\t/**\n\t * 骨架屏是否显示微边框\n\t * 默认:false\n\t */\n\tbordered?: boolean;\n\t/**\n\t * 是否只加载一次(默认 true:进入视口后保持挂载,移出不会销毁与重复请求)\n\t * 若设为 false,则移出视口时会自动卸载,再次移入时重新挂载\n\t */\n\tonce?: boolean;\n\t/**\n\t * 强制立即渲染(忽略视口距离,用于一键展开、批量导出、页面打印等场景)\n\t */\n\tforceRender?: boolean;\n\t/**\n\t * 指定局部滚动容器(支持 DOM 节点、RefObject、选择器字符串或 getter 函数),默认监听 window 视口\n\t */\n\tscrollContainer?:\n\t\t| HTMLElement\n\t\t| null\n\t\t| string\n\t\t| RefObject<HTMLElement | null>\n\t\t| (() => HTMLElement | null);\n\t/**\n\t * 交叉比例阈值(0 ~ 1),默认 0\n\t */\n\tthreshold?: number | number[];\n\t/**\n\t * 是否在加载完成后启用平滑淡入动效\n\t * 默认:true\n\t */\n\tanimate?: boolean;\n\t/**\n\t * 服务端渲染(SSR)时是否直接渲染内容(默认为 false)\n\t */\n\tssr?: boolean;\n\t/**\n\t * 首次进入可视/预加载区域触发加载时的回调\n\t */\n\tonVisible?: () => void;\n\t/**\n\t * 可见性变化时的实时回调\n\t */\n\tonInViewChange?: (inView: boolean) => void;\n\t/** 自定义类名 */\n\tclassName?: string;\n\t/** 自定义样式 */\n\tstyle?: CSSProperties;\n}\n\n/** 规范化 offset 为标准 CSS 4 方向 rootMargin 字符串 */\nfunction parseRootMargin(offset: LazyOffset): string {\n\tif (typeof offset === 'number') {\n\t\treturn `${offset}px 0px ${offset}px 0px`;\n\t}\n\tif (typeof offset === 'string') {\n\t\treturn offset;\n\t}\n\tif (Array.isArray(offset)) {\n\t\tif (offset.length === 2) {\n\t\t\tconst [v, h] = offset.map((item) => (typeof item === 'number' ? `${item}px` : item));\n\t\t\treturn `${v} ${h} ${v} ${h}`;\n\t\t}\n\t\tif (offset.length === 4) {\n\t\t\treturn offset.map((item) => (typeof item === 'number' ? `${item}px` : item)).join(' ');\n\t\t}\n\t}\n\treturn '150px 0px 150px 0px';\n}\n\nexport const LazyLoadBox = forwardRef<LazyLoadBoxRef, LazyLoadBoxProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\toffset = 150,\n\t\t\theight = 180,\n\t\t\twidth,\n\t\t\tplaceholder,\n\t\t\tskeleton = true,\n\t\t\tbordered = false,\n\t\t\tonce = true,\n\t\t\tforceRender = false,\n\t\t\tscrollContainer,\n\t\t\tthreshold = 0,\n\t\t\tanimate = true,\n\t\t\tssr = false,\n\t\t\tonVisible,\n\t\t\tonInViewChange,\n\t\t\tclassName = '',\n\t\t\tstyle,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\t\tconst [isInView, setIsInView] = useState<boolean>(Boolean(ssr || forceRender));\n\t\tconst [hasLoaded, setHasLoaded] = useState<boolean>(Boolean(ssr || forceRender));\n\t\tconst hasLoadedRef = useRef<boolean>(hasLoaded);\n\t\tconst onVisibleRef = useRef(onVisible);\n\t\tconst onInViewChangeRef = useRef(onInViewChange);\n\n\t\tonVisibleRef.current = onVisible;\n\t\tonInViewChangeRef.current = onInViewChange;\n\n\t\tconst rootMargin = parseRootMargin(offset);\n\n\t\tconst triggerLoad = () => {\n\t\t\tif (!hasLoadedRef.current) {\n\t\t\t\tsetHasLoaded(true);\n\t\t\t\tsetIsInView(true);\n\t\t\t\thasLoadedRef.current = true;\n\t\t\t\tonVisibleRef.current?.();\n\t\t\t}\n\t\t};\n\n\t\t// 暴露命令式操作方法\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tload: triggerLoad,\n\t\t\treset: () => {\n\t\t\t\tsetHasLoaded(false);\n\t\t\t\tsetIsInView(false);\n\t\t\t\thasLoadedRef.current = false;\n\t\t\t},\n\t\t\tgetInView: () => isInView,\n\t\t\tgetHasLoaded: () => hasLoadedRef.current,\n\t\t\tgetDOMNode: () => containerRef.current,\n\t\t}));\n\n\t\t// 响应 forceRender 受控属性变化\n\t\tuseEffect(() => {\n\t\t\tif (forceRender && !hasLoadedRef.current) {\n\t\t\t\ttriggerLoad();\n\t\t\t}\n\t\t}, [forceRender]);\n\n\t\tuseEffect(() => {\n\t\t\t// 如果已经加载且 once 为 true,则无需挂载 Observer\n\t\t\tif (hasLoaded && once) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst target = containerRef.current;\n\t\t\tif (!target) return;\n\n\t\t\t// 环境不支持 IntersectionObserver,降级为立即加载\n\t\t\tif (typeof window === 'undefined' || !('IntersectionObserver' in window)) {\n\t\t\t\ttriggerLoad();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// 解析 scrollContainer 根节点\n\t\t\tlet rootElement: HTMLElement | null = null;\n\t\t\tif (typeof scrollContainer === 'string') {\n\t\t\t\trootElement = document.querySelector(scrollContainer);\n\t\t\t} else if (typeof scrollContainer === 'function') {\n\t\t\t\trootElement = scrollContainer();\n\t\t\t} else if (scrollContainer && 'current' in scrollContainer) {\n\t\t\t\trootElement = (scrollContainer as RefObject<HTMLElement | null>).current;\n\t\t\t} else if (scrollContainer instanceof HTMLElement) {\n\t\t\t\trootElement = scrollContainer;\n\t\t\t}\n\n\t\t\tlet observer: IntersectionObserver | null = null;\n\n\t\t\ttry {\n\t\t\t\tobserver = new IntersectionObserver(\n\t\t\t\t\t(entries) => {\n\t\t\t\t\t\tentries.forEach((entry) => {\n\t\t\t\t\t\t\tconst inView = entry.isIntersecting;\n\t\t\t\t\t\t\tsetIsInView(inView);\n\t\t\t\t\t\t\tonInViewChangeRef.current?.(inView);\n\n\t\t\t\t\t\t\tif (inView) {\n\t\t\t\t\t\t\t\tif (!hasLoadedRef.current) {\n\t\t\t\t\t\t\t\t\tsetHasLoaded(true);\n\t\t\t\t\t\t\t\t\thasLoadedRef.current = true;\n\t\t\t\t\t\t\t\t\tonVisibleRef.current?.();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (once) {\n\t\t\t\t\t\t\t\t\tobserver?.unobserve(target);\n\t\t\t\t\t\t\t\t\tobserver?.disconnect();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (!once) {\n\t\t\t\t\t\t\t\t\tsetHasLoaded(false);\n\t\t\t\t\t\t\t\t\thasLoadedRef.current = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\troot: rootElement,\n\t\t\t\t\t\trootMargin,\n\t\t\t\t\t\tthreshold,\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tobserver.observe(target);\n\t\t\t} catch {\n\t\t\t\t// 如果传参格式或环境发生意外,安全降级立即触发\n\t\t\t\ttriggerLoad();\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tif (observer) {\n\t\t\t\t\tobserver.unobserve(target);\n\t\t\t\t\tobserver.disconnect();\n\t\t\t\t}\n\t\t\t};\n\t\t}, [rootMargin, threshold, once, hasLoaded, scrollContainer]);\n\n\t\tconst formattedHeight = typeof height === 'number' ? `${height}px` : height;\n\t\tconst formattedWidth = typeof width === 'number' ? `${width}px` : width;\n\n\t\t// 默认骨架占位\n\t\tconst defaultPlaceholder = skeleton ? (\n\t\t\t<div\n\t\t\t\tclassName={`rpc_lazy_load_placeholder ${bordered ? 'rpc_lazy_load_placeholder_bordered' : ''}`}\n\t\t\t\tstyle={{\n\t\t\t\t\tminHeight: formattedHeight,\n\t\t\t\t\twidth: formattedWidth,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className=\"rpc_lazy_load_skeleton\" />\n\t\t\t</div>\n\t\t) : (\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tminHeight: formattedHeight,\n\t\t\t\t\twidth: formattedWidth,\n\t\t\t\t}}\n\t\t\t/>\n\t\t);\n\n\t\tconst shouldRenderContent = hasLoaded || (once ? hasLoaded : isInView);\n\n\t\tconst containerClass = [\n\t\t\t'rpc_lazy_load_box',\n\t\t\tshouldRenderContent ? 'rpc_lazy_load_loaded' : 'rpc_lazy_load_pending',\n\t\t\tanimate && shouldRenderContent ? 'rpc_lazy_load_fade_in' : '',\n\t\t\tclassName,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(' ');\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName={containerClass}\n\t\t\t\tstyle={{\n\t\t\t\t\tminHeight: shouldRenderContent ? undefined : formattedHeight,\n\t\t\t\t\twidth: formattedWidth,\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{shouldRenderContent ? (\n\t\t\t\t\ttypeof children === 'function' ? (\n\t\t\t\t\t\t(children as (props: LazyRenderProps) => ReactNode)({\n\t\t\t\t\t\t\tisInView,\n\t\t\t\t\t\t\thasLoaded,\n\t\t\t\t\t\t\tload: triggerLoad,\n\t\t\t\t\t\t})\n\t\t\t\t\t) : (\n\t\t\t\t\t\tchildren\n\t\t\t\t\t)\n\t\t\t\t) : placeholder !== undefined ? (\n\t\t\t\t\tplaceholder\n\t\t\t\t) : (\n\t\t\t\t\tdefaultPlaceholder\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nLazyLoadBox.displayName = 'LazyLoadBox';\n\nexport default LazyLoadBox;\n"]}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { forwardRef, useRef, useState, useImperativeHandle, useEffect } from 'react';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// LazyLoadBox/index.tsx
|
|
5
|
+
function parseRootMargin(offset) {
|
|
6
|
+
if (typeof offset === "number") {
|
|
7
|
+
return `${offset}px 0px ${offset}px 0px`;
|
|
8
|
+
}
|
|
9
|
+
if (typeof offset === "string") {
|
|
10
|
+
return offset;
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(offset)) {
|
|
13
|
+
if (offset.length === 2) {
|
|
14
|
+
const [v, h] = offset.map((item) => typeof item === "number" ? `${item}px` : item);
|
|
15
|
+
return `${v} ${h} ${v} ${h}`;
|
|
16
|
+
}
|
|
17
|
+
if (offset.length === 4) {
|
|
18
|
+
return offset.map((item) => typeof item === "number" ? `${item}px` : item).join(" ");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return "150px 0px 150px 0px";
|
|
22
|
+
}
|
|
23
|
+
var LazyLoadBox = forwardRef(
|
|
24
|
+
({
|
|
25
|
+
children,
|
|
26
|
+
offset = 150,
|
|
27
|
+
height = 180,
|
|
28
|
+
width,
|
|
29
|
+
placeholder,
|
|
30
|
+
skeleton = true,
|
|
31
|
+
bordered = false,
|
|
32
|
+
once = true,
|
|
33
|
+
forceRender = false,
|
|
34
|
+
scrollContainer,
|
|
35
|
+
threshold = 0,
|
|
36
|
+
animate = true,
|
|
37
|
+
ssr = false,
|
|
38
|
+
onVisible,
|
|
39
|
+
onInViewChange,
|
|
40
|
+
className = "",
|
|
41
|
+
style
|
|
42
|
+
}, ref) => {
|
|
43
|
+
const containerRef = useRef(null);
|
|
44
|
+
const [isInView, setIsInView] = useState(Boolean(ssr || forceRender));
|
|
45
|
+
const [hasLoaded, setHasLoaded] = useState(Boolean(ssr || forceRender));
|
|
46
|
+
const hasLoadedRef = useRef(hasLoaded);
|
|
47
|
+
const onVisibleRef = useRef(onVisible);
|
|
48
|
+
const onInViewChangeRef = useRef(onInViewChange);
|
|
49
|
+
onVisibleRef.current = onVisible;
|
|
50
|
+
onInViewChangeRef.current = onInViewChange;
|
|
51
|
+
const rootMargin = parseRootMargin(offset);
|
|
52
|
+
const triggerLoad = () => {
|
|
53
|
+
var _a;
|
|
54
|
+
if (!hasLoadedRef.current) {
|
|
55
|
+
setHasLoaded(true);
|
|
56
|
+
setIsInView(true);
|
|
57
|
+
hasLoadedRef.current = true;
|
|
58
|
+
(_a = onVisibleRef.current) == null ? void 0 : _a.call(onVisibleRef);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
useImperativeHandle(ref, () => ({
|
|
62
|
+
load: triggerLoad,
|
|
63
|
+
reset: () => {
|
|
64
|
+
setHasLoaded(false);
|
|
65
|
+
setIsInView(false);
|
|
66
|
+
hasLoadedRef.current = false;
|
|
67
|
+
},
|
|
68
|
+
getInView: () => isInView,
|
|
69
|
+
getHasLoaded: () => hasLoadedRef.current,
|
|
70
|
+
getDOMNode: () => containerRef.current
|
|
71
|
+
}));
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (forceRender && !hasLoadedRef.current) {
|
|
74
|
+
triggerLoad();
|
|
75
|
+
}
|
|
76
|
+
}, [forceRender]);
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (hasLoaded && once) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const target = containerRef.current;
|
|
82
|
+
if (!target) return;
|
|
83
|
+
if (typeof window === "undefined" || !("IntersectionObserver" in window)) {
|
|
84
|
+
triggerLoad();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
let rootElement = null;
|
|
88
|
+
if (typeof scrollContainer === "string") {
|
|
89
|
+
rootElement = document.querySelector(scrollContainer);
|
|
90
|
+
} else if (typeof scrollContainer === "function") {
|
|
91
|
+
rootElement = scrollContainer();
|
|
92
|
+
} else if (scrollContainer && "current" in scrollContainer) {
|
|
93
|
+
rootElement = scrollContainer.current;
|
|
94
|
+
} else if (scrollContainer instanceof HTMLElement) {
|
|
95
|
+
rootElement = scrollContainer;
|
|
96
|
+
}
|
|
97
|
+
let observer = null;
|
|
98
|
+
try {
|
|
99
|
+
observer = new IntersectionObserver(
|
|
100
|
+
(entries) => {
|
|
101
|
+
entries.forEach((entry) => {
|
|
102
|
+
var _a, _b;
|
|
103
|
+
const inView = entry.isIntersecting;
|
|
104
|
+
setIsInView(inView);
|
|
105
|
+
(_a = onInViewChangeRef.current) == null ? void 0 : _a.call(onInViewChangeRef, inView);
|
|
106
|
+
if (inView) {
|
|
107
|
+
if (!hasLoadedRef.current) {
|
|
108
|
+
setHasLoaded(true);
|
|
109
|
+
hasLoadedRef.current = true;
|
|
110
|
+
(_b = onVisibleRef.current) == null ? void 0 : _b.call(onVisibleRef);
|
|
111
|
+
}
|
|
112
|
+
if (once) {
|
|
113
|
+
observer == null ? void 0 : observer.unobserve(target);
|
|
114
|
+
observer == null ? void 0 : observer.disconnect();
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
if (!once) {
|
|
118
|
+
setHasLoaded(false);
|
|
119
|
+
hasLoadedRef.current = false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
root: rootElement,
|
|
126
|
+
rootMargin,
|
|
127
|
+
threshold
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
observer.observe(target);
|
|
131
|
+
} catch (e) {
|
|
132
|
+
triggerLoad();
|
|
133
|
+
}
|
|
134
|
+
return () => {
|
|
135
|
+
if (observer) {
|
|
136
|
+
observer.unobserve(target);
|
|
137
|
+
observer.disconnect();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}, [rootMargin, threshold, once, hasLoaded, scrollContainer]);
|
|
141
|
+
const formattedHeight = typeof height === "number" ? `${height}px` : height;
|
|
142
|
+
const formattedWidth = typeof width === "number" ? `${width}px` : width;
|
|
143
|
+
const defaultPlaceholder = skeleton ? /* @__PURE__ */ jsx(
|
|
144
|
+
"div",
|
|
145
|
+
{
|
|
146
|
+
className: `rpc_lazy_load_placeholder ${bordered ? "rpc_lazy_load_placeholder_bordered" : ""}`,
|
|
147
|
+
style: {
|
|
148
|
+
minHeight: formattedHeight,
|
|
149
|
+
width: formattedWidth
|
|
150
|
+
},
|
|
151
|
+
children: /* @__PURE__ */ jsx("div", { className: "rpc_lazy_load_skeleton" })
|
|
152
|
+
}
|
|
153
|
+
) : /* @__PURE__ */ jsx(
|
|
154
|
+
"div",
|
|
155
|
+
{
|
|
156
|
+
style: {
|
|
157
|
+
minHeight: formattedHeight,
|
|
158
|
+
width: formattedWidth
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
const shouldRenderContent = hasLoaded || (once ? hasLoaded : isInView);
|
|
163
|
+
const containerClass = [
|
|
164
|
+
"rpc_lazy_load_box",
|
|
165
|
+
shouldRenderContent ? "rpc_lazy_load_loaded" : "rpc_lazy_load_pending",
|
|
166
|
+
animate && shouldRenderContent ? "rpc_lazy_load_fade_in" : "",
|
|
167
|
+
className
|
|
168
|
+
].filter(Boolean).join(" ");
|
|
169
|
+
return /* @__PURE__ */ jsx(
|
|
170
|
+
"div",
|
|
171
|
+
{
|
|
172
|
+
ref: containerRef,
|
|
173
|
+
className: containerClass,
|
|
174
|
+
style: {
|
|
175
|
+
minHeight: shouldRenderContent ? void 0 : formattedHeight,
|
|
176
|
+
width: formattedWidth,
|
|
177
|
+
...style
|
|
178
|
+
},
|
|
179
|
+
children: shouldRenderContent ? typeof children === "function" ? children({
|
|
180
|
+
isInView,
|
|
181
|
+
hasLoaded,
|
|
182
|
+
load: triggerLoad
|
|
183
|
+
}) : children : placeholder !== void 0 ? placeholder : defaultPlaceholder
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
LazyLoadBox.displayName = "LazyLoadBox";
|
|
189
|
+
var LazyLoadBox_default = LazyLoadBox;
|
|
190
|
+
|
|
191
|
+
export { LazyLoadBox, LazyLoadBox_default };
|
|
192
|
+
//# sourceMappingURL=chunk-VYPIRVL4.js.map
|
|
193
|
+
//# sourceMappingURL=chunk-VYPIRVL4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../LazyLoadBox/index.tsx"],"names":[],"mappings":"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","file":"chunk-VYPIRVL4.js","sourcesContent":["import React, {\n\tuseState,\n\tuseEffect,\n\tuseRef,\n\tuseImperativeHandle,\n\tforwardRef,\n\tCSSProperties,\n\tReactNode,\n\tRefObject,\n} from 'react';\nimport './index.less';\n\nexport interface LazyLoadBoxRef {\n\t/** 立即强制触发加载真实内容 */\n\tload: () => void;\n\t/** 重置加载状态(仅在 once=false 或需要重新触发时可用) */\n\treset: () => void;\n\t/** 获取当前元素是否在可视/预加载区域内 */\n\tgetInView: () => boolean;\n\t/** 获取当前是否已经完成过加载 */\n\tgetHasLoaded: () => boolean;\n\t/** 获取容器原生 DOM 节点 */\n\tgetDOMNode: () => HTMLDivElement | null;\n}\n\nexport interface LazyRenderProps {\n\t/** 当前是否在视口范围内 */\n\tisInView: boolean;\n\t/** 是否已经触发过加载并完成挂载 */\n\thasLoaded: boolean;\n\t/** 重新触发加载函数 */\n\tload: () => void;\n}\n\nexport type LazyOffset = number | string | [number | string, number | string] | [number | string, number | string, number | string, number | string];\n\nexport interface LazyLoadBoxProps {\n\t/**\n\t * 子组件或 Render Props\n\t * 当为普通组件时:未进入视口时不渲染,进入视口预加载范围后挂载并触发其内部网络请求与渲染;\n\t * 当为函数时:接收 ({ isInView, hasLoaded, load }) 回传参数\n\t */\n\tchildren?: ReactNode | ((props: LazyRenderProps) => ReactNode);\n\t/**\n\t * 距离视口/滚动条多远时提前触发加载(单位 px,或标准 rootMargin 字符串/数组)\n\t * 例如:\n\t * - 纯数字:offset={200} (表示上下预加载 200px)\n\t * - 字符串:offset=\"200px 0px\"\n\t * - 数组:offset={[100, 200]} (表示上下预加载距离)\n\t * 默认:150\n\t */\n\toffset?: LazyOffset;\n\t/**\n\t * 未加载前的预估高度/最小高度,防止页面未渲染时高度坍塌导致滚动条剧烈跳动(CLS)\n\t * 默认:180\n\t */\n\theight?: number | string;\n\t/**\n\t * 预估宽度/最小宽度(可选)\n\t */\n\twidth?: number | string;\n\t/**\n\t * 未加载时显示的占位内容(如骨架屏或加载动画)\n\t * 默认提供内置的高品质流光呼吸骨架屏\n\t */\n\tplaceholder?: ReactNode;\n\t/**\n\t * 是否显示默认占位骨架屏(当 placeholder 未指定时生效)\n\t * 默认:true\n\t */\n\tskeleton?: boolean;\n\t/**\n\t * 骨架屏是否显示微边框\n\t * 默认:false\n\t */\n\tbordered?: boolean;\n\t/**\n\t * 是否只加载一次(默认 true:进入视口后保持挂载,移出不会销毁与重复请求)\n\t * 若设为 false,则移出视口时会自动卸载,再次移入时重新挂载\n\t */\n\tonce?: boolean;\n\t/**\n\t * 强制立即渲染(忽略视口距离,用于一键展开、批量导出、页面打印等场景)\n\t */\n\tforceRender?: boolean;\n\t/**\n\t * 指定局部滚动容器(支持 DOM 节点、RefObject、选择器字符串或 getter 函数),默认监听 window 视口\n\t */\n\tscrollContainer?:\n\t\t| HTMLElement\n\t\t| null\n\t\t| string\n\t\t| RefObject<HTMLElement | null>\n\t\t| (() => HTMLElement | null);\n\t/**\n\t * 交叉比例阈值(0 ~ 1),默认 0\n\t */\n\tthreshold?: number | number[];\n\t/**\n\t * 是否在加载完成后启用平滑淡入动效\n\t * 默认:true\n\t */\n\tanimate?: boolean;\n\t/**\n\t * 服务端渲染(SSR)时是否直接渲染内容(默认为 false)\n\t */\n\tssr?: boolean;\n\t/**\n\t * 首次进入可视/预加载区域触发加载时的回调\n\t */\n\tonVisible?: () => void;\n\t/**\n\t * 可见性变化时的实时回调\n\t */\n\tonInViewChange?: (inView: boolean) => void;\n\t/** 自定义类名 */\n\tclassName?: string;\n\t/** 自定义样式 */\n\tstyle?: CSSProperties;\n}\n\n/** 规范化 offset 为标准 CSS 4 方向 rootMargin 字符串 */\nfunction parseRootMargin(offset: LazyOffset): string {\n\tif (typeof offset === 'number') {\n\t\treturn `${offset}px 0px ${offset}px 0px`;\n\t}\n\tif (typeof offset === 'string') {\n\t\treturn offset;\n\t}\n\tif (Array.isArray(offset)) {\n\t\tif (offset.length === 2) {\n\t\t\tconst [v, h] = offset.map((item) => (typeof item === 'number' ? `${item}px` : item));\n\t\t\treturn `${v} ${h} ${v} ${h}`;\n\t\t}\n\t\tif (offset.length === 4) {\n\t\t\treturn offset.map((item) => (typeof item === 'number' ? `${item}px` : item)).join(' ');\n\t\t}\n\t}\n\treturn '150px 0px 150px 0px';\n}\n\nexport const LazyLoadBox = forwardRef<LazyLoadBoxRef, LazyLoadBoxProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\toffset = 150,\n\t\t\theight = 180,\n\t\t\twidth,\n\t\t\tplaceholder,\n\t\t\tskeleton = true,\n\t\t\tbordered = false,\n\t\t\tonce = true,\n\t\t\tforceRender = false,\n\t\t\tscrollContainer,\n\t\t\tthreshold = 0,\n\t\t\tanimate = true,\n\t\t\tssr = false,\n\t\t\tonVisible,\n\t\t\tonInViewChange,\n\t\t\tclassName = '',\n\t\t\tstyle,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst containerRef = useRef<HTMLDivElement | null>(null);\n\t\tconst [isInView, setIsInView] = useState<boolean>(Boolean(ssr || forceRender));\n\t\tconst [hasLoaded, setHasLoaded] = useState<boolean>(Boolean(ssr || forceRender));\n\t\tconst hasLoadedRef = useRef<boolean>(hasLoaded);\n\t\tconst onVisibleRef = useRef(onVisible);\n\t\tconst onInViewChangeRef = useRef(onInViewChange);\n\n\t\tonVisibleRef.current = onVisible;\n\t\tonInViewChangeRef.current = onInViewChange;\n\n\t\tconst rootMargin = parseRootMargin(offset);\n\n\t\tconst triggerLoad = () => {\n\t\t\tif (!hasLoadedRef.current) {\n\t\t\t\tsetHasLoaded(true);\n\t\t\t\tsetIsInView(true);\n\t\t\t\thasLoadedRef.current = true;\n\t\t\t\tonVisibleRef.current?.();\n\t\t\t}\n\t\t};\n\n\t\t// 暴露命令式操作方法\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tload: triggerLoad,\n\t\t\treset: () => {\n\t\t\t\tsetHasLoaded(false);\n\t\t\t\tsetIsInView(false);\n\t\t\t\thasLoadedRef.current = false;\n\t\t\t},\n\t\t\tgetInView: () => isInView,\n\t\t\tgetHasLoaded: () => hasLoadedRef.current,\n\t\t\tgetDOMNode: () => containerRef.current,\n\t\t}));\n\n\t\t// 响应 forceRender 受控属性变化\n\t\tuseEffect(() => {\n\t\t\tif (forceRender && !hasLoadedRef.current) {\n\t\t\t\ttriggerLoad();\n\t\t\t}\n\t\t}, [forceRender]);\n\n\t\tuseEffect(() => {\n\t\t\t// 如果已经加载且 once 为 true,则无需挂载 Observer\n\t\t\tif (hasLoaded && once) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst target = containerRef.current;\n\t\t\tif (!target) return;\n\n\t\t\t// 环境不支持 IntersectionObserver,降级为立即加载\n\t\t\tif (typeof window === 'undefined' || !('IntersectionObserver' in window)) {\n\t\t\t\ttriggerLoad();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// 解析 scrollContainer 根节点\n\t\t\tlet rootElement: HTMLElement | null = null;\n\t\t\tif (typeof scrollContainer === 'string') {\n\t\t\t\trootElement = document.querySelector(scrollContainer);\n\t\t\t} else if (typeof scrollContainer === 'function') {\n\t\t\t\trootElement = scrollContainer();\n\t\t\t} else if (scrollContainer && 'current' in scrollContainer) {\n\t\t\t\trootElement = (scrollContainer as RefObject<HTMLElement | null>).current;\n\t\t\t} else if (scrollContainer instanceof HTMLElement) {\n\t\t\t\trootElement = scrollContainer;\n\t\t\t}\n\n\t\t\tlet observer: IntersectionObserver | null = null;\n\n\t\t\ttry {\n\t\t\t\tobserver = new IntersectionObserver(\n\t\t\t\t\t(entries) => {\n\t\t\t\t\t\tentries.forEach((entry) => {\n\t\t\t\t\t\t\tconst inView = entry.isIntersecting;\n\t\t\t\t\t\t\tsetIsInView(inView);\n\t\t\t\t\t\t\tonInViewChangeRef.current?.(inView);\n\n\t\t\t\t\t\t\tif (inView) {\n\t\t\t\t\t\t\t\tif (!hasLoadedRef.current) {\n\t\t\t\t\t\t\t\t\tsetHasLoaded(true);\n\t\t\t\t\t\t\t\t\thasLoadedRef.current = true;\n\t\t\t\t\t\t\t\t\tonVisibleRef.current?.();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (once) {\n\t\t\t\t\t\t\t\t\tobserver?.unobserve(target);\n\t\t\t\t\t\t\t\t\tobserver?.disconnect();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (!once) {\n\t\t\t\t\t\t\t\t\tsetHasLoaded(false);\n\t\t\t\t\t\t\t\t\thasLoadedRef.current = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\troot: rootElement,\n\t\t\t\t\t\trootMargin,\n\t\t\t\t\t\tthreshold,\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\tobserver.observe(target);\n\t\t\t} catch {\n\t\t\t\t// 如果传参格式或环境发生意外,安全降级立即触发\n\t\t\t\ttriggerLoad();\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tif (observer) {\n\t\t\t\t\tobserver.unobserve(target);\n\t\t\t\t\tobserver.disconnect();\n\t\t\t\t}\n\t\t\t};\n\t\t}, [rootMargin, threshold, once, hasLoaded, scrollContainer]);\n\n\t\tconst formattedHeight = typeof height === 'number' ? `${height}px` : height;\n\t\tconst formattedWidth = typeof width === 'number' ? `${width}px` : width;\n\n\t\t// 默认骨架占位\n\t\tconst defaultPlaceholder = skeleton ? (\n\t\t\t<div\n\t\t\t\tclassName={`rpc_lazy_load_placeholder ${bordered ? 'rpc_lazy_load_placeholder_bordered' : ''}`}\n\t\t\t\tstyle={{\n\t\t\t\t\tminHeight: formattedHeight,\n\t\t\t\t\twidth: formattedWidth,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className=\"rpc_lazy_load_skeleton\" />\n\t\t\t</div>\n\t\t) : (\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tminHeight: formattedHeight,\n\t\t\t\t\twidth: formattedWidth,\n\t\t\t\t}}\n\t\t\t/>\n\t\t);\n\n\t\tconst shouldRenderContent = hasLoaded || (once ? hasLoaded : isInView);\n\n\t\tconst containerClass = [\n\t\t\t'rpc_lazy_load_box',\n\t\t\tshouldRenderContent ? 'rpc_lazy_load_loaded' : 'rpc_lazy_load_pending',\n\t\t\tanimate && shouldRenderContent ? 'rpc_lazy_load_fade_in' : '',\n\t\t\tclassName,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(' ');\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName={containerClass}\n\t\t\t\tstyle={{\n\t\t\t\t\tminHeight: shouldRenderContent ? undefined : formattedHeight,\n\t\t\t\t\twidth: formattedWidth,\n\t\t\t\t\t...style,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{shouldRenderContent ? (\n\t\t\t\t\ttypeof children === 'function' ? (\n\t\t\t\t\t\t(children as (props: LazyRenderProps) => ReactNode)({\n\t\t\t\t\t\t\tisInView,\n\t\t\t\t\t\t\thasLoaded,\n\t\t\t\t\t\t\tload: triggerLoad,\n\t\t\t\t\t\t})\n\t\t\t\t\t) : (\n\t\t\t\t\t\tchildren\n\t\t\t\t\t)\n\t\t\t\t) : placeholder !== undefined ? (\n\t\t\t\t\tplaceholder\n\t\t\t\t) : (\n\t\t\t\t\tdefaultPlaceholder\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nLazyLoadBox.displayName = 'LazyLoadBox';\n\nexport default LazyLoadBox;\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkR4V3EJVP_cjs = require('./chunk-R4V3EJVP.cjs');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
var AnnouncementBar = ({
|
|
8
|
+
children,
|
|
9
|
+
type = "primary",
|
|
10
|
+
background,
|
|
11
|
+
color,
|
|
12
|
+
sticky = false,
|
|
13
|
+
fixed = false,
|
|
14
|
+
top = 0,
|
|
15
|
+
zIndex = 1e3,
|
|
16
|
+
closable = true,
|
|
17
|
+
closeIcon,
|
|
18
|
+
storageKey,
|
|
19
|
+
marquee = false,
|
|
20
|
+
onClose,
|
|
21
|
+
className = "",
|
|
22
|
+
style
|
|
23
|
+
}) => {
|
|
24
|
+
const [visible, setVisible] = react.useState(() => {
|
|
25
|
+
if (typeof window !== "undefined" && storageKey) {
|
|
26
|
+
try {
|
|
27
|
+
return localStorage.getItem(`rpc_announcement_${storageKey}`) !== "closed";
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
});
|
|
34
|
+
const [isClosing, setIsClosing] = react.useState(false);
|
|
35
|
+
if (!visible) return null;
|
|
36
|
+
const handleClose = () => {
|
|
37
|
+
setIsClosing(true);
|
|
38
|
+
if (storageKey && typeof window !== "undefined") {
|
|
39
|
+
try {
|
|
40
|
+
localStorage.setItem(`rpc_announcement_${storageKey}`, "closed");
|
|
41
|
+
} catch (e) {
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
setVisible(false);
|
|
46
|
+
onClose == null ? void 0 : onClose();
|
|
47
|
+
}, 250);
|
|
48
|
+
};
|
|
49
|
+
const positionStyle = {};
|
|
50
|
+
if (fixed) {
|
|
51
|
+
positionStyle.position = "fixed";
|
|
52
|
+
positionStyle.top = top;
|
|
53
|
+
positionStyle.left = 0;
|
|
54
|
+
positionStyle.right = 0;
|
|
55
|
+
positionStyle.zIndex = zIndex;
|
|
56
|
+
} else if (sticky) {
|
|
57
|
+
positionStyle.position = "sticky";
|
|
58
|
+
positionStyle.top = top;
|
|
59
|
+
positionStyle.zIndex = zIndex;
|
|
60
|
+
}
|
|
61
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
className: `rpc_announcement_bar rpc_announcement_bar_${type} ${sticky ? "rpc_announcement_bar_sticky" : ""} ${fixed ? "rpc_announcement_bar_fixed" : ""} ${isClosing ? "rpc_announcement_bar_closing" : ""} ${className}`,
|
|
65
|
+
style: {
|
|
66
|
+
background: background || void 0,
|
|
67
|
+
color: color || void 0,
|
|
68
|
+
...positionStyle,
|
|
69
|
+
...style
|
|
70
|
+
},
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rpc_announcement_bar_body", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `rpc_announcement_bar_content ${marquee ? "rpc_announcement_bar_marquee" : ""}`, children }) }),
|
|
73
|
+
closable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
74
|
+
"button",
|
|
75
|
+
{
|
|
76
|
+
type: "button",
|
|
77
|
+
className: "rpc_announcement_bar_close",
|
|
78
|
+
onClick: handleClose,
|
|
79
|
+
title: "\u5173\u95ED\u901A\u77E5",
|
|
80
|
+
children: closeIcon || /* @__PURE__ */ jsxRuntime.jsx(chunkR4V3EJVP_cjs.CloseOutlined, { style: { fontSize: 13 } })
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
var AnnouncementBar_default = AnnouncementBar;
|
|
88
|
+
|
|
89
|
+
exports.AnnouncementBar_default = AnnouncementBar_default;
|
|
90
|
+
//# sourceMappingURL=chunk-ZXMFWVE4.cjs.map
|
|
91
|
+
//# sourceMappingURL=chunk-ZXMFWVE4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../AnnouncementBar/index.tsx"],"names":["useState","jsxs","jsx","CloseOutlined"],"mappings":"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","file":"chunk-ZXMFWVE4.cjs","sourcesContent":["import React, { useState, useEffect, ReactNode, CSSProperties } from 'react';\nimport { CloseOutlined } from '../src/icons';\nimport './index.less';\n\nexport type AnnouncementType = 'primary' | 'warning' | 'success' | 'danger' | 'purple';\n\nexport interface AnnouncementBarProps {\n\t/** 横幅广播内容 */\n\tchildren: ReactNode;\n\t/** 预设主题色系:'primary' | 'warning' | 'success' | 'danger' | 'purple' */\n\ttype?: AnnouncementType;\n\t/** 自定义渐变或背景样式(传值时覆盖 type 预设) */\n\tbackground?: string;\n\t/** 自定义文字颜色 */\n\tcolor?: string;\n\t/** 是否开启智能吸顶 (position: sticky),默认为 false */\n\tsticky?: boolean;\n\t/** 是否开启固定吸顶 (position: fixed),默认为 false */\n\tfixed?: boolean;\n\t/** 吸顶时距离顶部的距离偏移(像素或 CSS 字符串),默认为 0 */\n\ttop?: number | string;\n\t/** 图层层级 z-index,默认为 1000 */\n\tzIndex?: number;\n\t/** 是否支持点击关闭,默认为 true */\n\tclosable?: boolean;\n\t/** 自定义关闭图标 */\n\tcloseIcon?: ReactNode;\n\t/** LocalStorage 记忆 Key(若传入则关闭后自动持久化记忆,不再重复弹出) */\n\tstorageKey?: string;\n\t/** 内容过长时是否开启跑马灯无缝水平滚动,默认为 false */\n\tmarquee?: boolean;\n\t/** 关闭时的回调函数 */\n\tonClose?: () => void;\n\t/** 自定义类名 */\n\tclassName?: string;\n\t/** 自定义样式 */\n\tstyle?: CSSProperties;\n}\n\nconst AnnouncementBar: React.FC<AnnouncementBarProps> = ({\n\tchildren,\n\ttype = 'primary',\n\tbackground,\n\tcolor,\n\tsticky = false,\n\tfixed = false,\n\ttop = 0,\n\tzIndex = 1000,\n\tclosable = true,\n\tcloseIcon,\n\tstorageKey,\n\tmarquee = false,\n\tonClose,\n\tclassName = '',\n\tstyle,\n}) => {\n\tconst [visible, setVisible] = useState<boolean>(() => {\n\t\tif (typeof window !== 'undefined' && storageKey) {\n\t\t\ttry {\n\t\t\t\treturn localStorage.getItem(`rpc_announcement_${storageKey}`) !== 'closed';\n\t\t\t} catch {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t});\n\n\tconst [isClosing, setIsClosing] = useState<boolean>(false);\n\n\tif (!visible) return null;\n\n\tconst handleClose = () => {\n\t\tsetIsClosing(true);\n\n\t\tif (storageKey && typeof window !== 'undefined') {\n\t\t\ttry {\n\t\t\t\tlocalStorage.setItem(`rpc_announcement_${storageKey}`, 'closed');\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tsetVisible(false);\n\t\t\tonClose?.();\n\t\t}, 250);\n\t};\n\n\tconst positionStyle: CSSProperties = {};\n\tif (fixed) {\n\t\tpositionStyle.position = 'fixed';\n\t\tpositionStyle.top = top;\n\t\tpositionStyle.left = 0;\n\t\tpositionStyle.right = 0;\n\t\tpositionStyle.zIndex = zIndex;\n\t} else if (sticky) {\n\t\tpositionStyle.position = 'sticky';\n\t\tpositionStyle.top = top;\n\t\tpositionStyle.zIndex = zIndex;\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tclassName={`rpc_announcement_bar rpc_announcement_bar_${type} ${\n\t\t\t\tsticky ? 'rpc_announcement_bar_sticky' : ''\n\t\t\t} ${fixed ? 'rpc_announcement_bar_fixed' : ''} ${\n\t\t\t\tisClosing ? 'rpc_announcement_bar_closing' : ''\n\t\t\t} ${className}`}\n\t\t\tstyle={{\n\t\t\t\tbackground: background || undefined,\n\t\t\t\tcolor: color || undefined,\n\t\t\t\t...positionStyle,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div className=\"rpc_announcement_bar_body\">\n\t\t\t\t<div className={`rpc_announcement_bar_content ${marquee ? 'rpc_announcement_bar_marquee' : ''}`}>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{closable && (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"rpc_announcement_bar_close\"\n\t\t\t\t\tonClick={handleClose}\n\t\t\t\t\ttitle=\"关闭通知\"\n\t\t\t\t>\n\t\t\t\t\t{closeIcon || <CloseOutlined style={{ fontSize: 13 }} />}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n};\n\nexport default AnnouncementBar;\n"]}
|