@fe-free/core 4.1.37 → 4.1.38
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/CHANGELOG.md +8 -0
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/scroll/helper.tsx +23 -0
- package/src/scroll/index.tsx +58 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/core",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.38",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"author": "",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"i18next-icu": "^2.4.1",
|
|
51
51
|
"react": "^19.2.0",
|
|
52
52
|
"react-i18next": "^16.4.0",
|
|
53
|
-
"@fe-free/icons": "4.1.
|
|
54
|
-
"@fe-free/tool": "4.1.
|
|
53
|
+
"@fe-free/icons": "4.1.38",
|
|
54
|
+
"@fe-free/tool": "4.1.38"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"i18n-extract": "rm -rf ./src/locales/zh-CN && npx i18next-cli extract"
|
package/src/index.ts
CHANGED
|
@@ -58,6 +58,7 @@ export type { PageLayoutProps, PageLayoutTabsProps } from './page_layout';
|
|
|
58
58
|
export { Record, RecordArray } from './record';
|
|
59
59
|
export type { RecordArrayProps, RecordProps } from './record';
|
|
60
60
|
export { routeTool } from './route';
|
|
61
|
+
export { ScrollFixed, getScrollbarWidth, useScrollFixed } from './scroll';
|
|
61
62
|
export { NumberSlider, PercentageSlider } from './slider';
|
|
62
63
|
export type { NumberSliderProps, PercentageSliderProps } from './slider';
|
|
63
64
|
export { Tabs } from './tabs';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function getScrollbarWidth() {
|
|
2
|
+
const target = document.body;
|
|
3
|
+
|
|
4
|
+
// 创建一个不可见的 div 元素
|
|
5
|
+
const outer = document.createElement('div');
|
|
6
|
+
outer.style.visibility = 'hidden';
|
|
7
|
+
outer.style.overflow = 'scroll'; // 强制显示滚动条
|
|
8
|
+
target.appendChild(outer);
|
|
9
|
+
|
|
10
|
+
// 创建一个内部 div,宽度为 100%
|
|
11
|
+
const inner = document.createElement('div');
|
|
12
|
+
outer.appendChild(inner);
|
|
13
|
+
|
|
14
|
+
// 滚动条宽度 = 外部容器的宽度 - 内部内容的宽度
|
|
15
|
+
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
|
|
16
|
+
|
|
17
|
+
// 清理 DOM
|
|
18
|
+
target.removeChild(outer);
|
|
19
|
+
|
|
20
|
+
return scrollbarWidth;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { getScrollbarWidth };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { getScrollbarWidth } from './helper';
|
|
4
|
+
|
|
5
|
+
function useScrollFixed({ ref }: { ref: React.RefObject<HTMLElement | null> }) {
|
|
6
|
+
const [marginRight, setMarginRight] = useState(0);
|
|
7
|
+
|
|
8
|
+
const scrollbarWidth = useMemo(() => {
|
|
9
|
+
return getScrollbarWidth();
|
|
10
|
+
}, []);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const el = ref.current;
|
|
14
|
+
if (!el) return;
|
|
15
|
+
|
|
16
|
+
const updateMargin = () => {
|
|
17
|
+
const hasVerticalScrollbar = el.scrollHeight > el.clientHeight;
|
|
18
|
+
setMarginRight(hasVerticalScrollbar ? scrollbarWidth : 0);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
updateMargin();
|
|
22
|
+
|
|
23
|
+
const resizeObserver = new ResizeObserver(updateMargin);
|
|
24
|
+
resizeObserver.observe(el);
|
|
25
|
+
el.addEventListener('scroll', updateMargin);
|
|
26
|
+
|
|
27
|
+
return () => {
|
|
28
|
+
resizeObserver.disconnect();
|
|
29
|
+
el.removeEventListener('scroll', updateMargin);
|
|
30
|
+
};
|
|
31
|
+
}, [ref, scrollbarWidth]);
|
|
32
|
+
|
|
33
|
+
return { marginRight };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function ScrollFixed({
|
|
37
|
+
refScroll,
|
|
38
|
+
className,
|
|
39
|
+
children,
|
|
40
|
+
...rest
|
|
41
|
+
}: {
|
|
42
|
+
refScroll?: React.RefObject<HTMLDivElement | null>;
|
|
43
|
+
className?: string;
|
|
44
|
+
style?: React.CSSProperties;
|
|
45
|
+
children: React.ReactNode;
|
|
46
|
+
}) {
|
|
47
|
+
const innerRef = useRef<HTMLDivElement>(null);
|
|
48
|
+
const ref = refScroll || innerRef;
|
|
49
|
+
const { marginRight } = useScrollFixed({ ref });
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div ref={ref} {...rest} className={classNames('h-full w-full overflow-y-auto', className)}>
|
|
53
|
+
<div style={{ marginRight: `-${marginRight || 0}px` }}>{children}</div>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { getScrollbarWidth, ScrollFixed, useScrollFixed };
|