@snack-uikit/list 0.11.1-preview-5d3667ec.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +22 -61
- package/dist/components/Items/AccordionItem/AccordionItem.d.ts +4 -2
- package/dist/components/Items/AccordionItem/AccordionItem.js +18 -16
- package/dist/components/Items/BaseItem/BaseItem.d.ts +8 -4
- package/dist/components/Items/BaseItem/BaseItem.js +20 -14
- package/dist/components/Items/BaseItem/styles.module.css +20 -119
- package/dist/components/Items/GroupItem/GroupItem.d.ts +5 -1
- package/dist/components/Items/GroupItem/GroupItem.js +1 -3
- package/dist/components/Items/GroupSelectItem/GroupSelectItem.d.ts +4 -0
- package/dist/components/Items/GroupSelectItem/GroupSelectItem.js +18 -0
- package/dist/components/Items/GroupSelectItem/index.d.ts +1 -0
- package/dist/components/Items/GroupSelectItem/index.js +1 -0
- package/dist/components/Items/NextListItem/NextListItem.d.ts +6 -2
- package/dist/components/Items/NextListItem/NextListItem.js +55 -45
- package/dist/components/Items/NextListItem/constants.d.ts +2 -0
- package/dist/components/Items/NextListItem/constants.js +10 -0
- package/dist/components/Items/PinGroupItem/PinGroupItem.js +7 -3
- package/dist/components/Items/PinGroupItem/styles.module.css +26 -14
- package/dist/components/Items/SearchItem/SearchItem.d.ts +3 -1
- package/dist/components/Items/SearchItem/SearchItem.js +5 -8
- package/dist/components/Items/hooks.d.ts +11 -10
- package/dist/components/Items/hooks.js +64 -46
- package/dist/components/Items/index.d.ts +1 -5
- package/dist/components/Items/index.js +1 -5
- package/dist/components/Items/styles.module.css +33 -26
- package/dist/components/Items/types.d.ts +68 -34
- package/dist/components/Items/utils.d.ts +34 -16
- package/dist/components/Items/utils.js +135 -37
- package/dist/components/Lists/Droplist/DropList.d.ts +1 -1
- package/dist/components/Lists/Droplist/DropList.js +78 -50
- package/dist/components/Lists/List/List.d.ts +5 -9
- package/dist/components/Lists/List/List.js +61 -54
- package/dist/components/Lists/ListPrivate/ListPrivate.d.ts +6 -20
- package/dist/components/Lists/ListPrivate/ListPrivate.js +9 -8
- package/dist/components/Lists/ListPrivate/styles.module.css +1 -0
- 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 +32 -0
- package/dist/components/Lists/contexts/{ListProvider.js → NewListProvider.js} +10 -5
- package/dist/components/Lists/contexts/SelectionProvider.d.ts +25 -15
- package/dist/components/Lists/contexts/SelectionProvider.js +17 -13
- package/dist/components/Lists/contexts/index.d.ts +3 -2
- package/dist/components/Lists/contexts/index.js +3 -2
- package/dist/components/Lists/hooks.d.ts +10 -12
- package/dist/components/Lists/hooks.js +73 -40
- package/dist/components/Lists/index.d.ts +2 -1
- package/dist/components/Lists/index.js +1 -0
- package/dist/components/Lists/types.d.ts +12 -14
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +1 -1
- 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/Separator/Separator.d.ts +8 -2
- package/dist/helperComponents/Separator/Separator.js +22 -2
- package/dist/helperComponents/Separator/constants.d.ts +2 -0
- package/dist/helperComponents/Separator/constants.js +5 -0
- package/dist/helperComponents/Separator/styles.module.css +20 -1
- package/dist/helperComponents/index.d.ts +1 -0
- package/dist/helperComponents/index.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/types.d.ts +1 -1
- package/package.json +13 -18
- package/src/components/Items/AccordionItem/AccordionItem.tsx +24 -20
- package/src/components/Items/BaseItem/BaseItem.tsx +91 -82
- package/src/components/Items/BaseItem/styles.module.scss +19 -77
- package/src/components/Items/GroupItem/GroupItem.tsx +5 -5
- package/src/components/Items/GroupSelectItem/GroupSelectItem.tsx +44 -0
- package/src/components/Items/GroupSelectItem/index.ts +1 -0
- package/src/components/Items/NextListItem/NextListItem.tsx +88 -85
- package/src/components/Items/NextListItem/constants.ts +12 -0
- package/src/components/Items/PinGroupItem/PinGroupItem.tsx +14 -4
- package/src/components/Items/PinGroupItem/styles.module.scss +14 -14
- package/src/components/Items/SearchItem/SearchItem.tsx +6 -8
- package/src/components/Items/hooks.tsx +86 -66
- package/src/components/Items/index.ts +1 -5
- package/src/components/Items/styles.module.scss +36 -25
- package/src/components/Items/types.ts +91 -42
- package/src/components/Items/utils.ts +199 -52
- package/src/components/Lists/Droplist/DropList.tsx +155 -98
- package/src/components/Lists/List/List.tsx +129 -104
- package/src/components/Lists/ListPrivate/ListPrivate.tsx +19 -20
- package/src/components/Lists/ListPrivate/styles.module.scss +1 -0
- package/src/components/Lists/contexts/CollapseProvider.tsx +22 -0
- package/src/components/Lists/contexts/FocusListProvider.tsx +15 -0
- package/src/components/Lists/contexts/NewListProvider.tsx +54 -0
- package/src/components/Lists/contexts/SelectionProvider.tsx +56 -39
- package/src/components/Lists/contexts/index.ts +3 -2
- package/src/components/Lists/hooks.ts +124 -75
- package/src/components/Lists/index.ts +2 -2
- package/src/components/Lists/types.ts +20 -24
- package/src/components/index.ts +17 -2
- 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 +26 -12
- package/src/helperComponents/Separator/Separator.tsx +49 -3
- package/src/helperComponents/Separator/constants.ts +7 -0
- package/src/helperComponents/Separator/styles.module.scss +41 -1
- package/src/helperComponents/index.ts +1 -0
- package/src/index.ts +4 -2
- package/src/types.ts +1 -1
- 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/dist/hooks.d.ts +0 -5
- package/dist/hooks.js +0 -15
- package/dist/utils.d.ts +0 -30
- package/dist/utils.js +0 -115
- 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
- package/src/hooks.ts +0 -27
- package/src/utils.ts +0 -175
|
@@ -12,75 +12,82 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import cn from 'classnames';
|
|
14
14
|
import mergeRefs from 'merge-refs';
|
|
15
|
-
import { forwardRef, useMemo, useRef } from 'react';
|
|
16
|
-
import {
|
|
15
|
+
import { forwardRef, useCallback, useMemo, useRef } from 'react';
|
|
16
|
+
import { useValueControl } from '@snack-uikit/utils';
|
|
17
17
|
import { HiddenTabButton } from '../../../helperComponents';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { useKeyboardNavigation } from '../hooks';
|
|
18
|
+
import { extractActiveItems, kindFlattenItems, useCreateBaseItems } from '../../Items';
|
|
19
|
+
import { CollapseContext, FocusListContext, NewListContextProvider, SelectionProvider } from '../contexts';
|
|
20
|
+
import { useNewKeyboardNavigation } from '../hooks';
|
|
22
21
|
import { ListPrivate } from '../ListPrivate';
|
|
23
22
|
import styles from '../styles.module.css';
|
|
24
23
|
export const List = forwardRef((_a, ref) => {
|
|
25
|
-
var
|
|
26
|
-
var { items: itemsProp, search, pinBottom, pinTop, footerActiveElementsRefs, onKeyDown, tabIndex = 0, className, collapse = {} } = _a, props = __rest(_a, ["items", "search", "pinBottom", "pinTop", "footerActiveElementsRefs", "onKeyDown", "tabIndex", "className", "collapse"]);
|
|
24
|
+
var { items: itemsProp = [], search, pinBottom: pinBottomProp = [], pinTop: pinTopProp = [], footerActiveElementsRefs, onKeyDown, tabIndex = 0, className, collapse = {}, selection, contentRender, size = 's', marker = true } = _a, props = __rest(_a, ["items", "search", "pinBottom", "pinTop", "footerActiveElementsRefs", "onKeyDown", "tabIndex", "className", "collapse", "selection", "contentRender", "size", "marker"]);
|
|
27
25
|
const hasSearch = useMemo(() => Boolean(search), [search]);
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
const [openCollapseItems = [], setOpenCollapsedItems] = useValueControl(collapse);
|
|
27
|
+
const toggleOpenCollapseItem = useCallback((id) => setOpenCollapsedItems((items) => (items === null || items === void 0 ? void 0 : items.includes(id)) ? items.filter(item => item !== id) : (items !== null && items !== void 0 ? items : []).concat([id])), [setOpenCollapsedItems]);
|
|
28
|
+
const { searchItem, footerItems } = useCreateBaseItems({ footerActiveElementsRefs });
|
|
29
|
+
/**
|
|
30
|
+
* Объект с пропсами всех вложенных айтемов; ключ id
|
|
31
|
+
*/
|
|
32
|
+
const _b = useMemo(() => {
|
|
33
|
+
const pinTop = kindFlattenItems({ items: pinTopProp, prefix: '~pinTop', parentId: '~main' });
|
|
34
|
+
const items = kindFlattenItems({ items: itemsProp, prefix: '~main', parentId: '~main' });
|
|
35
|
+
const pinBottom = kindFlattenItems({ items: pinBottomProp, prefix: '~pinBottom', parentId: '~main' });
|
|
36
|
+
const flattenItems = Object.assign(Object.assign(Object.assign({}, pinTop.flattenItems), pinBottom.flattenItems), items.flattenItems);
|
|
37
|
+
const focusFlattenItems = Object.assign(Object.assign(Object.assign({}, pinTop.focusFlattenItems), pinBottom.focusFlattenItems), items.focusFlattenItems);
|
|
38
|
+
[...footerItems, searchItem].forEach(item => {
|
|
39
|
+
flattenItems[item.id] = item;
|
|
40
|
+
focusFlattenItems[item.id] = Object.assign(Object.assign({}, item), { originalId: item.id, items: [], key: item.id, allChildIds: [] });
|
|
41
|
+
});
|
|
42
|
+
return { items, pinTop, pinBottom, flattenItems, focusFlattenItems };
|
|
43
|
+
}, [itemsProp, pinTopProp, pinBottomProp, searchItem, footerItems]), { flattenItems, focusFlattenItems } = _b, memorizedItems = __rest(_b, ["flattenItems", "focusFlattenItems"]);
|
|
44
|
+
const { ids, expandedIds } = useMemo(() => {
|
|
45
|
+
const { pinTop, items, pinBottom } = memorizedItems;
|
|
46
|
+
let ids = [];
|
|
47
|
+
let expandedIds = [];
|
|
48
|
+
if (hasSearch) {
|
|
49
|
+
ids.push(searchItem.id);
|
|
50
|
+
}
|
|
51
|
+
[pinTop, items, pinBottom].forEach(({ focusFlattenItems, focusCloseChildIds }) => {
|
|
52
|
+
const activeItems = extractActiveItems({
|
|
53
|
+
focusFlattenItems,
|
|
54
|
+
focusCloseChildIds,
|
|
55
|
+
openCollapseItems,
|
|
56
|
+
isSelectionMultiple: (selection === null || selection === void 0 ? void 0 : selection.mode) === 'multiple',
|
|
57
|
+
});
|
|
58
|
+
ids = ids.concat(activeItems.ids);
|
|
59
|
+
expandedIds = expandedIds.concat(activeItems.expandedIds);
|
|
60
|
+
});
|
|
61
|
+
footerItems.forEach(footerItem => {
|
|
62
|
+
ids.push(footerItem.id);
|
|
38
63
|
});
|
|
39
|
-
const items = searchItem.concat(res.items).concat(footerRefs);
|
|
40
64
|
return {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
itemRefs: extractItemRefs(searchItem).concat(res.itemRefs).concat(extractItemRefs(footerRefs)),
|
|
44
|
-
expandedIds: res.expandedIds,
|
|
65
|
+
ids,
|
|
66
|
+
expandedIds,
|
|
45
67
|
};
|
|
46
|
-
}, [
|
|
47
|
-
const slicedItems = useMemo(() => getSlicedItems({ items, hasSearch, pinTop, pinBottom, footerRefs }), [items, hasSearch, pinTop, pinBottom, footerRefs]);
|
|
68
|
+
}, [footerItems, hasSearch, memorizedItems, openCollapseItems, searchItem.id, selection === null || selection === void 0 ? void 0 : selection.mode]);
|
|
48
69
|
const listRef = useRef(null);
|
|
49
70
|
const btnRef = useRef(null);
|
|
50
|
-
const {
|
|
51
|
-
|
|
52
|
-
ids,
|
|
53
|
-
expandedIds,
|
|
54
|
-
parentRef: listRef,
|
|
71
|
+
const { handleListKeyDownFactory, activeItemId, resetActiveItemId, forceUpdateActiveItemId } = useNewKeyboardNavigation({
|
|
72
|
+
mainRef: listRef,
|
|
55
73
|
btnRef,
|
|
56
|
-
|
|
74
|
+
focusFlattenItems,
|
|
57
75
|
});
|
|
58
|
-
const
|
|
76
|
+
const handleListKeyDown = useCallback((e) => handleListKeyDownFactory(ids, expandedIds)(e), [handleListKeyDownFactory, ids, expandedIds]);
|
|
77
|
+
const isActive = listRef.current === document.activeElement && activeItemId === undefined;
|
|
59
78
|
const mergedHandlerKeyDown = (e) => {
|
|
60
79
|
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
|
|
61
80
|
handleListKeyDown === null || handleListKeyDown === void 0 ? void 0 : handleListKeyDown(e);
|
|
62
81
|
};
|
|
63
|
-
const handleOnFocus = (
|
|
64
|
-
|
|
65
|
-
(e.relatedTarget && itemRefs.every(({ current }) => current !== e.relatedTarget))) {
|
|
66
|
-
resetActiveFocusIndex();
|
|
67
|
-
}
|
|
82
|
+
const handleOnFocus = () => {
|
|
83
|
+
resetActiveItemId();
|
|
68
84
|
};
|
|
69
|
-
return (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
parentOpenNestedIndex: openNestedIndex,
|
|
78
|
-
triggerRef: triggerRef !== null && triggerRef !== void 0 ? triggerRef : listRef,
|
|
79
|
-
parentRef: listRef,
|
|
80
|
-
parentSetActiveFocusIndex: setActiveFocusIndex,
|
|
81
|
-
parentResetNestedIndex: resetNestedIndex,
|
|
82
|
-
parentResetActiveFocusIndex: resetActiveFocusIndex,
|
|
83
|
-
openCollapsedItems,
|
|
84
|
-
toggleOpenCollapsedItems: id => setOpenCollapsedItems((items = []) => items.includes(id) ? items.filter(item => item !== id) : items === null || items === void 0 ? void 0 : items.concat([id])),
|
|
85
|
-
}, children: _jsxs("div", { className: cn(styles.wrapper, className), "data-active": isActive || undefined, children: [_jsx(ListPrivate, Object.assign({}, props, slicedItems, { ref: mergeRefs(ref, listRef), onFocus: handleOnFocus, onKeyDown: mergedHandlerKeyDown, tabIndex: tabIndex, search: search, nested: false, parent: 'list' })), _jsx(HiddenTabButton, { ref: btnRef, listRef: listRef, tabIndex: tabIndex })] }) }) })));
|
|
85
|
+
return (_jsx(NewListContextProvider, { flattenItems: flattenItems, focusFlattenItems: focusFlattenItems, contentRender: contentRender, size: size, marker: marker, children: _jsx(SelectionProvider, Object.assign({}, selection, { children: _jsx(CollapseContext.Provider, { value: {
|
|
86
|
+
openCollapseItems,
|
|
87
|
+
toggleOpenCollapseItem,
|
|
88
|
+
}, children: _jsx(FocusListContext.Provider, { value: {
|
|
89
|
+
activeItemId,
|
|
90
|
+
handleListKeyDownFactory,
|
|
91
|
+
forceUpdateActiveItemId,
|
|
92
|
+
}, children: _jsxs("div", { className: cn(styles.wrapper, className), "data-active": isActive || undefined, children: [_jsx(ListPrivate, Object.assign({}, props, { items: memorizedItems.items.focusCloseChildIds, pinTop: memorizedItems.pinTop.focusCloseChildIds, pinBottom: memorizedItems.pinBottom.focusCloseChildIds, searchItem: searchItem, ref: mergeRefs(ref, listRef), onFocus: handleOnFocus, onKeyDown: mergedHandlerKeyDown, tabIndex: tabIndex, search: search, nested: false })), _jsx(HiddenTabButton, { ref: btnRef, listRef: listRef, tabIndex: tabIndex })] }) }) }) })) }));
|
|
86
93
|
});
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const ListPrivate: import("react").ForwardRefExoticComponent<{
|
|
3
|
-
'data-test-id'?: string | undefined;
|
|
4
|
-
} & import("react").AriaAttributes & {
|
|
5
|
-
items: import("../../Items").ItemProps[];
|
|
6
|
-
pinTop?: import("../../Items").ItemProps[] | undefined;
|
|
7
|
-
pinBottom?: import("../../Items").ItemProps[] | undefined;
|
|
8
|
-
footer?: import("react").ReactNode;
|
|
9
|
-
footerActiveElementsRefs?: RefObject<HTMLElement>[] | undefined;
|
|
10
|
-
search?: import("../../..").SearchState | undefined;
|
|
11
|
-
tabIndex?: number | undefined;
|
|
12
|
-
collapse?: {
|
|
13
|
-
value?: (string | number)[] | undefined;
|
|
14
|
-
onChange?(value: (string | number)[]): void;
|
|
15
|
-
defaultValue?: (string | number)[] | undefined;
|
|
16
|
-
} | undefined;
|
|
17
|
-
className?: string | undefined;
|
|
18
|
-
onKeyDown?(e: import("react").KeyboardEvent<HTMLElement>): void;
|
|
19
|
-
loading?: boolean | undefined;
|
|
20
|
-
} & import("../contexts").SelectionState & import("../contexts").ListContextType & import("../../../types").ScrollProps & import("../types").EmptyState & import("../contexts").ListContextPrivateType & {
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const ListPrivate: import("react").ForwardRefExoticComponent<Omit<import("../types").ListProps, "items" | "pinTop" | "pinBottom"> & {
|
|
21
3
|
nested?: boolean | undefined;
|
|
22
4
|
active?: boolean | undefined;
|
|
23
5
|
tabIndex?: number | undefined;
|
|
@@ -25,4 +7,8 @@ export declare const ListPrivate: import("react").ForwardRefExoticComponent<{
|
|
|
25
7
|
onBlur?(e: import("react").FocusEvent<HTMLElement, Element>): void;
|
|
26
8
|
onKeyDown?(e: import("react").KeyboardEvent<HTMLElement>): void;
|
|
27
9
|
limitedScrollHeight?: boolean | undefined;
|
|
10
|
+
searchItem?: import("../../Items").FlattenBaseItem | undefined;
|
|
11
|
+
pinTop?: import("../../Items").ItemId[] | undefined;
|
|
12
|
+
items: import("../../Items").ItemId[];
|
|
13
|
+
pinBottom?: import("../../Items").ItemId[] | undefined;
|
|
28
14
|
} & import("react").RefAttributes<HTMLElement>>;
|
|
@@ -17,25 +17,26 @@ import { Scroll } from '@snack-uikit/scroll';
|
|
|
17
17
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
18
18
|
import { ListEmptyState, useEmptyState } from '../../../helperComponents';
|
|
19
19
|
import { PinBottomGroupItem, PinTopGroupItem, SearchItem, useRenderItems } from '../../Items';
|
|
20
|
-
import {
|
|
20
|
+
import { useNewListContext } from '../contexts';
|
|
21
21
|
import commonStyles from '../styles.module.css';
|
|
22
22
|
import styles from './styles.module.css';
|
|
23
23
|
export const ListPrivate = forwardRef((_a, ref) => {
|
|
24
|
-
var { items, pinTop, pinBottom, onKeyDown, onBlur, onFocus, tabIndex, active, scroll, nested, search, scrollRef, scrollContainerRef, footer, loading,
|
|
24
|
+
var { items, pinTop, pinBottom, onKeyDown, onBlur, onFocus, tabIndex, active, scroll, nested, search, searchItem, scrollRef, scrollContainerRef, footer, loading, limitedScrollHeight, className, noDataState, noResultsState, errorDataState, dataError, dataFiltered } = _a, props = __rest(_a, ["items", "pinTop", "pinBottom", "onKeyDown", "onBlur", "onFocus", "tabIndex", "active", "scroll", "nested", "search", "searchItem", "scrollRef", "scrollContainerRef", "footer", "loading", "limitedScrollHeight", "className", "noDataState", "noResultsState", "errorDataState", "dataError", "dataFiltered"]);
|
|
25
|
+
const { size = 's' } = useNewListContext();
|
|
25
26
|
const itemsJSX = useRenderItems(items);
|
|
26
|
-
const itemsPinTopJSX = useRenderItems(pinTop
|
|
27
|
-
const itemsPinBottomJSX = useRenderItems(pinBottom
|
|
27
|
+
const itemsPinTopJSX = useRenderItems(pinTop);
|
|
28
|
+
const itemsPinBottomJSX = useRenderItems(pinBottom);
|
|
28
29
|
const emptyStates = useEmptyState({ noDataState, noResultsState, errorDataState });
|
|
29
30
|
const hasNoItems = items.length === 0;
|
|
30
31
|
const loadingJSX = useMemo(() => loading && (_jsx("div", { role: 'spinbutton', tabIndex: -1, className: styles.loader, "data-size": size, "data-no-items": hasNoItems || undefined, "data-test-id": 'list__loader', children: _jsx(Spinner, { size: size === 'l' ? 's' : 'xs' }) })), [hasNoItems, loading, size]);
|
|
31
|
-
const content = useMemo(() => (_jsxs("div", { className: styles.content, children: [itemsJSX, loadingJSX, _jsx(ListEmptyState, { loading: loading, dataError: dataError, emptyStates: emptyStates,
|
|
32
|
-
const listJSX = (_jsxs("ul", Object.assign({ className: cn(commonStyles.listContainer, className), ref: ref, onKeyDown: onKeyDown, tabIndex: tabIndex, onFocus:
|
|
32
|
+
const content = useMemo(() => (_jsxs("div", { className: styles.content, children: [itemsJSX, loadingJSX, _jsx(ListEmptyState, { loading: loading, dataError: dataError, emptyStates: emptyStates, hasNoItems: hasNoItems, dataFiltered: dataFiltered !== null && dataFiltered !== void 0 ? dataFiltered : Boolean(search === null || search === void 0 ? void 0 : search.value) })] })), [dataError, dataFiltered, emptyStates, hasNoItems, itemsJSX, loading, loadingJSX, search === null || search === void 0 ? void 0 : search.value]);
|
|
33
|
+
const listJSX = (_jsxs("ul", Object.assign({ className: cn(commonStyles.listContainer, className), ref: ref, onKeyDown: onKeyDown, tabIndex: tabIndex, onFocus: onFocus, onBlur: onBlur, "data-active": active || undefined, role: 'menu' }, extractSupportProps(props), { children: [(Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 || search) && (_jsxs(PinTopGroupItem, { children: [search && _jsx(SearchItem, Object.assign({ search: search }, searchItem)), Number(pinTop === null || pinTop === void 0 ? void 0 : pinTop.length) > 0 && itemsPinTopJSX] })), scroll ? (_jsxs(Scroll, { className: cn({
|
|
33
34
|
[commonStyles.scrollContainerS]: scroll && limitedScrollHeight && size === 's',
|
|
34
35
|
[commonStyles.scrollContainerM]: scroll && limitedScrollHeight && size === 'm',
|
|
35
36
|
[commonStyles.scrollContainerL]: scroll && limitedScrollHeight && size === 'l',
|
|
36
|
-
}), barHideStrategy: 'never', size: size === 's' ? 's' : 'm', ref: scrollContainerRef, children: [content, _jsx("div", { className: styles.scrollStub, ref: scrollRef })] })) : (_jsx(_Fragment, { children: content })), Number(pinBottom === null || pinBottom === void 0 ? void 0 : pinBottom.length) > 0 && _jsx(PinBottomGroupItem, { children: itemsPinBottomJSX }), footer && _jsx("div", { className: styles.footer, children: footer })] })));
|
|
37
|
+
}), barHideStrategy: 'never', size: size === 's' ? 's' : 'm', ref: scrollContainerRef, children: [content, _jsx("div", { className: styles.scrollStub, ref: scrollRef })] })) : (_jsx(_Fragment, { children: content })), Number(pinBottom === null || pinBottom === void 0 ? void 0 : pinBottom.length) > 0 && _jsx(PinBottomGroupItem, { children: itemsPinBottomJSX }), footer && (_jsx("div", { className: styles.footer, onFocus: e => e.stopPropagation(), children: footer }))] })));
|
|
37
38
|
if (!nested) {
|
|
38
|
-
return
|
|
39
|
+
return listJSX;
|
|
39
40
|
}
|
|
40
41
|
return (_jsx("li", { style: { listStyleType: 'none' }, role: 'menuitem', children: listJSX }));
|
|
41
42
|
});
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
2
|
+
import { ItemId } from '../../Items';
|
|
3
|
+
export type CollapseLevelContextType = {
|
|
3
4
|
level?: number;
|
|
4
5
|
};
|
|
6
|
+
export declare const CollapseLevelContext: import("react").Context<CollapseLevelContextType>;
|
|
7
|
+
export declare const useCollapseLevelContext: () => CollapseLevelContextType;
|
|
8
|
+
export type CollapseContextType = {
|
|
9
|
+
openCollapseItems?: ItemId[];
|
|
10
|
+
toggleOpenCollapseItem?(id: ItemId): void;
|
|
11
|
+
};
|
|
5
12
|
export declare const CollapseContext: import("react").Context<CollapseContextType>;
|
|
6
13
|
export declare const useCollapseContext: () => CollapseContextType;
|
|
14
|
+
export type CollapseState = {
|
|
15
|
+
value?: ItemId[];
|
|
16
|
+
onChange?(value?: ItemId[]): void;
|
|
17
|
+
defaultValue?: ItemId[];
|
|
18
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { createContext, useContext } from 'react';
|
|
2
|
+
export const CollapseLevelContext = createContext({});
|
|
3
|
+
export const useCollapseLevelContext = () => useContext(CollapseLevelContext);
|
|
2
4
|
export const CollapseContext = createContext({});
|
|
3
5
|
export const useCollapseContext = () => useContext(CollapseContext);
|
|
@@ -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,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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
export const ListContext = createContext({
|
|
15
|
+
flattenItems: {},
|
|
16
|
+
focusFlattenItems: {},
|
|
17
|
+
});
|
|
18
|
+
export function useNewListContext() {
|
|
19
|
+
return useContext(ListContext);
|
|
18
20
|
}
|
|
19
|
-
|
|
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
|
-
|
|
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?:
|
|
7
|
+
defaultValue?: ItemId;
|
|
6
8
|
/** Controlled состояние */
|
|
7
|
-
value?:
|
|
9
|
+
value?: ItemId;
|
|
8
10
|
/** Controlled обработчик измения состояния */
|
|
9
|
-
onChange
|
|
11
|
+
onChange?: OnChangeHandler;
|
|
10
12
|
/** Режим выбора */
|
|
11
13
|
mode: 'single';
|
|
12
14
|
};
|
|
13
15
|
export type SelectionSingleProps = {
|
|
14
|
-
setValue?(value:
|
|
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?:
|
|
24
|
+
defaultValue?: ItemId[];
|
|
23
25
|
/** Controlled состояние */
|
|
24
|
-
value?:
|
|
26
|
+
value?: ItemId[];
|
|
25
27
|
/** Controlled обработчик измения состояния */
|
|
26
|
-
onChange
|
|
28
|
+
onChange?: OnChangeHandler;
|
|
27
29
|
/** Режим выбора */
|
|
28
30
|
mode: 'multiple';
|
|
29
31
|
};
|
|
30
32
|
export type SelectionMultipleProps = {
|
|
31
|
-
setValue?(value:
|
|
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?:
|
|
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:
|
|
53
|
-
export declare function isSelectionSingleProps(props:
|
|
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
|
|
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 {
|
|
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] =
|
|
30
|
-
|
|
31
|
-
|
|
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] =
|
|
50
|
-
|
|
51
|
-
|
|
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(
|
|
89
|
+
return _jsx(SelectionNoneProvider, { children: children });
|
|
85
90
|
}
|
|
86
|
-
export
|
|
87
|
-
|
|
88
|
-
return Object.assign({}, (selection !== null && selection !== void 0 ? selection : {}));
|
|
91
|
+
export function useSelectionContext() {
|
|
92
|
+
return useContext(SelectionContext);
|
|
89
93
|
}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { KeyboardEvent, RefObject } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
6
|
+
focusFlattenItems: Record<string, FocusFlattenItem>;
|
|
8
7
|
};
|
|
9
|
-
export declare function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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 {};
|