@snack-uikit/list 0.1.1-preview-57c837e3.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 0.1.2 (2024-01-31)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **FF-4198:** reset active focus index when clicking the item with mouse ([638e6f0](https://github.com/cloud-ru-tech/snack-uikit/commit/638e6f0069ec7f444b39d62d91d6e845e13aee9f))
12
+
13
+
14
+
15
+
16
+
17
+ ## 0.1.1 (2024-01-30)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **FF-4075:** add public scope ([57c837e](https://github.com/cloud-ru-tech/snack-uikit/commit/57c837e3bff8fbabf1962ec56c76bc76e0b45e5e))
23
+
24
+
25
+
26
+
27
+
6
28
  # 0.1.0 (2024-01-30)
7
29
 
8
30
 
package/README.md CHANGED
@@ -20,52 +20,53 @@
20
20
  ### Props
21
21
  | name | type | default value | description |
22
22
  |------|------|---------------|-------------|
23
- | items* | `ItemProps[]` | - | |
24
- | triggerElemRef | `RefObject<HTMLElement>` | - | |
25
- | open | `boolean` | - | |
26
- | onOpenChange | `(open: boolean) => void` | - | |
27
- | trigger | enum Trigger: `"click"`, `"hover"`, `"focusVisible"`, `"focus"`, `"hoverAndFocusVisible"`, `"hoverAndFocus"`, `"clickAndFocusVisible"` | - | |
28
- | placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | |
29
- | widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | - | |
30
- | pinTop | `ItemProps[]` | - | |
31
- | pinBottom | `ItemProps[]` | - | |
32
- | footer | `ReactNode` | - | |
33
- | search | `SearchState` | - | |
34
- | loading | `boolean` | - | |
35
- | noData | `string` | - | |
36
- | noResults | `string` | - | |
37
- | footerActiveElementsRefs | `RefObject<HTMLElement>[]` | - | |
23
+ | items* | `ItemProps[]` | - | Основные элементы списка |
24
+ | triggerElemRef | `RefObject<HTMLElement>` | - | Ссылка на элемент-триггер для дроплиста |
25
+ | children | `ReactNode` | - | Триггер для дроплиста |
26
+ | open | `boolean` | - | Управляет состоянием показан/не показан. |
27
+ | onOpenChange | `(isOpen: boolean) => void` | - | Колбек отображения компонента. Срабатывает при изменении состояния open. |
28
+ | widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | auto | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
29
+ | trigger | enum Trigger: `"click"`, `"hover"`, `"focusVisible"`, `"focus"`, `"hoverAndFocusVisible"`, `"hoverAndFocus"`, `"clickAndFocusVisible"` | - | Условие отображения поповера: <br> - `click` - открывать по клику <br> - `hover` - открывать по ховеру <br> - `focusVisible` - открывать по focus-visible <br> - `focus` - открывать по фокусу <br> - `hoverAndFocusVisible` - открывать по ховеру и focus-visible <br> - `hoverAndFocus` - открывать по ховеру и фокусу <br> - `clickAndFocusVisible` - открывать по клику и focus-visible |
30
+ | placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Положение поповера относительно своего триггера (children). |
31
+ | pinTop | `ItemProps[]` | - | Элементы списка, закрепленные сверху |
32
+ | pinBottom | `ItemProps[]` | - | Элементы списка, закрепленные снизу |
33
+ | footer | `ReactNode` | - | Кастомизируемый элемент, помещаемый внизу списка |
34
+ | footerActiveElementsRefs | `RefObject<HTMLElement>[]` | - | Список ссылок на костомные элементы, помещенные в специальную секцию внизу списка |
35
+ | search | `SearchState` | - | Настройки поисковой строки |
36
+ | loading | `boolean` | - | Флаг, отвещающий за состояние загрузки списка |
37
+ | noData | `string` | - | Текст для состояния "Отсутсвие данных" |
38
+ | noResults | `string` | - | Текст для состояния "Отсутсвие результата" при поиске |
38
39
  | value | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Controlled состояние |
39
40
  | defaultValue | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Начальное состояние |
40
41
  | onChange | `((value: any) => void) \| ((value: any) => void)` | - | Controlled обработчик измения состояния |
41
42
  | selection | "single" \| "multiple" | - | Режим выбора |
42
- | size | "s" \| "m" \| "l" | - | |
43
- | marker | `boolean` | - | |
44
- | scroll | `boolean` | - | |
45
- | scrollRef | `RefObject<HTMLElement>` | - | |
46
- | scrollContainerRef | `RefObject<HTMLElement>` | - | |
43
+ | size | "s" \| "m" \| "l" | - | Размер списка |
44
+ | marker | `boolean` | - | Отображать ли маркер у выбранного жлемента списка |
45
+ | scroll | `boolean` | - | Включить ли скролл для основной части списка |
46
+ | scrollRef | `RefObject<HTMLElement>` | - | Ссылка на элемент, обозначающий самый конец прокручиваемого списка |
47
+ | scrollContainerRef | `RefObject<HTMLElement>` | - | Ссылка на контейнер, который скроллится |
47
48
  ## List
48
49
  ### Props
49
50
  | name | type | default value | description |
50
51
  |------|------|---------------|-------------|
51
- | items* | `ItemProps[]` | - | |
52
- | pinTop | `ItemProps[]` | - | |
53
- | pinBottom | `ItemProps[]` | - | |
54
- | footer | `ReactNode` | - | |
55
- | search | `SearchState` | - | |
56
- | loading | `boolean` | - | |
57
- | noData | `string` | - | |
58
- | noResults | `string` | - | |
59
- | footerActiveElementsRefs | `RefObject<HTMLElement>[]` | - | |
52
+ | items* | `ItemProps[]` | - | Основные элементы списка |
53
+ | pinTop | `ItemProps[]` | - | Элементы списка, закрепленные сверху |
54
+ | pinBottom | `ItemProps[]` | - | Элементы списка, закрепленные снизу |
55
+ | footer | `ReactNode` | - | Кастомизируемый элемент, помещаемый внизу списка |
56
+ | footerActiveElementsRefs | `RefObject<HTMLElement>[]` | - | Список ссылок на костомные элементы, помещенные в специальную секцию внизу списка |
57
+ | search | `SearchState` | - | Настройки поисковой строки |
58
+ | loading | `boolean` | - | Флаг, отвещающий за состояние загрузки списка |
59
+ | noData | `string` | - | Текст для состояния "Отсутсвие данных" |
60
+ | noResults | `string` | - | Текст для состояния "Отсутсвие результата" при поиске |
60
61
  | value | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Controlled состояние |
61
62
  | defaultValue | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Начальное состояние |
62
63
  | onChange | `((value: any) => void) \| ((value: any) => void)` | - | Controlled обработчик измения состояния |
63
64
  | selection | "single" \| "multiple" | - | Режим выбора |
64
- | size | "s" \| "m" \| "l" | - | |
65
- | marker | `boolean` | - | |
66
- | scroll | `boolean` | - | |
67
- | scrollRef | `RefObject<HTMLElement>` | - | |
68
- | scrollContainerRef | `RefObject<HTMLElement>` | - | |
65
+ | size | "s" \| "m" \| "l" | - | Размер списка |
66
+ | marker | `boolean` | - | Отображать ли маркер у выбранного жлемента списка |
67
+ | scroll | `boolean` | - | Включить ли скролл для основной части списка |
68
+ | scrollRef | `RefObject<HTMLElement>` | - | Ссылка на элемент, обозначающий самый конец прокручиваемого списка |
69
+ | scrollContainerRef | `RefObject<HTMLElement>` | - | Ссылка на контейнер, который скроллится |
69
70
  | ref | `Ref<HTMLElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom |
70
71
  | key | `Key` | - | |
71
72
 
@@ -14,13 +14,14 @@ import cn from 'classnames';
14
14
  import { Checkbox, Switch } from '@snack-uikit/toggles';
15
15
  import { TruncateString } from '@snack-uikit/truncate-string';
16
16
  import { extractSupportProps } from '@snack-uikit/utils';
17
- import { useCollapseContext, useListContext, useSelectionContext } from '../../Lists/contexts';
17
+ import { useCollapseContext, useListContext, useParentListContext, useSelectionContext } from '../../Lists/contexts';
18
18
  import commonStyles from '../styles.module.css';
19
19
  import { CHECKBOX_SIZE_MAP } from './constants';
20
20
  import styles from './styles.module.css';
21
21
  export function BaseItem(_a) {
22
22
  var { beforeContent, afterContent, content, onClick, id, expandIcon, disabled, open, itemRef, switch: switchProp, onKeyDown, onFocus, indeterminate, onSelect, isParentNode } = _a, rest = __rest(_a, ["beforeContent", "afterContent", "content", "onClick", "id", "expandIcon", "disabled", "open", "itemRef", "switch", "onKeyDown", "onFocus", "indeterminate", "onSelect", "isParentNode"]);
23
23
  const { option, caption, description } = content || {};
24
+ const { parentResetActiveFocusIndex } = useParentListContext();
24
25
  const { size, marker } = useListContext();
25
26
  const { level = 0 } = useCollapseContext();
26
27
  const { value, onChange, selection, isSelectionSingle, isSelectionMultiple } = useSelectionContext();
@@ -29,6 +30,7 @@ export function BaseItem(_a) {
29
30
  onChange === null || onChange === void 0 ? void 0 : onChange(id !== null && id !== void 0 ? id : '');
30
31
  };
31
32
  const handleItemClick = (e) => {
33
+ parentResetActiveFocusIndex === null || parentResetActiveFocusIndex === void 0 ? void 0 : parentResetActiveFocusIndex();
32
34
  if (!isParentNode) {
33
35
  handleChange();
34
36
  }
@@ -6,9 +6,9 @@ export declare const List: import("react").ForwardRefExoticComponent<{
6
6
  pinTop?: import("../../Items").ItemProps[] | undefined;
7
7
  pinBottom?: import("../../Items").ItemProps[] | undefined;
8
8
  footer?: import("react").ReactNode;
9
+ footerActiveElementsRefs?: import("react").RefObject<HTMLElement>[] | undefined;
9
10
  search?: import("../../../types").SearchState | undefined;
10
11
  loading?: boolean | undefined;
11
12
  noData?: string | undefined;
12
13
  noResults?: string | undefined;
13
- footerActiveElementsRefs?: import("react").RefObject<HTMLElement>[] | undefined;
14
14
  } & Pick<import("../contexts").SelectionProviderProps, "value" | "defaultValue" | "selection" | "onChange"> & import("../contexts").ListContextType & import("../../../types").ScrollProps & import("react").RefAttributes<HTMLElement>>;
@@ -6,11 +6,11 @@ export declare const ListPrivate: import("react").ForwardRefExoticComponent<{
6
6
  pinTop?: import("../../Items").ItemProps[] | undefined;
7
7
  pinBottom?: import("../../Items").ItemProps[] | undefined;
8
8
  footer?: import("react").ReactNode;
9
+ footerActiveElementsRefs?: RefObject<HTMLElement>[] | undefined;
9
10
  search?: import("../../../types").SearchState | undefined;
10
11
  loading?: boolean | undefined;
11
12
  noData?: string | undefined;
12
13
  noResults?: string | undefined;
13
- footerActiveElementsRefs?: RefObject<HTMLElement>[] | undefined;
14
14
  } & Pick<import("../contexts").SelectionProviderProps, "value" | "defaultValue" | "selection" | "onChange"> & import("../contexts").ListContextType & import("../../../types").ScrollProps & {
15
15
  nested?: boolean | undefined;
16
16
  active?: boolean | undefined;
@@ -1,6 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  export type ListContextType = {
3
+ /** Размер списка */
3
4
  size?: 's' | 'm' | 'l';
5
+ /** Отображать ли маркер у выбранного жлемента списка */
4
6
  marker?: boolean;
5
7
  };
6
8
  type Child = {
@@ -5,25 +5,31 @@ import { ScrollProps, SearchState } from '../../types';
5
5
  import { ItemProps } from '../Items';
6
6
  import { ListContextType, SelectionProviderProps } from './contexts';
7
7
  export type ListProps = WithSupportProps<{
8
+ /** Основные элементы списка */
8
9
  items: ItemProps[];
10
+ /** Элементы списка, закрепленные сверху */
9
11
  pinTop?: ItemProps[];
12
+ /** Элементы списка, закрепленные снизу */
10
13
  pinBottom?: ItemProps[];
14
+ /** Кастомизируемый элемент, помещаемый внизу списка */
11
15
  footer?: ReactNode;
16
+ /** Список ссылок на костомные элементы, помещенные в специальную секцию внизу списка */
17
+ footerActiveElementsRefs?: RefObject<HTMLElement>[];
18
+ /** Настройки поисковой строки */
12
19
  search?: SearchState;
20
+ /** Флаг, отвещающий за состояние загрузки списка */
13
21
  loading?: boolean;
22
+ /** Текст для состояния "Отсутсвие данных" */
14
23
  noData?: string;
24
+ /** Текст для состояния "Отсутсвие результата" при поиске */
15
25
  noResults?: string;
16
- footerActiveElementsRefs?: RefObject<HTMLElement>[];
17
26
  } & Pick<SelectionProviderProps, 'value' | 'defaultValue' | 'onChange' | 'selection'> & ListContextType & ScrollProps>;
18
27
  export type DroplistProps = {
28
+ /** Ссылка на элемент-триггер для дроплиста */
19
29
  triggerElemRef?: RefObject<HTMLElement>;
30
+ /** Триггер для дроплиста */
20
31
  children?: ReactNode;
21
- open?: boolean;
22
- onOpenChange?(open: boolean): void;
23
- trigger?: DropdownProps['trigger'];
24
- placement?: DropdownProps['placement'];
25
- widthStrategy?: DropdownProps['widthStrategy'];
26
- } & ListProps;
32
+ } & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange'> & ListProps;
27
33
  export type ListPrivateProps = ListProps & {
28
34
  nested?: boolean;
29
35
  active?: boolean;
package/dist/types.d.ts CHANGED
@@ -6,7 +6,10 @@ export type SearchState = {
6
6
  loading?: boolean;
7
7
  };
8
8
  export type ScrollProps = {
9
+ /** Включить ли скролл для основной части списка */
9
10
  scroll?: boolean;
11
+ /** Ссылка на элемент, обозначающий самый конец прокручиваемого списка */
10
12
  scrollRef?: RefObject<HTMLElement>;
13
+ /** Ссылка на контейнер, который скроллится */
11
14
  scrollContainerRef?: RefObject<HTMLElement>;
12
15
  };
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "List",
7
- "version": "0.1.1-preview-57c837e3.0",
7
+ "version": "0.1.2",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -44,5 +44,5 @@
44
44
  "classnames": "2.5.1",
45
45
  "uncontrollable": "8.0.4"
46
46
  },
47
- "gitHead": "0539acbacf5bc065cdb55739e06f63366ac9178b"
47
+ "gitHead": "029bc819dd13f9006b9ad584fb56454517a2077d"
48
48
  }
@@ -5,7 +5,7 @@ import { Checkbox, Switch } from '@snack-uikit/toggles';
5
5
  import { TruncateString } from '@snack-uikit/truncate-string';
6
6
  import { extractSupportProps } from '@snack-uikit/utils';
7
7
 
8
- import { useCollapseContext, useListContext, useSelectionContext } from '../../Lists/contexts';
8
+ import { useCollapseContext, useListContext, useParentListContext, useSelectionContext } from '../../Lists/contexts';
9
9
  import commonStyles from '../styles.module.scss';
10
10
  import { BaseItemPrivateProps, BaseItemProps, SwitchProps } from '../types';
11
11
  import { CHECKBOX_SIZE_MAP } from './constants';
@@ -35,6 +35,7 @@ export function BaseItem({
35
35
  }: AllBaseItemProps) {
36
36
  const { option, caption, description } = content || {};
37
37
 
38
+ const { parentResetActiveFocusIndex } = useParentListContext();
38
39
  const { size, marker } = useListContext();
39
40
  const { level = 0 } = useCollapseContext();
40
41
  const { value, onChange, selection, isSelectionSingle, isSelectionMultiple } = useSelectionContext();
@@ -46,6 +47,8 @@ export function BaseItem({
46
47
  };
47
48
 
48
49
  const handleItemClick = (e: MouseEvent<HTMLButtonElement>) => {
50
+ parentResetActiveFocusIndex?.();
51
+
49
52
  if (!isParentNode) {
50
53
  handleChange();
51
54
  }
@@ -1,9 +1,11 @@
1
1
  import { createContext, ReactNode, useContext } from 'react';
2
2
 
3
3
  export type ListContextType = {
4
+ /** Размер списка */
4
5
  size?: 's' | 'm' | 'l';
5
6
  // TODO
6
7
  // collapse?: 'single' | 'multiple';
8
+ /** Отображать ли маркер у выбранного жлемента списка */
7
9
  marker?: boolean;
8
10
  };
9
11
 
@@ -9,31 +9,38 @@ import { ListContextType, SelectionProviderProps } from './contexts';
9
9
 
10
10
  export type ListProps = WithSupportProps<
11
11
  {
12
+ /** Основные элементы списка */
12
13
  items: ItemProps[];
14
+ /** Элементы списка, закрепленные сверху */
13
15
  pinTop?: ItemProps[];
16
+ /** Элементы списка, закрепленные снизу */
14
17
  pinBottom?: ItemProps[];
18
+ /** Кастомизируемый элемент, помещаемый внизу списка */
15
19
  footer?: ReactNode;
20
+ /** Список ссылок на костомные элементы, помещенные в специальную секцию внизу списка */
21
+ footerActiveElementsRefs?: RefObject<HTMLElement>[];
16
22
  // TODO: add later
17
23
  // collapse?: 'single' | 'multiple';
24
+ /** Настройки поисковой строки */
18
25
  search?: SearchState;
26
+ /** Флаг, отвещающий за состояние загрузки списка */
19
27
  loading?: boolean;
28
+ /** Текст для состояния "Отсутсвие данных" */
20
29
  noData?: string;
30
+ /** Текст для состояния "Отсутсвие результата" при поиске */
21
31
  noResults?: string;
22
- footerActiveElementsRefs?: RefObject<HTMLElement>[];
23
32
  } & Pick<SelectionProviderProps, 'value' | 'defaultValue' | 'onChange' | 'selection'> &
24
33
  ListContextType &
25
34
  ScrollProps
26
35
  >;
27
36
 
28
37
  export type DroplistProps = {
38
+ /** Ссылка на элемент-триггер для дроплиста */
29
39
  triggerElemRef?: RefObject<HTMLElement>;
40
+ /** Триггер для дроплиста */
30
41
  children?: ReactNode;
31
- open?: boolean;
32
- onOpenChange?(open: boolean): void;
33
- trigger?: DropdownProps['trigger'];
34
- placement?: DropdownProps['placement'];
35
- widthStrategy?: DropdownProps['widthStrategy'];
36
- } & ListProps;
42
+ } & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange'> &
43
+ ListProps;
37
44
 
38
45
  export type ListPrivateProps = ListProps & {
39
46
  nested?: boolean;
package/src/types.ts CHANGED
@@ -8,7 +8,10 @@ export type SearchState = {
8
8
  };
9
9
 
10
10
  export type ScrollProps = {
11
+ /** Включить ли скролл для основной части списка */
11
12
  scroll?: boolean;
13
+ /** Ссылка на элемент, обозначающий самый конец прокручиваемого списка */
12
14
  scrollRef?: RefObject<HTMLElement>;
15
+ /** Ссылка на контейнер, который скроллится */
13
16
  scrollContainerRef?: RefObject<HTMLElement>;
14
17
  };