From 79c08cffd43736bde29869fe827ae0a08a27c402 Mon Sep 17 00:00:00 2001 From: ngorin Date: Fri, 6 Oct 2023 12:31:54 +0300 Subject: [PATCH 1/6] fix: refactor hook: useUniqId --- src/components/Disclosure/DisclosureContext.tsx | 2 +- src/components/Menu/MenuGroup.tsx | 2 +- src/components/Select/Select.tsx | 2 +- src/components/controls/TextArea/TextArea.tsx | 2 +- src/components/controls/TextInput/TextInput.tsx | 2 +- src/components/index.ts | 1 - src/components/utils/FocusTrap.tsx | 3 ++- src/components/utils/useRadio.ts | 2 +- src/components/utils/useRadioGroup.ts | 3 +-- src/hooks/index.ts | 1 + src/hooks/useUniqId/README.md | 15 +++++++++++++++ src/hooks/useUniqId/index.ts | 2 ++ .../utils => hooks/useUniqId}/useUniqId.ts | 8 +++++--- 13 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 src/hooks/useUniqId/README.md create mode 100644 src/hooks/useUniqId/index.ts rename src/{components/utils => hooks/useUniqId}/useUniqId.ts (64%) diff --git a/src/components/Disclosure/DisclosureContext.tsx b/src/components/Disclosure/DisclosureContext.tsx index 59cc50d44d..b048ac548a 100644 --- a/src/components/Disclosure/DisclosureContext.tsx +++ b/src/components/Disclosure/DisclosureContext.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {useUniqId} from '../utils/useUniqId'; +import {useUniqId} from '../../hooks'; import type {DisclosureProps} from './Disclosure'; diff --git a/src/components/Menu/MenuGroup.tsx b/src/components/Menu/MenuGroup.tsx index 2471438034..fd7a8a46cb 100644 --- a/src/components/Menu/MenuGroup.tsx +++ b/src/components/Menu/MenuGroup.tsx @@ -1,8 +1,8 @@ import React from 'react'; +import {useUniqId} from '../../hooks'; import type {DOMProps, QAProps} from '../types'; import {block} from '../utils/cn'; -import {useUniqId} from '../utils/useUniqId'; const b = block('menu'); diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx index c852f89c5b..62b01f6dd6 100644 --- a/src/components/Select/Select.tsx +++ b/src/components/Select/Select.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import {useUniqId} from '../../hooks'; import type {List} from '../List'; import {KeyCode} from '../constants'; import {useMobile} from '../mobile'; @@ -7,7 +8,6 @@ import type {CnMods} from '../utils/cn'; import {useFocusWithin} from '../utils/interactions'; import {useForkRef} from '../utils/useForkRef'; import {useSelect} from '../utils/useSelect'; -import {useUniqId} from '../utils/useUniqId'; import {EmptyOptions, SelectControl, SelectFilter, SelectList, SelectPopup} from './components'; import {DEFAULT_VIRTUALIZATION_THRESHOLD, selectBlock} from './constants'; diff --git a/src/components/controls/TextArea/TextArea.tsx b/src/components/controls/TextArea/TextArea.tsx index ecc623d742..f8f36caafc 100644 --- a/src/components/controls/TextArea/TextArea.tsx +++ b/src/components/controls/TextArea/TextArea.tsx @@ -1,8 +1,8 @@ import React from 'react'; +import {useUniqId} from '../../../hooks'; import {blockNew} from '../../utils/cn'; import {useForkRef} from '../../utils/useForkRef'; -import {useUniqId} from '../../utils/useUniqId'; import {ClearButton, mapTextInputSizeToButtonSize} from '../common'; import {OuterAdditionalContent} from '../common/OuterAdditionalContent/OuterAdditionalContent'; import type { diff --git a/src/components/controls/TextInput/TextInput.tsx b/src/components/controls/TextInput/TextInput.tsx index 2b6d2cbdf1..31e6b13592 100644 --- a/src/components/controls/TextInput/TextInput.tsx +++ b/src/components/controls/TextInput/TextInput.tsx @@ -2,12 +2,12 @@ import React from 'react'; import {TriangleExclamation} from '@gravity-ui/icons'; +import {useUniqId} from '../../../hooks'; import {Icon} from '../../Icon'; import {Popover} from '../../Popover'; import {block} from '../../utils/cn'; import {useElementSize} from '../../utils/useElementSize'; import {useForkRef} from '../../utils/useForkRef'; -import {useUniqId} from '../../utils/useUniqId'; import {ClearButton, mapTextInputSizeToButtonSize} from '../common'; import {OuterAdditionalContent} from '../common/OuterAdditionalContent/OuterAdditionalContent'; import type { diff --git a/src/components/index.ts b/src/components/index.ts index af7bcfca2e..cb55b864e6 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -63,5 +63,4 @@ export * from './utils/interactions'; export * from './utils/xpath'; export * from './utils/useFileInput/useFileInput'; export {useActionHandlers} from './utils/useActionHandlers'; -export {useUniqId} from './utils/useUniqId'; export {getLayersCount} from './utils/LayerManager'; diff --git a/src/components/utils/FocusTrap.tsx b/src/components/utils/FocusTrap.tsx index 96d95bb971..78b503d271 100644 --- a/src/components/utils/FocusTrap.tsx +++ b/src/components/utils/FocusTrap.tsx @@ -3,8 +3,9 @@ import React from 'react'; import {createFocusTrap} from 'focus-trap'; import type {FocusTrap as FocusTrapInstance} from 'focus-trap'; +import {useUniqId} from '../../hooks'; + import {useForkRef} from './useForkRef'; -import {useUniqId} from './useUniqId'; interface FocusTrapContext { addNode: (id: string, node: HTMLElement) => void; diff --git a/src/components/utils/useRadio.ts b/src/components/utils/useRadio.ts index 2891a17020..7611c03714 100644 --- a/src/components/utils/useRadio.ts +++ b/src/components/utils/useRadio.ts @@ -1,10 +1,10 @@ import React from 'react'; +import {useUniqId} from '../../hooks'; import type {ControlProps} from '../types'; import {eventBroker} from './event-broker'; import {useForkRef} from './useForkRef'; -import {useUniqId} from './useUniqId'; export function useRadio({ name, diff --git a/src/components/utils/useRadioGroup.ts b/src/components/utils/useRadioGroup.ts index c211b8ac13..ce56525f13 100644 --- a/src/components/utils/useRadioGroup.ts +++ b/src/components/utils/useRadioGroup.ts @@ -1,9 +1,8 @@ import React from 'react'; +import {useUniqId} from '../../hooks'; import type {ControlGroupProps} from '../types'; -import {useUniqId} from './useUniqId'; - export function useRadioGroup(props: ControlGroupProps) { const { name, diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 8ce4679d64..589e38fca9 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -2,3 +2,4 @@ export * from './useBodyScrollLock'; export * from './useOutsideClick'; export * from './usePortalContainer'; export * from './useVirtualElementRef'; +export * from './useUniqId'; diff --git a/src/hooks/useUniqId/README.md b/src/hooks/useUniqId/README.md new file mode 100644 index 0000000000..d2285a6718 --- /dev/null +++ b/src/hooks/useUniqId/README.md @@ -0,0 +1,15 @@ + + +# useUniqId + + + +```tsx +import {useUniqId} from '@gravity-ui/uikit'; +``` + +The `useUniqId` hook create uniq Id. + +## Result + +Id. `string` diff --git a/src/hooks/useUniqId/index.ts b/src/hooks/useUniqId/index.ts new file mode 100644 index 0000000000..25f2b3ba47 --- /dev/null +++ b/src/hooks/useUniqId/index.ts @@ -0,0 +1,2 @@ +export {useUniqId} from './useUniqId'; +export type {UseUniqIdResult} from './useUniqId'; diff --git a/src/components/utils/useUniqId.ts b/src/hooks/useUniqId/useUniqId.ts similarity index 64% rename from src/components/utils/useUniqId.ts rename to src/hooks/useUniqId/useUniqId.ts index cf660620f3..6bffc9efb9 100644 --- a/src/components/utils/useUniqId.ts +++ b/src/hooks/useUniqId/useUniqId.ts @@ -1,7 +1,9 @@ import React from 'react'; -import {NAMESPACE_NEW} from './cn'; -import {getUniqId} from './common'; +import {NAMESPACE_NEW} from '../../components/utils/cn'; +import {getUniqId} from '../../components/utils/common'; + +export type UseUniqIdResult = string; function useUniqIdFallback() { const idRef = React.useRef(); @@ -15,5 +17,5 @@ function useIdNative() { return `${NAMESPACE_NEW}${React.useId()}`; } -export const useUniqId: () => string = +export const useUniqId: () => UseUniqIdResult = typeof React.useId === 'function' ? useIdNative : useUniqIdFallback; From 57123c2fb199353b6f47cccd93f13cfc29a34b10 Mon Sep 17 00:00:00 2001 From: ngorin Date: Fri, 6 Oct 2023 15:14:26 +0300 Subject: [PATCH 2/6] fix: refactor hook: useActionHandlers --- CODEOWNERS | 2 ++ src/components/Card/Card.tsx | 2 +- src/components/List/constants.ts | 2 +- src/components/Menu/MenuItem.tsx | 2 +- .../PaginationInput/PaginationInput.tsx | 2 +- .../Popover/components/Trigger/Trigger.tsx | 2 +- src/components/Select/Select.tsx | 2 +- src/components/Select/utils.tsx | 2 +- src/components/Toc/TocItem/TocItem.tsx | 2 +- src/components/Tooltip/Tooltip.tsx | 2 +- src/components/index.ts | 1 - src/components/utils/LayerManager.ts | 2 +- src/{components => }/constants.ts | 0 src/hooks/index.ts | 1 + src/hooks/useActionHandlers/README.md | 21 +++++++++++++++++++ src/hooks/useActionHandlers/index.ts | 2 ++ .../useActionHandlers}/useActionHandlers.ts | 11 +++++++--- 17 files changed, 44 insertions(+), 14 deletions(-) rename src/{components => }/constants.ts (100%) create mode 100644 src/hooks/useActionHandlers/README.md create mode 100644 src/hooks/useActionHandlers/index.ts rename src/{components/utils => hooks/useActionHandlers}/useActionHandlers.ts (68%) diff --git a/CODEOWNERS b/CODEOWNERS index 2235f6b328..35452f3bd6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -47,7 +47,9 @@ /src/components/Tooltip @amje /src/components/theme @resure +/src/hooks/useActionHandlers @ogonkov /src/hooks/useOutsideClick @NikitaCG +/src/hooks/useUniqId @ValeraS # Allow everyone to update dependencies /package.json diff --git a/src/components/Card/Card.tsx b/src/components/Card/Card.tsx index 9028b18e15..cc26ad7e8c 100644 --- a/src/components/Card/Card.tsx +++ b/src/components/Card/Card.tsx @@ -1,8 +1,8 @@ import React from 'react'; +import {useActionHandlers} from '../../hooks'; import type {QAProps} from '../types'; import {block} from '../utils/cn'; -import {useActionHandlers} from '../utils/useActionHandlers'; import './Card.scss'; diff --git a/src/components/List/constants.ts b/src/components/List/constants.ts index bfe07a199a..554c3cc3d8 100644 --- a/src/components/List/constants.ts +++ b/src/components/List/constants.ts @@ -1,4 +1,4 @@ -import {KeyCode} from '../constants'; +import {KeyCode} from '../../constants'; export const ListQa = { ACTIVE_ITEM: 'list-active-item', diff --git a/src/components/Menu/MenuItem.tsx b/src/components/Menu/MenuItem.tsx index baee84fafa..5daa17e27c 100644 --- a/src/components/Menu/MenuItem.tsx +++ b/src/components/Menu/MenuItem.tsx @@ -1,9 +1,9 @@ import React from 'react'; +import {useActionHandlers} from '../../hooks'; import type {DOMProps, QAProps} from '../types'; import {block} from '../utils/cn'; import {eventBroker} from '../utils/event-broker'; -import {useActionHandlers} from '../utils/useActionHandlers'; const b = block('menu'); diff --git a/src/components/Pagination/components/PaginationInput/PaginationInput.tsx b/src/components/Pagination/components/PaginationInput/PaginationInput.tsx index 2768c928e8..76ec8eac6b 100644 --- a/src/components/Pagination/components/PaginationInput/PaginationInput.tsx +++ b/src/components/Pagination/components/PaginationInput/PaginationInput.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {KeyCode} from '../../../constants'; +import {KeyCode} from '../../../../constants'; import {TextInput, TextInputProps} from '../../../controls'; import {blockNew} from '../../../utils/cn'; import i18n from '../../i18n'; diff --git a/src/components/Popover/components/Trigger/Trigger.tsx b/src/components/Popover/components/Trigger/Trigger.tsx index f66f5607ef..4a185e594a 100644 --- a/src/components/Popover/components/Trigger/Trigger.tsx +++ b/src/components/Popover/components/Trigger/Trigger.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {useActionHandlers} from '../../../utils/useActionHandlers'; +import {useActionHandlers} from '../../../../hooks'; interface TriggerArgs { onClick: React.MouseEventHandler; diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx index 62b01f6dd6..b277bfcb29 100644 --- a/src/components/Select/Select.tsx +++ b/src/components/Select/Select.tsx @@ -1,8 +1,8 @@ import React from 'react'; +import {KeyCode} from '../../constants'; import {useUniqId} from '../../hooks'; import type {List} from '../List'; -import {KeyCode} from '../constants'; import {useMobile} from '../mobile'; import type {CnMods} from '../utils/cn'; import {useFocusWithin} from '../utils/interactions'; diff --git a/src/components/Select/utils.tsx b/src/components/Select/utils.tsx index dcf4f7350d..8e613ea1ea 100644 --- a/src/components/Select/utils.tsx +++ b/src/components/Select/utils.tsx @@ -1,7 +1,7 @@ import React from 'react'; +import {KeyCode} from '../../constants'; import type {List, ListItemData} from '../List'; -import {KeyCode} from '../constants'; import {GROUP_ITEM_MARGIN_TOP, MOBILE_ITEM_HEIGHT, SIZE_TO_ITEM_HEIGHT} from './constants'; import type {Option, OptionGroup} from './tech-components'; diff --git a/src/components/Toc/TocItem/TocItem.tsx b/src/components/Toc/TocItem/TocItem.tsx index f6b8406d0f..d4765075ed 100644 --- a/src/components/Toc/TocItem/TocItem.tsx +++ b/src/components/Toc/TocItem/TocItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; +import {useActionHandlers} from '../../../hooks'; import {blockNew} from '../../utils/cn'; -import {useActionHandlers} from '../../utils/useActionHandlers'; import type {TocItem as TocItemType} from '../types'; import './TocItem.scss'; diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index eb1cf45054..885fc2f8ee 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -1,8 +1,8 @@ import React from 'react'; +import {KeyCode} from '../../constants'; import {Popup} from '../Popup'; import type {PopupPlacement} from '../Popup'; -import {KeyCode} from '../constants'; import type {DOMProps} from '../types'; import {block} from '../utils/cn'; import {useBoolean} from '../utils/useBoolean'; diff --git a/src/components/index.ts b/src/components/index.ts index cb55b864e6..d79208d529 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -62,5 +62,4 @@ export {useOnFocusOutside} from './utils/useOnFocusOutside'; export * from './utils/interactions'; export * from './utils/xpath'; export * from './utils/useFileInput/useFileInput'; -export {useActionHandlers} from './utils/useActionHandlers'; export {getLayersCount} from './utils/LayerManager'; diff --git a/src/components/utils/LayerManager.ts b/src/components/utils/LayerManager.ts index 2e0d276c67..047fb0c439 100644 --- a/src/components/utils/LayerManager.ts +++ b/src/components/utils/LayerManager.ts @@ -1,6 +1,6 @@ import type {VirtualElement} from '@popperjs/core'; -import {KeyCode} from '../constants'; +import {KeyCode} from '../../constants'; import {eventBroker} from './event-broker'; diff --git a/src/components/constants.ts b/src/constants.ts similarity index 100% rename from src/components/constants.ts rename to src/constants.ts diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 589e38fca9..74c1bc29dc 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1,3 +1,4 @@ +export * from './useActionHandlers'; export * from './useBodyScrollLock'; export * from './useOutsideClick'; export * from './usePortalContainer'; diff --git a/src/hooks/useActionHandlers/README.md b/src/hooks/useActionHandlers/README.md new file mode 100644 index 0000000000..b15f215212 --- /dev/null +++ b/src/hooks/useActionHandlers/README.md @@ -0,0 +1,21 @@ + + +# useActionHandlers + + + +```tsx +import {useActionHandlers} from '@gravity-ui/uikit'; +``` + +The `useActionHandlers` hook emulates behaviour of system controls, that respond to Enter and Spacebar + +## Properties + +| Name | Description | Type | Default | +| :------- | :------------------------- | :------------------------: | :-----: | +| callback | Callback for keydown event | `(...args: any[]) => any;` | | + +## Result + +Keyboard event handler. `React.KeyboardEventHandler` diff --git a/src/hooks/useActionHandlers/index.ts b/src/hooks/useActionHandlers/index.ts new file mode 100644 index 0000000000..cae5130d72 --- /dev/null +++ b/src/hooks/useActionHandlers/index.ts @@ -0,0 +1,2 @@ +export {useActionHandlers} from './useActionHandlers'; +export type {UseActionHandlersProps, UseActionHandlersResult} from './useActionHandlers'; diff --git a/src/components/utils/useActionHandlers.ts b/src/hooks/useActionHandlers/useActionHandlers.ts similarity index 68% rename from src/components/utils/useActionHandlers.ts rename to src/hooks/useActionHandlers/useActionHandlers.ts index a3a126f9dd..73309bd540 100644 --- a/src/components/utils/useActionHandlers.ts +++ b/src/hooks/useActionHandlers/useActionHandlers.ts @@ -1,11 +1,13 @@ import React from 'react'; -import {KeyCode} from '../constants'; +import {KeyCode} from '../../constants'; // eslint-disable-next-line @typescript-eslint/no-explicit-any type AnyFunction = (...args: any[]) => any; -interface UseActionHandlersResult { +export type UseActionHandlersProps = AnyFunction; + +export interface UseActionHandlersResult { onKeyDown: React.KeyboardEventHandler; } @@ -14,13 +16,16 @@ interface UseActionHandlersResult { * @param callback * @return {onKeyDown} */ -export function useActionHandlers(callback?: AnyFunction): UseActionHandlersResult { +export function useActionHandlers( + callback?: UseActionHandlersProps, +): UseActionHandlersResult { const onKeyDown = React.useCallback( (event: React.KeyboardEvent) => { if ( callback && [KeyCode.ENTER, KeyCode.SPACEBAR, KeyCode.SPACEBAR_OLD].includes(event.key) ) { + // eslint-disable-next-line callback-return callback(event); } }, From 54c0827f90a1f9d3fba8d02591dea20cf14b0bb9 Mon Sep 17 00:00:00 2001 From: ngorin Date: Fri, 6 Oct 2023 17:18:40 +0300 Subject: [PATCH 3/6] fix: refactor hooks: useForkRef and useFileInput --- CODEOWNERS | 1 + src/components/Popup/Popup.tsx | 2 +- src/components/Select/Select.tsx | 3 +-- src/components/Tooltip/Tooltip.tsx | 2 +- src/components/controls/TextArea/TextArea.tsx | 3 +-- .../controls/TextArea/TextAreaControl.tsx | 2 +- .../controls/TextInput/TextInput.tsx | 3 +-- src/components/index.ts | 3 --- src/components/utils/FocusTrap.tsx | 4 +--- src/components/utils/useCheckbox.ts | 2 +- src/components/utils/useRadio.ts | 3 +-- src/hooks/index.ts | 2 ++ src/hooks/useFileInput/README.md | 23 +++++++++++++++++++ .../__stories__/UseFileInput.stories.tsx | 2 +- src/hooks/useFileInput/index.ts | 2 ++ .../useFileInput/useFileInput.ts | 8 ++++--- src/hooks/useForkRef/README.md | 21 +++++++++++++++++ src/hooks/useForkRef/index.ts | 3 +++ .../utils => hooks/useForkRef}/setRef.ts | 0 .../utils => hooks/useForkRef}/useForkRef.ts | 7 +++--- 20 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 src/hooks/useFileInput/README.md rename src/{components/utils => hooks}/useFileInput/__stories__/UseFileInput.stories.tsx (92%) create mode 100644 src/hooks/useFileInput/index.ts rename src/{components/utils => hooks}/useFileInput/useFileInput.ts (97%) create mode 100644 src/hooks/useForkRef/README.md create mode 100644 src/hooks/useForkRef/index.ts rename src/{components/utils => hooks/useForkRef}/setRef.ts (100%) rename src/{components/utils => hooks/useForkRef}/useForkRef.ts (66%) diff --git a/CODEOWNERS b/CODEOWNERS index 35452f3bd6..a5a7bf5925 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -48,6 +48,7 @@ /src/components/theme @resure /src/hooks/useActionHandlers @ogonkov +/src/hooks/useFileInput @korvin89 /src/hooks/useOutsideClick @NikitaCG /src/hooks/useUniqId @ValeraS diff --git a/src/components/Popup/Popup.tsx b/src/components/Popup/Popup.tsx index cac5a944df..c3c4edbd10 100644 --- a/src/components/Popup/Popup.tsx +++ b/src/components/Popup/Popup.tsx @@ -2,12 +2,12 @@ import React from 'react'; import {CSSTransition} from 'react-transition-group'; +import {useForkRef} from '../../hooks'; import {Portal} from '../Portal'; import type {DOMProps, QAProps} from '../types'; import {FocusTrap, useParentFocusTrap} from '../utils/FocusTrap'; import {block} from '../utils/cn'; import {getCSSTransitionClassNames} from '../utils/transition'; -import {useForkRef} from '../utils/useForkRef'; import {useLayer} from '../utils/useLayer'; import type {LayerExtendableProps} from '../utils/useLayer'; import {usePopper} from '../utils/usePopper'; diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx index b277bfcb29..9b5c75f970 100644 --- a/src/components/Select/Select.tsx +++ b/src/components/Select/Select.tsx @@ -1,12 +1,11 @@ import React from 'react'; import {KeyCode} from '../../constants'; -import {useUniqId} from '../../hooks'; +import {useForkRef, useUniqId} from '../../hooks'; import type {List} from '../List'; import {useMobile} from '../mobile'; import type {CnMods} from '../utils/cn'; import {useFocusWithin} from '../utils/interactions'; -import {useForkRef} from '../utils/useForkRef'; import {useSelect} from '../utils/useSelect'; import {EmptyOptions, SelectControl, SelectFilter, SelectList, SelectPopup} from './components'; diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index 885fc2f8ee..f65c68557f 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -1,12 +1,12 @@ import React from 'react'; import {KeyCode} from '../../constants'; +import {useForkRef} from '../../hooks'; import {Popup} from '../Popup'; import type {PopupPlacement} from '../Popup'; import type {DOMProps} from '../types'; import {block} from '../utils/cn'; import {useBoolean} from '../utils/useBoolean'; -import {useForkRef} from '../utils/useForkRef'; import './Tooltip.scss'; diff --git a/src/components/controls/TextArea/TextArea.tsx b/src/components/controls/TextArea/TextArea.tsx index f8f36caafc..b94ec7635f 100644 --- a/src/components/controls/TextArea/TextArea.tsx +++ b/src/components/controls/TextArea/TextArea.tsx @@ -1,8 +1,7 @@ import React from 'react'; -import {useUniqId} from '../../../hooks'; +import {useForkRef, useUniqId} from '../../../hooks'; import {blockNew} from '../../utils/cn'; -import {useForkRef} from '../../utils/useForkRef'; import {ClearButton, mapTextInputSizeToButtonSize} from '../common'; import {OuterAdditionalContent} from '../common/OuterAdditionalContent/OuterAdditionalContent'; import type { diff --git a/src/components/controls/TextArea/TextAreaControl.tsx b/src/components/controls/TextArea/TextAreaControl.tsx index 603e82135d..f0094049eb 100644 --- a/src/components/controls/TextArea/TextAreaControl.tsx +++ b/src/components/controls/TextArea/TextAreaControl.tsx @@ -1,7 +1,7 @@ import React from 'react'; +import {useForkRef} from '../../../hooks'; import {blockNew} from '../../utils/cn'; -import {useForkRef} from '../../utils/useForkRef'; import type {TextAreaProps} from './TextArea'; diff --git a/src/components/controls/TextInput/TextInput.tsx b/src/components/controls/TextInput/TextInput.tsx index 31e6b13592..1ff63392d4 100644 --- a/src/components/controls/TextInput/TextInput.tsx +++ b/src/components/controls/TextInput/TextInput.tsx @@ -2,12 +2,11 @@ import React from 'react'; import {TriangleExclamation} from '@gravity-ui/icons'; -import {useUniqId} from '../../../hooks'; +import {useForkRef, useUniqId} from '../../../hooks'; import {Icon} from '../../Icon'; import {Popover} from '../../Popover'; import {block} from '../../utils/cn'; import {useElementSize} from '../../utils/useElementSize'; -import {useForkRef} from '../../utils/useForkRef'; import {ClearButton, mapTextInputSizeToButtonSize} from '../common'; import {OuterAdditionalContent} from '../common/OuterAdditionalContent/OuterAdditionalContent'; import type { diff --git a/src/components/index.ts b/src/components/index.ts index d79208d529..ff58450f0c 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -56,10 +56,7 @@ export * from './utils/useLayer'; export {Lang, configure} from './utils/configure'; export * from './utils/useSelect'; export * from './utils/useListNavigation'; -export * from './utils/useForkRef'; -export * from './utils/setRef'; export {useOnFocusOutside} from './utils/useOnFocusOutside'; export * from './utils/interactions'; export * from './utils/xpath'; -export * from './utils/useFileInput/useFileInput'; export {getLayersCount} from './utils/LayerManager'; diff --git a/src/components/utils/FocusTrap.tsx b/src/components/utils/FocusTrap.tsx index 78b503d271..e4b177825f 100644 --- a/src/components/utils/FocusTrap.tsx +++ b/src/components/utils/FocusTrap.tsx @@ -3,9 +3,7 @@ import React from 'react'; import {createFocusTrap} from 'focus-trap'; import type {FocusTrap as FocusTrapInstance} from 'focus-trap'; -import {useUniqId} from '../../hooks'; - -import {useForkRef} from './useForkRef'; +import {useForkRef, useUniqId} from '../../hooks'; interface FocusTrapContext { addNode: (id: string, node: HTMLElement) => void; diff --git a/src/components/utils/useCheckbox.ts b/src/components/utils/useCheckbox.ts index 8f308c5bb8..7fcac924df 100644 --- a/src/components/utils/useCheckbox.ts +++ b/src/components/utils/useCheckbox.ts @@ -1,9 +1,9 @@ import React from 'react'; +import {useForkRef} from '../../hooks'; import type {ControlProps} from '../types'; import {eventBroker} from './event-broker'; -import {useForkRef} from './useForkRef'; export function useCheckbox({ name, diff --git a/src/components/utils/useRadio.ts b/src/components/utils/useRadio.ts index 7611c03714..a6876946f7 100644 --- a/src/components/utils/useRadio.ts +++ b/src/components/utils/useRadio.ts @@ -1,10 +1,9 @@ import React from 'react'; -import {useUniqId} from '../../hooks'; +import {useForkRef, useUniqId} from '../../hooks'; import type {ControlProps} from '../types'; import {eventBroker} from './event-broker'; -import {useForkRef} from './useForkRef'; export function useRadio({ name, diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 74c1bc29dc..3e266ab629 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1,5 +1,7 @@ export * from './useActionHandlers'; export * from './useBodyScrollLock'; +export * from './useFileInput'; +export * from './useForkRef'; export * from './useOutsideClick'; export * from './usePortalContainer'; export * from './useVirtualElementRef'; diff --git a/src/hooks/useFileInput/README.md b/src/hooks/useFileInput/README.md new file mode 100644 index 0000000000..1929538a6e --- /dev/null +++ b/src/hooks/useFileInput/README.md @@ -0,0 +1,23 @@ + + +# useFileInput + + + +```tsx +import {useFileInput} from '@gravity-ui/uikit'; +``` + +The `useFileInput` hook used to shape props for input with type "file" + +## Properties + +| Name | Description | Type | Default | +| :------- | :------------------- | :----------------------------------: | :-----: | +| onUpdate | Update file callback | `(files: File[]) => void` | | +| onChange | On change callback | `(event: React.ChangeEvent) => void` | | + +## Result + +- controlProps - props for the input with type 'file' `React.DetailedHTMLProps`. +- triggerProps - props for the interactive element that, when interacted with, should open a dialog window for file selection `{onClick: () => void;}`. diff --git a/src/components/utils/useFileInput/__stories__/UseFileInput.stories.tsx b/src/hooks/useFileInput/__stories__/UseFileInput.stories.tsx similarity index 92% rename from src/components/utils/useFileInput/__stories__/UseFileInput.stories.tsx rename to src/hooks/useFileInput/__stories__/UseFileInput.stories.tsx index 20bdf736dd..12e83ed6e5 100644 --- a/src/components/utils/useFileInput/__stories__/UseFileInput.stories.tsx +++ b/src/hooks/useFileInput/__stories__/UseFileInput.stories.tsx @@ -2,7 +2,7 @@ import React from 'react'; import type {Meta, StoryFn} from '@storybook/react'; -import {Button} from '../../../Button'; +import {Button} from '../../../components/Button'; import {useFileInput} from '../useFileInput'; export default {title: 'Hooks/useFileInput'} as Meta; diff --git a/src/hooks/useFileInput/index.ts b/src/hooks/useFileInput/index.ts new file mode 100644 index 0000000000..a327ebb520 --- /dev/null +++ b/src/hooks/useFileInput/index.ts @@ -0,0 +1,2 @@ +export {useFileInput} from './useFileInput'; +export type {UseFileInputProps, UseFileInputOutput, UseFileInputResult} from './useFileInput'; diff --git a/src/components/utils/useFileInput/useFileInput.ts b/src/hooks/useFileInput/useFileInput.ts similarity index 97% rename from src/components/utils/useFileInput/useFileInput.ts rename to src/hooks/useFileInput/useFileInput.ts index 642eba2905..2c202fa159 100644 --- a/src/components/utils/useFileInput/useFileInput.ts +++ b/src/hooks/useFileInput/useFileInput.ts @@ -16,18 +16,20 @@ export type UseFileInputOutput = { }; }; +export type UseFileInputResult = UseFileInputOutput; + /** * Used to shape props for input with type "file". - * + * * Usage example: ```tsx import React from 'react'; import {Button, useFileInput} from '@gravity-ui/uikit'; - + const Component = () => { const onUpdate = React.useCallback((files: File[]) => console.log(files), []); const {controlProps, triggerProps} = useFileInput({onUpdate}); - + return ( diff --git a/src/hooks/useForkRef/README.md b/src/hooks/useForkRef/README.md new file mode 100644 index 0000000000..b0cec6c276 --- /dev/null +++ b/src/hooks/useForkRef/README.md @@ -0,0 +1,21 @@ + + +# useForkRef + + + +```tsx +import {useForkRef} from '@gravity-ui/uikit'; +``` + +The `useForkRef` hook that can combine refs into a single Ref + +## Properties + +| Name | Description | Type | Default | +| :--- | :-------------- | :-----------------: | :-----: | +| refs | ref-links array | `React.RefObject[]` | | + +## Result + +Combined ref. `React.RefCallback` diff --git a/src/hooks/useForkRef/index.ts b/src/hooks/useForkRef/index.ts new file mode 100644 index 0000000000..73bbe3a2dd --- /dev/null +++ b/src/hooks/useForkRef/index.ts @@ -0,0 +1,3 @@ +export {useForkRef} from './useForkRef'; +export {setRef} from './setRef'; +export type {UseForkRefProps, UseForkRefResult} from './useForkRef'; diff --git a/src/components/utils/setRef.ts b/src/hooks/useForkRef/setRef.ts similarity index 100% rename from src/components/utils/setRef.ts rename to src/hooks/useForkRef/setRef.ts diff --git a/src/components/utils/useForkRef.ts b/src/hooks/useForkRef/useForkRef.ts similarity index 66% rename from src/components/utils/useForkRef.ts rename to src/hooks/useForkRef/useForkRef.ts index 570d43c0ab..9c45cb1fbb 100644 --- a/src/components/utils/useForkRef.ts +++ b/src/hooks/useForkRef/useForkRef.ts @@ -2,9 +2,10 @@ import React from 'react'; import {setRef} from './setRef'; -export function useForkRef( - ...refs: Array | undefined> -): React.RefCallback | null { +export type UseForkRefProps = Array | undefined>; +export type UseForkRefResult = React.RefCallback | null; + +export function useForkRef(...refs: UseForkRefProps): UseForkRefResult { return React.useMemo(() => { if (refs.every((ref) => ref === null || ref === undefined)) { return null; From f9c9e5f0ae112c0ef3587fd3529864fee47250ce Mon Sep 17 00:00:00 2001 From: ngorin Date: Fri, 6 Oct 2023 17:26:28 +0300 Subject: [PATCH 4/6] fix: refactor hooks: add row in CODEOWNERS --- CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/CODEOWNERS b/CODEOWNERS index a5a7bf5925..8637d2fa5f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -49,6 +49,7 @@ /src/hooks/useActionHandlers @ogonkov /src/hooks/useFileInput @korvin89 +/src/hooks/useForkRef @ValeraS /src/hooks/useOutsideClick @NikitaCG /src/hooks/useUniqId @ValeraS From 3baa152b70f838c8a0e1b7d21088b1f5e0fa2fa4 Mon Sep 17 00:00:00 2001 From: ngorin Date: Tue, 10 Oct 2023 17:12:50 +0300 Subject: [PATCH 5/6] fix: refactor hooks: review --- src/hooks/useFileInput/useFileInput.ts | 3 +++ src/hooks/useForkRef/README.md | 2 +- src/hooks/useUniqId/README.md | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hooks/useFileInput/useFileInput.ts b/src/hooks/useFileInput/useFileInput.ts index 2c202fa159..d777b920f8 100644 --- a/src/hooks/useFileInput/useFileInput.ts +++ b/src/hooks/useFileInput/useFileInput.ts @@ -6,6 +6,9 @@ export type UseFileInputProps = { onChange?: (event: React.ChangeEvent) => void; }; +/** + * @deprecated use UseFileInputResult instead + */ export type UseFileInputOutput = { controlProps: React.DetailedHTMLProps< React.InputHTMLAttributes, diff --git a/src/hooks/useForkRef/README.md b/src/hooks/useForkRef/README.md index b0cec6c276..463dadcf8c 100644 --- a/src/hooks/useForkRef/README.md +++ b/src/hooks/useForkRef/README.md @@ -8,7 +8,7 @@ import {useForkRef} from '@gravity-ui/uikit'; ``` -The `useForkRef` hook that can combine refs into a single Ref +The `useForkRef` hook that can combine refs into a single ref ## Properties diff --git a/src/hooks/useUniqId/README.md b/src/hooks/useUniqId/README.md index d2285a6718..08a614dda1 100644 --- a/src/hooks/useUniqId/README.md +++ b/src/hooks/useUniqId/README.md @@ -8,8 +8,8 @@ import {useUniqId} from '@gravity-ui/uikit'; ``` -The `useUniqId` hook create uniq Id. +The `useUniqId` hook create uniq ID. ## Result -Id. `string` +ID. `string` From 413e29201149d24a30e405ef9544400cafd76caf Mon Sep 17 00:00:00 2001 From: ngorin Date: Tue, 10 Oct 2023 17:18:09 +0300 Subject: [PATCH 6/6] fix: typos --- src/hooks/useUniqId/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useUniqId/README.md b/src/hooks/useUniqId/README.md index 08a614dda1..70a0919bb8 100644 --- a/src/hooks/useUniqId/README.md +++ b/src/hooks/useUniqId/README.md @@ -8,7 +8,7 @@ import {useUniqId} from '@gravity-ui/uikit'; ``` -The `useUniqId` hook create uniq ID. +The `useUniqId` hook creates unique ID. ## Result