Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Scrollbar component #315

Merged
merged 16 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 64 additions & 39 deletions packages/react-styled-ui/src/Scrollbar/Scrollbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const Scrollbar = forwardRef((
{
onScroll,
onUpdate,
alwaysShow = false,
horizontalVisibility = 'auto',
verticalVisibility = 'auto',
autoHideDelay = 1000,
thumbSize,
thumbMinSize = 30,
Expand All @@ -35,8 +36,8 @@ const Scrollbar = forwardRef((
},
ref,
) => {
const autoHide = !alwaysShow;
let hideTracksTimeout;
let hideHorizontalTrackTimeout;
let hideVerticalTrackTimeout;
let viewScrollLeft = 0;
let viewScrollTop = 0;
let lastViewScrollLeft = 0;
Expand All @@ -57,8 +58,8 @@ const Scrollbar = forwardRef((

const containerStyle = useContainerStyle({ autoHeight, autoHeightMin, autoHeightMax, style });
const viewStyle = useViewStyle({ scrollbarWidth, autoHeight, autoHeightMin, autoHeightMax });
const trackHorizontalStyle = useTrackHorizontalStyle({ scrollbarWidth, autoHide });
const trackVerticalStyle = useTrackVerticalStyle({ scrollbarWidth, autoHide });
const trackHorizontalStyle = useTrackHorizontalStyle({ scrollbarWidth, horizontalVisibility });
const trackVerticalStyle = useTrackVerticalStyle({ scrollbarWidth, verticalVisibility });
const thumbHorizontalStyle = useThumbHorizontalStyle();
const thumbVerticalStyle = useThumbVerticalStyle();

Expand Down Expand Up @@ -140,6 +141,30 @@ const Scrollbar = forwardRef((
}
return Math.max(height, thumbMinSize);
};
const hideHorizontalTrack = () => {
if (horizontalVisibility === true) {
return;
}

clearTimeout(hideHorizontalTrackTimeout);
hideHorizontalTrackTimeout = setTimeout(() => {
if (trackHorizontalRef.current) {
trackHorizontalRef.current.style.opacity = 0;
}
}, autoHideDelay);
};
const hideVerticalTrack = () => {
if (verticalVisibility === true) {
return;
}

clearTimeout(hideVerticalTrackTimeout);
hideVerticalTrackTimeout = setTimeout(() => {
if (trackVerticalRef.current) {
trackVerticalRef.current.style.opacity = 0;
}
}, autoHideDelay);
};
const hideTracks = () => {
if (isDragging) {
return;
Expand All @@ -153,25 +178,32 @@ const Scrollbar = forwardRef((
if (isViewMouseOver) {
return;
}
clearTimeout(hideTracksTimeout);
hideTracksTimeout = setTimeout(() => {
if (trackHorizontalRef.current) {
trackHorizontalRef.current.style.opacity = 0;
}
if (trackVerticalRef.current) {
trackVerticalRef.current.style.opacity = 0;
}
}, autoHideDelay);
hideHorizontalTrack();
hideVerticalTrack();
};
const showTracks = () => {
clearTimeout(hideTracksTimeout);
const showHorizontalTrack = () => {
if (horizontalVisibility === false) {
return;
}

clearTimeout(hideHorizontalTrackTimeout);
if (trackHorizontalRef.current) {
trackHorizontalRef.current.style.opacity = 1;
}
};
const showVerticalTrack = () => {
if (verticalVisibility === false) {
return;
}
clearTimeout(hideVerticalTrackTimeout);
if (trackVerticalRef.current) {
trackVerticalRef.current.style.opacity = 1;
}
};
const showTracks = () => {
showHorizontalTrack();
showVerticalTrack();
};
const getScrollLeftForOffset = (offset) => {
const { scrollWidth, clientWidth } = viewRef.current;
const trackWidth = getInnerWidth(trackHorizontalRef.current);
Expand All @@ -186,23 +218,25 @@ const Scrollbar = forwardRef((
};

/* Start Scrolling Events */
const handleScrollStartAutoShow = () => {
if (!autoHide) {
return;
}
showTracks();
const handleHorizontalScrollStartAutoShow = () => {
showHorizontalTrack();
};
const handleScrollStopAutoHide = () => {
if (!autoHide) {
return;
}
hideTracks();
};
const handleScrollStop = () => {
handleScrollStopAutoHide();
const handleVerticalScrollStartAutoShow = () => {
showVerticalTrack();
};
const handleScrollStart = () => {
handleScrollStartAutoShow();
handleHorizontalScrollStartAutoShow();
handleVerticalScrollStartAutoShow();
};
const horizontalScrollStopAutoHide = () => {
hideHorizontalTrack();
};
const verticalScrollStopAutoHide = () => {
hideVerticalTrack();
};
const handleScrollStop = () => {
horizontalScrollStopAutoHide();
verticalScrollStopAutoHide();
};
const detectScrolling = () => {
if (isScrolling) {
Expand Down Expand Up @@ -254,9 +288,6 @@ const Scrollbar = forwardRef((
return false;
};
const handleDragEndAutoHide = () => {
if (!autoHide) {
return;
}
hideTracks();
};
const setupDragging = () => {
Expand Down Expand Up @@ -288,15 +319,9 @@ const Scrollbar = forwardRef((

/* Start Mouse Events */
const handleTrackMouseEnterAutoShow = () => {
if (!autoHide) {
return;
}
showTracks();
};
const handleTrackMouseLeaveAutoHide = () => {
if (!autoHide) {
return;
}
hideTracks();
};
const handleViewMouseEnter = () => {
Expand Down
12 changes: 8 additions & 4 deletions packages/react-styled-ui/src/Scrollbar/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,30 +47,34 @@ const useTrackAutoHideStyle = props => ({
});

const useTrackHorizontalStyle = props => {
const { autoHide, scrollbarWidth } = props;
const { horizontalVisibility, scrollbarWidth } = props;
const trackAutoHideStyle = useTrackAutoHideStyle();
const autoHide = horizontalVisibility === 'auto';
const alwaysHide = !scrollbarWidth || horizontalVisibility === false;
return {
position: 'absolute',
height: styledScrollbarWidth,
right: 0,
bottom: 0,
left: 0,
...(autoHide && trackAutoHideStyle),
...(!scrollbarWidth && { display: 'none' }),
...(alwaysHide && { display: 'none' }),
};
};

const useTrackVerticalStyle = props => {
const { autoHide, scrollbarWidth } = props;
const { verticalVisibility, scrollbarWidth } = props;
const trackAutoHideStyle = useTrackAutoHideStyle();
const autoHide = verticalVisibility === 'auto';
const alwaysHide = !scrollbarWidth || verticalVisibility === false;
return {
position: 'absolute',
width: styledScrollbarWidth,
right: 0,
bottom: 0,
top: 0,
...(autoHide && trackAutoHideStyle),
...(!scrollbarWidth && { display: 'none' }),
...(alwaysHide && { display: 'none' }),
};
};

Expand Down
18 changes: 10 additions & 8 deletions packages/styled-ui-docs/pages/scrollbar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ function CustomScrollbar({

return (
<Scrollbar
alwaysShow
horizontalVisibility={true}
verticalVisibility={true}
renderView={renderScrollView}
renderTrackHorizontal={renderScrollTrack}
renderTrackVertical={renderScrollTrack}
Expand Down Expand Up @@ -260,17 +261,18 @@ render(

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| alwaysShow | boolean | false | Enable always-show mode. |
| autoHideDelay | number | 1000 | Hide delay in ms. |
| autoHeight | boolean | false | Enable auto-height mode. |
| autoHeightMax | number | 200 | Set a maximum height for auto-height mode. default is `200px`. |
| autoHeightMin | number | 0 | Set a minimum height for auto-height mode. |
| horizontalVisibility | string \| boolean | 'auto' | Acceptable values: `'auto'`, `true`, `false`. If `'auto'`, the horizontal scrollbar will auto show/hide. If `true`, the horizontal scrollbar always to show. If `false`, the horizontal scrollbar always to hide. |
cheton marked this conversation as resolved.
Show resolved Hide resolved
| verticalVisibility | string \| boolean | 'auto' | Acceptable values: `'auto'`, `true`, `false`. If `'auto'`, the vertical scrollbar will auto show/hide. If `true`, the vertical scrollbar always to show. If `false`, the vertical scrollbar always to hide. |
| autoHideDelay | number | 1000 | Hide delay in ms. |transitionDelay
cheton marked this conversation as resolved.
Show resolved Hide resolved
| autoHeight | boolean | false | If `true`, activate auto height mode. |
| autoHeightMax | number | 200 | Set a maximum height (in pixels) for auto-height mode. |
| autoHeightMin | number | 0 | Set a minimum height (in pixels) for auto-height mode. |
| onScroll | function | | Event handler. |
| onUpdate | function({ values, hasHorizontalScrollbar, hasVerticalScrollbar }) | | Called whenever the component is updated. |
| renderView | function | | The element your content will be rendered in. |
| renderTrackHorizontal | function | | Horizontal track element. |
| renderTrackVertical | function | | Vertical track element. |
| renderThumbHorizontal | function | | Horizontal thumb element. |
| renderThumbVertical | function | | Vertical thumb element. |
cheton marked this conversation as resolved.
Show resolved Hide resolved
| thumbMinSize | number | 30 | Minimal thumb size. default is `30px`. |
| thumbSize | number | | Set a fixed size for thumbs. |
| thumbMinSize | number | 30 | Minimal thumb size in pixels. |
cheton marked this conversation as resolved.
Show resolved Hide resolved
| thumbSize | number | | Set a fixed size (in pixels) for thumbs. |