@snack-uikit/list 0.10.0 → 0.10.1-preview-69abc1d3.0

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.
Files changed (127) hide show
  1. package/README.md +56 -24
  2. package/dist/components/Items/AccordionItem/AccordionItem.d.ts +4 -2
  3. package/dist/components/Items/AccordionItem/AccordionItem.js +18 -16
  4. package/dist/components/Items/BaseItem/BaseItem.d.ts +8 -4
  5. package/dist/components/Items/BaseItem/BaseItem.js +20 -14
  6. package/dist/components/Items/BaseItem/styles.module.css +9 -122
  7. package/dist/components/Items/GroupItem/GroupItem.d.ts +5 -1
  8. package/dist/components/Items/GroupItem/GroupItem.js +1 -3
  9. package/dist/components/Items/GroupSelectItem/GroupSelectItem.d.ts +4 -0
  10. package/dist/components/Items/GroupSelectItem/GroupSelectItem.js +18 -0
  11. package/dist/components/Items/GroupSelectItem/index.d.ts +1 -0
  12. package/dist/components/Items/GroupSelectItem/index.js +1 -0
  13. package/dist/components/Items/NextListItem/NextListItem.d.ts +6 -2
  14. package/dist/components/Items/NextListItem/NextListItem.js +53 -45
  15. package/dist/components/Items/NextListItem/constants.d.ts +2 -0
  16. package/dist/components/Items/NextListItem/constants.js +10 -0
  17. package/dist/components/Items/SearchItem/SearchItem.d.ts +3 -1
  18. package/dist/components/Items/SearchItem/SearchItem.js +5 -8
  19. package/dist/components/Items/hooks.d.ts +11 -10
  20. package/dist/components/Items/hooks.js +64 -46
  21. package/dist/components/Items/index.d.ts +1 -5
  22. package/dist/components/Items/index.js +1 -5
  23. package/dist/components/Items/types.d.ts +68 -34
  24. package/dist/components/Items/utils.d.ts +33 -16
  25. package/dist/components/Items/utils.js +132 -37
  26. package/dist/components/Lists/Droplist/DropList.d.ts +1 -1
  27. package/dist/components/Lists/Droplist/DropList.js +73 -50
  28. package/dist/components/Lists/List/List.d.ts +5 -9
  29. package/dist/components/Lists/List/List.js +56 -54
  30. package/dist/components/Lists/ListPrivate/ListPrivate.d.ts +6 -20
  31. package/dist/components/Lists/ListPrivate/ListPrivate.js +9 -8
  32. package/dist/components/Lists/ListPrivate/styles.module.css +1 -0
  33. package/dist/components/Lists/contexts/CollapseProvider.d.ts +13 -1
  34. package/dist/components/Lists/contexts/CollapseProvider.js +2 -0
  35. package/dist/components/Lists/contexts/FocusListProvider.d.ts +9 -0
  36. package/dist/components/Lists/contexts/FocusListProvider.js +5 -0
  37. package/dist/components/Lists/contexts/NewListProvider.d.ts +32 -0
  38. package/dist/components/Lists/contexts/{ListProvider.js → NewListProvider.js} +10 -5
  39. package/dist/components/Lists/contexts/SelectionProvider.d.ts +25 -15
  40. package/dist/components/Lists/contexts/SelectionProvider.js +17 -13
  41. package/dist/components/Lists/contexts/index.d.ts +2 -2
  42. package/dist/components/Lists/contexts/index.js +2 -2
  43. package/dist/components/Lists/hooks.d.ts +10 -12
  44. package/dist/components/Lists/hooks.js +73 -40
  45. package/dist/components/Lists/types.d.ts +12 -14
  46. package/dist/components/index.d.ts +2 -2
  47. package/dist/components/index.js +1 -1
  48. package/dist/helperComponents/ItemContent/ItemContent.d.ts +15 -0
  49. package/dist/helperComponents/ItemContent/ItemContent.js +23 -0
  50. package/dist/helperComponents/ItemContent/index.d.ts +1 -0
  51. package/dist/helperComponents/ItemContent/index.js +1 -0
  52. package/dist/helperComponents/ItemContent/styles.module.css +117 -0
  53. package/dist/helperComponents/ListEmptyState/ListEmptyState.d.ts +2 -2
  54. package/dist/helperComponents/ListEmptyState/ListEmptyState.js +13 -4
  55. package/dist/helperComponents/Separator/Separator.d.ts +8 -2
  56. package/dist/helperComponents/Separator/Separator.js +22 -2
  57. package/dist/helperComponents/Separator/constants.d.ts +2 -0
  58. package/dist/helperComponents/Separator/constants.js +5 -0
  59. package/dist/helperComponents/Separator/styles.module.css +20 -1
  60. package/dist/helperComponents/index.d.ts +1 -0
  61. package/dist/helperComponents/index.js +1 -0
  62. package/dist/hooks.d.ts +1 -1
  63. package/dist/hooks.js +15 -10
  64. package/dist/index.d.ts +3 -2
  65. package/dist/index.js +3 -2
  66. package/dist/legacy/components/Items/hooks.d.ts +12 -0
  67. package/dist/legacy/components/Items/hooks.js +33 -0
  68. package/dist/legacy/components/index.d.ts +1 -0
  69. package/dist/legacy/components/index.js +1 -0
  70. package/dist/legacy/hooks.d.ts +5 -0
  71. package/dist/legacy/hooks.js +15 -0
  72. package/dist/legacy/index.d.ts +3 -0
  73. package/dist/legacy/index.js +3 -0
  74. package/dist/{utils.d.ts → legacy/utils.d.ts} +2 -3
  75. package/dist/{utils.js → legacy/utils.js} +4 -12
  76. package/dist/types.d.ts +1 -1
  77. package/package.json +14 -14
  78. package/src/components/Items/AccordionItem/AccordionItem.tsx +24 -20
  79. package/src/components/Items/BaseItem/BaseItem.tsx +48 -43
  80. package/src/components/Items/BaseItem/styles.module.scss +8 -70
  81. package/src/components/Items/GroupItem/GroupItem.tsx +5 -5
  82. package/src/components/Items/GroupSelectItem/GroupSelectItem.tsx +44 -0
  83. package/src/components/Items/GroupSelectItem/index.ts +1 -0
  84. package/src/components/Items/NextListItem/NextListItem.tsx +86 -85
  85. package/src/components/Items/NextListItem/constants.ts +12 -0
  86. package/src/components/Items/SearchItem/SearchItem.tsx +6 -8
  87. package/src/components/Items/hooks.tsx +86 -66
  88. package/src/components/Items/index.ts +1 -5
  89. package/src/components/Items/types.ts +91 -42
  90. package/src/components/Items/utils.ts +193 -52
  91. package/src/components/Lists/Droplist/DropList.tsx +151 -98
  92. package/src/components/Lists/List/List.tsx +124 -104
  93. package/src/components/Lists/ListPrivate/ListPrivate.tsx +19 -20
  94. package/src/components/Lists/ListPrivate/styles.module.scss +1 -0
  95. package/src/components/Lists/contexts/CollapseProvider.tsx +22 -0
  96. package/src/components/Lists/contexts/FocusListProvider.tsx +16 -0
  97. package/src/components/Lists/contexts/NewListProvider.tsx +54 -0
  98. package/src/components/Lists/contexts/SelectionProvider.tsx +56 -39
  99. package/src/components/Lists/contexts/index.ts +3 -2
  100. package/src/components/Lists/hooks.ts +124 -75
  101. package/src/components/Lists/types.ts +20 -24
  102. package/src/components/index.ts +16 -2
  103. package/src/helperComponents/ItemContent/ItemContent.tsx +63 -0
  104. package/src/helperComponents/ItemContent/index.ts +1 -0
  105. package/src/helperComponents/ItemContent/styles.module.scss +78 -0
  106. package/src/helperComponents/ListEmptyState/ListEmptyState.tsx +26 -12
  107. package/src/helperComponents/Separator/Separator.tsx +49 -3
  108. package/src/helperComponents/Separator/constants.ts +7 -0
  109. package/src/helperComponents/Separator/styles.module.scss +41 -1
  110. package/src/helperComponents/index.ts +1 -0
  111. package/src/hooks.ts +21 -15
  112. package/src/index.ts +5 -2
  113. package/src/legacy/components/Items/hooks.tsx +53 -0
  114. package/src/legacy/components/index.ts +1 -0
  115. package/src/legacy/hooks.ts +27 -0
  116. package/src/legacy/index.ts +3 -0
  117. package/src/{utils.ts → legacy/utils.ts} +4 -13
  118. package/src/types.ts +1 -1
  119. package/dist/components/Items/NextListItem/hooks.d.ts +0 -19
  120. package/dist/components/Items/NextListItem/hooks.js +0 -80
  121. package/dist/components/Lists/contexts/ListProvider.d.ts +0 -17
  122. package/dist/components/Lists/contexts/ParentListProvider.d.ts +0 -18
  123. package/dist/components/Lists/contexts/ParentListProvider.js +0 -12
  124. package/src/components/Items/NextListItem/hooks.ts +0 -105
  125. package/src/components/Lists/contexts/CollapseProvider.ts +0 -9
  126. package/src/components/Lists/contexts/ListProvider.tsx +0 -28
  127. package/src/components/Lists/contexts/ParentListProvider.tsx +0 -35
