From cd0a81f236f92f121b661a3f31b001bd70e2f6ba Mon Sep 17 00:00:00 2001 From: Sara Marcondes Date: Fri, 12 Feb 2021 11:16:32 -0800 Subject: [PATCH 1/3] Components: Add hooks based Scrollable component wrapper --- .../components/src/ui/scrollable/component.js | 21 +++++ packages/components/src/ui/scrollable/hook.js | 45 +++++++++ .../components/src/ui/scrollable/index.js | 3 + .../src/ui/scrollable/stories/index.js | 18 ++++ .../components/src/ui/scrollable/styles.js | 59 ++++++++++++ .../test/__snapshots__/index.js.snap | 91 +++++++++++++++++++ .../src/ui/scrollable/test/index.js | 31 +++++++ .../components/src/ui/scrollable/types.ts | 16 ++++ 8 files changed, 284 insertions(+) create mode 100644 packages/components/src/ui/scrollable/component.js create mode 100644 packages/components/src/ui/scrollable/hook.js create mode 100644 packages/components/src/ui/scrollable/index.js create mode 100644 packages/components/src/ui/scrollable/stories/index.js create mode 100644 packages/components/src/ui/scrollable/styles.js create mode 100644 packages/components/src/ui/scrollable/test/__snapshots__/index.js.snap create mode 100644 packages/components/src/ui/scrollable/test/index.js create mode 100644 packages/components/src/ui/scrollable/types.ts diff --git a/packages/components/src/ui/scrollable/component.js b/packages/components/src/ui/scrollable/component.js new file mode 100644 index 00000000000000..7d9d493f35ac6f --- /dev/null +++ b/packages/components/src/ui/scrollable/component.js @@ -0,0 +1,21 @@ +/** + * Internal dependencies + */ +import { createComponent } from '../utils'; +import { useScrollable } from './hook'; + +/** + * `Scrollable` is a layout component that content in a scrollable container. + * + * @example + * ```jsx + * ... + * ``` + */ +const Scrollable = createComponent( { + as: 'div', + useHook: useScrollable, + name: 'Scrollable', +} ); + +export default Scrollable; diff --git a/packages/components/src/ui/scrollable/hook.js b/packages/components/src/ui/scrollable/hook.js new file mode 100644 index 00000000000000..dd1bb36ac4371a --- /dev/null +++ b/packages/components/src/ui/scrollable/hook.js @@ -0,0 +1,45 @@ +/** + * External dependencies + */ +import { useContextSystem } from '@wp-g2/context'; +import { cx } from '@wp-g2/styles'; + +/** + * WordPress dependencies + */ +import { useMemo } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import * as styles from './styles'; + +/* eslint-disable jsdoc/valid-types */ +/** + * @param {import('@wp-g2/create-styles').ViewOwnProps} props + */ +/* eslint-enable jsdoc/valid-types */ +export function useScrollable( props ) { + const { + className, + scrollDirection = 'y', + smoothScroll = false, + ...otherProps + } = useContextSystem( props, 'Scrollable' ); + + const classes = useMemo( + () => + cx( + styles.Scrollable, + styles.scrollableScrollbar, + smoothScroll && styles.smoothScroll, + scrollDirection === 'x' && styles.scrollX, + scrollDirection === 'y' && styles.scrollY, + scrollDirection === 'auto' && styles.scrollAuto, + className + ), + [ className, scrollDirection, smoothScroll ] + ); + + return { ...otherProps, className: classes }; +} diff --git a/packages/components/src/ui/scrollable/index.js b/packages/components/src/ui/scrollable/index.js new file mode 100644 index 00000000000000..1a8ae2905eecb8 --- /dev/null +++ b/packages/components/src/ui/scrollable/index.js @@ -0,0 +1,3 @@ +export { default as Scrollable } from './component'; + +export * from './hook'; diff --git a/packages/components/src/ui/scrollable/stories/index.js b/packages/components/src/ui/scrollable/stories/index.js new file mode 100644 index 00000000000000..cf91a552e7f8c0 --- /dev/null +++ b/packages/components/src/ui/scrollable/stories/index.js @@ -0,0 +1,18 @@ +/** + * Internal dependencies + */ +import { View } from '../../index'; +import { Scrollable } from '../index'; + +export default { + component: Scrollable, + title: 'G2 Components (Experimental)/Scrollable', +}; + +export const _default = () => { + return ( + + + + ); +}; diff --git a/packages/components/src/ui/scrollable/styles.js b/packages/components/src/ui/scrollable/styles.js new file mode 100644 index 00000000000000..ccdea0f7abeafd --- /dev/null +++ b/packages/components/src/ui/scrollable/styles.js @@ -0,0 +1,59 @@ +/** + * External dependencies + */ +import { css, ui } from '@wp-g2/styles'; + +export const scrollableScrollbar = css` + @media only screen and ( min-device-width: 40em ) { + &::-webkit-scrollbar { + height: 12px; + width: 12px; + } + + &::-webkit-scrollbar-track { + background-color: transparent; + } + + &::-webkit-scrollbar-track { + background: ${ ui.get( 'colorScrollbarTrack' ) }; + border-radius: 8px; + } + + &::-webkit-scrollbar-thumb { + background-clip: padding-box; + background-color: ${ ui.get( 'colorScrollbarThumb' ) }; + border: 2px solid rgba( 0, 0, 0, 0 ); + border-radius: 7px; + } + + &:hover::-webkit-scrollbar-thumb { + background-color: ${ ui.get( 'colorScrollbarThumbHover' ) }; + } + } +`; + +export const Scrollable = css` + height: 100%; +`; + +export const Content = css` + position: relative; +`; + +export const smoothScroll = css` + scroll-behavior: smooth; +`; + +export const scrollX = css` + overflow-x: auto; + overflow-y: hidden; +`; + +export const scrollY = css` + overflow-x: hidden; + overflow-y: auto; +`; + +export const scrollAuto = css` + overflow-y: auto; +`; diff --git a/packages/components/src/ui/scrollable/test/__snapshots__/index.js.snap b/packages/components/src/ui/scrollable/test/__snapshots__/index.js.snap new file mode 100644 index 00000000000000..19a42ef16b5aaa --- /dev/null +++ b/packages/components/src/ui/scrollable/test/__snapshots__/index.js.snap @@ -0,0 +1,91 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`props should render correctly 1`] = ` +.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0 { + box-sizing: border-box; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + font-family: Inter,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",sans-serif; + font-family: var(--wp-g2-font-family); + font-size: 13px; + font-size: var(--wp-g2-font-size); + font-weight: normal; + font-weight: var(--wp-g2-font-weight); + margin: 0; + height: 100%; + overflow-x: hidden; + overflow-y: auto; +} + +@media (prefers-reduced-motion) { + .emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0 { + -webkit-transition: none !important; + transition: none !important; + } +} + +[data-system-ui-reduced-motion-mode="true"] .emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0 { + -webkit-transition: none !important; + transition: none !important; +} + +@media only screen and ( min-device-width:40em ) { + .emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0::-webkit-scrollbar { + height: 12px; + width: 12px; + } + + .emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0::-webkit-scrollbar-track { + background-color: transparent; + } + + .emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.04); + background: var(--wp-g2-color-scrollbar-track); + border-radius: 8px; + } + + .emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0::-webkit-scrollbar-thumb { + background-clip: padding-box; + background-color: rgba(0, 0, 0, 0.2); + background-color: var(--wp-g2-color-scrollbar-thumb); + border: 2px solid rgba( 0,0,0,0 ); + border-radius: 7px; + } + + .emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0.emotion-0:hover::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.5); + background-color: var(--wp-g2-color-scrollbar-thumb-hover); + } +} + +
+ WordPress.org - Code is Poetry +
+`; + +exports[`props should render smoothScroll 1`] = ` +"Snapshot Diff: +- First value ++ Second value + +- Snapshot Diff: +- - First value +- + Second value +- +- @@ -7,10 +7,9 @@ +- \\"margin-top\\": \\"0px\\", +- \\"margin-right\\": \\"0px\\", +- \\"margin-bottom\\": \\"0px\\", +- \\"margin-left\\": \\"0px\\", +- \\"height\\": \\"100%\\", +- - \\"scroll-behavior\\": \\"smooth\\", +- \\"overflow-x\\": \\"hidden\\", +- \\"overflow-y\\": \\"auto\\", +- \\"visibility\\": \\"visible\\" +- }" +`; diff --git a/packages/components/src/ui/scrollable/test/index.js b/packages/components/src/ui/scrollable/test/index.js new file mode 100644 index 00000000000000..3520a25097bd3d --- /dev/null +++ b/packages/components/src/ui/scrollable/test/index.js @@ -0,0 +1,31 @@ +/** + * External dependencies + */ +import { render } from '@testing-library/react'; + +/** + * Internal dependencies + */ +import { Scrollable } from '../index'; + +describe( 'props', () => { + let base; + + beforeEach( () => { + ( { container: base } = render( + WordPress.org - Code is Poetry + ) ); + } ); + test( 'should render correctly', () => { + expect( base.firstChild ).toMatchSnapshot(); + } ); + + test( 'should render smoothScroll', () => { + const { container } = render( + WordPress.org - Code is Poetry + ); + expect( container.firstChild ).toMatchStyleDiffSnapshot( + base.firstChild + ); + } ); +} ); diff --git a/packages/components/src/ui/scrollable/types.ts b/packages/components/src/ui/scrollable/types.ts new file mode 100644 index 00000000000000..9b5d86db916bff --- /dev/null +++ b/packages/components/src/ui/scrollable/types.ts @@ -0,0 +1,16 @@ +export type ScrollableDirection = 'x' | 'y' | 'auto'; + +export type Props = { + /** + * Renders a scrollbar for a specific axis when content overflows. + * + * @default 'y' + */ + scrollDirection?: ScrollableDirection; + /** + * Enables (CSS) smooth scrolling. + * + * @default false + */ + smoothScroll?: boolean; +}; From aadc54f70b2ea321bf389559280735a9a8d2b039 Mon Sep 17 00:00:00 2001 From: Jon Q Date: Tue, 16 Feb 2021 11:12:07 -0500 Subject: [PATCH 2/3] Add README for Scrollable --- .../components/src/ui/scrollable/README.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 packages/components/src/ui/scrollable/README.md diff --git a/packages/components/src/ui/scrollable/README.md b/packages/components/src/ui/scrollable/README.md new file mode 100644 index 00000000000000..aad335dacc2994 --- /dev/null +++ b/packages/components/src/ui/scrollable/README.md @@ -0,0 +1,31 @@ +# Scrollable + +`Scrollable` is a layout component that renders a stylized scrollbar. + +## Usage + +```jsx +import { Scrollable, View } from '@wordpress/components/ui'; + +function Example() { + return ( + + ... + + ); +} +``` + +## Props + +##### scrollDirection + +**Type**: `x` | `y` | `auto` + +Renders a scrollbar for a specific axis when content overflows. + +##### smoothScroll + +**Type**: `boolean` + +Enables (CSS) smooth scrolling. From bab687b7e6ebf62e950c74aabc6fdce5b366676d Mon Sep 17 00:00:00 2001 From: Jon Q Date: Tue, 16 Feb 2021 11:14:05 -0500 Subject: [PATCH 3/3] Update example doc for scrollable/component.js and README --- packages/components/src/ui/scrollable/README.md | 2 +- packages/components/src/ui/scrollable/component.js | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/components/src/ui/scrollable/README.md b/packages/components/src/ui/scrollable/README.md index aad335dacc2994..a3996eab2dcc05 100644 --- a/packages/components/src/ui/scrollable/README.md +++ b/packages/components/src/ui/scrollable/README.md @@ -1,6 +1,6 @@ # Scrollable -`Scrollable` is a layout component that renders a stylized scrollbar. +`Scrollable` is a layout component that content in a scrollable container. ## Usage diff --git a/packages/components/src/ui/scrollable/component.js b/packages/components/src/ui/scrollable/component.js index 7d9d493f35ac6f..71aa440432a85b 100644 --- a/packages/components/src/ui/scrollable/component.js +++ b/packages/components/src/ui/scrollable/component.js @@ -9,9 +9,18 @@ import { useScrollable } from './hook'; * * @example * ```jsx - * ... + * import { Scrollable, View } from `@wordpress/components/ui`; + + * function Example() { + * return ( + * + * ... + * + * ); + * } * ``` */ + const Scrollable = createComponent( { as: 'div', useHook: useScrollable,