@snack-uikit/list 0.9.2-preview-c8f85f20.0 → 0.9.2-preview-0a44b2fc.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 (105) hide show
  1. package/README.md +51 -23
  2. package/dist/components/Items/AccordionItem/AccordionItem.d.ts +2 -2
  3. package/dist/components/Items/AccordionItem/AccordionItem.js +19 -16
  4. package/dist/components/Items/BaseItem/BaseItem.d.ts +5 -4
  5. package/dist/components/Items/BaseItem/BaseItem.js +22 -16
  6. package/dist/components/Items/BaseItem/styles.module.css +9 -122
  7. package/dist/components/Items/GroupItem/GroupItem.d.ts +2 -2
  8. package/dist/components/Items/GroupItem/GroupItem.js +3 -3
  9. package/dist/components/Items/NextListItem/NextListItem.d.ts +2 -2
  10. package/dist/components/Items/NextListItem/NextListItem.js +37 -36
  11. package/dist/components/Items/SearchItem/SearchItem.d.ts +3 -1
  12. package/dist/components/Items/SearchItem/SearchItem.js +7 -8
  13. package/dist/components/Items/hooks.d.ts +14 -9
  14. package/dist/components/Items/hooks.js +46 -30
  15. package/dist/components/Items/types.d.ts +41 -26
  16. package/dist/components/Items/utils.d.ts +7 -17
  17. package/dist/components/Items/utils.js +3 -31
  18. package/dist/components/Lists/Droplist/DropList.d.ts +2 -1
  19. package/dist/components/Lists/Droplist/DropList.js +85 -50
  20. package/dist/components/Lists/List/List.d.ts +7 -11
  21. package/dist/components/Lists/List/List.js +61 -53
  22. package/dist/components/Lists/ListPrivate/ListPrivate.d.ts +18 -20
  23. package/dist/components/Lists/ListPrivate/ListPrivate.js +10 -9
  24. package/dist/components/Lists/contexts/CollapseProvider.d.ts +13 -1
  25. package/dist/components/Lists/contexts/CollapseProvider.js +2 -0
  26. package/dist/components/Lists/contexts/FocusListProvider.d.ts +9 -0
  27. package/dist/components/Lists/contexts/FocusListProvider.js +5 -0
  28. package/dist/components/Lists/contexts/NewListProvider.d.ts +27 -0
  29. package/dist/components/Lists/contexts/{ListProvider.js → NewListProvider.js} +10 -5
  30. package/dist/components/Lists/contexts/SelectionProvider.d.ts +28 -15
  31. package/dist/components/Lists/contexts/SelectionProvider.js +14 -8
  32. package/dist/components/Lists/contexts/index.d.ts +2 -2
  33. package/dist/components/Lists/contexts/index.js +2 -2
  34. package/dist/components/Lists/hooks.d.ts +11 -11
  35. package/dist/components/Lists/hooks.js +80 -41
  36. package/dist/components/Lists/types.d.ts +19 -15
  37. package/dist/helperComponents/ItemContent/ItemContent.d.ts +15 -0
  38. package/dist/helperComponents/ItemContent/ItemContent.js +23 -0
  39. package/dist/helperComponents/ItemContent/index.d.ts +1 -0
  40. package/dist/helperComponents/ItemContent/index.js +1 -0
  41. package/dist/helperComponents/ItemContent/styles.module.css +117 -0
  42. package/dist/helperComponents/ListEmptyState/ListEmptyState.d.ts +2 -2
  43. package/dist/helperComponents/ListEmptyState/ListEmptyState.js +13 -4
  44. package/dist/helperComponents/index.d.ts +1 -0
  45. package/dist/helperComponents/index.js +1 -0
  46. package/dist/hooks.d.ts +1 -1
  47. package/dist/hooks.js +15 -10
  48. package/dist/index.d.ts +3 -2
  49. package/dist/index.js +3 -2
  50. package/dist/legacy/components/Items/hooks.d.ts +12 -0
  51. package/dist/legacy/components/Items/hooks.js +33 -0
  52. package/dist/legacy/components/index.d.ts +1 -0
  53. package/dist/legacy/components/index.js +1 -0
  54. package/dist/legacy/hooks.d.ts +5 -0
  55. package/dist/legacy/hooks.js +15 -0
  56. package/dist/legacy/index.d.ts +3 -0
  57. package/dist/legacy/index.js +3 -0
  58. package/dist/legacy/utils.d.ts +29 -0
  59. package/dist/legacy/utils.js +107 -0
  60. package/dist/types.d.ts +1 -1
  61. package/dist/utils.d.ts +27 -25
  62. package/dist/utils.js +74 -103
  63. package/package.json +12 -12
  64. package/src/components/Items/AccordionItem/AccordionItem.tsx +26 -19
  65. package/src/components/Items/BaseItem/BaseItem.tsx +48 -46
  66. package/src/components/Items/BaseItem/styles.module.scss +8 -70
  67. package/src/components/Items/GroupItem/GroupItem.tsx +6 -5
  68. package/src/components/Items/NextListItem/NextListItem.tsx +67 -78
  69. package/src/components/Items/SearchItem/SearchItem.tsx +8 -8
  70. package/src/components/Items/hooks.tsx +76 -54
  71. package/src/components/Items/types.ts +61 -31
  72. package/src/components/Items/utils.ts +9 -58
  73. package/src/components/Lists/Droplist/DropList.tsx +155 -102
  74. package/src/components/Lists/List/List.tsx +120 -105
  75. package/src/components/Lists/ListPrivate/ListPrivate.tsx +26 -27
  76. package/src/components/Lists/contexts/CollapseProvider.tsx +22 -0
  77. package/src/components/Lists/contexts/FocusListProvider.tsx +16 -0
  78. package/src/components/Lists/contexts/NewListProvider.tsx +49 -0
  79. package/src/components/Lists/contexts/SelectionProvider.tsx +63 -36
  80. package/src/components/Lists/contexts/index.ts +3 -2
  81. package/src/components/Lists/hooks.ts +139 -75
  82. package/src/components/Lists/types.ts +29 -27
  83. package/src/helperComponents/ItemContent/ItemContent.tsx +63 -0
  84. package/src/helperComponents/ItemContent/index.ts +1 -0
  85. package/src/helperComponents/ItemContent/styles.module.scss +78 -0
  86. package/src/helperComponents/ListEmptyState/ListEmptyState.tsx +21 -13
  87. package/src/helperComponents/index.ts +1 -0
  88. package/src/hooks.ts +21 -15
  89. package/src/index.ts +9 -2
  90. package/src/legacy/components/Items/hooks.tsx +53 -0
  91. package/src/legacy/components/index.ts +1 -0
  92. package/src/legacy/hooks.ts +27 -0
  93. package/src/legacy/index.ts +3 -0
  94. package/src/legacy/utils.ts +166 -0
  95. package/src/types.ts +1 -1
  96. package/src/utils.ts +153 -139
  97. package/dist/components/Items/NextListItem/hooks.d.ts +0 -19
  98. package/dist/components/Items/NextListItem/hooks.js +0 -80
  99. package/dist/components/Lists/contexts/ListProvider.d.ts +0 -17
  100. package/dist/components/Lists/contexts/ParentListProvider.d.ts +0 -18
  101. package/dist/components/Lists/contexts/ParentListProvider.js +0 -12
  102. package/src/components/Items/NextListItem/hooks.ts +0 -105
  103. package/src/components/Lists/contexts/CollapseProvider.ts +0 -9
  104. package/src/components/Lists/contexts/ListProvider.tsx +0 -28
  105. package/src/components/Lists/contexts/ParentListProvider.tsx +0 -35
