@hh.ru/magritte-ui-tree-selector 1.0.2 → 1.1.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/Action.d.ts +11 -0
- package/Action.js +18 -0
- package/Action.js.map +1 -0
- package/Item.d.ts +18 -0
- package/Item.js +46 -0
- package/Item.js.map +1 -0
- package/ItemContent-3c0cd83c.js +20 -0
- package/ItemContent-3c0cd83c.js.map +1 -0
- package/ItemContent.d.ts +19 -0
- package/ItemContent.js +11 -0
- package/ItemContent.js.map +1 -0
- package/ItemsList.d.ts +18 -0
- package/ItemsList.js +23 -0
- package/ItemsList.js.map +1 -0
- package/TreeSelector.d.ts +4 -0
- package/TreeSelector.js +29 -0
- package/TreeSelector.js.map +1 -0
- package/UncontrolledTreeSelector.d.ts +4 -0
- package/UncontrolledTreeSelector.js +38 -0
- package/UncontrolledTreeSelector.js.map +1 -0
- package/collection/treeCollection.js +1 -0
- package/collection/treeCollectionHelper.js +1 -0
- package/collection/types.js +1 -0
- package/index.css +46 -0
- package/index.d.ts +1 -1
- package/index.js +15 -1
- package/index.js.map +1 -1
- package/package.json +14 -2
- package/strategy/createSingleValueToggler.js +1 -0
- package/strategy/createTreeCollectionToggler.d.ts +2 -2
- package/strategy/createTreeCollectionToggler.js +3 -2
- package/strategy/createTreeCollectionToggler.js.map +1 -1
- package/strategy/dummyToggle.js +1 -0
- package/strategy/immutableSelectionStrategy.d.ts +0 -1
- package/strategy/immutableSelectionStrategy.js +1 -6
- package/strategy/immutableSelectionStrategy.js.map +1 -1
- package/strategy/selectionStrategy.d.ts +0 -2
- package/strategy/selectionStrategy.js +2 -10
- package/strategy/selectionStrategy.js.map +1 -1
- package/strategy/types.d.ts +0 -4
- package/strategy/types.js +1 -0
- package/types.d.ts +22 -0
- package/types.js +3 -0
- package/types.js.map +1 -0
- package/useExpanded.d.ts +16 -0
- package/useExpanded.js +50 -0
- package/useExpanded.js.map +1 -0
- package/useIndeterminate.d.ts +17 -0
- package/useIndeterminate.js +29 -0
- package/useIndeterminate.js.map +1 -0
- package/useSelected.d.ts +16 -0
- package/useSelected.js +19 -0
- package/useSelected.js.map +1 -0
- package/strategy/createTreeSelectionExcluder.d.ts +0 -11
- package/strategy/createTreeSelectionExcluder.js +0 -52
- package/strategy/createTreeSelectionExcluder.js.map +0 -1
package/Action.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { TreeModel } from './collection/types';
|
|
3
|
+
interface ActionProps {
|
|
4
|
+
singleChoice?: boolean;
|
|
5
|
+
onChange: (id: string, isSelected: boolean) => void;
|
|
6
|
+
id: TreeModel['id'];
|
|
7
|
+
selected: boolean;
|
|
8
|
+
indeterminate: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const Action: FC<ActionProps>;
|
|
11
|
+
export {};
|
package/Action.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import { Radio, Checkbox } from '@hh.ru/magritte-ui-checkbox-radio';
|
|
5
|
+
|
|
6
|
+
const Action = ({ id, singleChoice, indeterminate, selected, onChange }) => {
|
|
7
|
+
const handleChange = useCallback((event) => {
|
|
8
|
+
onChange(id, event.target.checked);
|
|
9
|
+
}, [id, onChange]);
|
|
10
|
+
const inputProps = {
|
|
11
|
+
checked: selected,
|
|
12
|
+
onChange: handleChange,
|
|
13
|
+
};
|
|
14
|
+
return singleChoice ? jsx(Radio, { ...inputProps }) : jsx(Checkbox, { ...inputProps, indeterminate: indeterminate });
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { Action };
|
|
18
|
+
//# sourceMappingURL=Action.js.map
|
package/Action.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Action.js","sources":["../src/Action.tsx"],"sourcesContent":["import { ChangeEventHandler, FC, useCallback } from 'react';\n\nimport { Checkbox, Radio } from '@hh.ru/magritte-ui-checkbox-radio';\nimport { TreeModel } from '@hh.ru/magritte-ui-tree-selector/collection/types';\n\ninterface ActionProps {\n singleChoice?: boolean;\n onChange: (id: string, isSelected: boolean) => void;\n id: TreeModel['id'];\n selected: boolean;\n indeterminate: boolean;\n}\n\nexport const Action: FC<ActionProps> = ({ id, singleChoice, indeterminate, selected, onChange }) => {\n const handleChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (event) => {\n onChange(id, event.target.checked);\n },\n [id, onChange]\n );\n\n const inputProps = {\n checked: selected,\n onChange: handleChange,\n };\n\n return singleChoice ? <Radio {...inputProps} /> : <Checkbox {...inputProps} indeterminate={indeterminate} />;\n};\n"],"names":["_jsx"],"mappings":";;;;AAaa,MAAA,MAAM,GAAoB,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAI;AAC/F,IAAA,MAAM,YAAY,GAAyC,WAAW,CAClE,CAAC,KAAK,KAAI;QACN,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACvC,KAAC,EACD,CAAC,EAAE,EAAE,QAAQ,CAAC,CACjB,CAAC;AAEF,IAAA,MAAM,UAAU,GAAG;AACf,QAAA,OAAO,EAAE,QAAQ;AACjB,QAAA,QAAQ,EAAE,YAAY;KACzB,CAAC;IAEF,OAAO,YAAY,GAAGA,IAAC,KAAK,EAAA,EAAA,GAAK,UAAU,EAAI,CAAA,GAAGA,GAAA,CAAC,QAAQ,EAAK,EAAA,GAAA,UAAU,EAAE,aAAa,EAAE,aAAa,EAAA,CAAI,CAAC;AACjH;;;;"}
|
package/Item.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PropsWithChildren, ReactElement } from 'react';
|
|
2
|
+
import TreeCollection from './collection/treeCollection';
|
|
3
|
+
import { AdditionalDefault, IdCollectionPredicate, TreeModel } from './collection/types';
|
|
4
|
+
interface ItemProps<A extends AdditionalDefault> extends PropsWithChildren {
|
|
5
|
+
collection: TreeCollection<A>;
|
|
6
|
+
parentId?: string;
|
|
7
|
+
item: TreeModel<A>;
|
|
8
|
+
leavesOnly?: boolean;
|
|
9
|
+
checkSelectable?: IdCollectionPredicate;
|
|
10
|
+
isExpanded: boolean;
|
|
11
|
+
isSelected: boolean;
|
|
12
|
+
singleChoice?: boolean;
|
|
13
|
+
isIndeterminate: boolean;
|
|
14
|
+
onExpansion: (id: string) => void;
|
|
15
|
+
onChange: (id: string, isSelected: boolean) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare const Item: <A extends AdditionalDefault>({ collection, item, parentId, isExpanded, isSelected, isIndeterminate, leavesOnly, singleChoice, checkSelectable, onExpansion, onChange, children, }: ItemProps<A>) => ReactElement;
|
|
18
|
+
export {};
|
package/Item.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
import { s as styles, I as ItemContent } from './ItemContent-3c0cd83c.js';
|
|
6
|
+
import '@hh.ru/magritte-ui-cell';
|
|
7
|
+
import '@hh.ru/magritte-ui-icon/icon';
|
|
8
|
+
import './Action.js';
|
|
9
|
+
import '@hh.ru/magritte-ui-checkbox-radio';
|
|
10
|
+
import '@hh.ru/magritte-ui-typography';
|
|
11
|
+
|
|
12
|
+
const Item = ({ collection, item, parentId, isExpanded, isSelected, isIndeterminate, leavesOnly, singleChoice, checkSelectable, onExpansion, onChange, children, }) => {
|
|
13
|
+
const modelsOnLevel = useMemo(() => (parentId ? collection.getChildren(parentId) : collection.getTopLevel()), [parentId, collection]);
|
|
14
|
+
const hasChildrenOnLevel = useMemo(() => {
|
|
15
|
+
return modelsOnLevel.some((model) => {
|
|
16
|
+
return collection.hasChildren(model.id);
|
|
17
|
+
});
|
|
18
|
+
}, [modelsOnLevel, collection]);
|
|
19
|
+
const hasActionOnLevel = useMemo(() => {
|
|
20
|
+
return modelsOnLevel.some((model) => {
|
|
21
|
+
const hasChildren = collection.hasChildren(model.id);
|
|
22
|
+
const hasAction = !(leavesOnly && hasChildren) && checkSelectable?.(model.id, collection);
|
|
23
|
+
return hasAction;
|
|
24
|
+
});
|
|
25
|
+
}, [modelsOnLevel, collection, leavesOnly, checkSelectable]);
|
|
26
|
+
const hasLetterOnLevel = useMemo(() => {
|
|
27
|
+
return modelsOnLevel.some((model) => model.additional?.char);
|
|
28
|
+
}, [modelsOnLevel]);
|
|
29
|
+
const hasChildren = collection.hasChildren(item.id);
|
|
30
|
+
const hasAction = !(leavesOnly && hasChildren) && checkSelectable?.(item.id, collection);
|
|
31
|
+
const hasLetter = item.additional?.char;
|
|
32
|
+
const hasParentAction = parentId ? !leavesOnly && checkSelectable?.(parentId, collection) : false;
|
|
33
|
+
const actionsCount = +hasLetterOnLevel + +hasActionOnLevel + +hasChildrenOnLevel;
|
|
34
|
+
const hasShift = actionsCount > 1 &&
|
|
35
|
+
((hasParentAction && (hasChildrenOnLevel || hasLetterOnLevel)) ||
|
|
36
|
+
(!hasParentAction && (hasLetterOnLevel || (!hasChildrenOnLevel && hasActionOnLevel))));
|
|
37
|
+
return (jsxs("div", { className: classnames({
|
|
38
|
+
[styles.withLetter]: hasLetter || hasLetterOnLevel,
|
|
39
|
+
[styles.withChevron]: hasChildren || hasChildrenOnLevel,
|
|
40
|
+
[styles.withAction]: hasAction || hasActionOnLevel,
|
|
41
|
+
[styles.withShift]: hasShift && parentId,
|
|
42
|
+
}), children: [jsx(ItemContent, { item: item, hasChildren: hasChildren, hasAction: !!hasAction, letter: hasLetter, hasChildrenOnLevel: hasChildrenOnLevel, expanded: isExpanded, onExpansion: onExpansion, selected: isSelected, onChange: onChange, singleChoice: singleChoice, indeterminate: isIndeterminate, hasActionOnLevel: hasActionOnLevel, hasLetterOnLevel: hasLetterOnLevel }), children && jsx("div", { className: styles.children, children: children })] }));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { Item };
|
|
46
|
+
//# sourceMappingURL=Item.js.map
|
package/Item.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Item.js","sources":["../src/Item.tsx"],"sourcesContent":["import { PropsWithChildren, ReactElement, useMemo } from 'react';\nimport classnames from 'classnames';\n\nimport { ItemContent } from '@hh.ru/magritte-ui-tree-selector/ItemContent';\nimport TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { AdditionalDefault, IdCollectionPredicate, TreeModel } from '@hh.ru/magritte-ui-tree-selector/collection/types';\n\nimport styles from './tree-selector-item.less';\n\ninterface ItemProps<A extends AdditionalDefault> extends PropsWithChildren {\n collection: TreeCollection<A>;\n parentId?: string;\n item: TreeModel<A>;\n leavesOnly?: boolean;\n checkSelectable?: IdCollectionPredicate;\n isExpanded: boolean;\n isSelected: boolean;\n singleChoice?: boolean;\n isIndeterminate: boolean;\n onExpansion: (id: string) => void;\n onChange: (id: string, isSelected: boolean) => void;\n}\n\nexport const Item = <A extends AdditionalDefault>({\n collection,\n item,\n parentId,\n isExpanded,\n isSelected,\n isIndeterminate,\n leavesOnly,\n singleChoice,\n checkSelectable,\n onExpansion,\n onChange,\n children,\n}: ItemProps<A>): ReactElement => {\n const modelsOnLevel = useMemo(\n () => (parentId ? collection.getChildren(parentId) : collection.getTopLevel()),\n [parentId, collection]\n );\n const hasChildrenOnLevel = useMemo(() => {\n return modelsOnLevel.some((model) => {\n return collection.hasChildren(model.id);\n });\n }, [modelsOnLevel, collection]);\n const hasActionOnLevel = useMemo(() => {\n return modelsOnLevel.some((model) => {\n const hasChildren = collection.hasChildren(model.id);\n const hasAction = !(leavesOnly && hasChildren) && checkSelectable?.(model.id, collection);\n return hasAction;\n });\n }, [modelsOnLevel, collection, leavesOnly, checkSelectable]);\n const hasLetterOnLevel = useMemo(() => {\n return modelsOnLevel.some((model) => model.additional?.char);\n }, [modelsOnLevel]);\n const hasChildren = collection.hasChildren(item.id);\n const hasAction = !(leavesOnly && hasChildren) && checkSelectable?.(item.id, collection);\n const hasLetter = item.additional?.char;\n const hasParentAction = parentId ? !leavesOnly && checkSelectable?.(parentId, collection) : false;\n const actionsCount = +hasLetterOnLevel + +hasActionOnLevel + +hasChildrenOnLevel;\n const hasShift =\n actionsCount > 1 &&\n ((hasParentAction && (hasChildrenOnLevel || hasLetterOnLevel)) ||\n (!hasParentAction && (hasLetterOnLevel || (!hasChildrenOnLevel && hasActionOnLevel))));\n\n return (\n <div\n className={classnames({\n [styles.withLetter]: hasLetter || hasLetterOnLevel,\n [styles.withChevron]: hasChildren || hasChildrenOnLevel,\n [styles.withAction]: hasAction || hasActionOnLevel,\n [styles.withShift]: hasShift && parentId,\n })}\n >\n <ItemContent\n item={item}\n hasChildren={hasChildren}\n hasAction={!!hasAction}\n letter={hasLetter}\n hasChildrenOnLevel={hasChildrenOnLevel}\n expanded={isExpanded}\n onExpansion={onExpansion}\n selected={isSelected}\n onChange={onChange}\n singleChoice={singleChoice}\n indeterminate={isIndeterminate}\n hasActionOnLevel={hasActionOnLevel}\n hasLetterOnLevel={hasLetterOnLevel}\n />\n {children && <div className={styles.children}>{children}</div>}\n </div>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
import { Cell, CellText } from '@hh.ru/magritte-ui-cell';
|
|
6
|
+
import { DotFilledSize24, ChevronDownOutlinedSize24, ChevronUpOutlinedSize24 } from '@hh.ru/magritte-ui-icon/icon';
|
|
7
|
+
import { Action } from './Action.js';
|
|
8
|
+
import { Text } from '@hh.ru/magritte-ui-typography';
|
|
9
|
+
|
|
10
|
+
var styles = {"wrapper":"magritte-wrapper___GHKV6_1-1-0","letter":"magritte-letter___yZOCU_1-1-0","icon":"magritte-icon___kO3Fj_1-1-0","iconActive":"magritte-iconActive___4yrG5_1-1-0","content":"magritte-content___ZRc6R_1-1-0","with-action":"magritte-with-action___-lsFP_1-1-0","withAction":"magritte-with-action___-lsFP_1-1-0","children":"magritte-children___kq-eq_1-1-0","with-letter":"magritte-with-letter___skx30_1-1-0","withLetter":"magritte-with-letter___skx30_1-1-0","with-chevron":"magritte-with-chevron___VOytc_1-1-0","withChevron":"magritte-with-chevron___VOytc_1-1-0","with-shift":"magritte-with-shift___ZErxZ_1-1-0","withShift":"magritte-with-shift___ZErxZ_1-1-0"};
|
|
11
|
+
|
|
12
|
+
const ItemContent = ({ item, hasAction, hasChildren, letter, expanded, onExpansion, hasChildrenOnLevel, hasLetterOnLevel, selected, onChange, indeterminate, singleChoice, hasActionOnLevel, }) => {
|
|
13
|
+
const handleExpandableClick = useCallback(() => onExpansion && onExpansion(item.id), [item.id, onExpansion]);
|
|
14
|
+
return (jsxs("div", { className: styles.wrapper, children: [(letter || hasLetterOnLevel) && (jsx("div", { className: styles.letter, children: letter && (jsx(Text, { typography: "subtitle-1-semibold", style: "secondary", Element: "span", children: letter })) })), hasActionOnLevel && hasChildren && !hasAction && (jsx("div", { className: styles.icon, children: jsx(DotFilledSize24, { initial: "tertiary" }) })), (hasChildrenOnLevel || hasChildren) && (jsxs("div", { className: classnames(styles.icon, {
|
|
15
|
+
[styles.iconActive]: hasChildren,
|
|
16
|
+
}), onClick: handleExpandableClick, children: [expanded && hasChildren && jsx(ChevronDownOutlinedSize24, { initial: "tertiary" }), !expanded && hasChildren && jsx(ChevronUpOutlinedSize24, { initial: "tertiary" }), hasChildrenOnLevel && !hasChildren && jsx(DotFilledSize24, { initial: "tertiary" })] })), jsx(Cell, { left: hasAction ? (jsx(Action, { selected: selected, onChange: onChange, id: item.id, indeterminate: indeterminate, singleChoice: singleChoice })) : undefined, children: jsx(CellText, { children: item.text }) })] }));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export { ItemContent as I, styles as s };
|
|
20
|
+
//# sourceMappingURL=ItemContent-3c0cd83c.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ItemContent-3c0cd83c.js","sources":["../src/ItemContent.tsx"],"sourcesContent":["import { ReactElement, useCallback } from 'react';\nimport classnames from 'classnames';\n\nimport { Cell, CellText } from '@hh.ru/magritte-ui-cell';\nimport { ChevronDownOutlinedSize24, ChevronUpOutlinedSize24, DotFilledSize24 } from '@hh.ru/magritte-ui-icon/icon';\nimport { Action } from '@hh.ru/magritte-ui-tree-selector/Action';\nimport { AdditionalDefault, TreeModel } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './tree-selector-item.less';\n\ninterface ItemContent<A extends AdditionalDefault> {\n item: TreeModel<A>;\n hasChildren: boolean;\n hasAction: boolean;\n letter?: string;\n onExpansion: (id: string) => void;\n expanded?: boolean;\n hasChildrenOnLevel: boolean;\n selected: boolean;\n onChange: (id: string, isSelected: boolean) => void;\n indeterminate: boolean;\n singleChoice?: boolean;\n hasActionOnLevel: boolean;\n hasLetterOnLevel: boolean;\n}\n\nconst ItemContent = <A extends AdditionalDefault>({\n item,\n hasAction,\n hasChildren,\n letter,\n expanded,\n onExpansion,\n hasChildrenOnLevel,\n hasLetterOnLevel,\n selected,\n onChange,\n indeterminate,\n singleChoice,\n hasActionOnLevel,\n}: ItemContent<A>): ReactElement => {\n const handleExpandableClick = useCallback(() => onExpansion && onExpansion(item.id), [item.id, onExpansion]);\n\n return (\n <div className={styles.wrapper}>\n {(letter || hasLetterOnLevel) && (\n <div className={styles.letter}>\n {letter && (\n <Text typography=\"subtitle-1-semibold\" style=\"secondary\" Element=\"span\">\n {letter}\n </Text>\n )}\n </div>\n )}\n {hasActionOnLevel && hasChildren && !hasAction && (\n <div className={styles.icon}>\n <DotFilledSize24 initial=\"tertiary\" />\n </div>\n )}\n\n {(hasChildrenOnLevel || hasChildren) && (\n <div\n className={classnames(styles.icon, {\n [styles.iconActive]: hasChildren,\n })}\n onClick={handleExpandableClick}\n >\n {expanded && hasChildren && <ChevronDownOutlinedSize24 initial=\"tertiary\" />}\n {!expanded && hasChildren && <ChevronUpOutlinedSize24 initial=\"tertiary\" />}\n {hasChildrenOnLevel && !hasChildren && <DotFilledSize24 initial=\"tertiary\" />}\n </div>\n )}\n\n <Cell\n left={\n hasAction ? (\n <Action\n selected={selected}\n onChange={onChange}\n id={item.id}\n indeterminate={indeterminate}\n singleChoice={singleChoice}\n />\n ) : undefined\n }\n >\n <CellText>{item.text}</CellText>\n </Cell>\n </div>\n );\n};\n\nexport { ItemContent };\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;;;;AA2BA,MAAM,WAAW,GAAG,CAA8B,EAC9C,IAAI,EACJ,SAAS,EACT,WAAW,EACX,MAAM,EACN,QAAQ,EACR,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,gBAAgB,GACH,KAAkB;IAC/B,MAAM,qBAAqB,GAAG,WAAW,CAAC,MAAM,WAAW,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;AAE7G,IAAA,QACIA,IAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,OAAO,EACzB,QAAA,EAAA,CAAA,CAAC,MAAM,IAAI,gBAAgB,MACxBC,GAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,MAAM,EAAA,QAAA,EACxB,MAAM,KACHA,IAAC,IAAI,EAAA,EAAC,UAAU,EAAC,qBAAqB,EAAC,KAAK,EAAC,WAAW,EAAC,OAAO,EAAC,MAAM,EAAA,QAAA,EAClE,MAAM,EACJ,CAAA,CACV,EACC,CAAA,CACT,EACA,gBAAgB,IAAI,WAAW,IAAI,CAAC,SAAS,KAC1CA,GAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,IAAI,EACvB,QAAA,EAAAA,GAAA,CAAC,eAAe,EAAC,EAAA,OAAO,EAAC,UAAU,GAAG,EACpC,CAAA,CACT,EAEA,CAAC,kBAAkB,IAAI,WAAW,MAC/BD,IAAA,CAAA,KAAA,EAAA,EACI,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE;AAC/B,oBAAA,CAAC,MAAM,CAAC,UAAU,GAAG,WAAW;iBACnC,CAAC,EACF,OAAO,EAAE,qBAAqB,aAE7B,QAAQ,IAAI,WAAW,IAAIC,GAAA,CAAC,yBAAyB,EAAC,EAAA,OAAO,EAAC,UAAU,EAAA,CAAG,EAC3E,CAAC,QAAQ,IAAI,WAAW,IAAIA,GAAA,CAAC,uBAAuB,EAAC,EAAA,OAAO,EAAC,UAAU,EAAA,CAAG,EAC1E,kBAAkB,IAAI,CAAC,WAAW,IAAIA,IAAC,eAAe,EAAA,EAAC,OAAO,EAAC,UAAU,GAAG,CAC3E,EAAA,CAAA,CACT,EAEDA,GAAA,CAAC,IAAI,EAAA,EACD,IAAI,EACA,SAAS,IACLA,GAAC,CAAA,MAAM,IACH,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,IAAI,CAAC,EAAE,EACX,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,GAC5B,IACF,SAAS,YAGjBA,GAAC,CAAA,QAAQ,cAAE,IAAI,CAAC,IAAI,EAAY,CAAA,EAAA,CAC7B,CACL,EAAA,CAAA,EACR;AACN;;;;"}
|
package/ItemContent.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { AdditionalDefault, TreeModel } from './collection/types';
|
|
3
|
+
interface ItemContent<A extends AdditionalDefault> {
|
|
4
|
+
item: TreeModel<A>;
|
|
5
|
+
hasChildren: boolean;
|
|
6
|
+
hasAction: boolean;
|
|
7
|
+
letter?: string;
|
|
8
|
+
onExpansion: (id: string) => void;
|
|
9
|
+
expanded?: boolean;
|
|
10
|
+
hasChildrenOnLevel: boolean;
|
|
11
|
+
selected: boolean;
|
|
12
|
+
onChange: (id: string, isSelected: boolean) => void;
|
|
13
|
+
indeterminate: boolean;
|
|
14
|
+
singleChoice?: boolean;
|
|
15
|
+
hasActionOnLevel: boolean;
|
|
16
|
+
hasLetterOnLevel: boolean;
|
|
17
|
+
}
|
|
18
|
+
declare const ItemContent: <A extends AdditionalDefault>({ item, hasAction, hasChildren, letter, expanded, onExpansion, hasChildrenOnLevel, hasLetterOnLevel, selected, onChange, indeterminate, singleChoice, hasActionOnLevel, }: ItemContent<A>) => ReactElement;
|
|
19
|
+
export { ItemContent };
|
package/ItemContent.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import 'react/jsx-runtime';
|
|
3
|
+
import 'react';
|
|
4
|
+
import 'classnames';
|
|
5
|
+
import '@hh.ru/magritte-ui-cell';
|
|
6
|
+
import '@hh.ru/magritte-ui-icon/icon';
|
|
7
|
+
import './Action.js';
|
|
8
|
+
import '@hh.ru/magritte-ui-typography';
|
|
9
|
+
export { I as ItemContent } from './ItemContent-3c0cd83c.js';
|
|
10
|
+
import '@hh.ru/magritte-ui-checkbox-radio';
|
|
11
|
+
//# sourceMappingURL=ItemContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ItemContent.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/ItemsList.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import TreeCollection from './collection/treeCollection';
|
|
3
|
+
import { AdditionalDefault, IdCollectionPredicate, TreeModel } from './collection/types';
|
|
4
|
+
interface ItemsListProps<A extends AdditionalDefault> {
|
|
5
|
+
items: TreeModel<A>[];
|
|
6
|
+
collection: TreeCollection<A>;
|
|
7
|
+
leavesOnly?: boolean;
|
|
8
|
+
checkSelectable?: IdCollectionPredicate;
|
|
9
|
+
parentId?: TreeModel<A>['id'];
|
|
10
|
+
onExpansion: (id: string) => void;
|
|
11
|
+
expanded: string[];
|
|
12
|
+
selected: string[];
|
|
13
|
+
onChange: (id: string, isSelected: boolean) => void;
|
|
14
|
+
indeterminate: string[];
|
|
15
|
+
singleChoice?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare const ItemsList: <A extends AdditionalDefault>(props: ItemsListProps<A>) => ReactElement;
|
|
18
|
+
export {};
|
package/ItemsList.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { Item } from './Item.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
import 'classnames';
|
|
6
|
+
import './ItemContent-3c0cd83c.js';
|
|
7
|
+
import '@hh.ru/magritte-ui-cell';
|
|
8
|
+
import '@hh.ru/magritte-ui-icon/icon';
|
|
9
|
+
import './Action.js';
|
|
10
|
+
import '@hh.ru/magritte-ui-checkbox-radio';
|
|
11
|
+
import '@hh.ru/magritte-ui-typography';
|
|
12
|
+
|
|
13
|
+
const ItemsList = (props) => {
|
|
14
|
+
const { items, collection, leavesOnly, checkSelectable, selected, parentId, expanded, onExpansion, indeterminate, onChange, singleChoice, } = props;
|
|
15
|
+
return (jsx(Fragment, { children: items.map((item) => {
|
|
16
|
+
const isExpanded = expanded.includes(item.id);
|
|
17
|
+
const hasChildren = collection.hasChildren(item.id);
|
|
18
|
+
return (jsx(Item, { collection: collection, checkSelectable: checkSelectable, isSelected: selected.includes(item.id), isExpanded: isExpanded, isIndeterminate: indeterminate.includes(item.id), parentId: parentId, item: item, leavesOnly: leavesOnly, singleChoice: singleChoice, onExpansion: onExpansion, onChange: onChange, children: hasChildren && isExpanded && (jsx(ItemsList, { ...props, items: collection.getChildren(item.id), parentId: item.id })) }, item.id));
|
|
19
|
+
}) }));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { ItemsList };
|
|
23
|
+
//# sourceMappingURL=ItemsList.js.map
|
package/ItemsList.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ItemsList.js","sources":["../src/ItemsList.tsx"],"sourcesContent":["import { ReactElement } from 'react';\n\nimport { Item } from '@hh.ru/magritte-ui-tree-selector/Item';\nimport TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { AdditionalDefault, IdCollectionPredicate, TreeModel } from '@hh.ru/magritte-ui-tree-selector/collection/types';\n\ninterface ItemsListProps<A extends AdditionalDefault> {\n items: TreeModel<A>[];\n collection: TreeCollection<A>;\n leavesOnly?: boolean;\n checkSelectable?: IdCollectionPredicate;\n parentId?: TreeModel<A>['id'];\n onExpansion: (id: string) => void;\n expanded: string[];\n selected: string[];\n onChange: (id: string, isSelected: boolean) => void;\n indeterminate: string[];\n singleChoice?: boolean;\n}\n\nexport const ItemsList = <A extends AdditionalDefault>(props: ItemsListProps<A>): ReactElement => {\n const {\n items,\n collection,\n leavesOnly,\n checkSelectable,\n selected,\n parentId,\n expanded,\n onExpansion,\n indeterminate,\n onChange,\n singleChoice,\n } = props;\n return (\n <>\n {items.map((item) => {\n const isExpanded = expanded.includes(item.id);\n const hasChildren = collection.hasChildren(item.id);\n\n return (\n <Item\n key={item.id}\n collection={collection}\n checkSelectable={checkSelectable}\n isSelected={selected.includes(item.id)}\n isExpanded={isExpanded}\n isIndeterminate={indeterminate.includes(item.id)}\n parentId={parentId}\n item={item}\n leavesOnly={leavesOnly}\n singleChoice={singleChoice}\n onExpansion={onExpansion}\n onChange={onChange}\n >\n {hasChildren && isExpanded && (\n <ItemsList {...props} items={collection.getChildren(item.id)} parentId={item.id} />\n )}\n </Item>\n );\n })}\n </>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;;;;;AAoBa,MAAA,SAAS,GAAG,CAA8B,KAAwB,KAAkB;IAC7F,MAAM,EACF,KAAK,EACL,UAAU,EACV,UAAU,EACV,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,aAAa,EACb,QAAQ,EACR,YAAY,GACf,GAAG,KAAK,CAAC;IACV,QACIA,0BACK,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;YAChB,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEpD,QACIA,IAAC,IAAI,EAAA,EAED,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe,EAChC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EACtC,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAChD,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAEjB,QAAA,EAAA,WAAW,IAAI,UAAU,KACtBA,GAAC,CAAA,SAAS,EAAK,EAAA,GAAA,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,GAAI,CACtF,EAAA,EAfI,IAAI,CAAC,EAAE,CAgBT,EACT;SACL,CAAC,EACH,CAAA,EACL;AACN;;;;"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { AdditionalDefault } from './collection/types';
|
|
3
|
+
import { ControlledTreeSelectorProps } from './types';
|
|
4
|
+
export declare const TreeSelector: <A extends AdditionalDefault>({ collection, checkSelectable, initialExpanded, value: selected, leavesOnly, singleChoice, expanded, onExpand, onChange, }: ControlledTreeSelectorProps<A>) => ReactElement;
|
package/TreeSelector.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { ItemsList } from './ItemsList.js';
|
|
4
|
+
import useExpanded from './useExpanded.js';
|
|
5
|
+
import { useIndeterminate } from './useIndeterminate.js';
|
|
6
|
+
import './Item.js';
|
|
7
|
+
import 'react';
|
|
8
|
+
import 'classnames';
|
|
9
|
+
import './ItemContent-3c0cd83c.js';
|
|
10
|
+
import '@hh.ru/magritte-ui-cell';
|
|
11
|
+
import '@hh.ru/magritte-ui-icon/icon';
|
|
12
|
+
import './Action.js';
|
|
13
|
+
import '@hh.ru/magritte-ui-checkbox-radio';
|
|
14
|
+
import '@hh.ru/magritte-ui-typography';
|
|
15
|
+
|
|
16
|
+
const defaultCheckSelectable = () => true;
|
|
17
|
+
const defaultArray = [];
|
|
18
|
+
const TreeSelector = ({ collection, checkSelectable = defaultCheckSelectable, initialExpanded = defaultArray, value: selected, leavesOnly, singleChoice, expanded, onExpand, onChange, }) => {
|
|
19
|
+
const { indeterminate } = useIndeterminate({ collection, selected });
|
|
20
|
+
const { expanded: currentExpanded, handleExpansion } = useExpanded({
|
|
21
|
+
initialValue: expanded ? expanded.slice() : initialExpanded.slice(),
|
|
22
|
+
controlledExpanded: expanded,
|
|
23
|
+
onExpand,
|
|
24
|
+
});
|
|
25
|
+
return (jsx("div", { children: jsx(ItemsList, { collection: collection, items: collection.getTopLevel(), leavesOnly: leavesOnly, checkSelectable: checkSelectable, expanded: currentExpanded, onExpansion: handleExpansion, selected: selected, onChange: onChange, singleChoice: singleChoice, indeterminate: indeterminate }) }));
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { TreeSelector };
|
|
29
|
+
//# sourceMappingURL=TreeSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeSelector.js","sources":["../src/TreeSelector.tsx"],"sourcesContent":["import { ReactElement } from 'react';\n\nimport { ItemsList } from '@hh.ru/magritte-ui-tree-selector/ItemsList';\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport { ControlledTreeSelectorProps } from '@hh.ru/magritte-ui-tree-selector/types';\nimport useExpanded from '@hh.ru/magritte-ui-tree-selector/useExpanded';\nimport { useIndeterminate } from '@hh.ru/magritte-ui-tree-selector/useIndeterminate';\n\nconst defaultCheckSelectable = () => true;\nconst defaultArray: string[] = [];\n\nexport const TreeSelector = <A extends AdditionalDefault>({\n collection,\n checkSelectable = defaultCheckSelectable,\n initialExpanded = defaultArray,\n value: selected,\n leavesOnly,\n singleChoice,\n expanded,\n onExpand,\n onChange,\n}: ControlledTreeSelectorProps<A>): ReactElement => {\n const { indeterminate } = useIndeterminate({ collection, selected });\n const { expanded: currentExpanded, handleExpansion } = useExpanded({\n initialValue: expanded ? expanded.slice() : initialExpanded.slice(),\n controlledExpanded: expanded,\n onExpand,\n });\n return (\n <div>\n <ItemsList\n collection={collection}\n items={collection.getTopLevel()}\n leavesOnly={leavesOnly}\n checkSelectable={checkSelectable}\n expanded={currentExpanded}\n onExpansion={handleExpansion}\n selected={selected}\n onChange={onChange}\n singleChoice={singleChoice}\n indeterminate={indeterminate}\n />\n </div>\n );\n};\n"],"names":["_jsx"],"mappings":";;;;;;;;;;;;;;AAQA,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC;AAC1C,MAAM,YAAY,GAAa,EAAE,CAAC;AAE3B,MAAM,YAAY,GAAG,CAA8B,EACtD,UAAU,EACV,eAAe,GAAG,sBAAsB,EACxC,eAAe,GAAG,YAAY,EAC9B,KAAK,EAAE,QAAQ,EACf,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,QAAQ,GACqB,KAAkB;AAC/C,IAAA,MAAM,EAAE,aAAa,EAAE,GAAG,gBAAgB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,WAAW,CAAC;AAC/D,QAAA,YAAY,EAAE,QAAQ,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,eAAe,CAAC,KAAK,EAAE;AACnE,QAAA,kBAAkB,EAAE,QAAQ;QAC5B,QAAQ;AACX,KAAA,CAAC,CAAC;IACH,QACIA,uBACIA,GAAC,CAAA,SAAS,IACN,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,UAAU,CAAC,WAAW,EAAE,EAC/B,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,eAAe,EAC5B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAAA,CAC9B,EACA,CAAA,EACR;AACN;;;;"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { AdditionalDefault } from './collection/types';
|
|
3
|
+
import { UncontrolledTreeSelectorProps } from './types';
|
|
4
|
+
export declare const UncontrolledTreeSelector: <A extends AdditionalDefault>(props: UncontrolledTreeSelectorProps<A>) => ReactElement;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { TreeSelector } from './TreeSelector.js';
|
|
5
|
+
import ImmutableSelectionStrategy from './strategy/immutableSelectionStrategy.js';
|
|
6
|
+
import { useSelected } from './useSelected.js';
|
|
7
|
+
import './ItemsList.js';
|
|
8
|
+
import './Item.js';
|
|
9
|
+
import 'classnames';
|
|
10
|
+
import './ItemContent-3c0cd83c.js';
|
|
11
|
+
import '@hh.ru/magritte-ui-cell';
|
|
12
|
+
import '@hh.ru/magritte-ui-icon/icon';
|
|
13
|
+
import './Action.js';
|
|
14
|
+
import '@hh.ru/magritte-ui-checkbox-radio';
|
|
15
|
+
import '@hh.ru/magritte-ui-typography';
|
|
16
|
+
import './useExpanded.js';
|
|
17
|
+
import './useIndeterminate.js';
|
|
18
|
+
import './strategy/selectionStrategy.js';
|
|
19
|
+
import './collection/treeCollectionHelper.js';
|
|
20
|
+
import './collection/treeCollection.js';
|
|
21
|
+
import './strategy/createSingleValueToggler.js';
|
|
22
|
+
import './strategy/createTreeCollectionToggler.js';
|
|
23
|
+
import './strategy/dummyToggle.js';
|
|
24
|
+
|
|
25
|
+
const defaultArray = [];
|
|
26
|
+
const UncontrolledTreeSelector = (props) => {
|
|
27
|
+
const { value = defaultArray, collection, singleChoice, leavesOnly, checkSelectable, onChange } = props;
|
|
28
|
+
const strategy = useMemo(() => new ImmutableSelectionStrategy(collection, {
|
|
29
|
+
singleChoice,
|
|
30
|
+
leavesOnly,
|
|
31
|
+
checkSelectable,
|
|
32
|
+
}), [collection, singleChoice, leavesOnly, checkSelectable]);
|
|
33
|
+
const { selected, setSelected } = useSelected({ value, strategy, onChange });
|
|
34
|
+
return jsx(TreeSelector, { ...props, value: selected, onChange: setSelected });
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export { UncontrolledTreeSelector };
|
|
38
|
+
//# sourceMappingURL=UncontrolledTreeSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UncontrolledTreeSelector.js","sources":["../src/UncontrolledTreeSelector.tsx"],"sourcesContent":["import { ReactElement, useMemo } from 'react';\n\nimport { TreeSelector } from '@hh.ru/magritte-ui-tree-selector/TreeSelector';\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport ImmutableSelectionStrategy from '@hh.ru/magritte-ui-tree-selector/strategy/immutableSelectionStrategy';\nimport { UncontrolledTreeSelectorProps } from '@hh.ru/magritte-ui-tree-selector/types';\nimport { useSelected } from '@hh.ru/magritte-ui-tree-selector/useSelected';\n\nconst defaultArray: string[] = [];\nexport const UncontrolledTreeSelector = <A extends AdditionalDefault>(\n props: UncontrolledTreeSelectorProps<A>\n): ReactElement => {\n const { value = defaultArray, collection, singleChoice, leavesOnly, checkSelectable, onChange } = props;\n const strategy = useMemo(\n () =>\n new ImmutableSelectionStrategy(collection, {\n singleChoice,\n leavesOnly,\n checkSelectable,\n }),\n [collection, singleChoice, leavesOnly, checkSelectable]\n );\n\n const { selected, setSelected } = useSelected({ value, strategy, onChange });\n return <TreeSelector {...props} value={selected} onChange={setSelected}></TreeSelector>;\n};\n"],"names":["_jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAM,YAAY,GAAa,EAAE,CAAC;AACrB,MAAA,wBAAwB,GAAG,CACpC,KAAuC,KACzB;AACd,IAAA,MAAM,EAAE,KAAK,GAAG,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACxG,MAAM,QAAQ,GAAG,OAAO,CACpB,MACI,IAAI,0BAA0B,CAAC,UAAU,EAAE;QACvC,YAAY;QACZ,UAAU;QACV,eAAe;KAClB,CAAC,EACN,CAAC,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,CAAC,CAC1D,CAAC;AAEF,IAAA,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC7E,IAAA,OAAOA,GAAC,CAAA,YAAY,EAAK,EAAA,GAAA,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,GAAiB,CAAC;AAC5F;;;;"}
|
package/collection/types.js
CHANGED
package/index.css
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.magritte-wrapper___GHKV6_1-1-0{
|
|
2
|
+
display:flex;
|
|
3
|
+
padding:12px 0;
|
|
4
|
+
gap:12px;
|
|
5
|
+
align-items:center;
|
|
6
|
+
}
|
|
7
|
+
.magritte-letter___yZOCU_1-1-0{
|
|
8
|
+
width:24px;
|
|
9
|
+
flex-shrink:0;
|
|
10
|
+
text-align:center;
|
|
11
|
+
}
|
|
12
|
+
.magritte-icon___kO3Fj_1-1-0{
|
|
13
|
+
flex-shrink:0;
|
|
14
|
+
line-height:0;
|
|
15
|
+
width:24px;
|
|
16
|
+
}
|
|
17
|
+
.magritte-iconActive___4yrG5_1-1-0{
|
|
18
|
+
cursor:pointer;
|
|
19
|
+
}
|
|
20
|
+
.magritte-content___ZRc6R_1-1-0{
|
|
21
|
+
flex-grow:1;
|
|
22
|
+
}
|
|
23
|
+
.magritte-with-action___-lsFP_1-1-0 > .magritte-children___kq-eq_1-1-0{
|
|
24
|
+
padding-left:36px;
|
|
25
|
+
}
|
|
26
|
+
.magritte-with-action___-lsFP_1-1-0.magritte-with-letter___skx30_1-1-0 > .magritte-children___kq-eq_1-1-0{
|
|
27
|
+
padding-left:72px;
|
|
28
|
+
}
|
|
29
|
+
.magritte-with-action___-lsFP_1-1-0.magritte-with-chevron___VOytc_1-1-0 > .magritte-children___kq-eq_1-1-0{
|
|
30
|
+
padding-left:72px;
|
|
31
|
+
}
|
|
32
|
+
.magritte-with-action___-lsFP_1-1-0.magritte-with-letter___skx30_1-1-0.magritte-with-chevron___VOytc_1-1-0 > .magritte-children___kq-eq_1-1-0{
|
|
33
|
+
padding-left:108px;
|
|
34
|
+
}
|
|
35
|
+
.magritte-with-letter___skx30_1-1-0 > .magritte-children___kq-eq_1-1-0{
|
|
36
|
+
padding-left:36px;
|
|
37
|
+
}
|
|
38
|
+
.magritte-with-letter___skx30_1-1-0.magritte-with-chevron___VOytc_1-1-0 > .magritte-children___kq-eq_1-1-0{
|
|
39
|
+
padding-left:72px;
|
|
40
|
+
}
|
|
41
|
+
.magritte-with-chevron___VOytc_1-1-0 > .magritte-children___kq-eq_1-1-0{
|
|
42
|
+
padding-left:36px;
|
|
43
|
+
}
|
|
44
|
+
.magritte-with-shift___ZErxZ_1-1-0{
|
|
45
|
+
margin-left:-36px;
|
|
46
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './TreeSelector';
|
package/index.js
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import './index.css';
|
|
2
|
+
export { TreeSelector } from './TreeSelector.js';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import './ItemsList.js';
|
|
5
|
+
import './Item.js';
|
|
6
|
+
import 'react';
|
|
7
|
+
import 'classnames';
|
|
8
|
+
import './ItemContent-3c0cd83c.js';
|
|
9
|
+
import '@hh.ru/magritte-ui-cell';
|
|
10
|
+
import '@hh.ru/magritte-ui-icon/icon';
|
|
11
|
+
import './Action.js';
|
|
12
|
+
import '@hh.ru/magritte-ui-checkbox-radio';
|
|
13
|
+
import '@hh.ru/magritte-ui-typography';
|
|
14
|
+
import './useExpanded.js';
|
|
15
|
+
import './useIndeterminate.js';
|
|
2
16
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hh.ru/magritte-ui-tree-selector",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"sideEffects": [
|
|
@@ -18,8 +18,20 @@
|
|
|
18
18
|
"ts-check": "yarn root:ts-check $(pwd)",
|
|
19
19
|
"test": "yarn root:test $(pwd)"
|
|
20
20
|
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@hh.ru/magritte-ui-cell": "2.2.6",
|
|
23
|
+
"@hh.ru/magritte-ui-checkbox-radio": "2.2.0",
|
|
24
|
+
"@hh.ru/magritte-ui-icon": "7.1.4",
|
|
25
|
+
"@hh.ru/magritte-ui-mock-component": "1.0.10",
|
|
26
|
+
"@hh.ru/magritte-ui-theme-provider": "1.1.21",
|
|
27
|
+
"@hh.ru/magritte-ui-typography": "3.0.8"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"classnames": ">=2.3.2",
|
|
31
|
+
"react": ">=18.2.0"
|
|
32
|
+
},
|
|
21
33
|
"publishConfig": {
|
|
22
34
|
"access": "public"
|
|
23
35
|
},
|
|
24
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "fb0ed62dbc8f4a497a5e18d3a2c887be8122a950"
|
|
25
37
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import TreeCollection from '../collection/treeCollection';
|
|
2
2
|
import { AdditionalDefault, IdCollectionPredicate } from '../collection/types';
|
|
3
|
-
import { Toggler
|
|
3
|
+
import { Toggler } from '../strategy/types';
|
|
4
4
|
/**
|
|
5
5
|
* Создаёт переключатель элементов в наборе с учётом иерархии элементов:
|
|
6
6
|
* — если выбран или сброшен родитель, выбираются или сбрасываются все его потомки;
|
|
7
7
|
* — если выбраны все потомки родителя, выбирается и родитель;
|
|
8
8
|
* — если сброшен хотя бы один потомок выбранного родителя, сбрасывается и родитель.
|
|
9
9
|
*/
|
|
10
|
-
declare const createTreeCollectionToggler: <A extends AdditionalDefault>(collection: TreeCollection<A>, checkSelectable: IdCollectionPredicate
|
|
10
|
+
declare const createTreeCollectionToggler: <A extends AdditionalDefault>(collection: TreeCollection<A>, checkSelectable: IdCollectionPredicate) => Toggler;
|
|
11
11
|
export default createTreeCollectionToggler;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import './../index.css';
|
|
1
2
|
import toggle from './dummyToggle.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -6,7 +7,7 @@ import toggle from './dummyToggle.js';
|
|
|
6
7
|
* — если выбраны все потомки родителя, выбирается и родитель;
|
|
7
8
|
* — если сброшен хотя бы один потомок выбранного родителя, сбрасывается и родитель.
|
|
8
9
|
*/
|
|
9
|
-
const createTreeCollectionToggler = (collection, checkSelectable
|
|
10
|
+
const createTreeCollectionToggler = (collection, checkSelectable) => {
|
|
10
11
|
/**
|
|
11
12
|
* Определение состояния по дочерним элементам
|
|
12
13
|
*/
|
|
@@ -48,7 +49,7 @@ const createTreeCollectionToggler = (collection, checkSelectable, options) => {
|
|
|
48
49
|
*/
|
|
49
50
|
return (set, id, state) => {
|
|
50
51
|
const toggleResult = toggle(set, id, state);
|
|
51
|
-
if (toggleResult
|
|
52
|
+
if (toggleResult) {
|
|
52
53
|
collection.walkParents(id, (parent) => {
|
|
53
54
|
if (checkSelectable(parent.id, collection)) {
|
|
54
55
|
toggle(set, parent.id, _getCumulativeParentState(set, parent.id));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createTreeCollectionToggler.js","sources":["../../src/strategy/createTreeCollectionToggler.ts"],"sourcesContent":["import TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { AdditionalDefault, IdCollectionPredicate } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport dummyToggle from '@hh.ru/magritte-ui-tree-selector/strategy/dummyToggle';\nimport { Toggler
|
|
1
|
+
{"version":3,"file":"createTreeCollectionToggler.js","sources":["../../src/strategy/createTreeCollectionToggler.ts"],"sourcesContent":["import TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { AdditionalDefault, IdCollectionPredicate } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport dummyToggle from '@hh.ru/magritte-ui-tree-selector/strategy/dummyToggle';\nimport { Toggler } from '@hh.ru/magritte-ui-tree-selector/strategy/types';\n\n/**\n * Создаёт переключатель элементов в наборе с учётом иерархии элементов:\n * — если выбран или сброшен родитель, выбираются или сбрасываются все его потомки;\n * — если выбраны все потомки родителя, выбирается и родитель;\n * — если сброшен хотя бы один потомок выбранного родителя, сбрасывается и родитель.\n */\n\nconst createTreeCollectionToggler = <A extends AdditionalDefault>(\n collection: TreeCollection<A>,\n checkSelectable: IdCollectionPredicate\n): Toggler => {\n /**\n * Определение состояния по дочерним элементам\n */\n const _getCumulativeParentState = (set: Set<string>, id: string) => {\n let hasSelectableChild = false;\n const allSelectableChildrenAreSelected = collection.getChildren(id).every((model) => {\n const isSelectable = checkSelectable(model.id, collection);\n hasSelectableChild = hasSelectableChild || isSelectable;\n return set.has(model.id) || !isSelectable;\n });\n return hasSelectableChild ? allSelectableChildrenAreSelected : set.has(id);\n };\n\n /**\n * Простановка состояния всем дочерним элементам\n */\n const _setStateForAllChildren = (set: Set<string>, id: string, state: boolean) => {\n collection.walkChildren(id, (model) => {\n if (checkSelectable(model.id, collection)) {\n dummyToggle(set, model.id, state);\n }\n });\n };\n\n const _toggleOtherParents = (set: Set<string>, id: string) => {\n // когда добавляем-убираем родительскую модель надо проверить и проставить статус другим родителям,\n // у которых есть общие модели-потомки с первоночальной родительской моделью\n if (collection.hasChildren(id)) {\n const childrenIds = collection.getChildrenIds(id);\n const otherParentsIds = childrenIds.reduce<string[]>((result, childrenId) => {\n const parentIds = collection\n .getParentIdsDuplicates(childrenId)\n .filter(\n (parentId) =>\n parentId !== id && !result.includes(parentId) && checkSelectable(parentId, collection)\n );\n return result.concat(parentIds);\n }, []);\n otherParentsIds.forEach((parentId) => dummyToggle(set, parentId, _getCumulativeParentState(set, parentId)));\n }\n };\n\n /**\n * Переключение состояния модели, её родителей и потомков.\n */\n return (set: Set<string>, id: string, state: boolean) => {\n const toggleResult = dummyToggle(set, id, state);\n\n if (toggleResult) {\n collection.walkParents(id, (parent) => {\n if (checkSelectable(parent.id, collection)) {\n dummyToggle(set, parent.id, _getCumulativeParentState(set, parent.id));\n }\n });\n }\n _setStateForAllChildren(set, id, state);\n _toggleOtherParents(set, id);\n };\n};\n\nexport default createTreeCollectionToggler;\n"],"names":["dummyToggle"],"mappings":"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"}
|
package/strategy/dummyToggle.js
CHANGED
|
@@ -10,7 +10,6 @@ declare class ImmutableSelectionStrategy<A extends AdditionalDefault = never> {
|
|
|
10
10
|
* @param addedItems Добавляемые элементы.
|
|
11
11
|
*/
|
|
12
12
|
add(items: string[], addedItems: string[]): string[];
|
|
13
|
-
exclude(items: string[], excludedItems: string[], processedItems: string[]): string[];
|
|
14
13
|
/**
|
|
15
14
|
* Возвращает новый набор, в котором из `items` удалены `removedItems`.
|
|
16
15
|
* @param items Текущий набор.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import './../index.css';
|
|
1
2
|
import SelectionStrategy from './selectionStrategy.js';
|
|
2
3
|
import '../collection/treeCollectionHelper.js';
|
|
3
4
|
import '../collection/treeCollection.js';
|
|
4
5
|
import './createSingleValueToggler.js';
|
|
5
6
|
import './createTreeCollectionToggler.js';
|
|
6
7
|
import './dummyToggle.js';
|
|
7
|
-
import './createTreeSelectionExcluder.js';
|
|
8
8
|
|
|
9
9
|
class ImmutableSelectionStrategy {
|
|
10
10
|
strategy;
|
|
@@ -21,11 +21,6 @@ class ImmutableSelectionStrategy {
|
|
|
21
21
|
this.strategy.add(result, addedItems);
|
|
22
22
|
return [...result];
|
|
23
23
|
}
|
|
24
|
-
exclude(items, excludedItems, processedItems) {
|
|
25
|
-
const excluded = new Set(excludedItems);
|
|
26
|
-
this.strategy.exclude(items, excluded, processedItems);
|
|
27
|
-
return [...excluded];
|
|
28
|
-
}
|
|
29
24
|
/**
|
|
30
25
|
* Возвращает новый набор, в котором из `items` удалены `removedItems`.
|
|
31
26
|
* @param items Текущий набор.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"immutableSelectionStrategy.js","sources":["../../src/strategy/immutableSelectionStrategy.ts"],"sourcesContent":["import TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport SelectionStrategy from '@hh.ru/magritte-ui-tree-selector/strategy/selectionStrategy';\nimport { StrategyOptions } from '@hh.ru/magritte-ui-tree-selector/strategy/types';\n\nclass ImmutableSelectionStrategy<A extends AdditionalDefault = never> {\n private strategy: SelectionStrategy<A>;\n\n constructor(collection: TreeCollection<A>, options: StrategyOptions) {\n this.strategy = new SelectionStrategy<A>(collection, options);\n }\n\n /**\n * Возвращает новый набор, в котором к `items` добавлены `addedItems`.\n * @param items Текущий набор.\n * @param addedItems Добавляемые элементы.\n */\n add(items: string[], addedItems: string[]): string[] {\n const result = new Set(items);\n this.strategy.add(result, addedItems);\n return [...result];\n }\n\n
|
|
1
|
+
{"version":3,"file":"immutableSelectionStrategy.js","sources":["../../src/strategy/immutableSelectionStrategy.ts"],"sourcesContent":["import TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport SelectionStrategy from '@hh.ru/magritte-ui-tree-selector/strategy/selectionStrategy';\nimport { StrategyOptions } from '@hh.ru/magritte-ui-tree-selector/strategy/types';\n\nclass ImmutableSelectionStrategy<A extends AdditionalDefault = never> {\n private strategy: SelectionStrategy<A>;\n\n constructor(collection: TreeCollection<A>, options: StrategyOptions) {\n this.strategy = new SelectionStrategy<A>(collection, options);\n }\n\n /**\n * Возвращает новый набор, в котором к `items` добавлены `addedItems`.\n * @param items Текущий набор.\n * @param addedItems Добавляемые элементы.\n */\n add(items: string[], addedItems: string[]): string[] {\n const result = new Set(items);\n this.strategy.add(result, addedItems);\n return [...result];\n }\n\n /**\n * Возвращает новый набор, в котором из `items` удалены `removedItems`.\n * @param items Текущий набор.\n * @param removedItems Удаляемые элементы.\n */\n remove(items: string[], removedItems: string[]): string[] {\n const result = new Set(items);\n this.strategy.remove(result, removedItems);\n return [...result];\n }\n}\n\nexport default ImmutableSelectionStrategy;\n"],"names":[],"mappings":";;;;;;;AAKA,MAAM,0BAA0B,CAAA;AACpB,IAAA,QAAQ,CAAuB;IAEvC,WAAY,CAAA,UAA6B,EAAE,OAAwB,EAAA;QAC/D,IAAI,CAAC,QAAQ,GAAG,IAAI,iBAAiB,CAAI,UAAU,EAAE,OAAO,CAAC,CAAC;KACjE;AAED;;;;AAIG;IACH,GAAG,CAAC,KAAe,EAAE,UAAoB,EAAA;AACrC,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AACtC,QAAA,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;KACtB;AAED;;;;AAIG;IACH,MAAM,CAAC,KAAe,EAAE,YAAsB,EAAA;AAC1C,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAC3C,QAAA,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;KACtB;AACJ;;;;"}
|
|
@@ -9,11 +9,9 @@ declare class SelectionStrategy<A extends AdditionalDefault = never> {
|
|
|
9
9
|
private options;
|
|
10
10
|
private checkSelectable;
|
|
11
11
|
private toggle;
|
|
12
|
-
private runExcluder;
|
|
13
12
|
constructor(collection: TreeCollection<A>, options: StrategyOptions);
|
|
14
13
|
add(items: Set<string>, ids: string[]): void;
|
|
15
14
|
remove(items: Set<string>, ids: string[]): void;
|
|
16
|
-
exclude(items: string[], excluded: Set<string>, ids: string[]): void;
|
|
17
15
|
set(items: Set<string>, ids: string[]): void;
|
|
18
16
|
}
|
|
19
17
|
export default SelectionStrategy;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import './../index.css';
|
|
1
2
|
import { filterMissingIds, filterParents } from '../collection/treeCollectionHelper.js';
|
|
2
3
|
import createSingleValueToggler from './createSingleValueToggler.js';
|
|
3
4
|
import createTreeCollectionToggler from './createTreeCollectionToggler.js';
|
|
4
|
-
import createTreeCollectionExcluder from './createTreeSelectionExcluder.js';
|
|
5
5
|
import toggle from './dummyToggle.js';
|
|
6
6
|
import '../collection/treeCollection.js';
|
|
7
7
|
|
|
@@ -26,15 +26,13 @@ class SelectionStrategy {
|
|
|
26
26
|
options;
|
|
27
27
|
checkSelectable;
|
|
28
28
|
toggle;
|
|
29
|
-
runExcluder;
|
|
30
29
|
constructor(collection, options) {
|
|
31
30
|
this.collection = collection;
|
|
32
31
|
this.options = options;
|
|
33
32
|
this.checkSelectable = options.checkSelectable || defaultCheckSelectable;
|
|
34
33
|
this.toggle = options.singleChoice
|
|
35
34
|
? createSingleValueToggler()
|
|
36
|
-
: createTreeCollectionToggler(collection, this.checkSelectable
|
|
37
|
-
this.runExcluder = createTreeCollectionExcluder(collection, this.checkSelectable);
|
|
35
|
+
: createTreeCollectionToggler(collection, this.checkSelectable);
|
|
38
36
|
}
|
|
39
37
|
add(items, ids) {
|
|
40
38
|
let filteredIds = filterMissingIds(this.collection, ids);
|
|
@@ -65,12 +63,6 @@ class SelectionStrategy {
|
|
|
65
63
|
this.toggle(items, id, false);
|
|
66
64
|
});
|
|
67
65
|
}
|
|
68
|
-
exclude(items, excluded, ids) {
|
|
69
|
-
const filteredIds = this.options.checkSelectable
|
|
70
|
-
? _filterSelectable(this.collection, filterMissingIds(this.collection, ids), this.options.checkSelectable)
|
|
71
|
-
: filterMissingIds(this.collection, ids);
|
|
72
|
-
this.runExcluder(items, excluded, filteredIds);
|
|
73
|
-
}
|
|
74
66
|
set(items, ids) {
|
|
75
67
|
items.clear();
|
|
76
68
|
this.add(items, ids);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectionStrategy.js","sources":["../../src/strategy/selectionStrategy.ts"],"sourcesContent":["import TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { filterMissingIds, filterParents } from '@hh.ru/magritte-ui-tree-selector/collection/treeCollectionHelper';\nimport { AdditionalDefault, IdCollectionPredicate } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport createSingleValueToggler from '@hh.ru/magritte-ui-tree-selector/strategy/createSingleValueToggler';\nimport createTreeCollectionToggler from '@hh.ru/magritte-ui-tree-selector/strategy/createTreeCollectionToggler';\nimport
|
|
1
|
+
{"version":3,"file":"selectionStrategy.js","sources":["../../src/strategy/selectionStrategy.ts"],"sourcesContent":["import TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { filterMissingIds, filterParents } from '@hh.ru/magritte-ui-tree-selector/collection/treeCollectionHelper';\nimport { AdditionalDefault, IdCollectionPredicate } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport createSingleValueToggler from '@hh.ru/magritte-ui-tree-selector/strategy/createSingleValueToggler';\nimport createTreeCollectionToggler from '@hh.ru/magritte-ui-tree-selector/strategy/createTreeCollectionToggler';\nimport dummyToggle from '@hh.ru/magritte-ui-tree-selector/strategy/dummyToggle';\nimport { StrategyOptions, Toggler } from '@hh.ru/magritte-ui-tree-selector/strategy/types';\n\nconst _filterSelectable = <A extends AdditionalDefault>(\n collection: TreeCollection<A>,\n ids: string[],\n checkSelectable: IdCollectionPredicate\n) => {\n return ids.filter((id) => checkSelectable(id, collection));\n};\n\nconst defaultCheckSelectable = () => true;\n\n/**\n * Оставляет в массиве только последний ID\n */\nconst _filterMultipleIds = (ids: string[]) => {\n if (ids.length > 1) {\n return [ids[ids.length - 1]];\n }\n return ids;\n};\n\n/**\n * Стратегия переключения флага `selected` для иерархической коллекции.\n */\nclass SelectionStrategy<A extends AdditionalDefault = never> {\n private collection: TreeCollection<A>;\n private options: StrategyOptions;\n private checkSelectable: IdCollectionPredicate;\n private toggle: Toggler;\n\n constructor(collection: TreeCollection<A>, options: StrategyOptions) {\n this.collection = collection;\n this.options = options;\n this.checkSelectable = options.checkSelectable || defaultCheckSelectable;\n this.toggle = options.singleChoice\n ? createSingleValueToggler()\n : createTreeCollectionToggler(collection, this.checkSelectable);\n }\n\n add(items: Set<string>, ids: string[]): void {\n let filteredIds = filterMissingIds(this.collection, ids);\n\n if (this.options.singleChoice) {\n filteredIds = _filterMultipleIds(filteredIds);\n }\n if (this.options.leavesOnly) {\n filteredIds = filterParents(this.collection, filteredIds);\n }\n if (this.options.checkSelectable) {\n filteredIds = _filterSelectable(this.collection, filteredIds, this.options.checkSelectable);\n }\n\n if (this.options.leavesOnly && !this.options.singleChoice) {\n // Тут не нужно выбирать или сбрасывать родителей\n filteredIds.forEach((id) => {\n dummyToggle(items, id, true);\n });\n } else {\n filteredIds.forEach((id) => {\n this.toggle(items, id, true);\n });\n }\n }\n\n remove(items: Set<string>, ids: string[]): void {\n const filteredIds = filterMissingIds(this.collection, ids);\n\n filteredIds.forEach((id) => {\n this.toggle(items, id, false);\n });\n }\n\n set(items: Set<string>, ids: string[]): void {\n items.clear();\n this.add(items, ids);\n }\n}\n\nexport default SelectionStrategy;\n"],"names":["dummyToggle"],"mappings":"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"}
|
package/strategy/types.d.ts
CHANGED
|
@@ -2,12 +2,8 @@ import { IdCollectionPredicate } from '../collection/types';
|
|
|
2
2
|
export interface StrategyOptions {
|
|
3
3
|
checkSelectable?: IdCollectionPredicate;
|
|
4
4
|
singleChoice?: boolean;
|
|
5
|
-
withExcluded?: boolean;
|
|
6
5
|
leavesOnly?: boolean;
|
|
7
6
|
}
|
|
8
7
|
export interface Toggler {
|
|
9
8
|
(set: Set<string>, id: string, state: boolean): void | boolean;
|
|
10
9
|
}
|
|
11
|
-
export interface Excluder {
|
|
12
|
-
(items: string[], excluded: Set<string>, ids: string[]): void;
|
|
13
|
-
}
|
package/strategy/types.js
CHANGED
package/types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import TreeCollection from './collection/treeCollection';
|
|
2
|
+
import { AdditionalDefault, IdCollectionPredicate } from './collection/types';
|
|
3
|
+
export interface TreeSelectorProps<A extends AdditionalDefault> {
|
|
4
|
+
collection: TreeCollection<A>;
|
|
5
|
+
singleChoice?: boolean;
|
|
6
|
+
leavesOnly?: boolean;
|
|
7
|
+
checkSelectable?: IdCollectionPredicate;
|
|
8
|
+
initialExpanded?: string[];
|
|
9
|
+
expanded?: string[];
|
|
10
|
+
onExpand?: (expanded: string[]) => void;
|
|
11
|
+
}
|
|
12
|
+
interface ControlledProps {
|
|
13
|
+
value: string[];
|
|
14
|
+
onChange: (id: string, isSelected: boolean) => void;
|
|
15
|
+
}
|
|
16
|
+
type UncontrolledProps = {
|
|
17
|
+
value?: string[];
|
|
18
|
+
onChange?: (id: string, isSelected: boolean, allSelected: string[]) => void;
|
|
19
|
+
};
|
|
20
|
+
export type ControlledTreeSelectorProps<A extends AdditionalDefault> = TreeSelectorProps<A> & ControlledProps;
|
|
21
|
+
export type UncontrolledTreeSelectorProps<A extends AdditionalDefault> = TreeSelectorProps<A> & UncontrolledProps;
|
|
22
|
+
export {};
|
package/types.js
ADDED
package/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/useExpanded.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const areEqualArrays: (arr1: string[], arr2: string[]) => boolean;
|
|
2
|
+
interface UseExpandedHookProps {
|
|
3
|
+
initialValue: string[];
|
|
4
|
+
controlledExpanded?: string[];
|
|
5
|
+
onExpand?: (expanded: string[]) => void;
|
|
6
|
+
}
|
|
7
|
+
interface UseExpandedHookReturn {
|
|
8
|
+
expanded: string[];
|
|
9
|
+
handleSetExpanded: (expanded: string[]) => void;
|
|
10
|
+
handleExpansion: (id: string) => void;
|
|
11
|
+
}
|
|
12
|
+
interface UseExpandedHook {
|
|
13
|
+
(props: UseExpandedHookProps): UseExpandedHookReturn;
|
|
14
|
+
}
|
|
15
|
+
declare const useExpanded: UseExpandedHook;
|
|
16
|
+
export default useExpanded;
|
package/useExpanded.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
const areEqualArrays = (arr1, arr2) => {
|
|
5
|
+
if (arr1.length !== arr2.length) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const sortArr2 = arr2.slice().sort();
|
|
9
|
+
return arr1
|
|
10
|
+
.slice()
|
|
11
|
+
.sort()
|
|
12
|
+
.every((item, index) => item === sortArr2[index]);
|
|
13
|
+
};
|
|
14
|
+
const useExpanded = ({ initialValue, controlledExpanded, onExpand }) => {
|
|
15
|
+
const [expanded, setExpanded] = useState(initialValue);
|
|
16
|
+
const expandedRef = useRef(initialValue);
|
|
17
|
+
const handlerRef = useRef(onExpand);
|
|
18
|
+
const handleSetExpanded = useCallback((updatedExpanded) => {
|
|
19
|
+
handlerRef.current?.(updatedExpanded.slice());
|
|
20
|
+
if (!areEqualArrays(expandedRef.current, updatedExpanded)) {
|
|
21
|
+
setExpanded(updatedExpanded);
|
|
22
|
+
}
|
|
23
|
+
}, []);
|
|
24
|
+
const handleExpansion = useCallback((id) => {
|
|
25
|
+
let updatedExpanded;
|
|
26
|
+
if (expandedRef.current.includes(id)) {
|
|
27
|
+
updatedExpanded = expandedRef.current.filter((itemId) => itemId !== id);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
updatedExpanded = expandedRef.current.slice();
|
|
31
|
+
updatedExpanded.push(id);
|
|
32
|
+
}
|
|
33
|
+
handleSetExpanded(updatedExpanded);
|
|
34
|
+
}, [handleSetExpanded]);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
handlerRef.current = onExpand;
|
|
37
|
+
}, [onExpand]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
expandedRef.current = expanded;
|
|
40
|
+
}, [expanded]);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (controlledExpanded) {
|
|
43
|
+
handleSetExpanded(controlledExpanded.slice());
|
|
44
|
+
}
|
|
45
|
+
}, [controlledExpanded, handleSetExpanded]);
|
|
46
|
+
return { expanded, handleSetExpanded, handleExpansion };
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export { areEqualArrays, useExpanded as default };
|
|
50
|
+
//# sourceMappingURL=useExpanded.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useExpanded.js","sources":["../src/useExpanded.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport const areEqualArrays = (arr1: string[], arr2: string[]): boolean => {\n if (arr1.length !== arr2.length) {\n return false;\n }\n const sortArr2 = arr2.slice().sort();\n return arr1\n .slice()\n .sort()\n .every((item, index) => item === sortArr2[index]);\n};\n\ninterface UseExpandedHookProps {\n initialValue: string[];\n controlledExpanded?: string[];\n onExpand?: (expanded: string[]) => void;\n}\n\ninterface UseExpandedHookReturn {\n expanded: string[];\n handleSetExpanded: (expanded: string[]) => void;\n handleExpansion: (id: string) => void;\n}\ninterface UseExpandedHook {\n (props: UseExpandedHookProps): UseExpandedHookReturn;\n}\n\nconst useExpanded: UseExpandedHook = ({ initialValue, controlledExpanded, onExpand }) => {\n const [expanded, setExpanded] = useState(initialValue);\n const expandedRef = useRef(initialValue);\n const handlerRef = useRef(onExpand);\n\n const handleSetExpanded = useCallback((updatedExpanded: string[]) => {\n handlerRef.current?.(updatedExpanded.slice());\n\n if (!areEqualArrays(expandedRef.current, updatedExpanded)) {\n setExpanded(updatedExpanded);\n }\n }, []);\n\n const handleExpansion = useCallback(\n (id: string): void => {\n let updatedExpanded;\n if (expandedRef.current.includes(id)) {\n updatedExpanded = expandedRef.current.filter((itemId) => itemId !== id);\n } else {\n updatedExpanded = expandedRef.current.slice();\n updatedExpanded.push(id);\n }\n handleSetExpanded(updatedExpanded);\n },\n [handleSetExpanded]\n );\n\n useEffect(() => {\n handlerRef.current = onExpand;\n }, [onExpand]);\n\n useEffect(() => {\n expandedRef.current = expanded;\n }, [expanded]);\n\n useEffect(() => {\n if (controlledExpanded) {\n handleSetExpanded(controlledExpanded.slice());\n }\n }, [controlledExpanded, handleSetExpanded]);\n\n return { expanded, handleSetExpanded, handleExpansion };\n};\n\nexport default useExpanded;\n"],"names":[],"mappings":";;MAEa,cAAc,GAAG,CAAC,IAAc,EAAE,IAAc,KAAa;AACtE,IAAA,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE;AAC7B,QAAA,OAAO,KAAK,CAAC;AAChB,KAAA;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;AACrC,IAAA,OAAO,IAAI;AACN,SAAA,KAAK,EAAE;AACP,SAAA,IAAI,EAAE;AACN,SAAA,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1D,EAAE;AAiBI,MAAA,WAAW,GAAoB,CAAC,EAAE,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAI;IACpF,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;AACvD,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AACzC,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEpC,IAAA,MAAM,iBAAiB,GAAG,WAAW,CAAC,CAAC,eAAyB,KAAI;QAChE,UAAU,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC;QAE9C,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE;YACvD,WAAW,CAAC,eAAe,CAAC,CAAC;AAChC,SAAA;KACJ,EAAE,EAAE,CAAC,CAAC;AAEP,IAAA,MAAM,eAAe,GAAG,WAAW,CAC/B,CAAC,EAAU,KAAU;AACjB,QAAA,IAAI,eAAe,CAAC;QACpB,IAAI,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;AAClC,YAAA,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,EAAE,CAAC,CAAC;AAC3E,SAAA;AAAM,aAAA;AACH,YAAA,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;AAC9C,YAAA,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5B,SAAA;QACD,iBAAiB,CAAC,eAAe,CAAC,CAAC;AACvC,KAAC,EACD,CAAC,iBAAiB,CAAC,CACtB,CAAC;IAEF,SAAS,CAAC,MAAK;AACX,QAAA,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC;AAClC,KAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,SAAS,CAAC,MAAK;AACX,QAAA,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;AACnC,KAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,SAAS,CAAC,MAAK;AACX,QAAA,IAAI,kBAAkB,EAAE;AACpB,YAAA,iBAAiB,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC;AACjD,SAAA;AACL,KAAC,EAAE,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAE5C,IAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,eAAe,EAAE,CAAC;AAC5D;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import TreeCollection from './collection/treeCollection';
|
|
2
|
+
import { AdditionalDefault } from './collection/types';
|
|
3
|
+
/**
|
|
4
|
+
* Возвращает массив ID элементов дерева, у которых есть и выбранные, и невыбранные потомки.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getIndeterminateParentIds<A extends AdditionalDefault>(collection: TreeCollection<A>, selected: string[]): string[];
|
|
7
|
+
interface UseIndeterminateHookProps<A extends AdditionalDefault> {
|
|
8
|
+
collection: TreeCollection<A>;
|
|
9
|
+
selected: string[];
|
|
10
|
+
}
|
|
11
|
+
interface UseIndeterminateHook {
|
|
12
|
+
<A extends AdditionalDefault>(props: UseIndeterminateHookProps<A>): {
|
|
13
|
+
indeterminate: string[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare const useIndeterminate: UseIndeterminateHook;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { areEqualArrays } from './useExpanded.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Возвращает массив ID элементов дерева, у которых есть и выбранные, и невыбранные потомки.
|
|
7
|
+
*/
|
|
8
|
+
function getIndeterminateParentIds(collection, selected) {
|
|
9
|
+
const result = selected.reduce((currentResult, id) => {
|
|
10
|
+
collection.getParentIds(id).forEach((parentId) => {
|
|
11
|
+
if (!selected.includes(parentId)) {
|
|
12
|
+
currentResult.add(parentId);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return currentResult;
|
|
16
|
+
}, new Set());
|
|
17
|
+
return [...result];
|
|
18
|
+
}
|
|
19
|
+
const useIndeterminate = ({ collection, selected }) => {
|
|
20
|
+
const [indeterminate, setIndeterminate] = useState([]);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const updatedIndeterminateIds = getIndeterminateParentIds(collection, selected);
|
|
23
|
+
setIndeterminate((current) => areEqualArrays(current, updatedIndeterminateIds) ? current : updatedIndeterminateIds);
|
|
24
|
+
}, [selected, collection]);
|
|
25
|
+
return { indeterminate };
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { getIndeterminateParentIds, useIndeterminate };
|
|
29
|
+
//# sourceMappingURL=useIndeterminate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIndeterminate.js","sources":["../src/useIndeterminate.ts"],"sourcesContent":["import { useState, useEffect } from 'react';\n\nimport TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport { areEqualArrays } from '@hh.ru/magritte-ui-tree-selector/useExpanded';\n\n/**\n * Возвращает массив ID элементов дерева, у которых есть и выбранные, и невыбранные потомки.\n */\nexport function getIndeterminateParentIds<A extends AdditionalDefault>(\n collection: TreeCollection<A>,\n selected: string[]\n): string[] {\n const result = selected.reduce((currentResult, id) => {\n collection.getParentIds(id).forEach((parentId) => {\n if (!selected.includes(parentId)) {\n currentResult.add(parentId);\n }\n });\n return currentResult;\n }, new Set<string>());\n return [...result];\n}\n\ninterface UseIndeterminateHookProps<A extends AdditionalDefault> {\n collection: TreeCollection<A>;\n selected: string[];\n}\ninterface UseIndeterminateHook {\n <A extends AdditionalDefault>(props: UseIndeterminateHookProps<A>): { indeterminate: string[] };\n}\n\nexport const useIndeterminate: UseIndeterminateHook = ({ collection, selected }) => {\n const [indeterminate, setIndeterminate] = useState<string[]>([]);\n\n useEffect(() => {\n const updatedIndeterminateIds = getIndeterminateParentIds(collection, selected);\n setIndeterminate((current) =>\n areEqualArrays(current, updatedIndeterminateIds) ? current : updatedIndeterminateIds\n );\n }, [selected, collection]);\n return { indeterminate };\n};\n"],"names":[],"mappings":";;;AAMA;;AAEG;AACa,SAAA,yBAAyB,CACrC,UAA6B,EAC7B,QAAkB,EAAA;IAElB,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,EAAE,KAAI;QACjD,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAI;AAC7C,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AAC9B,gBAAA,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/B,aAAA;AACL,SAAC,CAAC,CAAC;AACH,QAAA,OAAO,aAAa,CAAC;AACzB,KAAC,EAAE,IAAI,GAAG,EAAU,CAAC,CAAC;AACtB,IAAA,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AACvB,CAAC;AAUY,MAAA,gBAAgB,GAAyB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAI;IAC/E,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAEjE,SAAS,CAAC,MAAK;QACX,MAAM,uBAAuB,GAAG,yBAAyB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAChF,gBAAgB,CAAC,CAAC,OAAO,KACrB,cAAc,CAAC,OAAO,EAAE,uBAAuB,CAAC,GAAG,OAAO,GAAG,uBAAuB,CACvF,CAAC;AACN,KAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE,aAAa,EAAE,CAAC;AAC7B;;;;"}
|
package/useSelected.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AdditionalDefault } from './collection/types';
|
|
2
|
+
import ImmutableSelectionStrategy from './strategy/immutableSelectionStrategy';
|
|
3
|
+
interface UseSelectedHookProps<A extends AdditionalDefault> {
|
|
4
|
+
value: string[];
|
|
5
|
+
strategy: ImmutableSelectionStrategy<A>;
|
|
6
|
+
onChange?: (id: string, isSelected: boolean, allSelected: string[]) => void;
|
|
7
|
+
}
|
|
8
|
+
type UseSelectedHookReturn = {
|
|
9
|
+
selected: string[];
|
|
10
|
+
setSelected: (id: string, isSelected: boolean) => void;
|
|
11
|
+
};
|
|
12
|
+
interface UseSelectedHook {
|
|
13
|
+
<A extends AdditionalDefault>(props: UseSelectedHookProps<A>): UseSelectedHookReturn;
|
|
14
|
+
}
|
|
15
|
+
export declare const useSelected: UseSelectedHook;
|
|
16
|
+
export {};
|
package/useSelected.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './index.css';
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
const useSelected = ({ value: initialValue, strategy, onChange }) => {
|
|
5
|
+
const [values, setValues] = useState(initialValue);
|
|
6
|
+
const setSelected = useCallback((id, isSelected) => {
|
|
7
|
+
const ids = [id];
|
|
8
|
+
const updatedSelected = isSelected ? strategy.add(values, ids) : strategy.remove(values, ids);
|
|
9
|
+
setValues(updatedSelected);
|
|
10
|
+
onChange?.(id, isSelected, updatedSelected);
|
|
11
|
+
}, [strategy, values, onChange]);
|
|
12
|
+
return {
|
|
13
|
+
selected: values,
|
|
14
|
+
setSelected,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { useSelected };
|
|
19
|
+
//# sourceMappingURL=useSelected.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSelected.js","sources":["../src/useSelected.ts"],"sourcesContent":["import { useState, useCallback } from 'react';\n\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport ImmutableSelectionStrategy from '@hh.ru/magritte-ui-tree-selector/strategy/immutableSelectionStrategy';\n\ninterface UseSelectedHookProps<A extends AdditionalDefault> {\n value: string[];\n strategy: ImmutableSelectionStrategy<A>;\n onChange?: (id: string, isSelected: boolean, allSelected: string[]) => void;\n}\n\ntype UseSelectedHookReturn = {\n selected: string[];\n setSelected: (id: string, isSelected: boolean) => void;\n};\n\ninterface UseSelectedHook {\n <A extends AdditionalDefault>(props: UseSelectedHookProps<A>): UseSelectedHookReturn;\n}\n\nexport const useSelected: UseSelectedHook = ({ value: initialValue, strategy, onChange }) => {\n const [values, setValues] = useState(initialValue);\n\n const setSelected = useCallback(\n (id: string, isSelected: boolean) => {\n const ids = [id];\n const updatedSelected = isSelected ? strategy.add(values, ids) : strategy.remove(values, ids);\n\n setValues(updatedSelected);\n onChange?.(id, isSelected, updatedSelected);\n },\n [strategy, values, onChange]\n );\n\n return {\n selected: values,\n setSelected,\n };\n};\n"],"names":[],"mappings":";;AAoBO,MAAM,WAAW,GAAoB,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAI;IACxF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEnD,MAAM,WAAW,GAAG,WAAW,CAC3B,CAAC,EAAU,EAAE,UAAmB,KAAI;AAChC,QAAA,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;QACjB,MAAM,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAE9F,SAAS,CAAC,eAAe,CAAC,CAAC;QAC3B,QAAQ,GAAG,EAAE,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;KAC/C,EACD,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAC/B,CAAC;IAEF,OAAO;AACH,QAAA,QAAQ,EAAE,MAAM;QAChB,WAAW;KACd,CAAC;AACN;;;;"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import TreeCollection from '../collection/treeCollection';
|
|
2
|
-
import type { AdditionalDefault, IdCollectionPredicate } from '../collection/types';
|
|
3
|
-
import type { Excluder } from '../strategy/types';
|
|
4
|
-
/**
|
|
5
|
-
* Создаёт исключатель элементов в наборе, учитывая набор выбранных элементов (вызывать с готовыми выбранными элементами):
|
|
6
|
-
* — если элемент был выбран, то мы либо удаляем его из "исключенных", либо ничего не делаем;
|
|
7
|
-
* — во всех случаях, когда меняется статус родителя, все его дети исключаются из "исключенных";
|
|
8
|
-
* — если элемент "отключили", то переводим его в "исключенные", но только в том случае, если его родитель выбран
|
|
9
|
-
*/
|
|
10
|
-
declare const createTreeCollectionExcluder: <A extends AdditionalDefault>(_collection: TreeCollection<A>, _checkSelectable: IdCollectionPredicate) => Excluder;
|
|
11
|
-
export default createTreeCollectionExcluder;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Проверяет был ли выбран родитель переданного элемента или находится в списке исключенных
|
|
3
|
-
*/
|
|
4
|
-
const isParentSelectedOrExcluded = (collection, selectedIds, childId, excluded = []) => {
|
|
5
|
-
const parentId = collection.getParentId(childId);
|
|
6
|
-
return {
|
|
7
|
-
isParentSelected: parentId ? selectedIds.includes(parentId) : false,
|
|
8
|
-
isParentExcluded: Boolean(parentId && excluded.includes(parentId)),
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Создаёт исключатель элементов в наборе, учитывая набор выбранных элементов (вызывать с готовыми выбранными элементами):
|
|
13
|
-
* — если элемент был выбран, то мы либо удаляем его из "исключенных", либо ничего не делаем;
|
|
14
|
-
* — во всех случаях, когда меняется статус родителя, все его дети исключаются из "исключенных";
|
|
15
|
-
* — если элемент "отключили", то переводим его в "исключенные", но только в том случае, если его родитель выбран
|
|
16
|
-
*/
|
|
17
|
-
const createTreeCollectionExcluder = (_collection, _checkSelectable) => {
|
|
18
|
-
function exclude(items, excluded, ids) {
|
|
19
|
-
if (!items.length) {
|
|
20
|
-
excluded.clear();
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
ids.forEach((id) => {
|
|
24
|
-
if (!_checkSelectable(id, _collection)) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
if (excluded.has(id)) {
|
|
28
|
-
excluded.delete(id);
|
|
29
|
-
_collection.walkChildren(id, ({ id: childId }) => _excludeOperationWithChild({ excluded, ids, items, childId, isAdding: false }));
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
const { isParentExcluded, isParentSelected } = isParentSelectedOrExcluded(_collection, items, id, [
|
|
33
|
-
...excluded,
|
|
34
|
-
]);
|
|
35
|
-
const isAdding = isParentSelected || isParentExcluded;
|
|
36
|
-
if (isAdding) {
|
|
37
|
-
excluded.add(id);
|
|
38
|
-
}
|
|
39
|
-
_collection.walkChildren(id, ({ id: childId }) => _excludeOperationWithChild({ excluded, ids, items, childId, isAdding }));
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
function _excludeOperationWithChild({ excluded, ids, items, childId, isAdding, }) {
|
|
44
|
-
return (!ids.includes(childId) &&
|
|
45
|
-
(isAdding ? !excluded.has(childId) : excluded.has(childId)) &&
|
|
46
|
-
exclude(items, excluded, [childId]));
|
|
47
|
-
}
|
|
48
|
-
return exclude;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export { createTreeCollectionExcluder as default };
|
|
52
|
-
//# sourceMappingURL=createTreeSelectionExcluder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createTreeSelectionExcluder.js","sources":["../../src/strategy/createTreeSelectionExcluder.ts"],"sourcesContent":["import TreeCollection from '@hh.ru/magritte-ui-tree-selector/collection/treeCollection';\nimport type { AdditionalDefault, IdCollectionPredicate } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport type { Excluder } from '@hh.ru/magritte-ui-tree-selector/strategy/types';\n\n/**\n * Проверяет был ли выбран родитель переданного элемента или находится в списке исключенных\n */\nconst isParentSelectedOrExcluded = <A extends AdditionalDefault = never>(\n collection: TreeCollection<A>,\n selectedIds: string[],\n childId: string,\n excluded: string[] = []\n): { isParentSelected: boolean; isParentExcluded: boolean } => {\n const parentId = collection.getParentId(childId);\n\n return {\n isParentSelected: parentId ? selectedIds.includes(parentId) : false,\n isParentExcluded: Boolean(parentId && excluded.includes(parentId)),\n };\n};\n\n/**\n * Создаёт исключатель элементов в наборе, учитывая набор выбранных элементов (вызывать с готовыми выбранными элементами):\n * — если элемент был выбран, то мы либо удаляем его из \"исключенных\", либо ничего не делаем;\n * — во всех случаях, когда меняется статус родителя, все его дети исключаются из \"исключенных\";\n * — если элемент \"отключили\", то переводим его в \"исключенные\", но только в том случае, если его родитель выбран\n */\nconst createTreeCollectionExcluder = <A extends AdditionalDefault>(\n _collection: TreeCollection<A>,\n _checkSelectable: IdCollectionPredicate\n): Excluder => {\n function exclude(items: string[], excluded: Set<string>, ids: string[]) {\n if (!items.length) {\n excluded.clear();\n return;\n }\n\n ids.forEach((id) => {\n if (!_checkSelectable(id, _collection)) {\n return;\n }\n\n if (excluded.has(id)) {\n excluded.delete(id);\n\n _collection.walkChildren(id, ({ id: childId }) =>\n _excludeOperationWithChild({ excluded, ids, items, childId, isAdding: false })\n );\n } else {\n const { isParentExcluded, isParentSelected } = isParentSelectedOrExcluded(_collection, items, id, [\n ...excluded,\n ]);\n\n const isAdding = isParentSelected || isParentExcluded;\n\n if (isAdding) {\n excluded.add(id);\n }\n\n _collection.walkChildren(id, ({ id: childId }) =>\n _excludeOperationWithChild({ excluded, ids, items, childId, isAdding })\n );\n }\n });\n }\n\n function _excludeOperationWithChild({\n excluded,\n ids,\n items,\n childId,\n isAdding,\n }: {\n excluded: Set<string>;\n ids: string[];\n items: string[];\n childId: string;\n isAdding: boolean;\n }) {\n return (\n !ids.includes(childId) &&\n (isAdding ? !excluded.has(childId) : excluded.has(childId)) &&\n exclude(items, excluded, [childId])\n );\n }\n\n return exclude;\n};\n\nexport default createTreeCollectionExcluder;\n"],"names":[],"mappings":"AAIA;;AAEG;AACH,MAAM,0BAA0B,GAAG,CAC/B,UAA6B,EAC7B,WAAqB,EACrB,OAAe,EACf,QAAA,GAAqB,EAAE,KACmC;IAC1D,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAEjD,OAAO;AACH,QAAA,gBAAgB,EAAE,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,KAAK;QACnE,gBAAgB,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;KACrE,CAAC;AACN,CAAC,CAAC;AAEF;;;;;AAKG;AACH,MAAM,4BAA4B,GAAG,CACjC,WAA8B,EAC9B,gBAAuC,KAC7B;AACV,IAAA,SAAS,OAAO,CAAC,KAAe,EAAE,QAAqB,EAAE,GAAa,EAAA;AAClE,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO;AACV,SAAA;AAED,QAAA,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAI;AACf,YAAA,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE;gBACpC,OAAO;AACV,aAAA;AAED,YAAA,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAClB,gBAAA,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEpB,gBAAA,WAAW,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KACzC,0BAA0B,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CACjF,CAAC;AACL,aAAA;AAAM,iBAAA;AACH,gBAAA,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,0BAA0B,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE;AAC9F,oBAAA,GAAG,QAAQ;AACd,iBAAA,CAAC,CAAC;AAEH,gBAAA,MAAM,QAAQ,GAAG,gBAAgB,IAAI,gBAAgB,CAAC;AAEtD,gBAAA,IAAI,QAAQ,EAAE;AACV,oBAAA,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACpB,iBAAA;AAED,gBAAA,WAAW,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KACzC,0BAA0B,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAC1E,CAAC;AACL,aAAA;AACL,SAAC,CAAC,CAAC;KACN;AAED,IAAA,SAAS,0BAA0B,CAAC,EAChC,QAAQ,EACR,GAAG,EACH,KAAK,EACL,OAAO,EACP,QAAQ,GAOX,EAAA;AACG,QAAA,QACI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;aACrB,QAAQ,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3D,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,EACrC;KACL;AAED,IAAA,OAAO,OAAO,CAAC;AACnB;;;;"}
|