-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
39e4575
commit 9e0131e
Showing
92 changed files
with
1,096 additions
and
453 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import styled from '@emotion/styled' | ||
|
||
export const HiddenInput = styled.input({ | ||
cursor: 'inherit', | ||
position: 'absolute', | ||
opacity: 0, | ||
width: '100%', | ||
height: '100%', | ||
top: 0, | ||
left: 0, | ||
margin: 0, | ||
padding: 0, | ||
zIndex: 1 | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
packages/harmony/src/components/scrollbar/Scrollbar.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
.scrollbar { | ||
height: 100%; | ||
min-height: 0; | ||
} | ||
|
||
.scrollbar :global(.ps__thumb-y) { | ||
opacity: 0.5; | ||
background-color: var(--neutral-dark-3); | ||
} | ||
|
||
.scrollbar :global(.ps__rail-y) { | ||
margin-top: var(--unit); | ||
margin-bottom: var(--unit); | ||
transition: background-color 0.2s ease-in-out, opacity 0.2s ease-in-out; | ||
} | ||
|
||
/* Cancel the default of perfect scroll, which always shows the scrollbar when hovering over container. Our desired behavior is to | ||
only show the scrollbar for ~1s, then fade away if not scrolling. */ | ||
:global(.ps:hover).scrollbar > :global(.ps__rail-y), | ||
:global(.ps:hover).scrollbar > :global(.ps__rail-x) { | ||
opacity: 0; | ||
} | ||
|
||
:global(.scrollbar--hovered-visible).scrollbar:not(:global(.ps--scrolling-y)) | ||
> :global(.ps__rail-y), | ||
:global(.scrollbar--hovered-visible).scrollbar:not(:global(.ps--scrolling-x)) | ||
> :global(.ps__rail-x) { | ||
opacity: 0.6; | ||
} | ||
|
||
:global(.ps--focus).scrollbar > :global(.ps__rail-x), | ||
:global(.ps--focus).scrollbar > :global(.ps__rail-y), | ||
:global(.ps--scrolling-x).scrollbar > :global(.ps__rail-x), | ||
:global(.ps--scrolling-y).scrollbar > :global(.ps__rail-y) { | ||
opacity: 0.6 !important; | ||
} | ||
|
||
.scrollbar > :global(.ps__rail-y):hover, | ||
.scrollbar > :global(.ps__rail-x):hover { | ||
opacity: 0.9 !important; | ||
} |
63 changes: 63 additions & 0 deletions
63
packages/harmony/src/components/scrollbar/Scrollbar.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { StoryObj } from '@storybook/react' | ||
|
||
import { TextLink } from 'components/text-link' | ||
|
||
import { Text } from '../text' | ||
|
||
import { Scrollbar } from '.' | ||
|
||
export default { | ||
component: Scrollbar, | ||
title: 'Components/Scrollbar' | ||
} | ||
|
||
type Story = StoryObj<typeof Scrollbar> | ||
|
||
export const Primary: Story = { | ||
render: () => ( | ||
<div css={{ height: 200 }}> | ||
<Scrollbar> | ||
<Text variant='body'> | ||
<Text> | ||
This is some content in a scrollable container. The surrounding | ||
`Scrollbar` component gives this a custom scrollbar. | ||
</Text> | ||
<Text> | ||
`Scrollbar` is meant to be used for small scrolling areas within a | ||
page/view (e.g. a scrolling navigation bar), not the entire page | ||
itself. | ||
</Text> | ||
<Text> | ||
`Scrollbar` uses{' '} | ||
<TextLink | ||
href='https://www.npmjs.com/package/react-perfect-scrollbar' | ||
isExternal | ||
> | ||
react-perfect-scrollbar | ||
</TextLink>{' '} | ||
under the hood. For advanced use cases, refer to the documentation. | ||
</Text> | ||
<Text style={{ paddingTop: 200 }}> | ||
This is some content in a scrollable container. The surrounding | ||
`Scrollbar` component gives this a custom scrollbar. | ||
</Text> | ||
<Text> | ||
`Scrollbar` is meant to be used for small scrolling areas within a | ||
page/view (e.g. a scrolling navigation bar), not the entire page | ||
itself. | ||
</Text> | ||
<Text> | ||
`Scrollbar` uses{' '} | ||
<TextLink | ||
href='https://www.npmjs.com/package/react-perfect-scrollbar' | ||
isExternal | ||
> | ||
react-perfect-scrollbar | ||
</TextLink>{' '} | ||
under the hood. For advanced use cases, refer to the documentation. | ||
</Text> | ||
</Text> | ||
</Scrollbar> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { useEffect, useRef, forwardRef, Ref, useCallback, useId } from 'react' | ||
|
||
import { ResizeObserver } from '@juggle/resize-observer' | ||
import cn from 'classnames' | ||
import PerfectScrollbar from 'react-perfect-scrollbar' | ||
import useMeasure from 'react-use-measure' | ||
|
||
import styles from './Scrollbar.module.css' | ||
import { ScrollbarProps } from './types' | ||
|
||
/** | ||
* A container with a custom scrollbar, meant to be used for small scrolling areas within a | ||
* page/view (e.g. a scrolling navigation bar), not the entire page itself. | ||
* `Scrollbar` uses react-perfect-scrollbar (https://www.npmjs.com/package/react-perfect-scrollbar) | ||
* under the hood. For advanced use cases, refer to the documentation. | ||
*/ | ||
export const Scrollbar = forwardRef( | ||
( | ||
{ children, className, id, forward, isHidden, ...props }: ScrollbarProps, | ||
forwardedRef: Ref<PerfectScrollbar> | ||
) => { | ||
// Do not remove: | ||
// useMeasure ref is required for infinite scrolling to work | ||
const [ref] = useMeasure({ polyfill: ResizeObserver }) | ||
const timerRef = useRef<NodeJS.Timeout | null>(null) | ||
const reactId = useId() | ||
const elementId = id || reactId | ||
|
||
useEffect(() => { | ||
return () => { | ||
if (timerRef.current !== null) { | ||
clearTimeout(timerRef.current) | ||
} | ||
} | ||
}, []) | ||
|
||
const hideScrollbar = useCallback(() => { | ||
const element = document.getElementById(elementId) | ||
if (element) { | ||
element.classList.remove('scrollbar--hovered-visible') | ||
} | ||
if (timerRef.current !== null) { | ||
clearTimeout(timerRef.current) | ||
} | ||
}, [elementId, timerRef]) | ||
|
||
const showScrollbar = useCallback(() => { | ||
if (isHidden) return | ||
const element = document.getElementById(elementId) | ||
if (element) { | ||
element.classList.add('scrollbar--hovered-visible') | ||
} | ||
if (timerRef.current !== null) { | ||
clearTimeout(timerRef.current) | ||
} | ||
timerRef.current = setTimeout(() => { | ||
const element = document.getElementById(elementId) | ||
if (element) { | ||
element.classList.remove('scrollbar--hovered-visible') | ||
} | ||
}, 1400) | ||
}, [elementId, timerRef, isHidden]) | ||
|
||
useEffect(() => { | ||
if (isHidden) { | ||
hideScrollbar() | ||
} | ||
}, [isHidden, hideScrollbar]) | ||
|
||
const content = forward ? children : <div ref={ref}>{children}</div> | ||
|
||
return ( | ||
<PerfectScrollbar | ||
{...props} | ||
ref={forwardedRef} | ||
id={elementId} | ||
className={cn(styles.scrollbar, className)} | ||
onMouseEnter={showScrollbar} | ||
onMouseLeave={hideScrollbar} | ||
> | ||
{content} | ||
</PerfectScrollbar> | ||
) | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { Scrollbar } from './Scrollbar' | ||
export { ScrollbarProps } from './types' |
Oops, something went wrong.