Skip to content

Commit

Permalink
Scrollable: Convert component to TypeScript (#42016)
Browse files Browse the repository at this point in the history
* Scrollable: Convert component to TypeScript

* Update CHANGELOG.md
  • Loading branch information
Petter Walbø Johnsgård authored Jul 1, 2022
1 parent 4ca5ef6 commit 5f39e3d
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 95 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- `Grid`: Convert to TypeScript ([#41923](https://github.com/WordPress/gutenberg/pull/41923)).
- `TextHighlight`: Convert to TypeScript ([#41698](https://github.com/WordPress/gutenberg/pull/41698)).
- `Scrollable`: Convert to TypeScript ([#42016](https://github.com/WordPress/gutenberg/pull/42016)).
- `TreeSelect`: Refactor away from `_.repeat()` ([#42070](https://github.com/WordPress/gutenberg/pull/42070/)).

## 19.14.0 (2022-06-29)
Expand Down
22 changes: 14 additions & 8 deletions packages/components/src/scrollable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This feature is still experimental. “Experimental” means this is an early im
## Usage

```jsx
import {__experimentalScrollable as Scrollable } from '@wordpress/components';
import { __experimentalScrollable as Scrollable } from '@wordpress/components';

function Example() {
return (
Expand All @@ -22,17 +22,23 @@ function Example() {

## Props

### `scrollDirection`: `string`
### `children`: `ReactNode`

The children elements.

- Required: No
- Default: `y`
- Allowed values: `x`, `y`, `auto`
- Required: Yes

### `scrollDirection`: `string`

Renders a scrollbar for a specific axis when content overflows.

### `smoothScroll`: `boolean`
- Required: No
- Default: `y`
- Allowed values: `x`, `y`, `auto`

- Required: No
- Default: `false`
### `smoothScroll`: `boolean`

Enables (CSS) smooth scrolling.

- Required: No
- Default: `false`
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
/**
* External dependencies
*/
import type { ForwardedRef } from 'react';

/**
* Internal dependencies
*/
import { contextConnect } from '../ui/context';
import { contextConnect, WordPressComponentProps } from '../ui/context';
import { View } from '../view';
import { useScrollable } from './hook';
import type { ScrollableProps } from './types';

/**
* @param {import('../ui/context').WordPressComponentProps<import('./types').Props, 'div'>} props
* @param {import('react').ForwardedRef<any>} forwardedRef
*/
function Scrollable( props, forwardedRef ) {
function UnconnectedScrollable(
props: WordPressComponentProps< ScrollableProps, 'div' >,
forwardedRef: ForwardedRef< any >
) {
const scrollableProps = useScrollable( props );

return <View { ...scrollableProps } ref={ forwardedRef } />;
Expand All @@ -18,7 +23,6 @@ function Scrollable( props, forwardedRef ) {
/**
* `Scrollable` is a layout component that content in a scrollable container.
*
* @example
* ```jsx
* import { __experimentalScrollable as Scrollable } from `@wordpress/components`;
*
Expand All @@ -31,7 +35,6 @@ function Scrollable( props, forwardedRef ) {
* }
* ```
*/
export const Scrollable = contextConnect( UnconnectedScrollable, 'Scrollable' );

const ConnectedScrollable = contextConnect( Scrollable, 'Scrollable' );

export default ConnectedScrollable;
export default Scrollable;
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ import { useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
import { useContextSystem } from '../ui/context';
import { useContextSystem, WordPressComponentProps } from '../ui/context';
import * as styles from './styles';
import { useCx } from '../utils/hooks/use-cx';
import type { ScrollableProps } from './types';

/* eslint-disable jsdoc/valid-types */
/**
* @param {import('../ui/context').WordPressComponentProps<import('./types').Props, 'div'>} props
*/
/* eslint-enable jsdoc/valid-types */
export function useScrollable( props ) {
export function useScrollable(
props: WordPressComponentProps< ScrollableProps, 'div' >
) {
const {
className,
scrollDirection = 'y',
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { boolean, select } from '@storybook/addon-knobs';
import type { ComponentMeta, ComponentStory } from '@storybook/react';

/**
* WordPress dependencies
Expand All @@ -12,58 +12,49 @@ import { useRef } from '@wordpress/element';
* Internal dependencies
*/
import { View } from '../../view';
import { Scrollable } from '../';
import { Scrollable } from '..';

export default {
const meta: ComponentMeta< typeof Scrollable > = {
component: Scrollable,
title: 'Components (Experimental)/Scrollable',
argTypes: {
as: {
control: { type: 'text' },
},
children: {
control: { type: null },
},
},
parameters: {
knobs: { disable: false },
controls: {
expanded: true,
},
docs: { source: { state: 'open' } },
},
};
export default meta;

export const _default = () => {
const targetRef = useRef( null );
const Template: ComponentStory< typeof Scrollable > = ( { ...args } ) => {
const targetRef = useRef< HTMLInputElement >( null );

const onButtonClick = () => {
targetRef.current?.focus();
};

const otherProps = {
smoothScroll: boolean(
'Scrollable: smoothScroll (hint: move focus in the scrollable container)',
false
),
scrollDirection: select(
'Scrollable: scrollDirection',
{
x: 'x',
y: 'y',
auto: 'auto',
},
'y'
),
};

const containerWidth = 300;
const containerHeight = 400;

return (
<Scrollable
style={ { height: containerHeight, width: containerWidth } }
{ ...otherProps }
{ ...args }
>
<View
style={ {
backgroundColor: '#eee',
height:
otherProps.scrollDirection === 'x'
? containerHeight
: 1000,
width:
otherProps.scrollDirection === 'y'
? containerWidth
: 1000,
args.scrollDirection === 'x' ? containerHeight : 1000,
width: args.scrollDirection === 'y' ? containerWidth : 1000,
position: 'relative',
} }
>
Expand All @@ -74,10 +65,8 @@ export const _default = () => {
ref={ targetRef }
style={ {
position: 'absolute',
bottom:
otherProps.scrollDirection === 'x' ? 'initial' : 0,
right:
otherProps.scrollDirection === 'y' ? 'initial' : 0,
bottom: args.scrollDirection === 'x' ? 'initial' : 0,
right: 0,
} }
type="text"
value="Focus me"
Expand All @@ -86,3 +75,9 @@ export const _default = () => {
</Scrollable>
);
};

export const Default: ComponentStory< typeof Scrollable > = Template.bind( {} );
Default.args = {
smoothScroll: false,
scrollDirection: 'y',
};
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ exports[`props should render correctly 1`] = `
<div
class="components-scrollable emotion-0 emotion-1"
data-testid="scrollable"
data-wp-c16t="true"
data-wp-component="Scrollable"
>
Expand Down
31 changes: 0 additions & 31 deletions packages/components/src/scrollable/test/index.js

This file was deleted.

34 changes: 34 additions & 0 deletions packages/components/src/scrollable/test/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* External dependencies
*/
import { render, screen } from '@testing-library/react';

/**
* Internal dependencies
*/
import { Scrollable } from '../index';

describe( 'props', () => {
beforeEach( () => {
render(
<Scrollable data-testid="scrollable">
WordPress.org - Code is Poetry
</Scrollable>
);
} );

test( 'should render correctly', () => {
expect( screen.getByTestId( 'scrollable' ) ).toMatchSnapshot();
} );

test( 'should render smoothScroll', () => {
render(
<Scrollable smoothScroll data-testid="smooth-scrollable">
WordPress.org - Code is Poetry
</Scrollable>
);
expect(
screen.getByTestId( 'smooth-scrollable' )
).toMatchStyleDiffSnapshot( screen.getByTestId( 'scrollable' ) );
} );
} );
15 changes: 10 additions & 5 deletions packages/components/src/scrollable/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
/**
* External dependencies
*/
import type { ReactNode } from 'react';

export type ScrollableDirection = 'x' | 'y' | 'auto';

export type Props = {
export type ScrollableProps = {
/**
* The children elements.
*/
children: ReactNode;
/**
* Renders a scrollbar for a specific axis when content overflows.
*
Expand All @@ -13,8 +22,4 @@ export type Props = {
* @default false
*/
smoothScroll?: boolean;
/**
* The children elements.
*/
children: React.ReactNode;
};

0 comments on commit 5f39e3d

Please sign in to comment.