From 148c816fabdb814ecb39aa238fcc642c60706465 Mon Sep 17 00:00:00 2001 From: chad1008 <13856531+chad1008@users.noreply.github.com> Date: Wed, 21 Sep 2022 03:20:22 -0400 Subject: [PATCH] Components: refactor `RangeControl` to pass `exhaustive-deps` (#44271) * RangeControl: add missing deps to tooltip useCallback * RangeControl: add missing dep to useControlledRangeValue useCallback * RangeControl: add missing deps to useDebouncedHoverInteraction useCallbacks * Components: update CHANGELOG * Remove unused show/hide tooltip logic and the whole `useDebouncedHoverInteraction` hook * Use Storybook actions for all `on.*` props on RangeControl * Cleanup unused imports Co-authored-by: Marco Ciampini --- packages/components/CHANGELOG.md | 1 + .../src/range-control/input-range.tsx | 22 +----- .../src/range-control/stories/index.tsx | 3 +- .../components/src/range-control/tooltip.tsx | 2 +- .../components/src/range-control/types.ts | 2 - .../components/src/range-control/utils.ts | 78 +------------------ 6 files changed, 8 insertions(+), 100 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 2206e37b3e953..3aa78f2d34c0c 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -13,6 +13,7 @@ ### Internal - `NavigationMenu` updated to ignore `react/exhaustive-deps` eslint rule ([#44090](https://github.com/WordPress/gutenberg/pull/44090)). +- `RangeControl`: updated to pass `react/exhaustive-deps` eslint rule ([#44271](https://github.com/WordPress/gutenberg/pull/44271)). - `UnitControl` updated to pass the `react/exhaustive-deps` eslint rule ([#44161](https://github.com/WordPress/gutenberg/pull/44161)). ## 21.0.0 (2022-09-13) diff --git a/packages/components/src/range-control/input-range.tsx b/packages/components/src/range-control/input-range.tsx index d7aaa028e6eb8..3b663309918ae 100644 --- a/packages/components/src/range-control/input-range.tsx +++ b/packages/components/src/range-control/input-range.tsx @@ -7,39 +7,19 @@ import { forwardRef } from '@wordpress/element'; * Internal dependencies */ import { InputRange as BaseInputRange } from './styles/range-control-styles'; -import { useDebouncedHoverInteraction } from './utils'; import type { InputRangeProps } from './types'; import type { WordPressComponentProps } from '../ui/context'; -const noop = () => {}; - function InputRange( props: WordPressComponentProps< InputRangeProps, 'input' >, ref: React.ForwardedRef< HTMLInputElement > ) { - const { - describedBy, - label, - onHideTooltip = noop, - onMouseLeave = noop, - onMouseMove = noop, - onShowTooltip = noop, - value, - ...otherProps - } = props; - - const hoverInteractions = useDebouncedHoverInteraction( { - onHide: onHideTooltip, - onMouseLeave, - onMouseMove, - onShow: onShowTooltip, - } ); + const { describedBy, label, value, ...otherProps } = props; return ( = { icon: { control: { type: null } }, marks: { control: { type: 'object' } }, onBlur: { control: { type: null } }, - onChange: { action: 'onChange' }, + onChange: { control: { type: null } }, onFocus: { control: { type: null } }, onMouseLeave: { control: { type: null } }, onMouseMove: { control: { type: null } }, @@ -46,6 +46,7 @@ const meta: ComponentMeta< typeof RangeControl > = { value: { control: { type: null } }, }, parameters: { + actions: { argTypesRegex: '^on.*' }, controls: { expanded: true }, docs: { source: { state: 'open' } }, }, diff --git a/packages/components/src/range-control/tooltip.tsx b/packages/components/src/range-control/tooltip.tsx index 81aeb5489976f..3c8403d1275c6 100644 --- a/packages/components/src/range-control/tooltip.tsx +++ b/packages/components/src/range-control/tooltip.tsx @@ -59,7 +59,7 @@ function useTooltipPosition( { inputRef, tooltipPosition }: TooltipProps ) { if ( inputRef && inputRef.current ) { setPosition( tooltipPosition ); } - }, [ tooltipPosition ] ); + }, [ tooltipPosition, inputRef ] ); useEffect( () => { setTooltipPosition(); diff --git a/packages/components/src/range-control/types.ts b/packages/components/src/range-control/types.ts index 594ce7a77a444..f8ba457ab77f4 100644 --- a/packages/components/src/range-control/types.ts +++ b/packages/components/src/range-control/types.ts @@ -236,10 +236,8 @@ export type RailProps = MarksProps & { export type InputRangeProps = { describedBy?: string; label?: string; - onHideTooltip?: () => void; onMouseLeave?: MouseEventHandler< HTMLInputElement >; onMouseMove?: MouseEventHandler< HTMLInputElement >; - onShowTooltip?: () => void; value?: number | ''; }; diff --git a/packages/components/src/range-control/utils.ts b/packages/components/src/range-control/utils.ts index 39cdc7b9f6f12..a80c8dffdffa1 100644 --- a/packages/components/src/range-control/utils.ts +++ b/packages/components/src/range-control/utils.ts @@ -1,12 +1,7 @@ -/** - * External dependencies - */ -import type { MouseEventHandler } from 'react'; - /** * WordPress dependencies */ -import { useCallback, useRef, useEffect, useState } from '@wordpress/element'; +import { useCallback } from '@wordpress/element'; /** * Internal dependencies @@ -14,12 +9,7 @@ import { useCallback, useRef, useEffect, useState } from '@wordpress/element'; import { useControlledState } from '../utils/hooks'; import { clamp } from '../utils/math'; -import type { - UseControlledRangeValueArgs, - UseDebouncedHoverInteractionArgs, -} from './types'; - -const noop = () => {}; +import type { UseControlledRangeValueArgs } from './types'; /** * A float supported clamp function for a specific value. @@ -64,72 +54,10 @@ export function useControlledRangeValue( setInternalState( floatClamp( nextValue, min, max ) ); } }, - [ min, max ] + [ min, max, setInternalState ] ); // `state` can't be an empty string because we specified a fallback value of // `null` in `useControlledState` return [ state as Exclude< typeof state, '' >, setState ] as const; } - -/** - * Hook to encapsulate the debouncing "hover" to better handle the showing - * and hiding of the Tooltip. - * - * @param settings - * @return Bound properties for use on a React.Node. - */ -export function useDebouncedHoverInteraction( - settings: UseDebouncedHoverInteractionArgs -) { - const { - onHide = noop, - onMouseLeave = noop as MouseEventHandler, - onMouseMove = noop as MouseEventHandler, - onShow = noop, - timeout = 300, - } = settings; - - const [ show, setShow ] = useState( false ); - const timeoutRef = useRef< number | undefined >(); - - const setDebouncedTimeout = useCallback( - ( callback ) => { - window.clearTimeout( timeoutRef.current ); - - timeoutRef.current = window.setTimeout( callback, timeout ); - }, - [ timeout ] - ); - - const handleOnMouseMove = useCallback( ( event ) => { - onMouseMove( event ); - - setDebouncedTimeout( () => { - if ( ! show ) { - setShow( true ); - onShow(); - } - } ); - }, [] ); - - const handleOnMouseLeave = useCallback( ( event ) => { - onMouseLeave( event ); - - setDebouncedTimeout( () => { - setShow( false ); - onHide(); - } ); - }, [] ); - - useEffect( () => { - return () => { - window.clearTimeout( timeoutRef.current ); - }; - } ); - - return { - onMouseMove: handleOnMouseMove, - onMouseLeave: handleOnMouseLeave, - }; -}