@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.
- package/README.md +51 -23
- package/dist/components/Items/AccordionItem/AccordionItem.d.ts +2 -2
- package/dist/components/Items/AccordionItem/AccordionItem.js +19 -16
- package/dist/components/Items/BaseItem/BaseItem.d.ts +5 -4
- package/dist/components/Items/BaseItem/BaseItem.js +22 -16
- package/dist/components/Items/BaseItem/styles.module.css +9 -122
- package/dist/components/Items/GroupItem/GroupItem.d.ts +2 -2
- package/dist/components/Items/GroupItem/GroupItem.js +3 -3
- package/dist/components/Items/NextListItem/NextListItem.d.ts +2 -2
- package/dist/components/Items/NextListItem/NextListItem.js +37 -36
- package/dist/components/Items/SearchItem/SearchItem.d.ts +3 -1
- package/dist/components/Items/SearchItem/SearchItem.js +7 -8
- package/dist/components/Items/hooks.d.ts +14 -9
- package/dist/components/Items/hooks.js +46 -30
- package/dist/components/Items/types.d.ts +41 -26
- package/dist/components/Items/utils.d.ts +7 -17
- package/dist/components/Items/utils.js +3 -31
- package/dist/components/Lists/Droplist/DropList.d.ts +2 -1
- package/dist/components/Lists/Droplist/DropList.js +85 -50
- package/dist/components/Lists/List/List.d.ts +7 -11
- package/dist/components/Lists/List/List.js +61 -53
- package/dist/components/Lists/ListPrivate/ListPrivate.d.ts +18 -20
- package/dist/components/Lists/ListPrivate/ListPrivate.js +10 -9
- package/dist/components/Lists/contexts/CollapseProvider.d.ts +13 -1
- package/dist/components/Lists/contexts/CollapseProvider.js +2 -0
- package/dist/components/Lists/contexts/FocusListProvider.d.ts +9 -0
- package/dist/components/Lists/contexts/FocusListProvider.js +5 -0
- package/dist/components/Lists/contexts/NewListProvider.d.ts +27 -0
- package/dist/components/Lists/contexts/{ListProvider.js → NewListProvider.js} +10 -5
- package/dist/components/Lists/contexts/SelectionProvider.d.ts +28 -15
- package/dist/components/Lists/contexts/SelectionProvider.js +14 -8
- package/dist/components/Lists/contexts/index.d.ts +2 -2
- package/dist/components/Lists/contexts/index.js +2 -2
- package/dist/components/Lists/hooks.d.ts +11 -11
- package/dist/components/Lists/hooks.js +80 -41
- package/dist/components/Lists/types.d.ts +19 -15
- package/dist/helperComponents/ItemContent/ItemContent.d.ts +15 -0
- package/dist/helperComponents/ItemContent/ItemContent.js +23 -0
- package/dist/helperComponents/ItemContent/index.d.ts +1 -0
- package/dist/helperComponents/ItemContent/index.js +1 -0
- package/dist/helperComponents/ItemContent/styles.module.css +117 -0
- package/dist/helperComponents/ListEmptyState/ListEmptyState.d.ts +2 -2
- package/dist/helperComponents/ListEmptyState/ListEmptyState.js +13 -4
- package/dist/helperComponents/index.d.ts +1 -0
- package/dist/helperComponents/index.js +1 -0
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +15 -10
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/legacy/components/Items/hooks.d.ts +12 -0
- package/dist/legacy/components/Items/hooks.js +33 -0
- package/dist/legacy/components/index.d.ts +1 -0
- package/dist/legacy/components/index.js +1 -0
- package/dist/legacy/hooks.d.ts +5 -0
- package/dist/legacy/hooks.js +15 -0
- package/dist/legacy/index.d.ts +3 -0
- package/dist/legacy/index.js +3 -0
- package/dist/legacy/utils.d.ts +29 -0
- package/dist/legacy/utils.js +107 -0
- package/dist/types.d.ts +1 -1
- package/dist/utils.d.ts +27 -25
- package/dist/utils.js +74 -103
- package/package.json +12 -12
- package/src/components/Items/AccordionItem/AccordionItem.tsx +26 -19
- package/src/components/Items/BaseItem/BaseItem.tsx +48 -46
- package/src/components/Items/BaseItem/styles.module.scss +8 -70
- package/src/components/Items/GroupItem/GroupItem.tsx +6 -5
- package/src/components/Items/NextListItem/NextListItem.tsx +67 -78
- package/src/components/Items/SearchItem/SearchItem.tsx +8 -8
- package/src/components/Items/hooks.tsx +76 -54
- package/src/components/Items/types.ts +61 -31
- package/src/components/Items/utils.ts +9 -58
- package/src/components/Lists/Droplist/DropList.tsx +155 -102
- package/src/components/Lists/List/List.tsx +120 -105
- package/src/components/Lists/ListPrivate/ListPrivate.tsx +26 -27
- package/src/components/Lists/contexts/CollapseProvider.tsx +22 -0
- package/src/components/Lists/contexts/FocusListProvider.tsx +16 -0
- package/src/components/Lists/contexts/NewListProvider.tsx +49 -0
- package/src/components/Lists/contexts/SelectionProvider.tsx +63 -36
- package/src/components/Lists/contexts/index.ts +3 -2
- package/src/components/Lists/hooks.ts +139 -75
- package/src/components/Lists/types.ts +29 -27
- package/src/helperComponents/ItemContent/ItemContent.tsx +63 -0
- package/src/helperComponents/ItemContent/index.ts +1 -0
- package/src/helperComponents/ItemContent/styles.module.scss +78 -0
- package/src/helperComponents/ListEmptyState/ListEmptyState.tsx +21 -13
- package/src/helperComponents/index.ts +1 -0
- package/src/hooks.ts +21 -15
- package/src/index.ts +9 -2
- package/src/legacy/components/Items/hooks.tsx +53 -0
- package/src/legacy/components/index.ts +1 -0
- package/src/legacy/hooks.ts +27 -0
- package/src/legacy/index.ts +3 -0
- package/src/legacy/utils.ts +166 -0
- package/src/types.ts +1 -1
- package/src/utils.ts +153 -139
- package/dist/components/Items/NextListItem/hooks.d.ts +0 -19
- package/dist/components/Items/NextListItem/hooks.js +0 -80
- package/dist/components/Lists/contexts/ListProvider.d.ts +0 -17
- package/dist/components/Lists/contexts/ParentListProvider.d.ts +0 -18
- package/dist/components/Lists/contexts/ParentListProvider.js +0 -12
- package/src/components/Items/NextListItem/hooks.ts +0 -105
- package/src/components/Lists/contexts/CollapseProvider.ts +0 -9
- package/src/components/Lists/contexts/ListProvider.tsx +0 -28
- package/src/components/Lists/contexts/ParentListProvider.tsx +0 -35
|
@@ -1,73 +1,112 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const [
|
|
5
|
-
const
|
|
6
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 (
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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(
|
|
31
|
-
|
|
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 (
|
|
77
|
+
if (activeItemIdRef.current !== undefined) {
|
|
39
78
|
e.preventDefault();
|
|
40
|
-
|
|
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
|
|
43
|
-
btnRef && !e.shiftKey ? (
|
|
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
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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 {
|
|
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 &
|
|
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
|
|
61
|
-
|
|
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
|
-
|
|
12
|
+
hasNoItems: boolean;
|
|
13
13
|
};
|
|
14
|
-
export declare function ListEmptyState({ dataError, dataFiltered,
|
|
14
|
+
export declare function ListEmptyState({ dataError, dataFiltered, hasNoItems, emptyStates, loading }: ListEmptyState): null;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
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,
|
|
5
|
-
if (
|
|
4
|
+
export function ListEmptyState({ dataError, dataFiltered, hasNoItems, emptyStates, loading }) {
|
|
5
|
+
if (loading) {
|
|
6
6
|
return null;
|
|
7
7
|
}
|
|
8
|
-
|
|
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
|
}
|
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[]
|
|
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
|
|
9
|
-
return useCallback((
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
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 {
|
|
3
|
+
export { kindFlattenItems } from './utils';
|
|
4
|
+
export * from './helperComponents/ItemContent';
|
|
5
|
+
export * from './legacy';
|
package/dist/index.js
CHANGED
|
@@ -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,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 {};
|