From 168576ba28b7ef689c44a25e71675decb82d5ea6 Mon Sep 17 00:00:00 2001 From: Tasso Date: Tue, 7 Jan 2025 18:22:22 -0300 Subject: [PATCH] fix(fuselage-hooks): Stricter generics for `useEffectEvent` --- .changeset/eight-birds-invite.md | 6 ++++++ packages/fuselage-hooks/src/useEffectEvent.ts | 10 +++++++--- .../src/components/PaginatedSelect/PaginatedSelect.tsx | 6 +++--- .../fuselage/src/components/Select/SelectLegacy.tsx | 8 ++++---- 4 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 .changeset/eight-birds-invite.md diff --git a/.changeset/eight-birds-invite.md b/.changeset/eight-birds-invite.md new file mode 100644 index 0000000000..7e3351cd3e --- /dev/null +++ b/.changeset/eight-birds-invite.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/fuselage-hooks': patch +'@rocket.chat/fuselage': patch +--- + +fix(fuselage-hooks): Stricter generics for `useEffectEvent` diff --git a/packages/fuselage-hooks/src/useEffectEvent.ts b/packages/fuselage-hooks/src/useEffectEvent.ts index bbe9f8a1b9..077db35a6f 100644 --- a/packages/fuselage-hooks/src/useEffectEvent.ts +++ b/packages/fuselage-hooks/src/useEffectEvent.ts @@ -13,10 +13,14 @@ import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'; * @returns a stable callback * @public */ -export const useEffectEvent =

( - fn: (...args: P) => T, -): ((...args: P) => T) => { +export const useEffectEvent = ( + fn: TFunction, +) => { const fnRef = useRef(fn); + + type P = TFunction extends (...args: infer P) => any ? P : never; + type T = TFunction extends (...args: any) => infer T ? T : never; + const stableFnRef = useRef( (...args: P): T => fnRef.current.call(undefined, ...args), ); diff --git a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx index c2cf23286a..09fa71fa05 100644 --- a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx +++ b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx @@ -1,7 +1,7 @@ import { useEffectEvent, useResizeObserver } from '@rocket.chat/fuselage-hooks'; import { type ElementType, useState, useRef, useMemo } from 'react'; -import { type SelectProps } from '..'; +import { OptionType, SelectOption, type SelectProps } from '..'; import { prevent } from '../../helpers/prevent'; import AnimatedVisibility from '../AnimatedVisibility'; import Box from '../Box'; @@ -52,9 +52,9 @@ export const PaginatedSelect = ({ const [visible, hide, show] = useVisible(); - const internalChangedByClick = useEffectEvent(([value]) => { + const internalChangedByClick = useEffectEvent(([value]: OptionType) => { setInternalValue(value); - onChange(value); + onChange(value as SelectOption[0]); // FIXME hide(); }); diff --git a/packages/fuselage/src/components/Select/SelectLegacy.tsx b/packages/fuselage/src/components/Select/SelectLegacy.tsx index 2f1e8b3c92..26ba243378 100644 --- a/packages/fuselage/src/components/Select/SelectLegacy.tsx +++ b/packages/fuselage/src/components/Select/SelectLegacy.tsx @@ -89,9 +89,9 @@ export const SelectLegacy = forwardRef( ) => { const [internalValue, setInternalValue] = useState(value || ''); - const internalChangedByKeyboard = useEffectEvent(([value]) => { + const internalChangedByKeyboard = useEffectEvent(([value]: OptionType) => { setInternalValue(value); - onChange(value); + onChange(value as SelectOption[0]); // FIXME }); const option = options.find( @@ -123,9 +123,9 @@ export const SelectLegacy = forwardRef( const removeFocusClass = () => innerRef.current?.classList.remove('focus-visible'); - const internalChangedByClick = useEffectEvent(([value]) => { + const internalChangedByClick = useEffectEvent(([value]: OptionType) => { setInternalValue(value); - onChange(value); + onChange(value as SelectOption[0]); // FIXME removeFocusClass(); hide(); });