@@ -1,73 +1,112 @@
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
+ import { isBaseItemProps, isGroupItemProps, } from '../Items';
3
+ export function useNewKeyboardNavigation({ mainRef, btnRef, flattenedItems, }) {
4
+ const [activeItemId, setActiveItemId] = useState();
5
+ const activeItemIdRef = useRef();
6
+ const handleListKeyDownFactory = useCallback((ids, expandedIds) => (e) => {
7
+ var _a, _b, _c, _d, _e, _f, _g;
7
8
  switch (e.key) {
8
9
  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
- // }
10
+ if (activeItemIdRef.current !== undefined) {
11
+ const activeIndex = ids.findIndex(id => id === activeItemIdRef.current);
12
+ const nextId = Math.min(activeIndex + 1, ids.length - 1);
13
+ const itemId = ids[nextId];
14
+ const item = flattenedItems[itemId];
15
+ activeItemIdRef.current = itemId;
16
+ setActiveItemId(itemId);
17
+ if (!isGroupItemProps(item)) {
18
+ (_a = item.itemRef.current) === null || _a === void 0 ? void 0 : _a.focus();
19
+ }
20
+ }
21
+ else {
22
+ const itemId = ids[0];
23
+ const item = flattenedItems[itemId];
24
+ activeItemIdRef.current = itemId;
25
+ setActiveItemId(itemId);
26
+ if (!isGroupItemProps(item)) {
27
+ (_b = item.itemRef.current) === null || _b === void 0 ? void 0 : _b.focus();
28
+ }
29
+ }
14
30
  e.stopPropagation();
15
31
  e.preventDefault();
16
32
  return;
17
33
  }
18
34
  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);
35
+ if (ids[0] === activeItemIdRef.current) {
36
+ const item = flattenedItems[ids[0]];
37
+ if (item.parentId === '~main') {
38
+ activeItemIdRef.current = undefined;
39
+ setActiveItemId(undefined);
40
+ (_c = mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) === null || _c === void 0 ? void 0 : _c.focus();
41
+ }
22
42
  return;
23
43
  }
24
- setActiveFocusIndex(activeIndex => Math.max(activeIndex - 1, 0));
44
+ if (activeItemIdRef.current !== undefined) {
45
+ const activeIndex = ids.findIndex(id => id === activeItemIdRef.current);
46
+ const nextId = Math.max(activeIndex - 1, 0);
47
+ const itemId = ids[nextId];
48
+ const item = flattenedItems[itemId];
49
+ activeItemIdRef.current = itemId;
50
+ setActiveItemId(itemId);
51
+ if (!isGroupItemProps(item)) {
52
+ (_d = item.itemRef.current) === null || _d === void 0 ? void 0 : _d.focus();
53
+ }
54
+ }
25
55
  e.stopPropagation();
26
56
  e.preventDefault();
27
57
  return;
28
58
  }
29
59
  case 'ArrowRight': {
30
- if (expandedIds.includes(ids[activeFocusIndex])) {
31
- setOpenNestedIndex(activeFocusIndex);
60
+ if (activeItemIdRef.current !== undefined && expandedIds.includes(activeItemIdRef.current)) {
61
+ const item = flattenedItems[activeItemIdRef.current];
62
+ if (!isBaseItemProps(item)) {
63
+ const newItemId = item.items[0];
64
+ const newItem = flattenedItems[newItemId];
65
+ activeItemIdRef.current = newItemId;
66
+ setActiveItemId(newItemId);
67
+ if (!isGroupItemProps(newItem)) {
68
+ setTimeout(() => { var _a; return (_a = newItem.itemRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
69
+ }
70
+ }
32
71
  }
33
72
  e.stopPropagation();
34
73
  e.preventDefault();
35
74
  return;
36
75
  }
37
76
  case 'Tab': {
38
- if (parentRef && activeFocusIndex !== -1) {
77
+ if (activeItemIdRef.current !== undefined) {
39
78
  e.preventDefault();
40
- (_b = parentRef === null || parentRef === void 0 ? void 0 : parentRef.current) === null || _b === void 0 ? void 0 : _b.focus();
79
+ activeItemIdRef.current = undefined;
80
+ setActiveItemId(undefined);
81
+ (_e = mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) === null || _e === void 0 ? void 0 : _e.focus();
41
82
  }
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();
83
+ else {
84
+ btnRef && !e.shiftKey ? (_f = btnRef === null || btnRef === void 0 ? void 0 : btnRef.current) === null || _f === void 0 ? void 0 : _f.focus() : (_g = mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) === null || _g === void 0 ? void 0 : _g.focus();
44
85
  }
45
- setOpenNestedIndex(-1);
46
- setActiveFocusIndex(-1);
47
86
  return;
48
87
  }
49
88
  default: {
50
89
  return;
51
90
  }
52
91
  }
53
- };
54
- const resetNestedIndex = () => {
55
- setActiveFocusIndex(openNestedIndex);
56
- setOpenNestedIndex(-1);
57
- };
58
- const resetActiveFocusIndex = () => {
59
- setActiveFocusIndex(-1);
60
- };
61
- useEffect(() => {
62
- 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]);
92
+ }, [flattenedItems, mainRef, btnRef]);
93
+ const resetActiveItemId = useCallback(() => {
94
+ setActiveItemId(undefined);
95
+ activeItemIdRef.current = undefined;
96
+ }, []);
97
+ const forceUpdateActiveItemId = useCallback((itemId) => {
98
+ var _a;
99
+ setActiveItemId(itemId);
100
+ activeItemIdRef.current = itemId;
101
+ const newItem = flattenedItems[itemId];
102
+ if (!isGroupItemProps(newItem)) {
103
+ (_a = newItem.itemRef.current) === null || _a === void 0 ? void 0 : _a.focus();
104
+ }
105
+ }, [flattenedItems]);
65
106
  return {
66
- activeFocusIndex,
67
- setActiveFocusIndex,
68
- openNestedIndex,
69
- resetNestedIndex,
70
- resetActiveFocusIndex,
71
- handleListKeyDown,
107
+ resetActiveItemId,
108
+ activeItemId,
109
+ forceUpdateActiveItemId,
110
+ handleListKeyDownFactory,
72
111
  };
73
112
  }
@@ -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 { AnyType, FlattenBaseItem, FlattenItem, ItemId, ItemProps } from '../Items';
7
+ import { CollapseState, PublicListContextType, SelectionState } from './contexts';
13
8
  export type EmptyState = {
14
9
  dataFiltered?: boolean;
15
10
  dataError?: boolean;
@@ -20,13 +15,13 @@ export type EmptyState = {
20
15
  /** Экран при ошибке запроса */
21
16
  errorDataState?: EmptyStateProps;
22
17
  };
23
- export type ListProps = WithSupportProps<{
18
+ export type ListProps<Meta = AnyType> = WithSupportProps<{
24
19
  /** Основные элементы списка */
25
- items: ItemProps[];
20
+ items: ItemProps<Meta>[];
26
21
  /** Элементы списка, закрепленные сверху */
27
- pinTop?: ItemProps[];
22
+ pinTop?: ItemProps<Meta>[];
28
23
  /** Элементы списка, закрепленные снизу */
29
- pinBottom?: ItemProps[];
24
+ pinBottom?: ItemProps<Meta>[];
30
25
  /**
31
26
  * Кастомизируемый элемент в конце списка
32
27
  * @type ReactNode;
@@ -45,8 +40,8 @@ export type ListProps = WithSupportProps<{
45
40
  onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
46
41
  /** Флаг, отвещающий за состояние загрузки списка */
47
42
  loading?: boolean;
48
- } & SelectionState & ListContextType & ScrollProps & EmptyState>;
49
- export type DroplistProps = {
43
+ } & SelectionState & PublicListContextType<Meta> & ScrollProps & EmptyState>;
44
+ export type DroplistProps<Meta = AnyType> = {
50
45
  /** Ссылка на элемент-триггер для дроплиста */
51
46
  triggerElemRef?: RefObject<HTMLElement>;
52
47
  /** Триггер для дроплиста
@@ -57,8 +52,13 @@ 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<Meta>, 'tabIndex' | 'onKeyDown'>;
56
+ type UseRenderItemsProps<Meta = AnyType> = {
57
+ items: ItemId[];
58
+ allChildIds?: ItemId[];
59
+ flattenedItems: Record<string, FlattenItem<Meta>>;
60
+ };
61
+ export type ListPrivateProps<Meta = AnyType> = Omit<ListProps<Meta>, 'pinTop' | 'pinBottom' | 'items'> & {
62
62
  nested?: boolean;
63
63
  active?: boolean;
64
64
  tabIndex?: number;
@@ -66,5 +66,9 @@ export type ListPrivateProps = ListProps & ListContextPrivateType & {
66
66
  onBlur?(e: FocusEvent<HTMLElement>): void;
67
67
  onKeyDown?(e: KeyboardEvent<HTMLElement>): void;
68
68
  limitedScrollHeight?: boolean;
69
+ searchItem?: FlattenBaseItem<Meta>;
70
+ pinTop?: UseRenderItemsProps<Meta>;
71
+ items: UseRenderItemsProps<Meta>;
72
+ pinBottom?: UseRenderItemsProps<Meta>;
69
73
  };
70
74
  export {};
@@ -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 !== null && disabled !== void 0 ? 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';
@@ -0,0 +1,117 @@
1
+ .headline{
2
+ display:flex;
3
+ align-items:center;
4
+ }
5
+
6
+ .label{
7
+ overflow:hidden;
8
+ flex:1;
9
+ color:var(--sys-neutral-text-main, #33333b);
10
+ }
11
+
12
+ .caption{
13
+ overflow:hidden;
14
+ color:var(--sys-neutral-text-light, #868892);
15
+ text-overflow:ellipsis;
16
+ white-space:nowrap;
17
+ }
18
+
19
+ .description{
20
+ color:var(--sys-neutral-text-support, #656771);
21
+ }
22
+
23
+ .content{
24
+ overflow:hidden;
25
+ flex-grow:1;
26
+ flex-shrink:1;
27
+ box-sizing:border-box;
28
+ }
29
+ .content[data-size=s] .headline{
30
+ gap:var(--space-drop-list-item-s-container-headline-gap, 8px);
31
+ height:var(--size-drop-list-item-headline, 24px);
32
+ }
33
+ .content[data-size=s] .label{
34
+ font-family:var(--sans-body-s-font-family, SB Sans Interface);
35
+ font-weight:var(--sans-body-s-font-weight, Regular);
36
+ line-height:var(--sans-body-s-line-height, 16px);
37
+ font-size:var(--sans-body-s-font-size, 12px);
38
+ letter-spacing:var(--sans-body-s-letter-spacing, 0.1px);
39
+ paragraph-spacing:var(--sans-body-s-paragraph-spacing, 6.6px);
40
+ }
41
+ .content[data-size=s] .caption{
42
+ font-family:var(--sans-body-s-font-family, SB Sans Interface);
43
+ font-weight:var(--sans-body-s-font-weight, Regular);
44
+ line-height:var(--sans-body-s-line-height, 16px);
45
+ font-size:var(--sans-body-s-font-size, 12px);
46
+ letter-spacing:var(--sans-body-s-letter-spacing, 0.1px);
47
+ paragraph-spacing:var(--sans-body-s-paragraph-spacing, 6.6px);
48
+ }
49
+ .content[data-size=s] .description{
50
+ font-family:var(--sans-body-s-font-family, SB Sans Interface);
51
+ font-weight:var(--sans-body-s-font-weight, Regular);
52
+ line-height:var(--sans-body-s-line-height, 16px);
53
+ font-size:var(--sans-body-s-font-size, 12px);
54
+ letter-spacing:var(--sans-body-s-letter-spacing, 0.1px);
55
+ paragraph-spacing:var(--sans-body-s-paragraph-spacing, 6.6px);
56
+ }
57
+ .content[data-size=m] .headline{
58
+ gap:var(--space-drop-list-item-m-container-headline-gap, 8px);
59
+ height:var(--size-drop-list-item-headline, 24px);
60
+ }
61
+ .content[data-size=m] .label{
62
+ font-family:var(--sans-body-m-font-family, SB Sans Interface);
63
+ font-weight:var(--sans-body-m-font-weight, Regular);
64
+ line-height:var(--sans-body-m-line-height, 20px);
65
+ font-size:var(--sans-body-m-font-size, 14px);
66
+ letter-spacing:var(--sans-body-m-letter-spacing, 0.1px);
67
+ paragraph-spacing:var(--sans-body-m-paragraph-spacing, 7.7px);
68
+ }
69
+ .content[data-size=m] .caption{
70
+ font-family:var(--sans-body-s-font-family, SB Sans Interface);
71
+ font-weight:var(--sans-body-s-font-weight, Regular);
72
+ line-height:var(--sans-body-s-line-height, 16px);
73
+ font-size:var(--sans-body-s-font-size, 12px);
74
+ letter-spacing:var(--sans-body-s-letter-spacing, 0.1px);
75
+ paragraph-spacing:var(--sans-body-s-paragraph-spacing, 6.6px);
76
+ }
77
+ .content[data-size=m] .description{
78
+ font-family:var(--sans-body-s-font-family, SB Sans Interface);
79
+ font-weight:var(--sans-body-s-font-weight, Regular);
80
+ line-height:var(--sans-body-s-line-height, 16px);
81
+ font-size:var(--sans-body-s-font-size, 12px);
82
+ letter-spacing:var(--sans-body-s-letter-spacing, 0.1px);
83
+ paragraph-spacing:var(--sans-body-s-paragraph-spacing, 6.6px);
84
+ }
85
+ .content[data-size=l] .headline{
86
+ gap:var(--space-drop-list-item-l-container-headline-gap, 8px);
87
+ height:var(--size-drop-list-item-headline, 24px);
88
+ }
89
+ .content[data-size=l] .label{
90
+ font-family:var(--sans-body-l-font-family, SB Sans Interface);
91
+ font-weight:var(--sans-body-l-font-weight, Regular);
92
+ line-height:var(--sans-body-l-line-height, 24px);
93
+ font-size:var(--sans-body-l-font-size, 16px);
94
+ letter-spacing:var(--sans-body-l-letter-spacing, 0.1px);
95
+ paragraph-spacing:var(--sans-body-l-paragraph-spacing, 8.8px);
96
+ }
97
+ .content[data-size=l] .caption{
98
+ font-family:var(--sans-body-m-font-family, SB Sans Interface);
99
+ font-weight:var(--sans-body-m-font-weight, Regular);
100
+ line-height:var(--sans-body-m-line-height, 20px);
101
+ font-size:var(--sans-body-m-font-size, 14px);
102
+ letter-spacing:var(--sans-body-m-letter-spacing, 0.1px);
103
+ paragraph-spacing:var(--sans-body-m-paragraph-spacing, 7.7px);
104
+ }
105
+ .content[data-size=l] .description{
106
+ font-family:var(--sans-body-m-font-family, SB Sans Interface);
107
+ font-weight:var(--sans-body-m-font-weight, Regular);
108
+ line-height:var(--sans-body-m-line-height, 20px);
109
+ font-size:var(--sans-body-m-font-size, 14px);
110
+ letter-spacing:var(--sans-body-m-letter-spacing, 0.1px);
111
+ paragraph-spacing:var(--sans-body-m-paragraph-spacing, 7.7px);
112
+ }
113
+ .content[data-disabled] .option,
114
+ .content[data-disabled] .description,
115
+ .content[data-disabled] .caption{
116
+ color:var(--sys-neutral-text-disabled, #b3b6bf);
117
+ }
@@ -9,6 +9,6 @@ export type ListEmptyState = {
9
9
  loading?: boolean;
10
10
  dataError?: boolean;
11
11
  dataFiltered?: boolean;
12
- itemsLength: number;
12
+ hasNoItems: boolean;
13
13
  };
14
- export declare function ListEmptyState({ dataError, dataFiltered, itemsLength, emptyStates, loading }: ListEmptyState): import("react/jsx-runtime").JSX.Element | null;
14
+ export declare function ListEmptyState({ dataError, dataFiltered, hasNoItems, emptyStates, loading }: ListEmptyState): null;
@@ -1,9 +1,18 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { InfoBlock } from '@snack-uikit/info-block';
3
3
  import styles from './styles.module.css';
4
- export function ListEmptyState({ dataError, dataFiltered, itemsLength, emptyStates, loading }) {
5
- if (itemsLength || loading) {
4
+ export function ListEmptyState({ dataError, dataFiltered, hasNoItems, emptyStates, loading }) {
5
+ if (loading) {
6
6
  return null;
7
7
  }
8
- return (_jsxs("div", { className: styles.listEmptyStateWrapper, children: [dataError && _jsx(InfoBlock, Object.assign({}, emptyStates.errorDataState, { size: 's', align: 'vertical' })), !dataError && dataFiltered && (_jsx(InfoBlock, Object.assign({}, emptyStates.noResultsState, { size: 's', align: 'vertical', "data-test-id": 'list__no-results' }))), !dataError && !dataFiltered && (_jsx(InfoBlock, Object.assign({}, emptyStates.noDataState, { size: 's', align: 'vertical', "data-test-id": 'list__no-data' })))] }));
8
+ if (dataError) {
9
+ _jsx("div", { className: styles.listEmptyStateWrapper, children: _jsx(InfoBlock, Object.assign({}, emptyStates.errorDataState, { size: 's', align: 'vertical' })) });
10
+ }
11
+ if (dataFiltered && hasNoItems) {
12
+ _jsx("div", { className: styles.listEmptyStateWrapper, children: _jsx(InfoBlock, Object.assign({}, emptyStates.noResultsState, { size: 's', align: 'vertical', "data-test-id": 'list__no-results' })) });
13
+ }
14
+ if (!dataFiltered && hasNoItems) {
15
+ _jsx("div", { className: styles.listEmptyStateWrapper, children: _jsx(InfoBlock, Object.assign({}, emptyStates.noDataState, { size: 's', align: 'vertical', "data-test-id": 'list__no-data' })) });
16
+ }
17
+ return null;
9
18
  }
@@ -2,3 +2,4 @@ export * from './CollapseBlockPrivate';
2
2
  export * from './Separator';
3
3
  export * from './HiddenTabButton';
4
4
  export * from './ListEmptyState';
5
+ export * from './ItemContent';
@@ -2,3 +2,4 @@ export * from './CollapseBlockPrivate';
2
2
  export * from './Separator';
3
3
  export * from './HiddenTabButton';
4
4
  export * from './ListEmptyState';
5
+ export * from './ItemContent';
package/dist/hooks.d.ts CHANGED
@@ -2,4 +2,4 @@ import { ItemProps } from './components/Items';
2
2
  /**
3
3
  * Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
4
4
  */
5
- export declare function useFuzzySearch(items: ItemProps[], minSearchInputLength?: number): (search: string) => ItemProps[];
5
+ export declare function useFuzzySearch(items: ItemProps[]): () => ItemProps[];
package/dist/hooks.js CHANGED
@@ -1,15 +1,20 @@
1
- import FuzzySearch from 'fuzzy-search';
1
+ // import FuzzySearch from 'fuzzy-search';
2
2
  import { useCallback } from 'react';
3
- import { flattenItems } from './utils';
4
- const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 2;
3
+ // import { flattenItems } from './utils';
4
+ // const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 2;
5
5
  /**
6
6
  * Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
7
7
  */
8
- export function useFuzzySearch(items, minSearchInputLength) {
9
- return useCallback((search) => {
10
- const searcher = new FuzzySearch(flattenItems(items), ['content.option', 'content.caption', 'content.description', 'label'], {});
11
- return search.length > (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH)
12
- ? searcher.search(search)
13
- : items;
14
- }, [items, minSearchInputLength]);
8
+ export function useFuzzySearch(items) {
9
+ return useCallback(() =>
10
+ // (search: string) =>
11
+ // const searcher = new FuzzySearch(
12
+ // // flattenItems(items),
13
+ // ['content.option', 'content.caption', 'content.description', 'label'],
14
+ // {},
15
+ // );
16
+ // return search.length > (minSearchInputLength ?? DEFAULT_MIN_SEARCH_INPUT_LENGTH)
17
+ // ? searcher.search(search)
18
+ // : items;
19
+ items, [items]);
15
20
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './components';
2
- export { useFuzzySearch } from './hooks';
3
2
  export type { SearchState } from './types';
4
- export { extractChildIds, flattenItems } from './utils';
3
+ export { kindFlattenItems } from './utils';
4
+ export * from './helperComponents/ItemContent';
5
+ export * from './legacy';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './components';
2
- export { useFuzzySearch } from './hooks';
3
- export { extractChildIds, flattenItems } from './utils';
2
+ export { kindFlattenItems } from './utils';
3
+ export * from './helperComponents/ItemContent';
4
+ export * from './legacy';
@@ -0,0 +1,12 @@
1
+ import { ItemProps } from '../../../components';
2
+ type UseGroupItemSelectionProps = {
3
+ items: ItemProps[];
4
+ id?: string | number;
5
+ disabled?: boolean;
6
+ };
7
+ export declare function useLegacyGroupItemSelection({ id, items, disabled }: UseGroupItemSelectionProps): {
8
+ checked: boolean | undefined;
9
+ isIndeterminate: boolean;
10
+ handleOnSelect: () => void;
11
+ };
12
+ export {};
@@ -0,0 +1,33 @@
1
+ import { useEffect, useMemo } from 'react';
2
+ import { useSelectionContext } from '../../../components/Lists/contexts';
3
+ import { extractAllChildIds, extractChildIds } from '../../utils';
4
+ export function useLegacyGroupItemSelection({ id = '', items, disabled }) {
5
+ const { value, setValue, isSelectionMultiple } = useSelectionContext();
6
+ const { childIds, allChildIds } = useMemo(() => ({ childIds: extractChildIds({ items }), allChildIds: extractAllChildIds({ items }) }), [items]);
7
+ const isIndeterminate = isSelectionMultiple
8
+ ? allChildIds.some(childId => value === null || value === void 0 ? void 0 : value.includes(childId))
9
+ : allChildIds.includes(value !== null && value !== void 0 ? value : '');
10
+ const checked = isSelectionMultiple ? allChildIds.every(childId => value === null || value === void 0 ? void 0 : value.includes(childId)) : undefined;
11
+ useEffect(() => {
12
+ if (isSelectionMultiple) {
13
+ if (checked && !(value === null || value === void 0 ? void 0 : value.includes(id))) {
14
+ setValue === null || setValue === void 0 ? void 0 : setValue((value) => (value !== null && value !== void 0 ? value : []).concat([id !== null && id !== void 0 ? id : '']));
15
+ }
16
+ if (!checked && (value === null || value === void 0 ? void 0 : value.includes(id))) {
17
+ setValue === null || setValue === void 0 ? void 0 : setValue((value) => (value !== null && value !== void 0 ? value : []).filter(itemId => itemId !== id));
18
+ }
19
+ }
20
+ }, [checked, disabled, id, isSelectionMultiple, setValue, value]);
21
+ const handleOnSelect = () => {
22
+ if (checked) {
23
+ setValue === null || setValue === void 0 ? void 0 : setValue((value) => (value !== null && value !== void 0 ? value : []).filter(itemId => itemId !== id && !childIds.includes(itemId)));
24
+ return;
25
+ }
26
+ if (isIndeterminate) {
27
+ setValue === null || setValue === void 0 ? void 0 : setValue((value) => Array.from(new Set([...(value !== null && value !== void 0 ? value : []), ...childIds, id])));
28
+ return;
29
+ }
30
+ setValue === null || setValue === void 0 ? void 0 : setValue((value) => (value !== null && value !== void 0 ? value : []).concat([...childIds, id !== null && id !== void 0 ? id : '']));
31
+ };
32
+ return { checked, isIndeterminate, handleOnSelect };
33
+ }
@@ -0,0 +1 @@
1
+ export { useLegacyGroupItemSelection } from './Items/hooks';
@@ -0,0 +1 @@
1
+ export { useLegacyGroupItemSelection } from './Items/hooks';
@@ -0,0 +1,5 @@
1
+ import { ItemProps } from '../components';
2
+ /**
3
+ * Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
4
+ */
5
+ export declare function useFuzzySearch(items: ItemProps[], minSearchInputLength?: number): (search: string) => ItemProps[];
@@ -0,0 +1,15 @@
1
+ import FuzzySearch from 'fuzzy-search';
2
+ import { useCallback } from 'react';
3
+ import { flattenItems } from './utils';
4
+ const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 2;
5
+ /**
6
+ * Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
7
+ */
8
+ export function useFuzzySearch(items, minSearchInputLength) {
9
+ return useCallback((search) => {
10
+ const searcher = new FuzzySearch(flattenItems(items), ['content.option', 'content.caption', 'content.description', 'label'], {});
11
+ return search.length > (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH)
12
+ ? searcher.search(search)
13
+ : items;
14
+ }, [items, minSearchInputLength]);
15
+ }
@@ -0,0 +1,3 @@
1
+ export * from './components';
2
+ export { useFuzzySearch } from './hooks';
3
+ export { extractChildIds, flattenItems } from './utils';
@@ -0,0 +1,3 @@
1
+ export * from './components';
2
+ export { useFuzzySearch } from './hooks';
3
+ export { extractChildIds, flattenItems } from './utils';
@@ -0,0 +1,29 @@
1
+ import { RefObject } from 'react';
2
+ import { AccordionItemProps, BaseItemProps, ItemProps, NextListItemProps } from '../components/Items';
3
+ type WithCollapsedItemsProps = {
4
+ items: ItemProps[];
5
+ openCollapsedItems: Array<number | string>;
6
+ };
7
+ export declare function withCollapsedItems({ items, openCollapsedItems }: WithCollapsedItemsProps): {
8
+ items: ItemProps[];
9
+ itemRefs: RefObject<HTMLElement>[];
10
+ ids: (string | number)[];
11
+ expandedIds: (string | number)[];
12
+ };
13
+ /**
14
+ * Функция возвращает массив id дочерних items
15
+ * @function extractItemIds
16
+ */
17
+ export declare function extractItemIds(items: ItemProps[]): Array<string | number>;
18
+ export declare function extractChildIds({ items }: {
19
+ items: ItemProps[];
20
+ }): Array<string | number>;
21
+ export declare function extractAllChildIds({ items }: {
22
+ items: ItemProps[];
23
+ }): Array<string | number>;
24
+ /**
25
+ *  Функция разворачивает массив айтемов в плоский список
26
+ * @function flattenItems
27
+ */
28
+ export declare function flattenItems(items: ItemProps[]): (BaseItemProps | AccordionItemProps | NextListItemProps)[];
29
+ export {};