@astral/ui 4.0.0-alpha.29 → 4.0.0-alpha.30
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/components/InfiniteTreeList/InfiniteTreeList.js +2 -2
- package/components/InfiniteTreeList/InfiniteTreeListActions/useLogic/useLogic.js +6 -6
- package/components/InfiniteTreeList/InfiniteTreeListContext/InfiniteTreeListContext.d.ts +2 -2
- package/components/InfiniteTreeList/InfiniteTreeListContext/InfiniteTreeListContext.js +2 -2
- package/components/InfiniteTreeList/InfiniteTreeListContext/InfiniteTreeListContextProvider/InfiniteTreeListContextProvider.js +11 -9
- package/components/InfiniteTreeList/InfiniteTreeListItem/InfiniteTreeListItem.js +1 -1
- package/components/InfiniteTreeList/InfiniteTreeListItem/TreeListItemContext/TreeListItemContext.d.ts +1 -1
- package/components/InfiniteTreeList/InfiniteTreeListItem/TreeListItemContext/TreeListItemContext.js +1 -1
- package/components/InfiniteTreeList/InfiniteTreeListItem/TreeListItemContext/TreeListItemContextProvider/TreeListItemContextProvider.js +6 -16
- package/components/InfiniteTreeList/InfiniteTreeListItem/useLogic/useLogic.d.ts +1 -3
- package/components/InfiniteTreeList/InfiniteTreeListItem/useLogic/useLogic.js +9 -4
- package/components/InfiniteTreeList/TreeItem/TreeItem.js +2 -1
- package/components/InfiniteTreeList/TreeItem/types.d.ts +3 -3
- package/components/InfiniteTreeList/TreeItem/useLogic/useLogic.d.ts +2 -2
- package/components/InfiniteTreeList/TreeItem/useLogic/useLogic.js +4 -2
- package/components/InfiniteTreeList/styles.d.ts +4 -4
- package/components/InfiniteTreeList/styles.js +3 -8
- package/components/InfiniteTreeList/types.d.ts +10 -7
- package/components/InfiniteTreeList/useLogic/useLogic.d.ts +2 -2
- package/components/InfiniteTreeList/useLogic/useLogic.js +2 -7
- package/components/InfiniteTreeList/useLogic/utils/flattenTree/flattenTree.js +9 -4
- package/components/InfiniteTreeList/useLogic/utils/getDescendants/getDescendants.js +2 -2
- package/components/InfiniteTreeList/useLogic/utils/getInitialExpandedIds/getInitialExpandedIds.js +1 -2
- package/components/InfiniteTreeList/useLogic/utils/sortCollapsed/sortCollapsed.js +3 -3
- package/components/PdfViewer/PdfViewer.js +5 -4
- package/components/PdfViewer/types.d.ts +6 -0
- package/components/PdfViewer/useLogic/useLogic.d.ts +16 -8
- package/components/PdfViewer/useLogic/useLogic.js +18 -9
- package/node/components/InfiniteTreeList/InfiniteTreeList.js +1 -1
- package/node/components/InfiniteTreeList/InfiniteTreeListActions/useLogic/useLogic.js +6 -6
- package/node/components/InfiniteTreeList/InfiniteTreeListContext/InfiniteTreeListContext.d.ts +2 -2
- package/node/components/InfiniteTreeList/InfiniteTreeListContext/InfiniteTreeListContext.js +2 -2
- package/node/components/InfiniteTreeList/InfiniteTreeListContext/InfiniteTreeListContextProvider/InfiniteTreeListContextProvider.js +11 -9
- package/node/components/InfiniteTreeList/InfiniteTreeListItem/InfiniteTreeListItem.js +1 -1
- package/node/components/InfiniteTreeList/InfiniteTreeListItem/TreeListItemContext/TreeListItemContext.d.ts +1 -1
- package/node/components/InfiniteTreeList/InfiniteTreeListItem/TreeListItemContext/TreeListItemContext.js +1 -1
- package/node/components/InfiniteTreeList/InfiniteTreeListItem/TreeListItemContext/TreeListItemContextProvider/TreeListItemContextProvider.js +6 -16
- package/node/components/InfiniteTreeList/InfiniteTreeListItem/useLogic/useLogic.d.ts +1 -3
- package/node/components/InfiniteTreeList/InfiniteTreeListItem/useLogic/useLogic.js +8 -3
- package/node/components/InfiniteTreeList/TreeItem/TreeItem.js +2 -1
- package/node/components/InfiniteTreeList/TreeItem/types.d.ts +3 -3
- package/node/components/InfiniteTreeList/TreeItem/useLogic/useLogic.d.ts +2 -2
- package/node/components/InfiniteTreeList/TreeItem/useLogic/useLogic.js +4 -2
- package/node/components/InfiniteTreeList/styles.d.ts +4 -4
- package/node/components/InfiniteTreeList/styles.js +4 -9
- package/node/components/InfiniteTreeList/types.d.ts +10 -7
- package/node/components/InfiniteTreeList/useLogic/useLogic.d.ts +2 -2
- package/node/components/InfiniteTreeList/useLogic/useLogic.js +2 -7
- package/node/components/InfiniteTreeList/useLogic/utils/flattenTree/flattenTree.js +9 -4
- package/node/components/InfiniteTreeList/useLogic/utils/getDescendants/getDescendants.js +2 -2
- package/node/components/InfiniteTreeList/useLogic/utils/getInitialExpandedIds/getInitialExpandedIds.js +1 -2
- package/node/components/InfiniteTreeList/useLogic/utils/sortCollapsed/sortCollapsed.js +3 -3
- package/node/components/PdfViewer/PdfViewer.js +5 -4
- package/node/components/PdfViewer/types.d.ts +6 -0
- package/node/components/PdfViewer/useLogic/useLogic.d.ts +16 -8
- package/node/components/PdfViewer/useLogic/useLogic.js +18 -9
- package/package.json +28 -10
|
@@ -9,7 +9,7 @@ import { InfiniteTreeListContextProvider } from './InfiniteTreeListContext';
|
|
|
9
9
|
import { TreeListItemContextProvider } from './InfiniteTreeListItem';
|
|
10
10
|
import { NoDataPlaceholder } from './NoDataPlaceholder';
|
|
11
11
|
import { OnTopButton } from './OnTopButton';
|
|
12
|
-
import { Footer } from './styles';
|
|
12
|
+
import { Footer, FooterDummy } from './styles';
|
|
13
13
|
import { TreeItem } from './TreeItem';
|
|
14
14
|
import { useLogic } from './useLogic';
|
|
15
15
|
export const InfiniteTreeList = (props) => {
|
|
@@ -19,7 +19,7 @@ export const InfiniteTreeList = (props) => {
|
|
|
19
19
|
Footer: () => {
|
|
20
20
|
const { isLoading, isError, isEndReached } = footerProps;
|
|
21
21
|
if (!isLoading && !isError && !isEndReached) {
|
|
22
|
-
return
|
|
22
|
+
return _jsx(FooterDummy, {});
|
|
23
23
|
}
|
|
24
24
|
return (_jsxs(Footer, { children: [isLoading && _jsx(Loader, {}), isError && _jsx(ErrorMessage, { onRetry: onRetry }), isEndReached && (_jsx(EndData, { endOfScrollMsg: endOfScrollMsg }))] }));
|
|
25
25
|
},
|
|
@@ -3,20 +3,20 @@ import { InfiniteTreeListContext } from '../../InfiniteTreeListContext';
|
|
|
3
3
|
import { TreeListItemContext } from '../../InfiniteTreeListItem';
|
|
4
4
|
export const useLogic = ({ actions }) => {
|
|
5
5
|
const { main, secondary = [] } = actions;
|
|
6
|
-
const {
|
|
7
|
-
const {
|
|
6
|
+
const { setDisabledReason, item } = useContext(TreeListItemContext);
|
|
7
|
+
const { setDisabled } = useContext(InfiniteTreeListContext);
|
|
8
8
|
const blockingAction = useMemo(() => [...main, ...secondary].find((action) => action.isBlockingOperation && action.loading), [main, secondary]);
|
|
9
9
|
const isDisabledAction = Boolean(blockingAction);
|
|
10
10
|
useEffect(() => {
|
|
11
11
|
if (blockingAction) {
|
|
12
|
-
setDisabled(true, blockingAction === null || blockingAction === void 0 ? void 0 : blockingAction.loadingNote);
|
|
13
12
|
// Добавляем id элемента в Set disabled элементов
|
|
14
|
-
|
|
13
|
+
setDisabled(item.id, true);
|
|
14
|
+
setDisabledReason(blockingAction === null || blockingAction === void 0 ? void 0 : blockingAction.loadingNote);
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
setDisabled(false);
|
|
18
17
|
// Удаляем id элемента из Set disabled элементов
|
|
19
|
-
|
|
18
|
+
setDisabled(item.id, false);
|
|
19
|
+
setDisabledReason('');
|
|
20
20
|
}, [blockingAction, item.id]);
|
|
21
21
|
const handleActionClick = useCallback((onClick) => () => {
|
|
22
22
|
onClick === null || onClick === void 0 ? void 0 : onClick(item);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
export type InfiniteTreeListContextProps = {
|
|
3
3
|
itemSkeleton: ReactNode;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
disabledIdList: Set<string>;
|
|
5
|
+
setDisabled: (itemId: string, disabled: boolean) => void;
|
|
6
6
|
};
|
|
7
7
|
export declare const InfiniteTreeListContext: import("react").Context<InfiniteTreeListContextProps>;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useSet } from '../../../hooks';
|
|
3
3
|
import { InfiniteTreeListContext, } from '../InfiniteTreeListContext';
|
|
4
4
|
export const InfiniteTreeListContextProvider = ({ children, itemSkeleton, }) => {
|
|
5
|
-
const [
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return next;
|
|
11
|
-
});
|
|
5
|
+
const [disabledIdList, disabledIdListActions] = useSet(new Set());
|
|
6
|
+
const setDisabled = (itemId, disabled) => {
|
|
7
|
+
disabled
|
|
8
|
+
? disabledIdListActions.add(itemId)
|
|
9
|
+
: disabledIdListActions.remove(itemId);
|
|
12
10
|
};
|
|
13
|
-
return (_jsx(InfiniteTreeListContext.Provider, { value: {
|
|
11
|
+
return (_jsx(InfiniteTreeListContext.Provider, { value: {
|
|
12
|
+
itemSkeleton,
|
|
13
|
+
disabledIdList,
|
|
14
|
+
setDisabled,
|
|
15
|
+
}, children: children }));
|
|
14
16
|
};
|
|
@@ -10,5 +10,5 @@ export const InfiniteTreeListItem = (props) => {
|
|
|
10
10
|
return (_jsx(ContentState, { isLoading: isLoading, loadingContent: _jsx(Wrapper, { "$isLoading": true, children: itemSkeleton }), isError: isError, errorState: {
|
|
11
11
|
onRetry,
|
|
12
12
|
errorList: [errorMsg || ''],
|
|
13
|
-
}, children: _jsx(Tooltip, Object.assign({}, tooltipProps, { children: _jsxs(Wrapper, { onClick: handleClick, className: className, "$isDisabled": isDisabled || isDisabledByActions, "$isLoading": isLoading, "$hasNested": item.hasNested, inert: isDisabled || isDisabledByActions ? '' : undefined, children: [item.hasNested && _jsx(Chevron, { isActive: isChevronActive }), children, actions && _jsx(ActionsWrapper, { children: actions })] }, `infinite-tree-list-item-${item.id}`) })) }));
|
|
13
|
+
}, children: _jsx(Tooltip, Object.assign({}, tooltipProps, { children: _jsxs(Wrapper, { onClick: handleClick, className: className, "$isDisabled": isDisabled || isDisabledByActions, "$isLoading": isLoading, "$hasNested": item.meta.hasNested, inert: isDisabled || isDisabledByActions ? '' : undefined, children: [item.meta.hasNested && _jsx(Chevron, { isActive: isChevronActive }), children, actions && _jsx(ActionsWrapper, { children: actions })] }, `infinite-tree-list-item-${item.id}`) })) }));
|
|
14
14
|
};
|
|
@@ -5,6 +5,6 @@ export type TreeListItemContextProps = {
|
|
|
5
5
|
onToggle: (item: InfiniteTreeListData) => void;
|
|
6
6
|
isDisabled: boolean;
|
|
7
7
|
disabledReason?: string;
|
|
8
|
-
|
|
8
|
+
setDisabledReason: (disabledReason?: string) => void;
|
|
9
9
|
};
|
|
10
10
|
export declare const TreeListItemContext: import("react").Context<TreeListItemContextProps>;
|
|
@@ -3,26 +3,16 @@ import { useContext, useMemo, useState } from 'react';
|
|
|
3
3
|
import { InfiniteTreeListContext } from '../../../InfiniteTreeListContext';
|
|
4
4
|
import { TreeListItemContext, } from '../TreeListItemContext';
|
|
5
5
|
export const TreeListItemContextProvider = ({ item, children, onToggle, }) => {
|
|
6
|
-
const [isDisabled, setIsDisabled] = useState(false);
|
|
7
6
|
const [disabledReason, setDisabledReason] = useState();
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// path содержит [parent1, parent2, ..., currentItem], поэтому проверяем все кроме последнего
|
|
13
|
-
const parentIds = item.path.slice(0, -1);
|
|
14
|
-
return parentIds.some((parentId) => disabledItemIds.has(parentId));
|
|
15
|
-
}, [item.path, disabledItemIds]);
|
|
16
|
-
const setDisabled = (disabled, reason) => {
|
|
17
|
-
setIsDisabled(disabled);
|
|
18
|
-
setDisabledReason(disabled ? reason : undefined);
|
|
19
|
-
};
|
|
20
|
-
const finalIsDisabled = isDisabled || isDisabledByParent;
|
|
7
|
+
const { disabledIdList } = useContext(InfiniteTreeListContext);
|
|
8
|
+
const isDisabled = useMemo(() => {
|
|
9
|
+
return item.meta.path.some((id) => disabledIdList.has(id));
|
|
10
|
+
}, [item.path, disabledIdList]);
|
|
21
11
|
return (_jsx(TreeListItemContext.Provider, { value: {
|
|
22
12
|
item,
|
|
23
13
|
onToggle,
|
|
24
|
-
isDisabled
|
|
14
|
+
isDisabled,
|
|
25
15
|
disabledReason,
|
|
26
|
-
|
|
16
|
+
setDisabledReason,
|
|
27
17
|
}, children: children }));
|
|
28
18
|
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { type MouseEvent } from 'react';
|
|
2
2
|
import { type TooltipProps } from '../../../Tooltip';
|
|
3
3
|
import { type InfiniteTreeListItemProps } from '../types';
|
|
4
|
-
|
|
5
|
-
export declare const useLogic: ({ isDisabled, disabledReason }: UseLogicParams) => {
|
|
4
|
+
export declare const useLogic: ({ isDisabled, disabledReason, }: InfiniteTreeListItemProps) => {
|
|
6
5
|
item: import("../..").FlattenTree<import("../..").InfiniteTreeListData>;
|
|
7
6
|
handleClick: (event: MouseEvent) => void;
|
|
8
7
|
itemSkeleton: import("react").ReactNode;
|
|
@@ -12,4 +11,3 @@ export declare const useLogic: ({ isDisabled, disabledReason }: UseLogicParams)
|
|
|
12
11
|
isDisabledByActions: boolean;
|
|
13
12
|
isChevronActive: boolean;
|
|
14
13
|
};
|
|
15
|
-
export {};
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { useCallback, useContext, useState } from 'react';
|
|
1
|
+
import { useCallback, useContext, useEffect, useState, } from 'react';
|
|
2
2
|
import { InfiniteTreeListContext } from '../../InfiniteTreeListContext';
|
|
3
3
|
import { TreeListItemContext } from '../TreeListItemContext';
|
|
4
|
-
export const useLogic = ({ isDisabled, disabledReason }) => {
|
|
5
|
-
const { itemSkeleton } = useContext(InfiniteTreeListContext);
|
|
4
|
+
export const useLogic = ({ isDisabled, disabledReason, }) => {
|
|
5
|
+
const { itemSkeleton, setDisabled } = useContext(InfiniteTreeListContext);
|
|
6
6
|
const { item, onToggle, isDisabled: isDisabledByActions, disabledReason: disabledReasonByActions, } = useContext(TreeListItemContext);
|
|
7
|
-
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (isDisabled) {
|
|
9
|
+
setDisabled(item.id, isDisabled);
|
|
10
|
+
}
|
|
11
|
+
}, [isDisabled]);
|
|
12
|
+
const [isChevronActive, setChevronActive] = useState(item.meta.isExpanded);
|
|
8
13
|
const handleClick = useCallback((event) => {
|
|
9
14
|
event.stopPropagation();
|
|
10
15
|
setChevronActive((prev) => !prev);
|
|
@@ -3,5 +3,6 @@ import { Wrapper } from './styles';
|
|
|
3
3
|
import { useLogic } from './useLogic';
|
|
4
4
|
export const TreeItem = (props) => {
|
|
5
5
|
const { item, renderItem, classname, onAnimationEnd } = useLogic(props);
|
|
6
|
-
|
|
6
|
+
const { nodeId, level, siblingIndex } = item.meta;
|
|
7
|
+
return (_jsx(Wrapper, { id: nodeId, className: classname, "$level": level, "$siblingIndex": siblingIndex, onAnimationEnd: onAnimationEnd, children: renderItem(item) }));
|
|
7
8
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ReactNode, RefObject } from 'react';
|
|
2
|
-
import type
|
|
2
|
+
import { type FlattenTree, type InfiniteTreeItemMeta, type InfiniteTreeListData } from '../types';
|
|
3
3
|
export type TreeItemProps<TData extends InfiniteTreeListData<TData>> = {
|
|
4
4
|
item: FlattenTree<TData>;
|
|
5
|
-
renderItem: (item: TData
|
|
6
|
-
|
|
5
|
+
renderItem: (item: TData & {
|
|
6
|
+
meta: InfiniteTreeItemMeta;
|
|
7
7
|
}) => ReactNode;
|
|
8
8
|
recentlyExpandedIds: RefObject<Set<string>>;
|
|
9
9
|
};
|
|
@@ -3,8 +3,8 @@ import type { InfiniteTreeListData } from '../../types';
|
|
|
3
3
|
import { type TreeItemProps } from '../types';
|
|
4
4
|
export declare const useLogic: <TData extends InfiniteTreeListData<TData>>({ item, renderItem, recentlyExpandedIds, }: TreeItemProps<TData>) => {
|
|
5
5
|
item: import("../../types").FlattenTree<TData>;
|
|
6
|
-
renderItem: (item: TData
|
|
7
|
-
|
|
6
|
+
renderItem: (item: TData & {
|
|
7
|
+
meta: import("../../types").InfiniteTreeItemMeta;
|
|
8
8
|
}) => import("react").ReactNode;
|
|
9
9
|
classname: string;
|
|
10
10
|
onAnimationEnd: () => void;
|
|
@@ -3,7 +3,8 @@ import { infiniteTreeListClassnames } from '../../constants';
|
|
|
3
3
|
export const useLogic = ({ item, renderItem, recentlyExpandedIds, }) => {
|
|
4
4
|
const deleteRecentlyExpandedId = () => {
|
|
5
5
|
var _a;
|
|
6
|
-
item.parentId &&
|
|
6
|
+
item.meta.parentId &&
|
|
7
|
+
((_a = recentlyExpandedIds.current) === null || _a === void 0 ? void 0 : _a.delete(item.meta.parentId));
|
|
7
8
|
};
|
|
8
9
|
useEffect(() => {
|
|
9
10
|
return () => {
|
|
@@ -15,7 +16,8 @@ export const useLogic = ({ item, renderItem, recentlyExpandedIds, }) => {
|
|
|
15
16
|
};
|
|
16
17
|
const classname = useMemo(() => {
|
|
17
18
|
var _a;
|
|
18
|
-
if ((item === null || item === void 0 ? void 0 : item.parentId) &&
|
|
19
|
+
if ((item === null || item === void 0 ? void 0 : item.meta.parentId) &&
|
|
20
|
+
((_a = recentlyExpandedIds.current) === null || _a === void 0 ? void 0 : _a.has(item === null || item === void 0 ? void 0 : item.meta.parentId))) {
|
|
19
21
|
return infiniteTreeListClassnames.addAnimation;
|
|
20
22
|
}
|
|
21
23
|
return '';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export declare const Wrapper: import("@emotion/styled").StyledComponent<{
|
|
3
|
-
theme?: import("@emotion/react").Theme | undefined;
|
|
4
|
-
as?: import("react").ElementType<any> | undefined;
|
|
5
|
-
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
6
2
|
export declare const Footer: import("@emotion/styled").StyledComponent<{
|
|
7
3
|
theme?: import("@emotion/react").Theme | undefined;
|
|
8
4
|
as?: import("react").ElementType<any> | undefined;
|
|
9
5
|
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, {}>;
|
|
6
|
+
export declare const FooterDummy: import("@emotion/styled").StyledComponent<{
|
|
7
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
8
|
+
as?: import("react").ElementType<any> | undefined;
|
|
9
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
import { styled } from '../styles';
|
|
2
|
-
export const Wrapper = styled.div `
|
|
3
|
-
position: relative;
|
|
4
|
-
|
|
5
|
-
display: flex;
|
|
6
|
-
flex-direction: column;
|
|
7
|
-
|
|
8
|
-
height: 100%;
|
|
9
|
-
`;
|
|
10
2
|
export const Footer = styled.footer `
|
|
11
3
|
display: flex;
|
|
12
4
|
flex-shrink: 0;
|
|
@@ -16,3 +8,6 @@ export const Footer = styled.footer `
|
|
|
16
8
|
min-height: 64px;
|
|
17
9
|
margin-top: ${({ theme }) => theme.spacing(1)};
|
|
18
10
|
`;
|
|
11
|
+
export const FooterDummy = styled.div `
|
|
12
|
+
min-height: 20px;
|
|
13
|
+
`;
|
|
@@ -7,10 +7,6 @@ export type InfiniteTreeListDataBase = {
|
|
|
7
7
|
* Уникальный идентификатор элемента
|
|
8
8
|
*/
|
|
9
9
|
id: string;
|
|
10
|
-
/**
|
|
11
|
-
* Флаг наличия дочерних элементов
|
|
12
|
-
*/
|
|
13
|
-
hasNested?: boolean;
|
|
14
10
|
/**
|
|
15
11
|
* Дополнительные поля
|
|
16
12
|
*/
|
|
@@ -66,8 +62,8 @@ export type InfiniteTreeListProps<TData extends InfiniteTreeListData<TData> = In
|
|
|
66
62
|
* </InfiniteTreeListItem>
|
|
67
63
|
* )}
|
|
68
64
|
*/
|
|
69
|
-
renderItem: (item: TData
|
|
70
|
-
|
|
65
|
+
renderItem: (item: TData & {
|
|
66
|
+
meta: InfiniteTreeItemMeta;
|
|
71
67
|
}) => ReactNode;
|
|
72
68
|
/**
|
|
73
69
|
* Уровень раскрытия дерева по умолчанию
|
|
@@ -91,7 +87,7 @@ export type InfiniteTreeListProps<TData extends InfiniteTreeListData<TData> = In
|
|
|
91
87
|
*/
|
|
92
88
|
errorImgSrc?: string;
|
|
93
89
|
};
|
|
94
|
-
export type
|
|
90
|
+
export type InfiniteTreeItemMeta = {
|
|
95
91
|
/**
|
|
96
92
|
* Уровень вложенности (начинается с 0)
|
|
97
93
|
*/
|
|
@@ -108,6 +104,10 @@ export type FlattenTree<TData extends InfiniteTreeListData<TData>> = TData & {
|
|
|
108
104
|
* Индекс элемента среди siblings (для каскадной анимации)
|
|
109
105
|
*/
|
|
110
106
|
siblingIndex: number;
|
|
107
|
+
/**
|
|
108
|
+
* Флаг имеет ли элемент вложенных потомков
|
|
109
|
+
*/
|
|
110
|
+
hasNested: boolean;
|
|
111
111
|
/**
|
|
112
112
|
* Флаг раскрытия узла
|
|
113
113
|
*/
|
|
@@ -117,3 +117,6 @@ export type FlattenTree<TData extends InfiniteTreeListData<TData>> = TData & {
|
|
|
117
117
|
*/
|
|
118
118
|
nodeId: string;
|
|
119
119
|
};
|
|
120
|
+
export type FlattenTree<TData extends InfiniteTreeListData<TData>> = TData & {
|
|
121
|
+
meta: InfiniteTreeItemMeta;
|
|
122
|
+
};
|
|
@@ -26,8 +26,8 @@ export declare const useLogic: <TData extends InfiniteTreeListData<TData>>({ ini
|
|
|
26
26
|
};
|
|
27
27
|
endOfScrollMsg: string | undefined;
|
|
28
28
|
itemSkeleton: import("react").ReactNode;
|
|
29
|
-
renderItem: (item: TData
|
|
30
|
-
|
|
29
|
+
renderItem: (item: TData & {
|
|
30
|
+
meta: import("../types").InfiniteTreeItemMeta;
|
|
31
31
|
}) => import("react").ReactNode;
|
|
32
32
|
items: TData[];
|
|
33
33
|
onLoadMore: (() => void) | undefined;
|
|
@@ -24,12 +24,7 @@ export const useLogic = ({ initialExpandedLevel, items, onRetry, errorMsg, isErr
|
|
|
24
24
|
/**
|
|
25
25
|
* Дерево, преобразованное в плоский список. Такая структура необходима для полноценной виртуализации
|
|
26
26
|
*/
|
|
27
|
-
const flatList = useMemo(() =>
|
|
28
|
-
const list = flattenTree(items, internalExpanded);
|
|
29
|
-
return list.map((item) => {
|
|
30
|
-
return Object.assign(Object.assign({}, item), { isExpanded: internalExpanded.has(item.id) });
|
|
31
|
-
});
|
|
32
|
-
}, [items, internalExpanded]);
|
|
27
|
+
const flatList = useMemo(() => flattenTree(items, internalExpanded), [items, internalExpanded]);
|
|
33
28
|
const onToggle = ({ id: itemId }) => {
|
|
34
29
|
const isExpanded = internalExpanded.has(itemId);
|
|
35
30
|
if (!isExpanded) {
|
|
@@ -38,7 +33,7 @@ export const useLogic = ({ initialExpandedLevel, items, onRetry, errorMsg, isErr
|
|
|
38
33
|
}
|
|
39
34
|
else {
|
|
40
35
|
const children = sortCollapsed(getDescendants(flatList, itemId));
|
|
41
|
-
children.forEach(({
|
|
36
|
+
children.forEach(({ meta }) => startRemoveAnimation(meta.nodeId));
|
|
42
37
|
const collapseDurationMs = theme.transitions.duration.shorter;
|
|
43
38
|
setTimeout(() => {
|
|
44
39
|
internalExpandedActions.remove(itemId);
|
|
@@ -7,10 +7,15 @@ export const flattenTree = (items, expandedIds, parentPath = [], level = 0, pare
|
|
|
7
7
|
const path = [...parentPath, item.id];
|
|
8
8
|
const isExpanded = expandedIds.has(item.id);
|
|
9
9
|
// Создаем flattened item с правильной типизацией
|
|
10
|
-
const flattenedItem = Object.assign(Object.assign({}, item), {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const flattenedItem = Object.assign(Object.assign({}, item), { meta: {
|
|
11
|
+
hasNested: Boolean(item.children),
|
|
12
|
+
level,
|
|
13
|
+
path,
|
|
14
|
+
isExpanded,
|
|
15
|
+
parentId,
|
|
16
|
+
siblingIndex: index,
|
|
17
|
+
nodeId: `infinite-tree-item-${item.id}`,
|
|
18
|
+
} });
|
|
14
19
|
result.push(flattenedItem);
|
|
15
20
|
// Рекурсивно обрабатываем детей с сохранением типизации
|
|
16
21
|
if (isExpanded && item.children && item.children.length > 0) {
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
export const getDescendants = (flatList, parentId) => {
|
|
10
10
|
const result = [];
|
|
11
11
|
const collectChildren = (id) => {
|
|
12
|
-
const children = flatList.filter((item) => item.parentId === id);
|
|
12
|
+
const children = flatList.filter((item) => item.meta.parentId === id);
|
|
13
13
|
children.forEach((child) => {
|
|
14
14
|
result.push(child);
|
|
15
|
-
if (child.isExpanded) {
|
|
15
|
+
if (child.meta.isExpanded) {
|
|
16
16
|
collectChildren(child.id);
|
|
17
17
|
}
|
|
18
18
|
});
|
package/components/InfiniteTreeList/useLogic/utils/getInitialExpandedIds/getInitialExpandedIds.js
CHANGED
|
@@ -10,8 +10,7 @@ export const getInitialExpandedIds = (prev, items, initialExpandedLevel, current
|
|
|
10
10
|
const shouldExpand = currentLevel < initialExpandedLevel;
|
|
11
11
|
items.forEach((item) => {
|
|
12
12
|
var _a;
|
|
13
|
-
|
|
14
|
-
if (shouldExpand && mightHaveChildren) {
|
|
13
|
+
if (shouldExpand && item.children) {
|
|
15
14
|
if (!(prev === null || prev === void 0 ? void 0 : prev.has(item.id))) {
|
|
16
15
|
expandedIds.add(item.id);
|
|
17
16
|
}
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export const sortCollapsed = (items) => {
|
|
10
10
|
return [...items].sort((a, b) => {
|
|
11
|
-
if (a.level !== b.level) {
|
|
12
|
-
return b.level - a.level;
|
|
11
|
+
if (a.meta.level !== b.meta.level) {
|
|
12
|
+
return b.meta.level - a.meta.level;
|
|
13
13
|
}
|
|
14
|
-
return a.siblingIndex - b.siblingIndex;
|
|
14
|
+
return a.meta.siblingIndex - b.meta.siblingIndex;
|
|
15
15
|
});
|
|
16
16
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createElement as _createElement } from "react";
|
|
2
3
|
import { pdfjs } from 'react-pdf';
|
|
3
4
|
import { ContentState } from '../ContentState';
|
|
4
5
|
import { LoadingPlaceholder } from '../placeholders';
|
|
@@ -16,10 +17,10 @@ pdfjs.GlobalWorkerOptions.workerSrc = PDFJS_WORKER_URL;
|
|
|
16
17
|
* Компонент для просмотра PDF файлов
|
|
17
18
|
*/
|
|
18
19
|
export const PdfViewer = (props) => {
|
|
19
|
-
const {
|
|
20
|
-
return (_jsx(ContentState, { isError: isError, errorState: errorState, children: _jsxs(Wrapper, { "$isViewerLite": isViewerLite, "$enabledZoom": enabledZoom, children: [_jsx(PDFViewerContainer, { "$isViewerLite": isViewerLite, "$enabledZoom": enabledZoom, children: _jsx(ScrollContainer, { ref: scrollContainerRef, "$isViewerLite": isViewerLite, "$enabledZoom": enabledZoom, children: _jsx(PDFDocument, {
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const { documentProps, pageProps, pageCount, pageHeightList, isError, errorState, paginationRef, isLoading, initialIndex, isRenderList, isViewerLite, scale, zoomOut, zoomIn, isDisabledZoomOutButton, isDisabledZoomInButton, scrollContainerRef, loadingPlaceholderTitle, enabledZoom, } = useLogic(props);
|
|
21
|
+
return (_jsx(ContentState, { isError: isError, errorState: errorState, children: _jsxs(Wrapper, { "$isViewerLite": isViewerLite, "$enabledZoom": enabledZoom, children: [_jsx(PDFViewerContainer, { "$isViewerLite": isViewerLite, "$enabledZoom": enabledZoom, children: _jsx(ScrollContainer, { ref: scrollContainerRef, "$isViewerLite": isViewerLite, "$enabledZoom": enabledZoom, children: _jsx(PDFDocument, Object.assign({}, documentProps, { isLoading: isLoading, loading: _jsx(LoadingPlaceholder, { title: loadingPlaceholderTitle }), isViewerLite: isViewerLite, enabledZoom: enabledZoom, children: isRenderList && (_jsx(List, { paginationRef: paginationRef, initialIndex: initialIndex, children: pageHeightList === null || pageHeightList === void 0 ? void 0 : pageHeightList.map((height, index) => (_createElement(PDFPage, Object.assign({}, pageProps, {
|
|
22
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: Страницы статичны
|
|
23
|
+
key: index, height: height * scale, pageNumber: index + 1, pageCount: pageCount, isViewerLite: isViewerLite, scale: scale, enabledZoom: enabledZoom })))) }, pageHeightList === null || pageHeightList === void 0 ? void 0 : pageHeightList[0])) })) }) }), _jsx(ControlBar, { zoomOut: zoomOut, zoomIn: zoomIn, pageNumber: Number(initialIndex) + 1, buttonProps: {
|
|
23
24
|
isDisabledZoomIn: isDisabledZoomInButton,
|
|
24
25
|
isDisabledZoomOut: isDisabledZoomOutButton,
|
|
25
26
|
}, isViewerLite: isViewerLite, isLoading: isLoading, pageCount: pageCount, enabledZoom: enabledZoom })] }) }));
|
|
@@ -17,6 +17,12 @@ export type PdfViewerProps = {
|
|
|
17
17
|
* Файл для отображения
|
|
18
18
|
*/
|
|
19
19
|
file: Blob | string | null | undefined;
|
|
20
|
+
options?: {
|
|
21
|
+
/**
|
|
22
|
+
* Флаг следует ли включать cookie в запрос. По-умолчанию `true`.
|
|
23
|
+
*/
|
|
24
|
+
withCredentials?: boolean | undefined;
|
|
25
|
+
};
|
|
20
26
|
/**
|
|
21
27
|
* Будет вызван после успешной загрузки файла
|
|
22
28
|
*/
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { type PdfViewerOnLoadSuccessProps, type PdfViewerProps } from '../types';
|
|
3
|
-
export declare const useLogic: ({ file, scrollRef, paginationRef, isFullHeight, renderPageRange, isHidePersonalData, isViewerLite, enabledZoom, ...props }: PdfViewerProps) => {
|
|
4
|
-
|
|
3
|
+
export declare const useLogic: ({ file, scrollRef, paginationRef, isFullHeight, renderPageRange, isHidePersonalData, isViewerLite, enabledZoom, options, ...props }: PdfViewerProps) => {
|
|
4
|
+
documentProps: {
|
|
5
|
+
file: string | Blob | null | undefined;
|
|
6
|
+
options: {
|
|
7
|
+
withCredentials: boolean;
|
|
8
|
+
};
|
|
9
|
+
onLoadSuccess: (pdf: PdfViewerOnLoadSuccessProps) => void;
|
|
10
|
+
onLoadError: (error: Error) => void;
|
|
11
|
+
setContainerWidth: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
12
|
+
};
|
|
13
|
+
pageProps: {
|
|
14
|
+
scrollRef: import("react").RefObject<HTMLElement>;
|
|
15
|
+
onChangePage: (newPage: number) => void;
|
|
16
|
+
isHidePersonalData: boolean | undefined;
|
|
17
|
+
currentPage: number;
|
|
18
|
+
};
|
|
5
19
|
pageCount: number;
|
|
6
20
|
pageHeightList: number[] | null;
|
|
7
21
|
isError: boolean;
|
|
@@ -13,15 +27,9 @@ export declare const useLogic: ({ file, scrollRef, paginationRef, isFullHeight,
|
|
|
13
27
|
title: string;
|
|
14
28
|
errorList: string[];
|
|
15
29
|
} | undefined;
|
|
16
|
-
onLoadSuccess: (pdf: PdfViewerOnLoadSuccessProps) => void;
|
|
17
|
-
onLoadError: (error: Error) => void;
|
|
18
30
|
onRetry: () => void;
|
|
19
|
-
scrollRef: import("react").RefObject<HTMLElement>;
|
|
20
31
|
paginationRef: import("react").RefObject<HTMLDivElement> | undefined;
|
|
21
|
-
setContainerWidth: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
22
|
-
changePage: (newPage: number) => void;
|
|
23
32
|
isLoading: boolean;
|
|
24
|
-
isHidePersonalData: boolean | undefined;
|
|
25
33
|
initialIndex: number | null;
|
|
26
34
|
isRenderList: boolean;
|
|
27
35
|
isViewerLite: boolean | undefined;
|
|
@@ -14,7 +14,7 @@ import { ConfigContext } from '../../ConfigProvider';
|
|
|
14
14
|
import { useZoom } from '../hooks';
|
|
15
15
|
import { getPageHeightList } from '../utils';
|
|
16
16
|
export const useLogic = (_a) => {
|
|
17
|
-
var { file, scrollRef, paginationRef, isFullHeight, renderPageRange, isHidePersonalData, isViewerLite, enabledZoom = true } = _a, props = __rest(_a, ["file", "scrollRef", "paginationRef", "isFullHeight", "renderPageRange", "isHidePersonalData", "isViewerLite", "enabledZoom"]);
|
|
17
|
+
var { file, scrollRef, paginationRef, isFullHeight, renderPageRange, isHidePersonalData, isViewerLite, enabledZoom = true, options } = _a, props = __rest(_a, ["file", "scrollRef", "paginationRef", "isFullHeight", "renderPageRange", "isHidePersonalData", "isViewerLite", "enabledZoom", "options"]);
|
|
18
18
|
const [containerWidth, setContainerWidth] = useState(1);
|
|
19
19
|
const scrollContainerRef = useRef(null);
|
|
20
20
|
const { zoomOut, scale, zoomIn, shouldAnimateZoom } = useZoom({
|
|
@@ -68,7 +68,7 @@ export const useLogic = (_a) => {
|
|
|
68
68
|
(_a = props.onLoadError) === null || _a === void 0 ? void 0 : _a.call(props, error);
|
|
69
69
|
};
|
|
70
70
|
const [initialIndex, setInitialIndex] = useState(null);
|
|
71
|
-
const
|
|
71
|
+
const onChangePage = (newPage) => {
|
|
72
72
|
var _a;
|
|
73
73
|
(_a = props.onChangePage) === null || _a === void 0 ? void 0 : _a.call(props, newPage);
|
|
74
74
|
setInitialIndex(newPage - 1);
|
|
@@ -77,21 +77,30 @@ export const useLogic = (_a) => {
|
|
|
77
77
|
const loadingPlaceholderTitle = isViewerLite
|
|
78
78
|
? undefined
|
|
79
79
|
: 'Загрузка данных...';
|
|
80
|
+
const getOptions = useMemo(() => {
|
|
81
|
+
return Object.assign({ withCredentials: true }, options);
|
|
82
|
+
}, [options]);
|
|
80
83
|
return {
|
|
81
|
-
|
|
84
|
+
documentProps: {
|
|
85
|
+
file,
|
|
86
|
+
options: getOptions,
|
|
87
|
+
onLoadSuccess,
|
|
88
|
+
onLoadError,
|
|
89
|
+
setContainerWidth,
|
|
90
|
+
},
|
|
91
|
+
pageProps: {
|
|
92
|
+
scrollRef,
|
|
93
|
+
onChangePage,
|
|
94
|
+
isHidePersonalData,
|
|
95
|
+
currentPage: Number(initialIndex) + 1,
|
|
96
|
+
},
|
|
82
97
|
pageCount: (pdfParams === null || pdfParams === void 0 ? void 0 : pdfParams.numPages) || 0,
|
|
83
98
|
pageHeightList,
|
|
84
99
|
isError,
|
|
85
100
|
errorState,
|
|
86
|
-
onLoadSuccess,
|
|
87
|
-
onLoadError,
|
|
88
101
|
onRetry,
|
|
89
|
-
scrollRef,
|
|
90
102
|
paginationRef,
|
|
91
|
-
setContainerWidth,
|
|
92
|
-
changePage,
|
|
93
103
|
isLoading,
|
|
94
|
-
isHidePersonalData,
|
|
95
104
|
initialIndex,
|
|
96
105
|
isRenderList,
|
|
97
106
|
isViewerLite,
|
|
@@ -22,7 +22,7 @@ const InfiniteTreeList = (props) => {
|
|
|
22
22
|
Footer: () => {
|
|
23
23
|
const { isLoading, isError, isEndReached } = footerProps;
|
|
24
24
|
if (!isLoading && !isError && !isEndReached) {
|
|
25
|
-
return
|
|
25
|
+
return (0, jsx_runtime_1.jsx)(styles_1.FooterDummy, {});
|
|
26
26
|
}
|
|
27
27
|
return ((0, jsx_runtime_1.jsxs)(styles_1.Footer, { children: [isLoading && (0, jsx_runtime_1.jsx)(Loader_1.Loader, {}), isError && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, { onRetry: onRetry }), isEndReached && ((0, jsx_runtime_1.jsx)(EndData_1.EndData, { endOfScrollMsg: endOfScrollMsg }))] }));
|
|
28
28
|
},
|
|
@@ -6,20 +6,20 @@ const InfiniteTreeListContext_1 = require("../../InfiniteTreeListContext");
|
|
|
6
6
|
const InfiniteTreeListItem_1 = require("../../InfiniteTreeListItem");
|
|
7
7
|
const useLogic = ({ actions }) => {
|
|
8
8
|
const { main, secondary = [] } = actions;
|
|
9
|
-
const {
|
|
10
|
-
const {
|
|
9
|
+
const { setDisabledReason, item } = (0, react_1.useContext)(InfiniteTreeListItem_1.TreeListItemContext);
|
|
10
|
+
const { setDisabled } = (0, react_1.useContext)(InfiniteTreeListContext_1.InfiniteTreeListContext);
|
|
11
11
|
const blockingAction = (0, react_1.useMemo)(() => [...main, ...secondary].find((action) => action.isBlockingOperation && action.loading), [main, secondary]);
|
|
12
12
|
const isDisabledAction = Boolean(blockingAction);
|
|
13
13
|
(0, react_1.useEffect)(() => {
|
|
14
14
|
if (blockingAction) {
|
|
15
|
-
setDisabled(true, blockingAction === null || blockingAction === void 0 ? void 0 : blockingAction.loadingNote);
|
|
16
15
|
// Добавляем id элемента в Set disabled элементов
|
|
17
|
-
|
|
16
|
+
setDisabled(item.id, true);
|
|
17
|
+
setDisabledReason(blockingAction === null || blockingAction === void 0 ? void 0 : blockingAction.loadingNote);
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
setDisabled(false);
|
|
21
20
|
// Удаляем id элемента из Set disabled элементов
|
|
22
|
-
|
|
21
|
+
setDisabled(item.id, false);
|
|
22
|
+
setDisabledReason('');
|
|
23
23
|
}, [blockingAction, item.id]);
|
|
24
24
|
const handleActionClick = (0, react_1.useCallback)((onClick) => () => {
|
|
25
25
|
onClick === null || onClick === void 0 ? void 0 : onClick(item);
|
package/node/components/InfiniteTreeList/InfiniteTreeListContext/InfiniteTreeListContext.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
export type InfiniteTreeListContextProps = {
|
|
3
3
|
itemSkeleton: ReactNode;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
disabledIdList: Set<string>;
|
|
5
|
+
setDisabled: (itemId: string, disabled: boolean) => void;
|
|
6
6
|
};
|
|
7
7
|
export declare const InfiniteTreeListContext: import("react").Context<InfiniteTreeListContextProps>;
|
|
@@ -4,6 +4,6 @@ exports.InfiniteTreeListContext = void 0;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
exports.InfiniteTreeListContext = (0, react_1.createContext)({
|
|
6
6
|
itemSkeleton: '',
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
disabledIdList: new Set(),
|
|
8
|
+
setDisabled: () => undefined,
|
|
9
9
|
});
|