Skip to content

Commit

Permalink
feat(scrollbar): 滚动条固定屏幕底部 (#3019) (#3020)
Browse files Browse the repository at this point in the history
* feat(scrollbar): 滚动条固定屏幕底部 (#3019)

* fix(scrollbar): 修改问题 (#3019)

* chore(scrollbar): 更改(#3019)

---------

Co-authored-by: wanjinping <[email protected]>
  • Loading branch information
fcppddl and wanjinping authored Nov 6, 2024
1 parent b2d784b commit 241447e
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changeset/breezy-pumas-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@hi-ui/scrollbar": patch
"@hi-ui/hiui": patch
---

feat(scrollbar): 滚动条固定在屏幕底部 (#3019)
12 changes: 11 additions & 1 deletion packages/ui/scrollbar/src/Scrollbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ScrollbarEventProps,
ScrollbarPositionEnum,
ScrollbarHelpers,
Settings,
} from './types'
import { ScrollbarEventToPsMap } from './utils'

Expand All @@ -28,6 +29,7 @@ export const Scrollbar = forwardRef<HTMLDivElement | null, ScrollbarProps>(
style,
zIndex,
innerRef,
settings = {},
...rest
},
ref
Expand All @@ -43,7 +45,7 @@ export const Scrollbar = forwardRef<HTMLDivElement | null, ScrollbarProps>(

useEffect(() => {
if (containerElement) {
setPs(new PerfectScrollbar(containerElement))
setPs(new PerfectScrollbar(containerElement, settings))

// 动态设置滚动条 z-index
zIndex && containerElement.style.setProperty('--scrollbar-zIndex', String(zIndex))
Expand Down Expand Up @@ -89,6 +91,9 @@ export const Scrollbar = forwardRef<HTMLDivElement | null, ScrollbarProps>(
() => ({
instance: ps,
containerElement: containerElement || undefined,
updata: () => {
ps?.update()
},
}),
[ps, containerElement]
)
Expand Down Expand Up @@ -172,6 +177,11 @@ export interface ScrollbarProps extends HiBaseHTMLProps<'div'>, ScrollbarEventPr
* @default false
*/
onlyScrollVisible?: boolean
/**
* 滚动条配置
* @default {}
*/
settings: Settings
}

if (__DEV__) {
Expand Down
18 changes: 18 additions & 0 deletions packages/ui/scrollbar/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export interface ScrollbarHelpers {
* 容器dom实例
*/
container?: HTMLDivElement
/**
* 更新滚动条
*/
updata?: () => void
}

export type ScrollbarAxesEnum = 'both' | 'x' | 'y' | 'none'
Expand Down Expand Up @@ -69,3 +73,17 @@ export type ScrollbarPositionEnum =
| 'fixed'
| 'relative'
| 'sticky'

/**
* 更多配置请参考:https://github.com/mdbootstrap/perfect-scrollbar/blob/main/types/perfect-scrollbar.d.ts
*/
export type Settings = PerfectScrollbar.Options & {
/**
* 开启滚动条吸底
*/
isBottomToScreenBottom?: boolean
/**
* 滚动条吸底距离
*/
heightFromBottom?: number
}
63 changes: 63 additions & 0 deletions packages/ui/scrollbar/stories/fixed.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useRef, useEffect } from 'react'
import Scrollbar from '../src'

/**
* @title 滚动条固定到屏幕底部
* @desc 默认不开启
*/
export const Fixed = () => {
const innerRef = useRef<any>()
useEffect(() => {
document.addEventListener('scroll', () => {
innerRef.current?.updata()
})
}, [])
return (
<div
id="outer"
style={{
height: '150vh',
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-end',
}}
>
<Scrollbar
innerRef={innerRef}
keepVisible
style={{
height: 400,
width: 600,
}}
settings={{ isBottomToScreenBottom: true, heightFromBottom: 20 }}
>
<div style={{ height: 640, width: '200%' }}>
<div
style={{
height: 160,
background: 'linear-gradient(90deg,#03A9F433,#03A9F4cc)',
}}
/>
<div
style={{
height: 160,
background: 'linear-gradient(90deg,#00968833,#009688cc)',
}}
/>
<div
style={{
height: 160,
background: 'linear-gradient(90deg,#FF572233,#FF5722cc)',
}}
/>
<div
style={{
height: 160,
background: 'linear-gradient(90deg,#E91E6333,#E91E63cc)',
}}
/>
</div>
</Scrollbar>
</div>
)
}
1 change: 1 addition & 0 deletions packages/ui/scrollbar/stories/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './basic.stories'
export * from './axes.stories'
export * from './config.stories'
export * from './event.stories'
export * from './fixed.stories'

export default {
title: 'Others/Scrollbar',
Expand Down
6 changes: 5 additions & 1 deletion packages/ui/table/stories/scrollbar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,11 @@ export const Scrollbar = () => {
columns={column}
data={data}
maxHeight={300}
scrollbar={{ keepVisible: true, zIndex: 9 }}
scrollbar={{
keepVisible: true,
zIndex: 9,
settings: { isBottomToScreenBottom: true, heightFromBottom: 20 },
}}
/>
</div>
</>
Expand Down
53 changes: 53 additions & 0 deletions patches/perfect-scrollbar+1.5.5.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
diff --git a/node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js b/node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js
index 4215b17..119e0da 100644
--- a/node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js
+++ b/node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js
@@ -418,6 +418,16 @@ function getThumbSize(i, thumbSize) {
return thumbSize;
}

+function getElementBottomToScreenBottomDistance(element, i) {
+ var rect = element.getBoundingClientRect();
+ var elementTop = rect.top;
+ var elementHeight = element.offsetHeight || element.clientHeight;
+ var viewportHeight = window.innerHeight || document.documentElement.clientHeight;
+ viewportHeight -= (i.settings && i.settings.heightFromBottom) || 0;
+ var distance = viewportHeight - (elementTop + elementHeight);
+ return distance;
+}
+
function updateCss(element, i) {
var xRailOffset = { width: i.railXWidth };
var roundedScrollTop = Math.floor(element.scrollTop);
@@ -431,10 +441,23 @@ function updateCss(element, i) {
} else {
xRailOffset.left = element.scrollLeft;
}
+ var bottomToScreenBottomDistance = 0
+ if(i.settings.isBottomToScreenBottom){
+ bottomToScreenBottomDistance = getElementBottomToScreenBottomDistance(
+ element,
+ i
+ );
+ }
if (i.isScrollbarXUsingBottom) {
xRailOffset.bottom = i.scrollbarXBottom - roundedScrollTop;
+ if (bottomToScreenBottomDistance < 0) {
+ xRailOffset.bottom -= bottomToScreenBottomDistance;
+ }
} else {
xRailOffset.top = i.scrollbarXTop + roundedScrollTop;
+ if (bottomToScreenBottomDistance < 0) {
+ xRailOffset.top += bottomToScreenBottomDistance;
+ }
}
set(i.scrollbarXRail, xRailOffset);

@@ -1263,6 +1286,7 @@ var PerfectScrollbar = function PerfectScrollbar(element, userSettings) {
this.lastScrollTop = Math.floor(element.scrollTop); // for onScroll only
this.lastScrollLeft = element.scrollLeft; // for onScroll only
this.event.bind(this.element, 'scroll', function (e) { return this$1.onScroll(e); });
+ this.event.bind(this.element, "mouseenter", function (e) { return this$1.update(e); });
updateGeometry(this);
};

0 comments on commit 241447e

Please sign in to comment.