diff --git a/CODEOWNERS b/CODEOWNERS index 8637d2fa5f..fcb6e65144 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -50,7 +50,10 @@ /src/hooks/useActionHandlers @ogonkov /src/hooks/useFileInput @korvin89 /src/hooks/useForkRef @ValeraS +/src/hooks/useIntersection @imechoim +/src/hooks/useTimeout @ogonkov /src/hooks/useOutsideClick @NikitaCG +/src/hooks/useViewportSize @NikitaCG /src/hooks/useUniqId @ValeraS # Allow everyone to update dependencies diff --git a/src/components/DropdownMenu/DropdownMenuPopup.tsx b/src/components/DropdownMenu/DropdownMenuPopup.tsx index c3b238d68c..86144b6f08 100644 --- a/src/components/DropdownMenu/DropdownMenuPopup.tsx +++ b/src/components/DropdownMenu/DropdownMenuPopup.tsx @@ -1,10 +1,10 @@ import React from 'react'; +import {useListNavigation} from '../../hooks'; import {Menu} from '../Menu'; import type {MenuProps} from '../Menu'; import {Popup} from '../Popup'; import type {PopupProps} from '../Popup'; -import {useListNavigation} from '../utils/useListNavigation'; import {cnDropdownMenu} from './DropdownMenu.classname'; import {DropdownMenuContext} from './DropdownMenuContext'; diff --git a/src/components/List/ListLoadingIndicator.tsx b/src/components/List/ListLoadingIndicator.tsx index 57bbf8683e..4bbb9e79cd 100644 --- a/src/components/List/ListLoadingIndicator.tsx +++ b/src/components/List/ListLoadingIndicator.tsx @@ -1,8 +1,8 @@ import React from 'react'; +import {useIntersection} from '../../hooks'; import {Loader} from '../Loader'; import {block} from '../utils/cn'; -import {useIntersection} from '../utils/useIntersection'; const b = block('list'); export const SelectLoadingIndicator = (props: {onIntersect?: () => void}) => { diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx index 9b5c75f970..ca4d62063e 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 {useForkRef, useUniqId} from '../../hooks'; +import {useForkRef, useSelect, useUniqId} from '../../hooks'; import type {List} from '../List'; import {useMobile} from '../mobile'; import type {CnMods} from '../utils/cn'; import {useFocusWithin} from '../utils/interactions'; -import {useSelect} from '../utils/useSelect'; import {EmptyOptions, SelectControl, SelectFilter, SelectList, SelectPopup} from './components'; import {DEFAULT_VIRTUALIZATION_THRESHOLD, selectBlock} from './constants'; diff --git a/src/components/Select/components/SelectList/SelectLoadingIndicator.tsx b/src/components/Select/components/SelectList/SelectLoadingIndicator.tsx index b73acbebfa..860a72ac04 100644 --- a/src/components/Select/components/SelectList/SelectLoadingIndicator.tsx +++ b/src/components/Select/components/SelectList/SelectLoadingIndicator.tsx @@ -1,7 +1,7 @@ import React from 'react'; +import {useIntersection} from '../../../../hooks'; import {Loader} from '../../../Loader/Loader'; -import {useIntersection} from '../../../utils/useIntersection'; import {selectListBlock} from '../../constants'; export const SelectLoadingIndicator = (props: {onIntersect?: () => void}) => { diff --git a/src/components/Select/types.ts b/src/components/Select/types.ts index 8e5360b62e..f4a4d917db 100644 --- a/src/components/Select/types.ts +++ b/src/components/Select/types.ts @@ -1,8 +1,8 @@ import type React from 'react'; +import type {UseOpenProps} from '../../hooks/useSelect/types'; import type {InputControlPin, InputControlSize, InputControlView} from '../controls'; import type {ControlGroupOption, ControlGroupProps, QAProps} from '../types'; -import type {UseOpenProps} from '../utils/useSelect/types'; import type {Option, OptionGroup} from './tech-components'; diff --git a/src/components/index.ts b/src/components/index.ts index ff58450f0c..de49f5698e 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -54,8 +54,6 @@ export * from './utils/withEventBrokerDomHandlers'; export * from './utils/useEventBroker'; export * from './utils/useLayer'; export {Lang, configure} from './utils/configure'; -export * from './utils/useSelect'; -export * from './utils/useListNavigation'; export {useOnFocusOutside} from './utils/useOnFocusOutside'; export * from './utils/interactions'; export * from './utils/xpath'; diff --git a/src/components/utils/useCloseOnTimeout.ts b/src/components/utils/useCloseOnTimeout.ts index 0c9787718e..e7ebf97ad8 100644 --- a/src/components/utils/useCloseOnTimeout.ts +++ b/src/components/utils/useCloseOnTimeout.ts @@ -1,5 +1,6 @@ +import {useTimeout} from '../../hooks'; + import {useHover} from './useHover'; -import {useTimeout} from './useTimeout'; interface UseCloseOnTimeoutProps { onClose: VoidFunction; diff --git a/src/components/utils/useListNavigation/README.md b/src/components/utils/useListNavigation/README.md deleted file mode 100644 index 70e17013df..0000000000 --- a/src/components/utils/useListNavigation/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# useListNavigation - -React hook used to navigate through the items in a list - -`ArrowDown` will increase currently active item index -`ArrowUp` will reduce currently active item index -`PageDown` will increase currently active item index by pageSize (works if `pageSize` passed) -`PageUp` will reduce currently active item index by pageSize (works if `pageSize` passed) -`Home` will navigate to the start of the list if `processHomeKey` (disable if you want to move the cursor to the start of active input on `Home` key, for example) -`End` will navigate to the end of the list if `processEndKey` (disable if you want to move the cursor to the end of active input on `End` key, for example) - -For skipping items you should pass `skip` function, which accepts an item and returns boolean value, representing if it's needed to skip the item - -The hook returns the following: - -- `activeItemIndex` - active item index -- `reset` - function, which should be called when you want to reset navigation - -### Arguments - -| Name | Type | Default | Description | -| :-------------- | :------------------------------------------------------------------- | :------ | :---------------------------------------------------------------------------------------------------- | -| items | `ItemType[]` | `-` | List items. Item can be any object. Also, it can contain `items` property, which represents sub-items | -| skip | `(item: ItemType) => boolean` | `-` | Returns true if the item should not participate in navigation (Called for each item) | -| pageSize | `number` | `-` | Items page size, if passed, then navigates by pageSize on PageDown/PageUp | -| processHomeKey | `boolean` | `false` | Navigate to the start of the list on Home key | -| processEndKey | `boolean` | `false` | Navigate to the end of the list on End key | -| disabled | `boolean` | `false` | Disable navigation | -| initialValue | `number` | `-1` | Initial active item index | -| anchorRef | `RefObject` | `-` | HTMLElement reference, the hook will listen keydown event on that element | -| onAnchorKeyDown | `(activeItemIndex: number, event: KeyboardEvent) => boolean or void` | `-` | Custom keydown handler, if returns false, then the hook won't process keydown | - -### Returns - -| Name | Type | Description | -| :----------------- | :------------------------ | :----------------------- | -| activeItemIndex | `number` | Index of the active item | -| setActiveItemIndex | `(index: number) => void` | Active item index setter | -| reset | `() => void` | Resets navigation | - -### Examples - -```tsx -const anchorRef = useRef(null); - -const items = [ - { - id: 1, - title: 'Item 1', - }, - { - id: 2, - title: 'Item 2', - }, -]; - -useListNavigation({ - items, - skip: (item) => item.disabled, - anchorRef, - onAnchorKeydown: (activeItemIndex: number, event: KeyboardEvent) => { - switch (event.key) { - case 'Enter': - case ' ': { - const activeItem = items[activeItemIndex]; - if (activeItem) { - event.preventDefault(); - - console.log(`${activeItem.title} selected`); - } - - return false; - } - } - }, -}); -``` diff --git a/src/components/utils/useListNavigation/index.ts b/src/components/utils/useListNavigation/index.ts deleted file mode 100644 index db701e3805..0000000000 --- a/src/components/utils/useListNavigation/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {useListNavigation} from './useListNavigation'; diff --git a/src/components/utils/useSelect/README.md b/src/components/utils/useSelect/README.md deleted file mode 100644 index 135083a171..0000000000 --- a/src/components/utils/useSelect/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# useSelect - -React hook used to handle items selection in list - -### Arguments - -| Name | Type | Default | Description | -| :----------- | :--------- | :------ | :-------------------------------------------------------- | -| value | `string[]` | `-` | Values that represent selected items | -| defaultValue | `string[]` | `[]` | Default values used in case of uncontrolled usage | -| multiple | `boolean` | `false` | Indicates that multiple items can be selected in the list | -| onUpdate | `function` | `-` | Invokes inside of `handleSelection` function | -| defaultOpen | `boolean` | `false` | Initial value for `open` property | -| open | `boolean` | - | Controlled `open` property | -| onOpenChange | `function` | `-` | Invokes while `open` property changes | - -### Return data - -| Name | Type | Description | -| :-------------- | :--------- | :---------------------------------------------------------- | -| value | `string[]` | Values that represent selected items | -| handleSelection | `function` | Handles item selection | -| open | `boolean` | List container visibility state | -| setOpen | `function` | (deprecated) use toggleOpen. Sets value for `open` property | -| toggleOpen | `function` | Inver the value of `open` | -| activeIndex | `number` | Index of active option | -| setActiveIndex | `function` | Sets value for `activeIndex` property | diff --git a/src/components/utils/useSelect/types.ts b/src/components/utils/useSelect/types.ts deleted file mode 100644 index 6b8a0dfeb4..0000000000 --- a/src/components/utils/useSelect/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type UseSelectOption = T & {value: string}; - -export type UseOpenProps = { - defaultOpen?: boolean; - open?: boolean; - onClose?: () => void; - onOpenChange?: (open: boolean) => void; -}; - -export type UseSelectProps = { - value?: string[]; - defaultValue?: string[]; - multiple?: boolean; - onUpdate?: (value: string[]) => void; -} & UseOpenProps; diff --git a/src/components/utils/useViewportSize/index.ts b/src/components/utils/useViewportSize/index.ts deleted file mode 100644 index 35c194400a..0000000000 --- a/src/components/utils/useViewportSize/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {useViewportSize} from './useViewportSize'; -export type {ViewportSize} from './useViewportSize'; diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 3e266ab629..0c7a7974ef 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -2,7 +2,12 @@ export * from './useActionHandlers'; export * from './useBodyScrollLock'; export * from './useFileInput'; export * from './useForkRef'; +export * from './useIntersection'; +export * from './useListNavigation'; export * from './useOutsideClick'; export * from './usePortalContainer'; +export * from './useSelect'; +export * from './useTimeout'; +export * from './useViewportSize'; export * from './useVirtualElementRef'; export * from './useUniqId'; diff --git a/src/hooks/useIntersection/README.md b/src/hooks/useIntersection/README.md new file mode 100644 index 0000000000..b8470365b4 --- /dev/null +++ b/src/hooks/useIntersection/README.md @@ -0,0 +1,19 @@ + + +# useIntersection + + + +```tsx +import {useIntersection} from '@gravity-ui/uikit'; +``` + +The `useIntersection` hook works with the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) and calls a callback at the 'isIntersected' event of the observed element + +## Properties + +| Name | Description | Type | Default | +| :---------- | :-------------------------------------------- | :------------------------: | :-----: | +| element | The observed element | `React.RefObject` | | +| options | Intersection observer options | `IntersectionObserverInit` | | +| onIntersect | Callback when observed element is intersected | `() => void` | | diff --git a/src/hooks/useIntersection/index.ts b/src/hooks/useIntersection/index.ts new file mode 100644 index 0000000000..f91f08e04b --- /dev/null +++ b/src/hooks/useIntersection/index.ts @@ -0,0 +1,2 @@ +export {useIntersection} from './useIntersection'; +export type {UseIntersection, UseIntersectionProps} from './useIntersection'; diff --git a/src/components/utils/useIntersection.ts b/src/hooks/useIntersection/useIntersection.ts similarity index 82% rename from src/components/utils/useIntersection.ts rename to src/hooks/useIntersection/useIntersection.ts index 842b228eb4..cfcbbe452a 100644 --- a/src/components/utils/useIntersection.ts +++ b/src/hooks/useIntersection/useIntersection.ts @@ -1,12 +1,17 @@ import React from 'react'; +/** + * @deprecated use UseIntersectionProps instead + */ export type UseIntersection = { element: Element | null; options?: IntersectionObserverInit; onIntersect?: () => void; }; -export const useIntersection = ({element, options, onIntersect}: UseIntersection) => { +export type UseIntersectionProps = UseIntersection; + +export const useIntersection = ({element, options, onIntersect}: UseIntersectionProps) => { React.useEffect(() => { const observer = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { diff --git a/src/hooks/useListNavigation/README.md b/src/hooks/useListNavigation/README.md new file mode 100644 index 0000000000..2f32365d3c --- /dev/null +++ b/src/hooks/useListNavigation/README.md @@ -0,0 +1,85 @@ + + +# useListNavigation + + + +```tsx +import {useListNavigation} from '@gravity-ui/uikit'; +``` + +The `useListNavigation` hook used to navigate through the items in a list + +`ArrowDown` will increase currently active item index +`ArrowUp` will reduce currently active item index +`PageDown` will increase currently active item index by pageSize (works if `pageSize` passed) +`PageUp` will reduce currently active item index by pageSize (works if `pageSize` passed) +`Home` will navigate to the start of the list if `processHomeKey` (disable if you want to move the cursor to the start of active input on `Home` key, for example) +`End` will navigate to the end of the list if `processEndKey` (disable if you want to move the cursor to the end of active input on `End` key, for example) + +For skipping items you should pass `skip` function, which accepts an item and returns boolean value, representing if it's needed to skip the item + +The hook returns the following: + +- `activeItemIndex` - active item index +- `reset` - function, which should be called when you want to reset navigation + +## Examples + +```tsx +const anchorRef = useRef(null); + +const items = [ + { + id: 1, + title: 'Item 1', + }, + { + id: 2, + title: 'Item 2', + }, +]; + +useListNavigation({ + items, + skip: (item) => item.disabled, + anchorRef, + onAnchorKeydown: (activeItemIndex: number, event: KeyboardEvent) => { + switch (event.key) { + case 'Enter': + case ' ': { + const activeItem = items[activeItemIndex]; + if (activeItem) { + event.preventDefault(); + + console.log(`${activeItem.title} selected`); + } + + return false; + } + } + }, +}); +``` + +## Properties + +| Name | Description | Type | Default | +| :-------------- | :---------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------: | :-----: | +| items | List items. Item can be any object. Also, it can contain `items` property, which represents sub-items | `ItemType[]` | | +| skip | Returns true if the item should not participate in navigation (Called for each item) | `(item: ItemType) => boolean` | | +| pageSize | Items page size, if passed, then navigates by pageSize on PageDown/PageUp | `number` | | +| processHomeKey | Navigate to the start of the list on Home key | `boolean` | `false` | +| processEndKey | Navigate to the end of the list on End key | `boolean` | `false` | +| disabled | Disable navigation | `boolean` | `false` | +| initialValue | Initial active item index | `number` | `-1` | +| anchorRef | HTMLElement reference, the hook will listen keydown event on that element | `RefObject` | | +| onAnchorKeyDown | Custom keydown handler, if returns false, then the hook won't process keydown | `(activeItemIndex: number, event: KeyboardEvent) => boolean or void` | | + +## Result + +| Name | Description | Type | +| :----------------- | :----------------------- | :-----------------------: | +| activeItemIndex | Index of the active item | `number` | +| setActiveItemIndex | Active item index setter | `(index: number) => void` | +| reset | Resets navigation | `() => void` | diff --git a/src/hooks/useListNavigation/index.ts b/src/hooks/useListNavigation/index.ts new file mode 100644 index 0000000000..0a4ea4bd91 --- /dev/null +++ b/src/hooks/useListNavigation/index.ts @@ -0,0 +1,2 @@ +export {useListNavigation} from './useListNavigation'; +export type {UseListNavigationProps, UseListNavigationResult} from './useListNavigation'; diff --git a/src/components/utils/useListNavigation/moveBack.ts b/src/hooks/useListNavigation/moveBack.ts similarity index 100% rename from src/components/utils/useListNavigation/moveBack.ts rename to src/hooks/useListNavigation/moveBack.ts diff --git a/src/components/utils/useListNavigation/moveForward.ts b/src/hooks/useListNavigation/moveForward.ts similarity index 100% rename from src/components/utils/useListNavigation/moveForward.ts rename to src/hooks/useListNavigation/moveForward.ts diff --git a/src/components/utils/useListNavigation/useListNavigation.ts b/src/hooks/useListNavigation/useListNavigation.ts similarity index 94% rename from src/components/utils/useListNavigation/useListNavigation.ts rename to src/hooks/useListNavigation/useListNavigation.ts index aa2e8fc7e6..0ea55519e3 100644 --- a/src/components/utils/useListNavigation/useListNavigation.ts +++ b/src/hooks/useListNavigation/useListNavigation.ts @@ -15,6 +15,12 @@ export type UseListNavigationProps = { onAnchorKeyDown?: (activeItemIndex: number, event: KeyboardEvent) => void | boolean; }; +export type UseListNavigationResult = { + activeItemIndex: number; + setActiveItemIndex: React.Dispatch>; + reset: () => void; +}; + export function useListNavigation({ items, skip, @@ -25,7 +31,7 @@ export function useListNavigation({ disabled = false, initialValue = -1, onAnchorKeyDown, -}: UseListNavigationProps) { +}: UseListNavigationProps): UseListNavigationResult { const [activeItemIndex, setActiveItemIndex] = React.useState(initialValue); const reset = React.useCallback(() => { diff --git a/src/hooks/useSelect/README.md b/src/hooks/useSelect/README.md new file mode 100644 index 0000000000..759109be9c --- /dev/null +++ b/src/hooks/useSelect/README.md @@ -0,0 +1,35 @@ + + +# useSelect + + + +```tsx +import {useSelect} from '@gravity-ui/uikit'; +``` + +The `useSelect` hook used to handle items selection in list + +## Properties + +| Name | Description | Type | Default | +| :----------- | :-------------------------------------------------------- | :--------: | :-----: | +| value | Values that represent selected items | `string[]` | | +| defaultValue | Default values used in case of uncontrolled usage | `string[]` | `[]` | +| multiple | Indicates that multiple items can be selected in the list | `boolean` | `false` | +| onUpdate | Invokes inside of `handleSelection` function | `function` | | +| defaultOpen | Initial value for `open` property | `boolean` | `false` | +| open | Controlled `open` property | `boolean` | | +| onOpenChange | Invokes while `open` property changes | `function` | | + +## Result + +| Name | Description | Type | +| :-------------- | :---------------------------------------------------------- | :--------: | +| value | Values that represent selected items | `string[]` | +| handleSelection | Handles item selection | `function` | +| open | List container visibility state | `boolean` | +| setOpen | (deprecated) use toggleOpen. Sets value for `open` property | `function` | +| toggleOpen | Inver the value of `open` | `function` | +| activeIndex | Index of active option | `number` | +| setActiveIndex | Sets value for `activeIndex` property | `function` | diff --git a/src/components/utils/useSelect/__tests__/useOpenState.test.tsx b/src/hooks/useSelect/__tests__/useOpenState.test.tsx similarity index 100% rename from src/components/utils/useSelect/__tests__/useOpenState.test.tsx rename to src/hooks/useSelect/__tests__/useOpenState.test.tsx diff --git a/src/components/utils/useSelect/index.ts b/src/hooks/useSelect/index.ts similarity index 100% rename from src/components/utils/useSelect/index.ts rename to src/hooks/useSelect/index.ts diff --git a/src/hooks/useSelect/types.ts b/src/hooks/useSelect/types.ts new file mode 100644 index 0000000000..aec84bce5e --- /dev/null +++ b/src/hooks/useSelect/types.ts @@ -0,0 +1,29 @@ +export type UseSelectOption = T & {value: string}; + +export type UseOpenProps = { + defaultOpen?: boolean; + open?: boolean; + onClose?: () => void; + onOpenChange?: (open: boolean) => void; +}; + +export type UseSelectProps = { + value?: string[]; + defaultValue?: string[]; + multiple?: boolean; + onUpdate?: (value: string[]) => void; +} & UseOpenProps; + +export type UseSelectResult = { + open: boolean; + value: string[]; + activeIndex: number | undefined; + handleSelection: (option: UseSelectOption) => void; + handleClearValue: () => void; + /** + * @deprecated use toggleOpen + */ + setOpen: (val?: boolean | undefined) => void; + toggleOpen: (val?: boolean | undefined) => void; + setActiveIndex: React.Dispatch>; +}; diff --git a/src/components/utils/useSelect/useOpenState.ts b/src/hooks/useSelect/useOpenState.ts similarity index 100% rename from src/components/utils/useSelect/useOpenState.ts rename to src/hooks/useSelect/useOpenState.ts diff --git a/src/components/utils/useSelect/useSelect.ts b/src/hooks/useSelect/useSelect.ts similarity index 95% rename from src/components/utils/useSelect/useSelect.ts rename to src/hooks/useSelect/useSelect.ts index ba9a20dd2b..a8db79e2af 100644 --- a/src/components/utils/useSelect/useSelect.ts +++ b/src/hooks/useSelect/useSelect.ts @@ -1,9 +1,9 @@ import React from 'react'; -import type {UseSelectOption, UseSelectProps} from './types'; +import type {UseSelectOption, UseSelectProps, UseSelectResult} from './types'; import {useOpenState} from './useOpenState'; -export const useSelect = (props: UseSelectProps) => { +export const useSelect = (props: UseSelectProps): UseSelectResult => { const {value: valueProps, defaultValue = [], multiple, onUpdate} = props; const [innerValue, setInnerValue] = React.useState(defaultValue); const [activeIndex, setActiveIndex] = React.useState(); diff --git a/src/hooks/useTimeout/README.md b/src/hooks/useTimeout/README.md new file mode 100644 index 0000000000..75592780a4 --- /dev/null +++ b/src/hooks/useTimeout/README.md @@ -0,0 +1,18 @@ + + +# useTimeout + + + +```tsx +import {useTimeout} from '@gravity-ui/uikit'; +``` + +The `useTimeout` hook executes callback after timeout + +## Properties + +| Name | Description | Type | Default | +| :------- | :-------------------------------------- | :------------: | :-----: | +| callback | Callback function after timeout expires | `VoidFunction` | | +| ms | Duration of the timeout in milliseconds | `number` | | diff --git a/src/hooks/useTimeout/index.ts b/src/hooks/useTimeout/index.ts new file mode 100644 index 0000000000..3b7f11c7cd --- /dev/null +++ b/src/hooks/useTimeout/index.ts @@ -0,0 +1,2 @@ +export {useTimeout} from './useTimeout'; +export type {UseTimeoutProps} from './useTimeout'; diff --git a/src/components/utils/useTimeout.ts b/src/hooks/useTimeout/useTimeout.ts similarity index 77% rename from src/components/utils/useTimeout.ts rename to src/hooks/useTimeout/useTimeout.ts index d435cf4dde..da60d62d64 100644 --- a/src/components/utils/useTimeout.ts +++ b/src/hooks/useTimeout/useTimeout.ts @@ -1,5 +1,9 @@ import React from 'react'; +export type UseTimeoutProps = Parameters< + (callback: VoidFunction, ms: number | null | undefined) => void +>; + export function useTimeout(callback: VoidFunction, ms: number | null | undefined): void { React.useEffect(() => { if (typeof ms !== 'number') { diff --git a/src/hooks/useViewportSize/README.md b/src/hooks/useViewportSize/README.md new file mode 100644 index 0000000000..df19338c38 --- /dev/null +++ b/src/hooks/useViewportSize/README.md @@ -0,0 +1,18 @@ + + +# useViewportSize + + + +```tsx +import {useViewportSize} from '@gravity-ui/uikit'; +``` + +The `useViewportSize` hook calculates the size of the viewport at the resize event + +## Result + +| Name | Description | Type | +| :----- | :-------------- | :------: | +| width | Viewport width | `number` | +| height | Viewport height | `number` | diff --git a/src/components/utils/useViewportSize/__tests__/useViewportSize.test.tsx b/src/hooks/useViewportSize/__tests__/useViewportSize.test.tsx similarity index 100% rename from src/components/utils/useViewportSize/__tests__/useViewportSize.test.tsx rename to src/hooks/useViewportSize/__tests__/useViewportSize.test.tsx diff --git a/src/hooks/useViewportSize/index.ts b/src/hooks/useViewportSize/index.ts new file mode 100644 index 0000000000..2bf8bd74a0 --- /dev/null +++ b/src/hooks/useViewportSize/index.ts @@ -0,0 +1,2 @@ +export {useViewportSize} from './useViewportSize'; +export type {UseViewportSizeResult} from './useViewportSize'; diff --git a/src/components/utils/useViewportSize/useViewportSize.tsx b/src/hooks/useViewportSize/useViewportSize.tsx similarity index 77% rename from src/components/utils/useViewportSize/useViewportSize.tsx rename to src/hooks/useViewportSize/useViewportSize.tsx index f481c32b11..193976358a 100644 --- a/src/components/utils/useViewportSize/useViewportSize.tsx +++ b/src/hooks/useViewportSize/useViewportSize.tsx @@ -1,11 +1,11 @@ import React from 'react'; -export interface ViewportSize { +export interface UseViewportSizeResult { width?: number; height?: number; } -const getViewportSize = (): ViewportSize => ({ +const getViewportSize = (): UseViewportSizeResult => ({ width: window?.visualViewport?.width ?? window?.innerWidth ?? undefined, height: window?.visualViewport?.height ?? window?.innerHeight ?? undefined, }); @@ -15,8 +15,8 @@ const getViewportSize = (): ViewportSize => ({ * * @return - {width, height} */ -export const useViewportSize = (): ViewportSize => { - const [size, setSize] = React.useState(getViewportSize()); +export const useViewportSize = (): UseViewportSizeResult => { + const [size, setSize] = React.useState(getViewportSize()); React.useEffect(() => { const onResize = () => {