@vnejs/uis.react.scrollbar 0.1.3 → 0.1.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/dist/Scrollbar.d.ts +0 -1
- package/dist/Scrollbar.d.ts.map +1 -1
- package/dist/Scrollbar.js +2 -3
- package/dist/Scrollbar.js.map +1 -1
- package/dist/Scrollbar.styles.d.ts +2 -0
- package/dist/Scrollbar.styles.d.ts.map +1 -0
- package/dist/Scrollbar.styles.js +62 -0
- package/dist/Scrollbar.styles.js.map +1 -0
- package/package.json +12 -17
- package/src/Scrollbar.stories.tsx +49 -0
- package/src/Scrollbar.styles.ts +64 -0
- package/src/Scrollbar.tsx +91 -0
- package/src/hooks/ref.hook.ts +11 -0
- package/src/hooks/scroll-to.hook.ts +34 -0
- package/src/hooks/scroll.hook.ts +57 -0
- package/src/hooks/thumb.hook.ts +29 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +18 -0
- package/dist/Scrollbar.styl +0 -55
package/dist/Scrollbar.d.ts
CHANGED
package/dist/Scrollbar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scrollbar.d.ts","sourceRoot":"","sources":["../src/Scrollbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Scrollbar.d.ts","sourceRoot":"","sources":["../src/Scrollbar.tsx"],"names":[],"mappings":"AAoBA,eAAO,MAAM,SAAS,GAAI;;;;;;;;;;;CAWzB,4CA2DA,CAAC"}
|
package/dist/Scrollbar.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { getVneLength } from "@vnejs/uis.utils";
|
|
4
4
|
import { useThumbHook } from "./hooks/thumb.hook";
|
|
5
5
|
import { useScrollHook } from "./hooks/scroll.hook";
|
|
6
6
|
import { useScrollToHook } from "./hooks/scroll-to.hook";
|
|
7
7
|
import { useRefForScrollHook } from "./hooks/ref.hook";
|
|
8
|
-
import "./Scrollbar.
|
|
9
|
-
const b = cn("Scrollbar");
|
|
8
|
+
import { b } from "./Scrollbar.styles.js";
|
|
10
9
|
const renderScroll = (thumbRef, isVisible, isHorizontal, isVertical) => (_jsx("div", { className: b("scroll", { isVisible, isHorizontal, isVertical }), children: _jsx("div", { className: b("thumb", { isHorizontal, isVertical }), ref: thumbRef }) }));
|
|
11
10
|
export const Scrollbar = ({ className = "", children, width = 0, height = 0, scrollTo = 0, scrollToEnd = false, hideScrolbars = false, disableScroll = false, wrapRef = null, textSize = null, }) => {
|
|
12
11
|
const { scrollbarWrapRef, scrollbarChildrenRef, thumbHorizontalRef, thumbVerticalRef } = useRefForScrollHook();
|
package/dist/Scrollbar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scrollbar.js","sourceRoot":"","sources":["../src/Scrollbar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Scrollbar.js","sourceRoot":"","sources":["../src/Scrollbar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scrollbar.styles.d.ts","sourceRoot":"","sources":["../src/Scrollbar.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC,4BAAkB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { cn, getVneLength, injectStyles, sel } from "@vnejs/uis.utils";
|
|
2
|
+
export const b = cn("Scrollbar");
|
|
3
|
+
const CSS = `
|
|
4
|
+
${sel(b())} {
|
|
5
|
+
--vne-scrollbar-color-vertical: var(--vne-color-disabled, rgba(255, 255, 255, 30%));
|
|
6
|
+
--vne-scrollbar-color-horizontal: var(--vne-color-disabled, rgba(255, 255, 255, 30%));
|
|
7
|
+
--vne-scrollbar-color-thumb: var(--vne-color-selected, rgba(255, 255, 255, 75%));
|
|
8
|
+
display: block;
|
|
9
|
+
position: relative;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
${sel(b("wrap"))} {
|
|
13
|
+
scrollbar-width: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
${sel(b("scroll"))} {
|
|
17
|
+
position: absolute;
|
|
18
|
+
transition: 1000ms;
|
|
19
|
+
border-radius: ${getVneLength(8)};
|
|
20
|
+
opacity: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
${sel(b("thumb"))} {
|
|
24
|
+
position: absolute;
|
|
25
|
+
background: var(--vne-scrollbar-color-thumb);
|
|
26
|
+
border-radius: ${getVneLength(12)};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
${sel(b("scroll", { isVertical: true }))} {
|
|
30
|
+
right: ${getVneLength(-24)};
|
|
31
|
+
top: 0;
|
|
32
|
+
bottom: ${getVneLength(36)};
|
|
33
|
+
width: ${getVneLength(12)};
|
|
34
|
+
background: var(--vne-scrollbar-color-vertical);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
${sel(b("thumb", { isVertical: true }))} {
|
|
38
|
+
right: ${getVneLength(-6)};
|
|
39
|
+
width: ${getVneLength(24)};
|
|
40
|
+
height: ${getVneLength(96)};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
${sel(b("scroll", { isHorizontal: true }))} {
|
|
44
|
+
bottom: ${getVneLength(-24)};
|
|
45
|
+
left: 0;
|
|
46
|
+
right: ${getVneLength(36)};
|
|
47
|
+
height: ${getVneLength(12)};
|
|
48
|
+
background: var(--vne-scrollbar-color-horizontal);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
${sel(b("thumb", { isHorizontal: true }))} {
|
|
52
|
+
top: ${getVneLength(-6)};
|
|
53
|
+
width: ${getVneLength(96)};
|
|
54
|
+
height: ${getVneLength(24)};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
${sel(b("scroll", { isVisible: true }))} {
|
|
58
|
+
opacity: 1;
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
injectStyles(CSS);
|
|
62
|
+
//# sourceMappingURL=Scrollbar.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scrollbar.styles.js","sourceRoot":"","sources":["../src/Scrollbar.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC;AAEjC,MAAM,GAAG,GAAG;EACV,GAAG,CAAC,CAAC,EAAE,CAAC;;;;;;;;EAQR,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;;;;EAId,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;;;mBAGC,YAAY,CAAC,CAAC,CAAC;;;;EAIhC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;;;mBAGE,YAAY,CAAC,EAAE,CAAC;;;EAGjC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;WAC7B,YAAY,CAAC,CAAC,EAAE,CAAC;;YAEhB,YAAY,CAAC,EAAE,CAAC;WACjB,YAAY,CAAC,EAAE,CAAC;;;;EAIzB,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;WAC5B,YAAY,CAAC,CAAC,CAAC,CAAC;WAChB,YAAY,CAAC,EAAE,CAAC;YACf,YAAY,CAAC,EAAE,CAAC;;;EAG1B,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9B,YAAY,CAAC,CAAC,EAAE,CAAC;;WAElB,YAAY,CAAC,EAAE,CAAC;YACf,YAAY,CAAC,EAAE,CAAC;;;;EAI1B,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;SAChC,YAAY,CAAC,CAAC,CAAC,CAAC;WACd,YAAY,CAAC,EAAE,CAAC;YACf,YAAY,CAAC,EAAE,CAAC;;;EAG1B,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;;;CAGtC,CAAC;AAEF,YAAY,CAAC,GAAG,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vnejs/uis.react.scrollbar",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"build": "
|
|
8
|
-
"publish:major:
|
|
9
|
-
"publish:minor:
|
|
10
|
-
"publish:patch:
|
|
11
|
-
"publish:major": "
|
|
12
|
-
"publish:minor": "
|
|
13
|
-
"publish:patch": "
|
|
7
|
+
"build": "npx @vnejs/monorepo package",
|
|
8
|
+
"publish:major:uis:react": "npm run publish:major",
|
|
9
|
+
"publish:minor:uis:react": "npm run publish:minor",
|
|
10
|
+
"publish:patch:uis:react": "npm run publish:patch",
|
|
11
|
+
"publish:major": "npx @vnejs/monorepo publish major --access public",
|
|
12
|
+
"publish:minor": "npx @vnejs/monorepo publish minor --access public",
|
|
13
|
+
"publish:patch": "npx @vnejs/monorepo publish patch --access public"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@
|
|
17
|
-
"@vnejs/uis.utils": "~0.1.0",
|
|
18
|
-
"react": "19.2.4",
|
|
19
|
-
"react-dom": "19.2.4"
|
|
16
|
+
"@vnejs/uis.utils": "~0.1.0"
|
|
20
17
|
},
|
|
21
18
|
"devDependencies": {
|
|
22
|
-
"@vnejs/uis.react": "~0.1.0"
|
|
23
|
-
"typescript": "^6.0.3",
|
|
24
|
-
"@types/react": "^19.0.10",
|
|
25
|
-
"@types/react-dom": "^19.0.4"
|
|
19
|
+
"@vnejs/uis.react": "~0.1.0"
|
|
26
20
|
},
|
|
27
21
|
"files": [
|
|
28
22
|
"dist",
|
|
29
|
-
"
|
|
23
|
+
"src",
|
|
24
|
+
"tsconfig.json"
|
|
30
25
|
]
|
|
31
26
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { renderWithVneWrap, VneWrap } from "@vnejs/uis.react";
|
|
2
|
+
|
|
3
|
+
import { Text, Scrollbar, Flex } from "@vnejs/uis.react";
|
|
4
|
+
|
|
5
|
+
export const Common = {
|
|
6
|
+
args: {
|
|
7
|
+
...VneWrap.DEFAULT_ARGS,
|
|
8
|
+
textCount: 6,
|
|
9
|
+
|
|
10
|
+
activeIndex: 0,
|
|
11
|
+
size: 48,
|
|
12
|
+
width: 600,
|
|
13
|
+
height: 600,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
title: "Primitives/Scrollbar",
|
|
19
|
+
render: renderWithVneWrap(({ textCount, height, width, size, activeIndex }) => (
|
|
20
|
+
<Scrollbar
|
|
21
|
+
height={height}
|
|
22
|
+
width={width}
|
|
23
|
+
scrollTo={activeIndex}
|
|
24
|
+
>
|
|
25
|
+
{Array.from({ length: textCount }, (_, index) => index).map((i) => (
|
|
26
|
+
<Text
|
|
27
|
+
key={i}
|
|
28
|
+
isActive={i === activeIndex}
|
|
29
|
+
size={size}
|
|
30
|
+
text="text text text text"
|
|
31
|
+
whiteSpace="nowrap"
|
|
32
|
+
/>
|
|
33
|
+
))}
|
|
34
|
+
</Scrollbar>
|
|
35
|
+
)),
|
|
36
|
+
argTypes: {
|
|
37
|
+
// engine
|
|
38
|
+
...VneWrap.ARGS,
|
|
39
|
+
|
|
40
|
+
// scrollbar
|
|
41
|
+
width: { control: { type: "number", min: 240, max: 900, step: 30 } },
|
|
42
|
+
height: { control: { type: "number", min: 240, max: 900, step: 30 } },
|
|
43
|
+
activeIndex: { control: { type: "number", min: 0, max: 12, step: 1 } },
|
|
44
|
+
|
|
45
|
+
// text
|
|
46
|
+
textCount: { control: { type: "number", min: 3, max: 12, step: 1 } },
|
|
47
|
+
size: { control: { type: "number", min: 24, max: 180, step: 6 } },
|
|
48
|
+
},
|
|
49
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { cn, getVneLength, injectStyles, sel } from "@vnejs/uis.utils";
|
|
2
|
+
|
|
3
|
+
export const b = cn("Scrollbar");
|
|
4
|
+
|
|
5
|
+
const CSS = `
|
|
6
|
+
${sel(b())} {
|
|
7
|
+
--vne-scrollbar-color-vertical: var(--vne-color-disabled, rgba(255, 255, 255, 30%));
|
|
8
|
+
--vne-scrollbar-color-horizontal: var(--vne-color-disabled, rgba(255, 255, 255, 30%));
|
|
9
|
+
--vne-scrollbar-color-thumb: var(--vne-color-selected, rgba(255, 255, 255, 75%));
|
|
10
|
+
display: block;
|
|
11
|
+
position: relative;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
${sel(b("wrap"))} {
|
|
15
|
+
scrollbar-width: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
${sel(b("scroll"))} {
|
|
19
|
+
position: absolute;
|
|
20
|
+
transition: 1000ms;
|
|
21
|
+
border-radius: ${getVneLength(8)};
|
|
22
|
+
opacity: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
${sel(b("thumb"))} {
|
|
26
|
+
position: absolute;
|
|
27
|
+
background: var(--vne-scrollbar-color-thumb);
|
|
28
|
+
border-radius: ${getVneLength(12)};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
${sel(b("scroll", { isVertical: true }))} {
|
|
32
|
+
right: ${getVneLength(-24)};
|
|
33
|
+
top: 0;
|
|
34
|
+
bottom: ${getVneLength(36)};
|
|
35
|
+
width: ${getVneLength(12)};
|
|
36
|
+
background: var(--vne-scrollbar-color-vertical);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
${sel(b("thumb", { isVertical: true }))} {
|
|
40
|
+
right: ${getVneLength(-6)};
|
|
41
|
+
width: ${getVneLength(24)};
|
|
42
|
+
height: ${getVneLength(96)};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
${sel(b("scroll", { isHorizontal: true }))} {
|
|
46
|
+
bottom: ${getVneLength(-24)};
|
|
47
|
+
left: 0;
|
|
48
|
+
right: ${getVneLength(36)};
|
|
49
|
+
height: ${getVneLength(12)};
|
|
50
|
+
background: var(--vne-scrollbar-color-horizontal);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
${sel(b("thumb", { isHorizontal: true }))} {
|
|
54
|
+
top: ${getVneLength(-6)};
|
|
55
|
+
width: ${getVneLength(96)};
|
|
56
|
+
height: ${getVneLength(24)};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
${sel(b("scroll", { isVisible: true }))} {
|
|
60
|
+
opacity: 1;
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
injectStyles(CSS);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { useEffect, useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
import { getVneLength } from "@vnejs/uis.utils";
|
|
4
|
+
|
|
5
|
+
import { useThumbHook } from "./hooks/thumb.hook";
|
|
6
|
+
import { useScrollHook } from "./hooks/scroll.hook";
|
|
7
|
+
import { useScrollToHook } from "./hooks/scroll-to.hook";
|
|
8
|
+
import { useRefForScrollHook } from "./hooks/ref.hook";
|
|
9
|
+
|
|
10
|
+
import { b } from "./Scrollbar.styles.js";
|
|
11
|
+
|
|
12
|
+
const renderScroll = (thumbRef, isVisible, isHorizontal, isVertical) => (
|
|
13
|
+
<div className={b("scroll", { isVisible, isHorizontal, isVertical })}>
|
|
14
|
+
<div
|
|
15
|
+
className={b("thumb", { isHorizontal, isVertical })}
|
|
16
|
+
ref={thumbRef}
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export const Scrollbar = ({
|
|
22
|
+
className = "",
|
|
23
|
+
children,
|
|
24
|
+
width = 0,
|
|
25
|
+
height = 0,
|
|
26
|
+
scrollTo = 0,
|
|
27
|
+
scrollToEnd = false,
|
|
28
|
+
hideScrolbars = false,
|
|
29
|
+
disableScroll = false,
|
|
30
|
+
wrapRef = null,
|
|
31
|
+
textSize = null,
|
|
32
|
+
}) => {
|
|
33
|
+
const { scrollbarWrapRef, scrollbarChildrenRef, thumbHorizontalRef, thumbVerticalRef } = useRefForScrollHook();
|
|
34
|
+
const { shouldRenderHorizontal, shouldRenderVertical } = useScrollHook(scrollbarWrapRef, scrollbarChildrenRef, width, height, textSize);
|
|
35
|
+
|
|
36
|
+
useThumbHook(scrollbarWrapRef, thumbVerticalRef, thumbHorizontalRef);
|
|
37
|
+
useScrollToHook(scrollTo, scrollToEnd, scrollbarWrapRef, scrollbarChildrenRef);
|
|
38
|
+
|
|
39
|
+
const style = useMemo(() => {
|
|
40
|
+
const result: Record<string, any> = {};
|
|
41
|
+
|
|
42
|
+
if (width) result.width = getVneLength(width);
|
|
43
|
+
if (height) result.height = getVneLength(height);
|
|
44
|
+
|
|
45
|
+
return result;
|
|
46
|
+
}, [width, height]);
|
|
47
|
+
|
|
48
|
+
const styleWrap = useMemo(() => {
|
|
49
|
+
const result: Record<string, any> = {};
|
|
50
|
+
|
|
51
|
+
if (disableScroll) {
|
|
52
|
+
result.overflowX = "hidden";
|
|
53
|
+
result.overflowY = "hidden";
|
|
54
|
+
} else {
|
|
55
|
+
if (shouldRenderHorizontal) result.overflowX = "auto";
|
|
56
|
+
if (shouldRenderVertical) result.overflowY = "auto";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (width) result.maxWidth = getVneLength(width);
|
|
60
|
+
if (height) result.maxHeight = getVneLength(height);
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
}, [width, height, scrollbarWrapRef.current, shouldRenderHorizontal, shouldRenderVertical, disableScroll]);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (wrapRef) wrapRef.current = scrollbarWrapRef.current;
|
|
67
|
+
}, [wrapRef, scrollbarWrapRef.current]);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div
|
|
71
|
+
className={b({}, [className])}
|
|
72
|
+
style={style}
|
|
73
|
+
>
|
|
74
|
+
{!hideScrolbars && renderScroll(thumbHorizontalRef, shouldRenderHorizontal, true, false)}
|
|
75
|
+
{!hideScrolbars && renderScroll(thumbVerticalRef, shouldRenderVertical, false, true)}
|
|
76
|
+
|
|
77
|
+
<div
|
|
78
|
+
className={b("wrap")}
|
|
79
|
+
ref={scrollbarWrapRef}
|
|
80
|
+
style={styleWrap}
|
|
81
|
+
>
|
|
82
|
+
<div
|
|
83
|
+
className={b("children")}
|
|
84
|
+
ref={scrollbarChildrenRef}
|
|
85
|
+
>
|
|
86
|
+
{children}
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
|
|
3
|
+
export const useRefForScrollHook = () => {
|
|
4
|
+
const scrollbarWrapRef = useRef(null);
|
|
5
|
+
const scrollbarChildrenRef = useRef(null);
|
|
6
|
+
|
|
7
|
+
const thumbVerticalRef = useRef(null);
|
|
8
|
+
const thumbHorizontalRef = useRef(null);
|
|
9
|
+
|
|
10
|
+
return { scrollbarWrapRef, scrollbarChildrenRef, thumbVerticalRef, thumbHorizontalRef };
|
|
11
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
export const useScrollToHook = (scrollTo, scrollToEnd, scrollbarWrapRef, scrollbarChildrenRef) => {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
if (!scrollTo) return;
|
|
6
|
+
|
|
7
|
+
const children = [...scrollbarChildrenRef.current.children];
|
|
8
|
+
|
|
9
|
+
if (children[scrollTo]) {
|
|
10
|
+
const element = children[scrollTo];
|
|
11
|
+
|
|
12
|
+
if (
|
|
13
|
+
scrollbarWrapRef.current.scrollTop > element.offsetTop ||
|
|
14
|
+
scrollbarWrapRef.current.scrollTop + scrollbarWrapRef.current.clientHeight < element.offsetTop + element.clientHeight ||
|
|
15
|
+
scrollbarWrapRef.current.scrollLeft > element.offsetleft ||
|
|
16
|
+
scrollbarWrapRef.current.scrollleft + scrollbarWrapRef.current.clientWidth < element.offsetleft + element.clientWidth
|
|
17
|
+
)
|
|
18
|
+
element.scrollIntoView({ behavior: "smooth" });
|
|
19
|
+
}
|
|
20
|
+
}, [scrollTo, scrollbarWrapRef.current]);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!scrollToEnd) return;
|
|
23
|
+
|
|
24
|
+
const scrollToBottom = () => scrollbarChildrenRef?.current?.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
25
|
+
|
|
26
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
27
|
+
setTimeout(scrollToBottom, 100);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
resizeObserver.observe(scrollbarChildrenRef.current);
|
|
31
|
+
|
|
32
|
+
return () => resizeObserver.disconnect();
|
|
33
|
+
}, [scrollToEnd, scrollbarWrapRef.current]);
|
|
34
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
export const useScrollHook = (scrollbarWrapRef, scrollbarChildrenRef, width, height, textSize) => {
|
|
4
|
+
const [shouldRenderHorizontal, setShouldRenderHorizontal] = useState(false);
|
|
5
|
+
const [shouldRenderVertical, setShouldRenderVertical] = useState(false);
|
|
6
|
+
|
|
7
|
+
const calcShouldRenderVertical = useCallback(() => {
|
|
8
|
+
const raf = requestAnimationFrame(
|
|
9
|
+
() => scrollbarWrapRef.current && setShouldRenderVertical(scrollbarWrapRef.current.scrollHeight !== scrollbarWrapRef.current.clientHeight),
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
return () => cancelAnimationFrame(raf);
|
|
13
|
+
}, [scrollbarWrapRef.current, setShouldRenderVertical, textSize]);
|
|
14
|
+
|
|
15
|
+
const calcShouldRenderHorizontal = useCallback(() => {
|
|
16
|
+
const raf = requestAnimationFrame(
|
|
17
|
+
() => scrollbarWrapRef.current && setShouldRenderHorizontal(scrollbarWrapRef.current.scrollWidth > scrollbarWrapRef.current.clientWidth),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
return () => cancelAnimationFrame(raf);
|
|
21
|
+
}, [scrollbarWrapRef.current, setShouldRenderHorizontal, textSize]);
|
|
22
|
+
|
|
23
|
+
useEffect(calcShouldRenderVertical, [height, calcShouldRenderVertical, textSize]);
|
|
24
|
+
useEffect(calcShouldRenderHorizontal, [width, calcShouldRenderHorizontal, textSize]);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!scrollbarWrapRef.current) return;
|
|
28
|
+
|
|
29
|
+
const observer = new ResizeObserver(() => {
|
|
30
|
+
if (!scrollbarWrapRef.current) return;
|
|
31
|
+
|
|
32
|
+
let [oldHeight, oldWidth] = [scrollbarWrapRef.current.scrollHeight, scrollbarWrapRef.current.scrollWidth];
|
|
33
|
+
|
|
34
|
+
const rerender = () => {
|
|
35
|
+
calcShouldRenderVertical();
|
|
36
|
+
calcShouldRenderHorizontal();
|
|
37
|
+
|
|
38
|
+
if (!scrollbarWrapRef.current) return;
|
|
39
|
+
|
|
40
|
+
if (oldHeight !== scrollbarWrapRef.current.scrollHeight || oldWidth !== scrollbarWrapRef.current.scrollWidth) {
|
|
41
|
+
oldHeight = scrollbarWrapRef.current.scrollHeight;
|
|
42
|
+
oldWidth = scrollbarWrapRef.current.scrollWidth;
|
|
43
|
+
|
|
44
|
+
setTimeout(rerender, 50);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
setTimeout(rerender, 50);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
observer.observe(scrollbarChildrenRef.current);
|
|
52
|
+
|
|
53
|
+
return () => observer.disconnect();
|
|
54
|
+
}, [scrollbarWrapRef.current, scrollbarChildrenRef.current, calcShouldRenderVertical, calcShouldRenderHorizontal, textSize]);
|
|
55
|
+
|
|
56
|
+
return { shouldRenderHorizontal, shouldRenderVertical };
|
|
57
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
const getPosition = (scrollPosition, thumbSize) => `calc(${100 * scrollPosition}% - ${scrollPosition * thumbSize}px)`;
|
|
4
|
+
|
|
5
|
+
export const useThumbHook = (scrollbarWrapRef, thumbVerticalRef, thumbHorizontalRef) => {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const handleScroll = () => {
|
|
8
|
+
if (!scrollbarWrapRef.current) return;
|
|
9
|
+
if (thumbHorizontalRef.current) {
|
|
10
|
+
const maxScroll = scrollbarWrapRef.current.scrollWidth - scrollbarWrapRef.current.clientWidth;
|
|
11
|
+
|
|
12
|
+
thumbHorizontalRef.current.style.left = getPosition(scrollbarWrapRef.current.scrollLeft / maxScroll, thumbVerticalRef.current.clientWidth);
|
|
13
|
+
}
|
|
14
|
+
if (thumbVerticalRef.current) {
|
|
15
|
+
const maxScroll = scrollbarWrapRef.current.scrollHeight - scrollbarWrapRef.current.clientHeight;
|
|
16
|
+
|
|
17
|
+
thumbVerticalRef.current.style.top = getPosition(scrollbarWrapRef.current.scrollTop / maxScroll, thumbVerticalRef.current.clientHeight);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const ref = scrollbarWrapRef.current;
|
|
22
|
+
|
|
23
|
+
ref.addEventListener("scroll", handleScroll);
|
|
24
|
+
|
|
25
|
+
handleScroll();
|
|
26
|
+
|
|
27
|
+
return () => ref.removeEventListener("scroll", handleScroll);
|
|
28
|
+
}, [scrollbarWrapRef.current, thumbHorizontalRef.current, thumbVerticalRef.current]);
|
|
29
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Scrollbar";
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.react.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist",
|
|
5
|
+
"rootDir": "src"
|
|
6
|
+
},
|
|
7
|
+
"include": [
|
|
8
|
+
"src/**/*.ts",
|
|
9
|
+
"src/**/*.tsx",
|
|
10
|
+
"../../../globals.d.ts",
|
|
11
|
+
"../../../peer-modules.d.ts"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"dist",
|
|
15
|
+
"node_modules",
|
|
16
|
+
"src/**/*.stories.tsx"
|
|
17
|
+
]
|
|
18
|
+
}
|
package/dist/Scrollbar.styl
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
.Scrollbar
|
|
2
|
-
--vne-scrollbar-color-vertical: var(--vne-color-disabled, rgba(255, 255, 255, 30%))
|
|
3
|
-
--vne-scrollbar-color-horizontal: var(--vne-color-disabled, rgba(255, 255, 255, 30%))
|
|
4
|
-
--vne-scrollbar-color-thumb: var(--vne-color-selected, rgba(255, 255, 255, 75%))
|
|
5
|
-
|
|
6
|
-
display: block
|
|
7
|
-
position: relative
|
|
8
|
-
|
|
9
|
-
&-wrap
|
|
10
|
-
scrollbar-width: none
|
|
11
|
-
|
|
12
|
-
&-scroll
|
|
13
|
-
position: absolute
|
|
14
|
-
|
|
15
|
-
transition: 1000ms
|
|
16
|
-
|
|
17
|
-
border-radius: s('round(down, min(calc(8 * 100vw / 3840), calc(8 * 100vh / 2160)), 1px)')
|
|
18
|
-
opacity: 0
|
|
19
|
-
|
|
20
|
-
&-thumb
|
|
21
|
-
position: absolute
|
|
22
|
-
|
|
23
|
-
background: var(--vne-scrollbar-color-thumb)
|
|
24
|
-
border-radius: s('round(down, min(calc(12 * 100vw / 3840), calc(12 * 100vh / 2160)), 1px)')
|
|
25
|
-
|
|
26
|
-
&-scroll_isVertical
|
|
27
|
-
right: s('round(down, min(calc(-24 * 100vw / 3840), calc(-24 * 100vh / 2160)), 1px)')
|
|
28
|
-
top: 0;
|
|
29
|
-
bottom: s('round(down, min(calc(36 * 100vw / 3840), calc(36 * 100vh / 2160)), 1px)')
|
|
30
|
-
|
|
31
|
-
width: s('round(down, min(calc(12 * 100vw / 3840), calc(12 * 100vh / 2160)), 1px)')
|
|
32
|
-
|
|
33
|
-
background: var(--vne-scrollbar-color-vertical)
|
|
34
|
-
|
|
35
|
-
&-thumb_isVertical
|
|
36
|
-
right: s('round(down, min(calc(-6 * 100vw / 3840), calc(-6 * 100vh / 2160)), 1px)')
|
|
37
|
-
width: s('round(down, min(calc(24 * 100vw / 3840), calc(24 * 100vh / 2160)), 1px)')
|
|
38
|
-
height: s('round(down, min(calc(96 * 100vw / 3840), calc(96 * 100vh / 2160)), 1px)')
|
|
39
|
-
|
|
40
|
-
&-scroll_isHorizontal
|
|
41
|
-
bottom: s('round(down, min(calc(-24 * 100vw / 3840), calc(-24 * 100vh / 2160)), 1px)')
|
|
42
|
-
left: 0;
|
|
43
|
-
right: s('round(down, min(calc(36 * 100vw / 3840), calc(36 * 100vh / 2160)), 1px)')
|
|
44
|
-
|
|
45
|
-
height: s('round(down, min(calc(12 * 100vw / 3840), calc(12 * 100vh / 2160)), 1px)')
|
|
46
|
-
|
|
47
|
-
background: var(--vne-scrollbar-color-horizontal)
|
|
48
|
-
|
|
49
|
-
&-thumb_isHorizontal
|
|
50
|
-
top: s('round(down, min(calc(-6 * 100vw / 3840), calc(-6 * 100vh / 2160)), 1px)')
|
|
51
|
-
width: s('round(down, min(calc(96 * 100vw / 3840), calc(96 * 100vh / 2160)), 1px)')
|
|
52
|
-
height: s('round(down, min(calc(24 * 100vw / 3840), calc(24 * 100vh / 2160)), 1px)')
|
|
53
|
-
|
|
54
|
-
&-scroll_isVisible
|
|
55
|
-
opacity: 1
|