@@ -0,0 +1,9 @@
1
+ import { KeyboardEvent } from 'react';
2
+ import { ItemId } from '../../Items';
3
+ export type FocusListContextType = {
4
+ activeItemId?: ItemId;
5
+ forceUpdateActiveItemId?(itemId: ItemId): void;
6
+ handleListKeyDownFactory: (ids: ItemId[], expandedIds: ItemId[]) => (e: KeyboardEvent<HTMLElement>) => void;
7
+ };
8
+ export declare const FocusListContext: import("react").Context<FocusListContextType>;
9
+ export declare const useFocusListContext: () => FocusListContextType;
@@ -0,0 +1,5 @@
1
+ import { createContext, useContext } from 'react';
2
+ export const FocusListContext = createContext({
3
+ handleListKeyDownFactory: () => () => { },
4
+ });
5
+ export const useFocusListContext = () => useContext(FocusListContext);
@@ -0,0 +1,32 @@
1
+ import { ReactNode } from 'react';
2
+ import { ItemContentProps } from '../../../helperComponents';
3
+ import { FlattenItem, FocusFlattenItem, ItemId } from '../../Items';
4
+ type ContentRenderProps = {
5
+ id?: ItemId;
6
+ content?: ItemContentProps | ReactNode;
7
+ };
8
+ export type PublicListContextType = {
9
+ /** Размер списка */
10
+ size?: 's' | 'm' | 'l';
11
+ /** Отображать ли маркер у выбранного жлемента списка */
12
+ marker?: boolean;
13
+ /**
14
+ * Рендер функция основного контента айтема
15
+ */
16
+ contentRender?(props: ContentRenderProps): ReactNode;
17
+ };
18
+ export type PrivateListContextType = {
19
+ flattenItems: Record<string, FlattenItem>;
20
+ focusFlattenItems: Record<string, FocusFlattenItem>;
21
+ };
22
+ type Child = {
23
+ children: ReactNode;
24
+ };
25
+ type ListContextType = PublicListContextType & PrivateListContextType;
26
+ export declare const ListContext: import("react").Context<{
27
+ flattenItems: {};
28
+ focusFlattenItems: {};
29
+ }>;
30
+ export declare function useNewListContext(): ListContextType;
31
+ export declare function NewListContextProvider({ children, ...props }: ListContextType & Child): import("react/jsx-runtime").JSX.Element;
32
+ export {};
@@ -11,12 +11,17 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { createContext, useContext } from 'react';
14
- export const ListContext = createContext({});
15
- export const useListContext = () => useContext(ListContext);
16
- function extractListProps({ size, marker, parent }) {
17
- return { size, marker, parent };
14
+ export const ListContext = createContext({
15
+ flattenItems: {},
16
+ focusFlattenItems: {},
17
+ });
18
+ export function useNewListContext() {
19
+ return useContext(ListContext);
18
20
  }
19
- export function ListContextProvider(_a) {
21
+ function extractListProps({ size, marker, flattenItems, focusFlattenItems, contentRender, }) {
22
+ return { size, marker, parent, contentRender, flattenItems, focusFlattenItems };
23
+ }
24
+ export function NewListContextProvider(_a) {
20
25
  var { children } = _a, props = __rest(_a, ["children"]);
21
26
  return _jsx(ListContext.Provider, { value: extractListProps(props), children: children });
22
27
  }
@@ -1,17 +1,19 @@
1
1
  import { ReactNode } from 'react';
2
- export type SelectionSingleValueType = string | number | undefined;
2
+ import { AnyType, ItemId } from '../../Items';
3
+ export type OnChangeHandler<T = AnyType> = (value: T) => void;
4
+ export type SelectionSingleValueType = ItemId;
3
5
  export type SelectionSingleState = {
4
6
  /** Начальное состояние */
5
- defaultValue?: SelectionSingleValueType;
7
+ defaultValue?: ItemId;
6
8
  /** Controlled состояние */
7
- value?: SelectionSingleValueType;
9
+ value?: ItemId;
8
10
  /** Controlled обработчик измения состояния */
9
- onChange?(value: any): void;
11
+ onChange?: OnChangeHandler;
10
12
  /** Режим выбора */
11
13
  mode: 'single';
12
14
  };
13
15
  export type SelectionSingleProps = {
14
- setValue?(value: any): void;
16
+ setValue?(value: AnyType): void;
15
17
  /** Режим выбора single */
16
18
  isSelectionSingle: true;
17
19
  /** Режим выбора multi */
@@ -19,23 +21,23 @@ export type SelectionSingleProps = {
19
21
  } & SelectionSingleState;
20
22
  export type SelectionMultipleState = {
21
23
  /** Начальное состояние */
22
- defaultValue?: SelectionSingleValueType[];
24
+ defaultValue?: ItemId[];
23
25
  /** Controlled состояние */
24
- value?: SelectionSingleValueType[];
26
+ value?: ItemId[];
25
27
  /** Controlled обработчик измения состояния */
26
- onChange?(value: any): void;
28
+ onChange?: OnChangeHandler;
27
29
  /** Режим выбора */
28
30
  mode: 'multiple';
29
31
  };
30
32
  export type SelectionMultipleProps = {
31
- setValue?(value: any): void;
33
+ setValue?(value: AnyType): void;
32
34
  /** Режим выбора single */
33
35
  isSelectionSingle: false;
34
36
  /** Режим выбора multi */
35
37
  isSelectionMultiple: true;
36
38
  } & SelectionMultipleState;
37
39
  type SelectionNoneProps = {
38
- mode?: undefined;
40
+ mode?: 'none';
39
41
  value?: undefined;
40
42
  onChange?: undefined;
41
43
  setValue?: undefined;
@@ -43,18 +45,26 @@ type SelectionNoneProps = {
43
45
  isSelectionSingle?: undefined;
44
46
  isSelectionMultiple?: undefined;
45
47
  };
46
- type SelectionProviderProps = SelectionSingleProps | SelectionMultipleProps | SelectionNoneProps;
47
48
  type SelectionContextType = Omit<SelectionNoneProps, 'defaultValue'> | Omit<SelectionSingleProps, 'defaultValue'> | Omit<SelectionMultipleProps, 'defaultValue'>;
48
49
  export type SelectionState = {
49
50
  selection?: SelectionSingleState | SelectionMultipleState;
50
51
  };
51
52
  export declare const SelectionContext: import("react").Context<SelectionContextType>;
52
- export declare function isSelectionMultipleProps(props: any): props is SelectionMultipleProps;
53
- export declare function isSelectionSingleProps(props: any): props is SelectionSingleProps;
53
+ export declare function isSelectionMultipleProps(props: AnyType): props is SelectionMultipleProps;
54
+ export declare function isSelectionSingleProps(props: AnyType): props is SelectionSingleProps;
54
55
  type Child = {
55
56
  children: ReactNode;
56
57
  };
58
+ type SelectionProviderProps = {
59
+ /** Начальное состояние */
60
+ defaultValue?: AnyType;
61
+ /** Controlled состояние */
62
+ value?: AnyType;
63
+ /** Controlled обработчик измения состояния */
64
+ onChange?: OnChangeHandler;
65
+ /** Режим выбора */
66
+ mode?: 'multiple' | 'single' | 'none';
67
+ };
57
68
  export declare function SelectionProvider({ children, ...props }: SelectionProviderProps & Child): import("react/jsx-runtime").JSX.Element;
58
- export declare const useSelectionContext: () => SelectionContextType;
59
- export declare function extractSelectionProps<T extends SelectionState>({ selection }: T): SelectionProviderProps;
69
+ export declare function useSelectionContext(): SelectionContextType;
60
70
  export {};
@@ -11,24 +11,28 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { createContext, useCallback, useContext } from 'react';
14
- import { useUncontrolledProp } from 'uncontrollable';
14
+ import { useValueControl } from '@snack-uikit/utils';
15
15
  export const SelectionContext = createContext({
16
16
  value: undefined,
17
17
  onChange: undefined,
18
18
  mode: undefined,
19
19
  });
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
20
  export function isSelectionMultipleProps(props) {
22
21
  return 'mode' in props && props['mode'] === 'multiple';
23
22
  }
24
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
23
  export function isSelectionSingleProps(props) {
26
24
  return 'mode' in props && props['mode'] === 'single';
27
25
  }
26
+ function SelectionNoneProvider({ children }) {
27
+ return (_jsx(SelectionContext.Provider, { value: {
28
+ mode: 'none',
29
+ }, children: children }));
30
+ }
28
31
  function SelectionSingleProvider({ value: valueProp, defaultValue, onChange: onChangeProp, children, }) {
29
- const [value, setValue] = useUncontrolledProp(valueProp, defaultValue, newValue => {
30
- const result = typeof newValue === 'function' ? newValue(value) : newValue;
31
- onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(result);
32
+ const [value, setValue] = useValueControl({
33
+ value: valueProp,
34
+ defaultValue,
35
+ onChange: onChangeProp,
32
36
  });
33
37
  const onChange = useCallback((newValue) => setValue((oldValue) => {
34
38
  if (newValue !== oldValue) {
@@ -46,9 +50,10 @@ function SelectionSingleProvider({ value: valueProp, defaultValue, onChange: onC
46
50
  }, children: children }));
47
51
  }
48
52
  function SelectionMultipleProvider({ value: valueProp, defaultValue, onChange: onChangeProp, children, }) {
49
- const [value, setValue] = useUncontrolledProp(valueProp, defaultValue, newValue => {
50
- const result = typeof newValue === 'function' ? newValue(value) : newValue;
51
- onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(result);
53
+ const [value, setValue] = useValueControl({
54
+ value: valueProp,
55
+ defaultValue,
56
+ onChange: onChangeProp,
52
57
  });
53
58
  const onChange = useCallback((newValue) => {
54
59
  setValue((oldValues) => {
@@ -81,9 +86,8 @@ export function SelectionProvider(_a) {
81
86
  if (isSelectionMultipleProps(props)) {
82
87
  return _jsx(SelectionMultipleProvider, Object.assign({}, props, { children: children }));
83
88
  }
84
- return _jsx(SelectionContext.Provider, { value: {}, children: children });
89
+ return _jsx(SelectionNoneProvider, { children: children });
85
90
  }
86
- export const useSelectionContext = () => useContext(SelectionContext);
87
- export function extractSelectionProps({ selection }) {
88
- return Object.assign({}, (selection !== null && selection !== void 0 ? selection : {}));
91
+ export function useSelectionContext() {
92
+ return useContext(SelectionContext);
89
93
  }
@@ -1,4 +1,4 @@
1
- export * from './ListProvider';
2
1
  export * from './SelectionProvider';
3
- export * from './ParentListProvider';
4
2
  export * from './CollapseProvider';
3
+ export * from './NewListProvider';
4
+ export { useFocusListContext, FocusListContext } from './FocusListProvider';
@@ -1,4 +1,4 @@
1
- export * from './ListProvider';
2
1
  export * from './SelectionProvider';
3
- export * from './ParentListProvider';
4
2
  export * from './CollapseProvider';
3
+ export * from './NewListProvider';
4
+ export { useFocusListContext, FocusListContext } from './FocusListProvider';
@@ -1,16 +1,14 @@
1
1
  import { KeyboardEvent, RefObject } from 'react';
2
- export type UseKeyboardNavigationProps<T extends HTMLElement> = {
3
- ids: Array<number | string>;
4
- expandedIds: Array<number | string>;
5
- parentRef?: RefObject<T>;
2
+ import { FocusFlattenItem, ItemId } from '../Items';
3
+ type UseNewKeyboardNavigationProps<T extends HTMLElement> = {
4
+ mainRef?: RefObject<T>;
6
5
  btnRef?: RefObject<HTMLButtonElement>;
7
- itemRefs?: RefObject<HTMLElement>[];
6
+ focusFlattenItems: Record<string, FocusFlattenItem>;
8
7
  };
9
- export declare function useKeyboardNavigation<T extends HTMLElement>({ ids, itemRefs, expandedIds, parentRef, btnRef, }: UseKeyboardNavigationProps<T>): {
10
- activeFocusIndex: number;
11
- setActiveFocusIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
12
- openNestedIndex: number;
13
- resetNestedIndex: () => void;
14
- resetActiveFocusIndex: () => void;
15
- handleListKeyDown: (e: KeyboardEvent<T>) => void;
8
+ export declare function useNewKeyboardNavigation<T extends HTMLElement>({ mainRef, btnRef, focusFlattenItems, }: UseNewKeyboardNavigationProps<T>): {
9
+ resetActiveItemId: () => void;
10
+ activeItemId: ItemId | undefined;
11
+ forceUpdateActiveItemId: (itemId: ItemId) => void;
12
+ handleListKeyDownFactory: (ids: ItemId[], expandedIds: ItemId[]) => (e: KeyboardEvent<T>) => void;
16
13
  };
14
+ export {};
@@ -1,73 +1,106 @@
1
- import { useEffect, useState } from 'react';
2
- export function useKeyboardNavigation({ ids, itemRefs, expandedIds, parentRef, btnRef, }) {
3
- const [activeFocusIndex, setActiveFocusIndex] = useState(-1);
4
- const [openNestedIndex, setOpenNestedIndex] = useState(-1);
5
- const handleListKeyDown = (e) => {
6
- var _a, _b, _c, _d;
1
+ import { useCallback, useRef, useState } from 'react';
2
+ export function useNewKeyboardNavigation({ mainRef, btnRef, focusFlattenItems, }) {
3
+ const [activeItemId, setActiveItemId] = useState();
4
+ const activeItemIdRef = useRef();
5
+ const handleListKeyDownFactory = useCallback((ids, expandedIds) => (e) => {
6
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
7
7
  switch (e.key) {
8
8
  case 'ArrowDown': {
9
- setActiveFocusIndex(activeIndex => Math.min(activeIndex + 1, ids.length - 1));
10
- // TODO: go to loader from last item
11
- // if (activeFocusIndex === ids.length - 2) {
12
- // return;
13
- // }
9
+ if (activeItemIdRef.current !== undefined) {
10
+ const activeIndex = ids.findIndex(id => id === activeItemIdRef.current);
11
+ const nextId = Math.min(activeIndex + 1, ids.length - 1);
12
+ const itemId = ids[nextId];
13
+ const item = focusFlattenItems[itemId];
14
+ activeItemIdRef.current = itemId;
15
+ setActiveItemId(itemId);
16
+ if (item.type !== 'group') {
17
+ (_b = (_a = item.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.focus();
18
+ }
19
+ }
20
+ else {
21
+ const itemId = ids[0];
22
+ const item = focusFlattenItems[itemId];
23
+ activeItemIdRef.current = itemId;
24
+ setActiveItemId(itemId);
25
+ if (item.type !== 'group') {
26
+ (_d = (_c = item.itemRef) === null || _c === void 0 ? void 0 : _c.current) === null || _d === void 0 ? void 0 : _d.focus();
27
+ }
28
+ }
14
29
  e.stopPropagation();
15
30
  e.preventDefault();
16
31
  return;
17
32
  }
18
33
  case 'ArrowUp': {
19
- if (activeFocusIndex === 0) {
20
- (_a = parentRef === null || parentRef === void 0 ? void 0 : parentRef.current) === null || _a === void 0 ? void 0 : _a.focus();
21
- setActiveFocusIndex(-1);
34
+ if (ids[0] === activeItemIdRef.current) {
35
+ const item = focusFlattenItems[ids[0]];
36
+ if (item.parentId === '~main') {
37
+ activeItemIdRef.current = undefined;
38
+ setActiveItemId(undefined);
39
+ (_e = mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) === null || _e === void 0 ? void 0 : _e.focus();
40
+ }
22
41
  return;
23
42
  }
24
- setActiveFocusIndex(activeIndex => Math.max(activeIndex - 1, 0));
43
+ if (activeItemIdRef.current !== undefined) {
44
+ const activeIndex = ids.findIndex(id => id === activeItemIdRef.current);
45
+ const nextId = Math.max(activeIndex - 1, 0);
46
+ const itemId = ids[nextId];
47
+ const item = focusFlattenItems[itemId];
48
+ activeItemIdRef.current = itemId;
49
+ setActiveItemId(itemId);
50
+ if (item.type !== 'group') {
51
+ (_g = (_f = item.itemRef) === null || _f === void 0 ? void 0 : _f.current) === null || _g === void 0 ? void 0 : _g.focus();
52
+ }
53
+ }
25
54
  e.stopPropagation();
26
55
  e.preventDefault();
27
56
  return;
28
57
  }
29
58
  case 'ArrowRight': {
30
- if (expandedIds.includes(ids[activeFocusIndex])) {
31
- setOpenNestedIndex(activeFocusIndex);
59
+ if (activeItemIdRef.current !== undefined && expandedIds.includes(activeItemIdRef.current)) {
60
+ const item = focusFlattenItems[activeItemIdRef.current];
61
+ const newItemId = item.items[0];
62
+ const newItem = focusFlattenItems[newItemId];
63
+ activeItemIdRef.current = newItemId;
64
+ setActiveItemId(newItemId);
65
+ setTimeout(() => { var _a, _b; return (_b = (_a = newItem.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.focus(); }, 0);
32
66
  }
33
67
  e.stopPropagation();
34
68
  e.preventDefault();
35
69
  return;
36
70
  }
37
71
  case 'Tab': {
38
- if (parentRef && activeFocusIndex !== -1) {
72
+ if (activeItemIdRef.current !== undefined) {
39
73
  e.preventDefault();
40
- (_b = parentRef === null || parentRef === void 0 ? void 0 : parentRef.current) === null || _b === void 0 ? void 0 : _b.focus();
74
+ e.stopPropagation();
75
+ activeItemIdRef.current = undefined;
76
+ setActiveItemId(undefined);
77
+ (_h = mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) === null || _h === void 0 ? void 0 : _h.focus();
41
78
  }
42
- else if (activeFocusIndex === -1) {
43
- btnRef && !e.shiftKey ? (_c = btnRef === null || btnRef === void 0 ? void 0 : btnRef.current) === null || _c === void 0 ? void 0 : _c.focus() : (_d = parentRef === null || parentRef === void 0 ? void 0 : parentRef.current) === null || _d === void 0 ? void 0 : _d.focus();
79
+ else {
80
+ btnRef && !e.shiftKey ? (_j = btnRef === null || btnRef === void 0 ? void 0 : btnRef.current) === null || _j === void 0 ? void 0 : _j.focus() : (_k = mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) === null || _k === void 0 ? void 0 : _k.focus();
44
81
  }
45
- setOpenNestedIndex(-1);
46
- setActiveFocusIndex(-1);
47
82
  return;
48
83
  }
49
84
  default: {
50
85
  return;
51
86
  }
52
87
  }
53
- };
54
- const resetNestedIndex = () => {
55
- setActiveFocusIndex(openNestedIndex);
56
- setOpenNestedIndex(-1);
57
- };
58
- const resetActiveFocusIndex = () => {
59
- setActiveFocusIndex(-1);
60
- };
61
- useEffect(() => {
88
+ }, [focusFlattenItems, mainRef, btnRef]);
89
+ const resetActiveItemId = useCallback(() => {
90
+ setActiveItemId(undefined);
91
+ activeItemIdRef.current = undefined;
92
+ }, []);
93
+ const forceUpdateActiveItemId = useCallback((itemId) => {
62
94
  var _a, _b;
63
- activeFocusIndex !== -1 && openNestedIndex === -1 && ((_b = (_a = itemRefs === null || itemRefs === void 0 ? void 0 : itemRefs[activeFocusIndex]) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.focus());
64
- }, [activeFocusIndex, itemRefs, openNestedIndex]);
95
+ setActiveItemId(itemId);
96
+ activeItemIdRef.current = itemId;
97
+ const item = focusFlattenItems[itemId];
98
+ (_b = (_a = item === null || item === void 0 ? void 0 : item.itemRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.focus();
99
+ }, [focusFlattenItems]);
65
100
  return {
66
- activeFocusIndex,
67
- setActiveFocusIndex,
68
- openNestedIndex,
69
- resetNestedIndex,
70
- resetActiveFocusIndex,
71
- handleListKeyDown,
101
+ resetActiveItemId,
102
+ activeItemId,
103
+ forceUpdateActiveItemId,
104
+ handleListKeyDownFactory,
72
105
  };
73
106
  }
@@ -3,13 +3,8 @@ import { DropdownProps } from '@snack-uikit/dropdown';
3
3
  import { WithSupportProps } from '@snack-uikit/utils';
4
4
  import { EmptyStateProps } from '../../helperComponents';
5
5
  import { ScrollProps, SearchState } from '../../types';
6
- import { ItemProps } from '../Items';
7
- import { ListContextPrivateType, ListContextType, SelectionState } from './contexts';
8
- type CollapseState = {
9
- value?: (string | number)[];
10
- onChange?(value: (string | number)[]): void;
11
- defaultValue?: (string | number)[];
12
- };
6
+ import { FlattenBaseItem, Item, ItemId } from '../Items';
7
+ import { CollapseState, PublicListContextType, SelectionState } from './contexts';
13
8
  export type EmptyState = {
14
9
  dataFiltered?: boolean;
15
10
  dataError?: boolean;
@@ -22,11 +17,11 @@ export type EmptyState = {
22
17
  };
23
18
  export type ListProps = WithSupportProps<{
24
19
  /** Основные элементы списка */
25
- items: ItemProps[];
20
+ items: Item[];
26
21
  /** Элементы списка, закрепленные сверху */
27
- pinTop?: ItemProps[];
22
+ pinTop?: Item[];
28
23
  /** Элементы списка, закрепленные снизу */
29
- pinBottom?: ItemProps[];
24
+ pinBottom?: Item[];
30
25
  /**
31
26
  * Кастомизируемый элемент в конце списка
32
27
  * @type ReactNode;
@@ -45,7 +40,7 @@ export type ListProps = WithSupportProps<{
45
40
  onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
46
41
  /** Флаг, отвещающий за состояние загрузки списка */
47
42
  loading?: boolean;
48
- } & SelectionState & ListContextType & ScrollProps & EmptyState>;
43
+ } & SelectionState & PublicListContextType & ScrollProps & EmptyState>;
49
44
  export type DroplistProps = {
50
45
  /** Ссылка на элемент-триггер для дроплиста */
51
46
  triggerElemRef?: RefObject<HTMLElement>;
@@ -57,8 +52,8 @@ export type DroplistProps = {
57
52
  children: ReactNode | ((params: {
58
53
  onKeyDown?: (e: KeyboardEvent<HTMLElement>) => void;
59
54
  }) => ReactNode);
60
- } & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange'> & Omit<ListProps, 'tabIndex' | 'onKeyDown'>;
61
- export type ListPrivateProps = ListProps & ListContextPrivateType & {
55
+ } & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange' | 'triggerClassName'> & Omit<ListProps, 'tabIndex' | 'onKeyDown'>;
56
+ export type ListPrivateProps = Omit<ListProps, 'pinTop' | 'pinBottom' | 'items'> & {
62
57
  nested?: boolean;
63
58
  active?: boolean;
64
59
  tabIndex?: number;
@@ -66,5 +61,8 @@ export type ListPrivateProps = ListProps & ListContextPrivateType & {
66
61
  onBlur?(e: FocusEvent<HTMLElement>): void;
67
62
  onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
68
63
  limitedScrollHeight?: boolean;
64
+ searchItem?: FlattenBaseItem;
65
+ pinTop?: ItemId[];
66
+ items: ItemId[];
67
+ pinBottom?: ItemId[];
69
68
  };
70
- export {};
@@ -1,4 +1,4 @@
1
1
  export * from './Lists';
2
- export type { AccordionItemProps, NextListItemProps, BaseItemProps, GroupItemProps, ItemProps } from './Items';
3
- export { isAccordionItemProps, isBaseItemProps, isGroupItemProps, isNextListItemProps } from './Items';
2
+ export type { AccordionItemProps, NextListItemProps, BaseItemProps, GroupItemProps, ItemProps, GroupSelectItemProps, } from './Items';
3
+ export { isAccordionItemProps, isBaseItemProps, isGroupItemProps, isNextListItemProps, isGroupSelectItem, } from './Items';
4
4
  export { useGroupItemSelection } from './Items/hooks';
@@ -1,3 +1,3 @@
1
1
  export * from './Lists';
2
- export { isAccordionItemProps, isBaseItemProps, isGroupItemProps, isNextListItemProps } from './Items';
2
+ export { isAccordionItemProps, isBaseItemProps, isGroupItemProps, isNextListItemProps, isGroupSelectItem, } from './Items';
3
3
  export { useGroupItemSelection } from './Items/hooks';
@@ -0,0 +1,15 @@
1
+ import { TruncateStringProps } from '@snack-uikit/truncate-string';
2
+ import { WithSupportProps } from '@snack-uikit/utils';
3
+ export type ItemContentProps = WithSupportProps<{
4
+ option: string | number;
5
+ caption?: string;
6
+ description?: string;
7
+ truncate?: {
8
+ option?: number;
9
+ description?: number;
10
+ variant?: TruncateStringProps['variant'];
11
+ };
12
+ disabled?: boolean;
13
+ className?: string;
14
+ }>;
15
+ export declare function ItemContent({ truncate, caption, description, option, className, disabled, ...rest }: ItemContentProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import cn from 'classnames';
14
+ import { TruncateString } from '@snack-uikit/truncate-string';
15
+ import { extractSupportProps } from '@snack-uikit/utils';
16
+ import { useNewListContext } from '../../components/Lists/contexts';
17
+ import styles from './styles.module.css';
18
+ export function ItemContent(_a) {
19
+ var _b, _c;
20
+ var { truncate, caption, description, option, className, disabled } = _a, rest = __rest(_a, ["truncate", "caption", "description", "option", "className", "disabled"]);
21
+ const { size = 's' } = useNewListContext();
22
+ return (_jsxs("div", Object.assign({ className: cn(styles.content, className) }, extractSupportProps(rest), { "data-size": size !== null && size !== void 0 ? size : 's', "data-disabled": disabled || undefined, children: [_jsxs("div", { className: styles.headline, children: [_jsx("span", { className: styles.label, children: _jsx(TruncateString, { variant: truncate === null || truncate === void 0 ? void 0 : truncate.variant, text: String(option), maxLines: (_b = truncate === null || truncate === void 0 ? void 0 : truncate.option) !== null && _b !== void 0 ? _b : 1, "data-test-id": 'list__base-item-option' }) }), caption && _jsx("span", { className: styles.caption, children: caption })] }), description && (_jsx("div", { className: styles.description, children: _jsx(TruncateString, { text: description, maxLines: (_c = truncate === null || truncate === void 0 ? void 0 : truncate.description) !== null && _c !== void 0 ? _c : 2, "data-test-id": 'list__base-item-description' }) }))] })));
23
+ }
@@ -0,0 +1 @@
1
+ export * from './ItemContent';
@@ -0,0 +1 @@
1
+ export * from './ItemContent';