Skip to content

Commit

Permalink
ScrollLock: Covert component to TypeScript (#42303)
Browse files Browse the repository at this point in the history
* ScrollLock: Covert component to TypeScript

* Update CHANGELOG.md

* Update CHANGELOG.md
  • Loading branch information
Petter Walbø Johnsgård committed Jul 14, 2022
1 parent 88e911e commit cfd9596
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 87 deletions.
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- `Divider`: Complete TypeScript migration ([#41991](https://github.com/WordPress/gutenberg/pull/41991)).
- `Divider`, `Flex`, `Spacer`: Improve documentation for the `SpaceInput` prop ([#42376](https://github.com/WordPress/gutenberg/pull/42376)).
- `Elevation`: Convert to TypeScript ([#42302](https://github.com/WordPress/gutenberg/pull/42302)).
- `ScrollLock`: Convert to TypeScript ([#42303](https://github.com/WordPress/gutenberg/pull/42303)).

## 19.15.0 (2022-07-13)

Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/scroll-lock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ScrollLock is a content-free React component for declaratively preventing scroll
Declare scroll locking as part of modal UI.

```jsx
import { ScrollLock } from '@wordpress/components';
import { ScrollLock, Button } from '@wordpress/components';
import { useState } from '@wordpress/element';

const MyScrollLock = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ import { useEffect } from '@wordpress/element';
*/
let previousScrollTop = 0;

/**
* @param {boolean} locked
*/
function setLocked( locked ) {
function setLocked( locked: boolean ) {
const scrollingElement = document.scrollingElement || document.body;

if ( locked ) {
Expand All @@ -36,11 +33,39 @@ function setLocked( locked ) {
let lockCounter = 0;

/**
* A component that will lock scrolling when it is mounted and unlock scrolling when it is unmounted.
* ScrollLock is a content-free React component for declaratively preventing
* scroll bleed from modal UI to the page body. This component applies a
* `lockscroll` class to the `document.documentElement` and
* `document.scrollingElement` elements to stop the body from scrolling. When it
* is present, the lock is applied.
*
* ```jsx
* import { ScrollLock, Button } from '@wordpress/components';
* import { useState } from '@wordpress/element';
*
* @return {null} Render nothing.
* const MyScrollLock = () => {
* const [ isScrollLocked, setIsScrollLocked ] = useState( false );
*
* const toggleLock = () => {
* setIsScrollLocked( ( locked ) => ! locked ) );
* };
*
* return (
* <div>
* <Button variant="secondary" onClick={ toggleLock }>
* Toggle scroll lock
* </Button>
* { isScrollLocked && <ScrollLock /> }
* <p>
* Scroll locked:
* <strong>{ isScrollLocked ? 'Yes' : 'No' }</strong>
* </p>
* </div>
* );
* };
* ```
*/
export default function ScrollLock() {
export function ScrollLock(): null {
useEffect( () => {
if ( lockCounter === 0 ) {
setLocked( true );
Expand All @@ -59,3 +84,5 @@ export default function ScrollLock() {

return null;
}

export default ScrollLock;
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/**
* External dependencies
*/
import type { ComponentMeta, ComponentStory } from '@storybook/react';
import type { ReactNode } from 'react';

/**
* WordPress dependencies
*/
Expand All @@ -7,32 +13,19 @@ import { useState } from '@wordpress/element';
* Internal dependencies
*/
import Button from '../../button';
import ScrollLock from '../';

export default { title: 'Components/ScrollLock', component: ScrollLock };

const Example = () => {
const [ isScrollLocked, setScrollLocked ] = useState( false );
const toggleLock = () => setScrollLocked( ! isScrollLocked );
import ScrollLock from '..';

return (
<StripedBackground>
<div>Start scrolling down...</div>
<ToggleContainer>
<Button variant="secondary" onClick={ toggleLock }>
Toggle Scroll Lock
</Button>
{ isScrollLocked && <ScrollLock /> }
<p>
Scroll locked:{ ' ' }
<strong>{ isScrollLocked ? 'Yes' : 'No' }</strong>
</p>
</ToggleContainer>
</StripedBackground>
);
const meta: ComponentMeta< typeof ScrollLock > = {
component: ScrollLock,
title: 'Components/ScrollLock',
parameters: {
controls: { hideNoControlsWarning: true },
docs: { source: { state: 'open' } },
},
};
export default meta;

function StripedBackground( props ) {
function StripedBackground( props: { children: ReactNode } ) {
return (
<div
style={ {
Expand All @@ -48,7 +41,7 @@ function StripedBackground( props ) {
);
}

function ToggleContainer( props ) {
function ToggleContainer( props: { children: ReactNode } ) {
const { children } = props;
return (
<div
Expand All @@ -66,6 +59,23 @@ function ToggleContainer( props ) {
);
}

export const _default = () => {
return <Example />;
export const Default: ComponentStory< typeof ScrollLock > = () => {
const [ isScrollLocked, setScrollLocked ] = useState( false );
const toggleLock = () => setScrollLocked( ! isScrollLocked );

return (
<StripedBackground>
<div>Start scrolling down...</div>
<ToggleContainer>
<Button variant="primary" onClick={ toggleLock }>
Toggle Scroll Lock
</Button>
{ isScrollLocked && <ScrollLock /> }
<p>
Scroll locked:{ ' ' }
<strong>{ isScrollLocked ? 'Yes' : 'No' }</strong>
</p>
</ToggleContainer>
</StripedBackground>
);
};
53 changes: 0 additions & 53 deletions packages/components/src/scroll-lock/test/index.js

This file was deleted.

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

/**
* Internal dependencies
*/
import ScrollLock from '..';

describe( 'scroll-lock', () => {
const lockingClassName = 'lockscroll';

it( 'locks when mounted', () => {
expect( document.documentElement ).not.toHaveClass( lockingClassName );
render( <ScrollLock /> );
expect( document.documentElement ).toHaveClass( lockingClassName );
} );

it( 'unlocks when unmounted', () => {
const { unmount } = render( <ScrollLock /> );
expect( document.documentElement ).toHaveClass( lockingClassName );
unmount();
expect( document.documentElement ).not.toHaveClass( lockingClassName );
} );
} );

0 comments on commit cfd9596

Please sign in to comment.