Skip to content

Commit

Permalink
Add useEventListener hook (#5810)
Browse files Browse the repository at this point in the history
* Add useEventListener hook

* Deprecate EventListener

* Change up API and fix lint

* Update polaris-react/src/components/EventListener/EventListener.tsx

Co-authored-by: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com>

* Update polaris-react/src/utilities/event-listener/hooks.ts

Co-authored-by: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com>

* Use ref for options, update options and handler when changed

* Allow for ref and improve findability

* Fix lint on tests

* Update polaris-react/src/utilities/use-event-listener.ts

Co-authored-by: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com>

* Update polaris-react/src/utilities/use-event-listener.ts

Co-authored-by: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com>

* Rebase and add changeset

Co-authored-by: Aaron Casanova <32409546+aaronccasanova@users.noreply.github.com>
  • Loading branch information
kyledurand and aaronccasanova committed May 20, 2022
1 parent eee9286 commit da6fce7
Show file tree
Hide file tree
Showing 32 changed files with 146 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/modern-moons-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris': minor
---

add useEventListenerHook
1 change: 1 addition & 0 deletions polaris-react/.storybook/GridOverlay/GridOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useEffect, useState} from 'react';
import debounce from 'lodash/debounce';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../src';
import {classNames} from '../../src/utilities/css';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
MenuGroupDescriptor,
} from '../../../../types';
import {ButtonGroup} from '../../../ButtonGroup';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';
import {MenuGroup} from '../MenuGroup';
import {SecondaryAction} from '../SecondaryAction';
Expand Down
3 changes: 2 additions & 1 deletion polaris-react/src/components/BulkActions/BulkActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import {ActionList} from '../ActionList';
import {Popover} from '../Popover';
import {Button} from '../Button';
import {ButtonGroup} from '../ButtonGroup';
import {EventListener} from '../EventListener';
import {CheckableButton} from '../CheckableButton';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';

import {BulkActionButton, BulkActionMenu} from './components';
import styles from './BulkActions.scss';
Expand Down
1 change: 1 addition & 0 deletions polaris-react/src/components/ColorPicker/ColorPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {clamp} from '../../utilities/clamp';
import {classNames} from '../../utilities/css';
import {hsbToRgb} from '../../utilities/color-transformers';
import type {HSBColor, HSBAColor} from '../../utilities/color-types';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';

import {AlphaPicker, HuePicker, Slidable, SlidableProps} from './components';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {PureComponent} from 'react';

import {isServer} from '../../../../utilities/target';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';
import styles from '../../ColorPicker.scss';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import {mountWithApp} from 'tests/utilities';

// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../EventListener';
import {Slidable, AlphaPicker} from '../components';
import {ColorPicker} from '../ColorPicker';
Expand Down Expand Up @@ -118,7 +119,7 @@ describe('<ColorPicker />', () => {
clientX: 1,
clientY: 1,
});

