Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactor hooks : moved few hooks in right folder #1049

Merged
merged 5 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/components/DropdownMenu/DropdownMenuPopup.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
2 changes: 1 addition & 1 deletion src/components/List/ListLoadingIndicator.tsx
Original file line number Diff line number Diff line change
@@ -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}) => {
Expand Down
3 changes: 1 addition & 2 deletions src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
Original file line number Diff line number Diff line change
@@ -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}) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Select/types.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
2 changes: 0 additions & 2 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
3 changes: 2 additions & 1 deletion src/components/utils/useCloseOnTimeout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {useTimeout} from '../../hooks';

import {useHover} from './useHover';
import {useTimeout} from './useTimeout';

interface UseCloseOnTimeoutProps {
onClose: VoidFunction;
Expand Down
77 changes: 0 additions & 77 deletions src/components/utils/useListNavigation/README.md

This file was deleted.

1 change: 0 additions & 1 deletion src/components/utils/useListNavigation/index.ts

This file was deleted.

27 changes: 0 additions & 27 deletions src/components/utils/useSelect/README.md

This file was deleted.

15 changes: 0 additions & 15 deletions src/components/utils/useSelect/types.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/components/utils/useViewportSize/index.ts

This file was deleted.

5 changes: 5 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
19 changes: 19 additions & 0 deletions src/hooks/useIntersection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!--GITHUB_BLOCK-->

# useIntersection

<!--/GITHUB_BLOCK-->

```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` | |
2 changes: 2 additions & 0 deletions src/hooks/useIntersection/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {useIntersection} from './useIntersection';
export type {UseIntersection, UseIntersectionProps} from './useIntersection';
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
85 changes: 85 additions & 0 deletions src/hooks/useListNavigation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!--GITHUB_BLOCK-->

# useListNavigation

<!--/GITHUB_BLOCK-->

```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
amje marked this conversation as resolved.
Show resolved Hide resolved

```tsx
const anchorRef = useRef<HTMLButtonElement>(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<AnchorType>` | |
| 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` |
2 changes: 2 additions & 0 deletions src/hooks/useListNavigation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {useListNavigation} from './useListNavigation';
export type {UseListNavigationProps, UseListNavigationResult} from './useListNavigation';
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ export type UseListNavigationProps<ItemType, AnchorType> = {
onAnchorKeyDown?: (activeItemIndex: number, event: KeyboardEvent) => void | boolean;
};

export type UseListNavigationResult = {
activeItemIndex: number;
setActiveItemIndex: React.Dispatch<React.SetStateAction<number>>;
reset: () => void;
};

export function useListNavigation<ItemType, AnchorType extends HTMLElement>({
items,
skip,
Expand All @@ -25,7 +31,7 @@ export function useListNavigation<ItemType, AnchorType extends HTMLElement>({
disabled = false,
initialValue = -1,
onAnchorKeyDown,
}: UseListNavigationProps<ItemType, AnchorType>) {
}: UseListNavigationProps<ItemType, AnchorType>): UseListNavigationResult {
const [activeItemIndex, setActiveItemIndex] = React.useState<number>(initialValue);

const reset = React.useCallback(() => {
Expand Down
Loading
Loading