// eslint-disable-next-line import/no-deprecated
expect(colorPicker).toContainReactComponent(EventListener, {
event: 'mousemove',
passive: false,
Expand All @@ -136,7 +137,7 @@ describe('<ColorPicker />', () => {
clientX: 1,
clientY: 1,
});

// eslint-disable-next-line import/no-deprecated
expect(colorPicker).toContainReactComponent(EventListener, {
event: 'touchmove',
passive: false,
Expand Down
1 change: 1 addition & 0 deletions polaris-react/src/components/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {debounce} from '../../utilities/debounce';
import {classNames} from '../../utilities/css';
import {useI18n} from '../../utilities/i18n';
import {headerCell} from '../shared';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';
import {AfterInitialMount} from '../AfterInitialMount';
import {Sticky} from '../Sticky';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface EventListenerProps extends BaseEventProps {
passive?: boolean;
}

// see https://github.com/oliviertassinari/react-event-listener/
/** @deprecated Use the useEventListener hook instead. */
export class EventListener extends PureComponent<EventListenerProps, never> {
componentDidMount() {
this.attachListener();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import {mountWithApp} from 'tests/utilities';

// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';

describe('<EventListener />', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {classNames} from '../../../../utilities/css';
import type {DisableableAction} from '../../../../types';
import {Popover} from '../../../Popover';
import {Button} from '../../../Button';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';

import {Item} from './components';
Expand Down
1 change: 1 addition & 0 deletions polaris-react/src/components/Frame/Frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {useMediaQuery} from '../../utilities/media-query';
import {classNames} from '../../utilities/css';
import type {Logo} from '../../utilities/frame/types';
import {Icon} from '../Icon';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';
import {Backdrop} from '../Backdrop';
import {TrapFocus} from '../TrapFocus';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {createRef, memo} from 'react';
import {TransitionGroup, CSSTransition} from 'react-transition-group';

import {classNames} from '../../../../utilities/css';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';
import {Portal} from '../../../Portal';
import type {ToastPropsWithID} from '../../../../utilities/frame';
Expand Down
1 change: 1 addition & 0 deletions polaris-react/src/components/IndexTable/IndexTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {useI18n} from '../../utilities/i18n';
import {Badge} from '../Badge';
import {Checkbox as PolarisCheckbox} from '../Checkbox';
import {EmptySearchResult} from '../EmptySearchResult';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';
import {Stack} from '../Stack';
import {Sticky} from '../Sticky';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {mountWithApp} from 'tests/utilities';

import {getTableHeadingsBySelector} from '../utilities';
import {EmptySearchResult} from '../../EmptySearchResult';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../EventListener';
import {Spinner} from '../../Spinner';
import {Sticky} from '../../Sticky';
Expand Down Expand Up @@ -231,7 +232,7 @@ describe('<IndexTable>', () => {
{mockTableItems.map(mockRenderRow)}
</IndexTable>,
);

// eslint-disable-next-line import/no-deprecated
index.find(EventListener)!.trigger('handler');

expect(spy).not.toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {useEffect, useState, useCallback, useMemo} from 'react';
import {debounce} from '../../utilities/debounce';
import {MediaQueryContext} from '../../utilities/media-query';
import {navigationBarCollapsed} from '../../utilities/breakpoints';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';

interface Props {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {matchMedia} from '@shopify/jest-dom-mocks';
import {act} from 'react-dom/test-utils';
import {mountWithApp} from 'tests/utilities';

// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../EventListener';
import {MediaQueryProvider} from '../MediaQueryProvider';
import {useMediaQuery} from '../../../utilities/media-query';
Expand All @@ -18,6 +19,7 @@ describe('MediaQueryProvider', () => {

it('renders EventListener with the resize event', () => {
const mediaQueryProvider = mountWithApp(<MediaQueryProvider />);
// eslint-disable-next-line import/no-deprecated
expect(mediaQueryProvider).toContainReactComponentTimes(EventListener, 1, {
event: 'resize',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '../../../../utilities/components';
import {Key} from '../../../../types';
import {overlay} from '../../../shared';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';
import {KeypressListener} from '../../../KeypressListener';
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {useRef} from 'react';
import {mountWithApp} from 'tests/utilities';

import {Key} from '../../../../../types';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../../EventListener';
import {TextContainer} from '../../../../TextContainer';
import {TextField} from '../../../../TextField';
Expand Down Expand Up @@ -244,7 +245,7 @@ describe('<PopoverOverlay />', () => {
);

const target = popoverOverlay.find(TextField)!.find('input')!.domNode;

// eslint-disable-next-line import/no-deprecated
const clickEventListener = popoverOverlay.find(EventListener, {
event: 'click',
})!;
Expand Down Expand Up @@ -277,7 +278,7 @@ describe('<PopoverOverlay />', () => {
);

const target = popoverOverlay.find(TextField)!.find('svg')!.domNode;

// eslint-disable-next-line import/no-deprecated
const clickEventListener = popoverOverlay.find(EventListener, {
event: 'click',
})!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {PureComponent} from 'react';

import {classNames} from '../../utilities/css';
import {getRectForNode, Rect} from '../../utilities/geometry';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';
import {Scrollable} from '../Scrollable';
import {layer, dataPolarisTopBar} from '../shared';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {useRef} from 'react';
import {mountWithApp} from 'tests/utilities';

// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../EventListener';
import {PositionedOverlay} from '../PositionedOverlay';
import * as mathModule from '../utilities/math';
Expand Down Expand Up @@ -246,6 +247,7 @@ describe('<PositionedOverlay />', () => {
const positionedOverlay = mountWithApp(
<PositionedOverlay {...mockProps} />,
);
// eslint-disable-next-line import/no-deprecated
expect(positionedOverlay).toContainReactComponent(EventListener, {
event: 'resize',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {classNames} from '../../../../utilities/css';
import {FeaturesContext} from '../../../../utilities/features';
import type {RangeSliderProps, DualValue} from '../../types';
import {Labelled, labelID} from '../../../Labelled';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';
import {Key} from '../../../../types';
import sharedStyles from '../../RangeSlider.scss';
Expand Down
1 change: 1 addition & 0 deletions polaris-react/src/components/ResourceList/ResourceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {CheckboxHandles} from '../../types';
import {classNames} from '../../utilities/css';
import {isElementOfType} from '../../utilities/components';
import {Button} from '../Button';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';
import {Sticky} from '../Sticky';
import {Spinner} from '../Spinner';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {Button} from '../../Button';
import {CheckableButton} from '../../CheckableButton';
import {EmptySearchResult} from '../../EmptySearchResult';
import {EmptyState} from '../../EmptyState';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../EventListener';
import {Select} from '../../Select';
import {Spinner} from '../../Spinner';
Expand Down Expand Up @@ -1190,6 +1191,7 @@ describe('<ResourceList />', () => {
);

setSmallScreen();
// eslint-disable-next-line import/no-deprecated
resourceList.find(EventListener)!.trigger('handler');
expect(resourceList).toContainReactComponent(Select, {
labelInline: false,
Expand All @@ -1207,6 +1209,7 @@ describe('<ResourceList />', () => {
);

resourceList.find(BulkActions)!.trigger('onSelectModeToggle', true);
// eslint-disable-next-line import/no-deprecated
resourceList.find(EventListener)!.trigger('handler');
expect(resourceList).toContainReactComponent(BulkActions, {
selectMode: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {memo, useEffect, useRef, useCallback} from 'react';

// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';
import {classNames} from '../../../../utilities/css';
import {useComponentDidMount} from '../../../../utilities/use-component-did-mount';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useRef, useEffect, useCallback, useLayoutEffect} from 'react';

// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../EventListener';
import styles from '../../TextField.scss';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {animationFrame, dimension} from '@shopify/jest-dom-mocks';
import {mountWithApp} from 'tests/utilities';

import {Resizer} from '../Resizer';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../../../EventListener';

describe('<Resizer />', () => {
Expand Down Expand Up @@ -33,6 +34,7 @@ describe('<Resizer />', () => {
);

resizer.setProps({currentHeight: 2});
// eslint-disable-next-line import/no-deprecated
resizer.find(EventListener)!.trigger('handler');

expect(cancelAnimationFrameSpy).toHaveBeenCalled();
Expand Down Expand Up @@ -155,6 +157,7 @@ describe('<Resizer />', () => {
/>,
);
resizer.setProps({currentHeight: 1});
// eslint-disable-next-line import/no-deprecated
resizer.find(EventListener)?.trigger('handler');
animationFrame.runFrame();
expect(spy).toHaveBeenCalledWith(30);
Expand All @@ -171,6 +174,7 @@ describe('<Resizer />', () => {
/>,
);
resizer.setProps({currentHeight: 1});
// eslint-disable-next-line import/no-deprecated
resizer.find(EventListener)?.trigger('handler');
animationFrame.runFrame();
expect(spy).toHaveBeenCalledTimes(0);
Expand All @@ -188,7 +192,7 @@ describe('<Resizer />', () => {
/>,
);
resizer.setProps({currentHeight: 1});

// eslint-disable-next-line import/no-deprecated
resizer.find(EventListener)?.trigger('handler');
animationFrame.runFrame();
expect(spy).toHaveBeenCalledTimes(0);
Expand Down
1 change: 1 addition & 0 deletions polaris-react/src/components/TrapFocus/TrapFocus.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {useRef, useEffect, useState} from 'react';

import {Key} from '../../types';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../EventListener';
import {KeypressListener} from '../KeypressListener';
import {Focus} from '../Focus';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import {mountWithApp} from 'tests/utilities';

import {Button} from '../../Button';
// eslint-disable-next-line import/no-deprecated
import {EventListener} from '../../EventListener';
import {Focus} from '../../Focus';
import {TextContainer} from '../../TextContainer';
Expand Down Expand Up @@ -54,6 +55,7 @@ describe('<TrapFocus />', () => {
expect(trapFocus).toContainReactComponent(Focus);

// Renders an event listener
// eslint-disable-next-line import/no-deprecated
expect(trapFocus).toContainReactComponent(EventListener, {
event: 'focusin',
});
Expand Down Expand Up @@ -101,6 +103,7 @@ describe('<TrapFocus />', () => {
const focusableButton = trapFocus.find('button', {id})?.domNode;
focusableButton?.focus();
trapFocus
// eslint-disable-next-line import/no-deprecated
.find(EventListener, {event: 'focusin'})
?.trigger('handler', {target: focusableButton});

Expand Down Expand Up @@ -177,7 +180,7 @@ describe('<TrapFocus />', () => {
relatedTarget: externalDomNode,
});
Object.assign(event, {preventDefault: jest.fn()});

// eslint-disable-next-line import/no-deprecated
trapFocus.find(EventListener)!.trigger('handler', event);
expect(event.preventDefault).not.toHaveBeenCalled();
});
Expand All @@ -201,7 +204,7 @@ describe('<TrapFocus />', () => {
relatedTarget: internalDomNode,
});
Object.assign(event, {preventDefault: jest.fn()});

// eslint-disable-next-line import/no-deprecated
trapFocus.find(EventListener)!.trigger('handler', event);
expect(event.preventDefault).not.toHaveBeenCalled();
});
Expand All @@ -219,6 +222,7 @@ describe('<TrapFocus />', () => {
target: document.createElement('div'),
preventDefault: () => {},
};
// eslint-disable-next-line import/no-deprecated
trapFocus.find(EventListener)!.trigger('handler', event);

expect(focusFirstFocusableNodeSpy).toHaveBeenCalledWith(
Expand Down
1 change: 1 addition & 0 deletions polaris-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ export {

export {ScrollLockManagerContext as _SECRET_INTERNAL_SCROLL_LOCK_MANAGER_CONTEXT} from './utilities/scroll-lock-manager';
export {WithinContentContext as _SECRET_INTERNAL_WITHIN_CONTENT_CONTEXT} from './utilities/within-content-context';
export {useEventListener} from './utilities/use-event-listener';
export {useIndexResourceState} from './utilities/use-index-resource-state';
export {
useRowHovered as useIndexTableRowHovered,
Expand Down

0 comments on commit da6fce7

Please sign in to comment.