@hh.ru/magritte-ui-tree-selector 5.5.80 → 5.5.82
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 +1 -1
- package/Action.js +15 -12
- package/Action.js.map +1 -1
- package/Item.d.ts +3 -3
- package/Item.js +106 -54
- package/Item.js.map +1 -1
- package/ItemContent.d.ts +2 -2
- package/ItemContent.js +69 -15
- package/ItemContent.js.map +1 -1
- package/ItemsList.d.ts +3 -3
- package/ItemsList.js +243 -159
- package/ItemsList.js.map +1 -1
- package/MobileDelimiter.js +1 -1
- package/MobileDelimiter.js.map +1 -1
- package/MobileItem.d.ts +2 -2
- package/MobileItem.js +26 -5
- package/MobileItem.js.map +1 -1
- package/MobileItemsList.d.ts +2 -2
- package/MobileItemsList.js +259 -132
- package/MobileItemsList.js.map +1 -1
- package/MobileParentItem.d.ts +3 -3
- package/MobileParentItem.js +33 -14
- package/MobileParentItem.js.map +1 -1
- package/TreeSelector.d.ts +2 -2
- package/TreeSelector.js +49 -20
- package/TreeSelector.js.map +1 -1
- package/TreeSelectorDummy.d.ts +2 -2
- package/TreeSelectorDummy.js +178 -109
- package/TreeSelectorDummy.js.map +1 -1
- package/TreeSelectorItemBase.d.ts +2 -2
- package/TreeSelectorItemBase.js +12 -6
- package/TreeSelectorItemBase.js.map +1 -1
- package/TreeSelectorWrapper.js +38 -24
- package/TreeSelectorWrapper.js.map +1 -1
- package/collection/treeCollection.d.ts +1 -1
- package/collection/treeCollection.js +178 -184
- package/collection/treeCollection.js.map +1 -1
- package/collection/treeCollectionHelper.d.ts +9 -3
- package/collection/treeCollectionHelper.js +68 -105
- package/collection/treeCollectionHelper.js.map +1 -1
- package/collection/types.d.ts +1 -1
- package/index.css +45 -45
- package/index.d.ts +9 -9
- package/index.js +1 -1
- package/index.mock.d.ts +6 -6
- package/index.mock.js +14 -6
- package/index.mock.js.map +1 -1
- package/package.json +23 -22
- package/strategy/createSingleValueToggler.d.ts +1 -1
- package/strategy/createSingleValueToggler.js +17 -41
- package/strategy/createSingleValueToggler.js.map +1 -1
- package/strategy/createTreeCollectionToggler.d.ts +3 -3
- package/strategy/createTreeCollectionToggler.js +42 -58
- package/strategy/createTreeCollectionToggler.js.map +1 -1
- package/strategy/dummyToggle.d.ts +1 -1
- package/strategy/dummyToggle.js +10 -13
- package/strategy/dummyToggle.js.map +1 -1
- package/strategy/immutableSelectionStrategy.d.ts +3 -3
- package/strategy/immutableSelectionStrategy.js +27 -26
- package/strategy/immutableSelectionStrategy.js.map +1 -1
- package/strategy/selectionStrategy.d.ts +3 -3
- package/strategy/selectionStrategy.js +47 -56
- package/strategy/selectionStrategy.js.map +1 -1
- package/strategy/types.d.ts +1 -1
- package/tree-selector-item-BYBFlI_G.js +5 -0
- package/tree-selector-item-BYBFlI_G.js.map +1 -0
- package/types.d.ts +2 -2
- package/useAnimationTimeout.js +14 -14
- package/useAnimationTimeout.js.map +1 -1
- package/useDisabled.d.ts +2 -2
- package/useDisabled.js +7 -10
- package/useDisabled.js.map +1 -1
- package/useExpanded.d.ts +2 -2
- package/useExpanded.js +65 -54
- package/useExpanded.js.map +1 -1
- package/useIndeterminate.d.ts +2 -2
- package/useIndeterminate.js +17 -18
- package/useIndeterminate.js.map +1 -1
- package/useRenderInput.d.ts +1 -1
- package/useRenderInput.js +44 -32
- package/useRenderInput.js.map +1 -1
- package/useSelected.d.ts +3 -3
- package/useSelected.js +36 -31
- package/useSelected.js.map +1 -1
- package/tree-selector-item-BOEDcwrO.js +0 -5
- package/tree-selector-item-BOEDcwrO.js.map +0 -1
package/useAnimationTimeout.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import './index.css';
|
|
2
2
|
import { useState, useLayoutEffect } from 'react';
|
|
3
3
|
|
|
4
|
-
var styles = {"item-animation-timeout":"magritte-item-animation-timeout___Pdli9_5-5-
|
|
4
|
+
var styles = {"item-animation-timeout":"magritte-item-animation-timeout___Pdli9_5-5-82","itemAnimationTimeout":"magritte-item-animation-timeout___Pdli9_5-5-82","fade-in":"magritte-fade-in___FDoho_5-5-82","fadeIn":"magritte-fade-in___FDoho_5-5-82"};
|
|
5
5
|
|
|
6
6
|
const useAnimationTimeout = () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
const [animationTimeout, setAnimationTimeout] = useState(0);
|
|
8
|
+
useLayoutEffect(() => {
|
|
9
|
+
const animationTimeoutElement = document.createElement("div");
|
|
10
|
+
animationTimeoutElement.classList.add(styles.itemAnimationTimeout);
|
|
11
|
+
document.body.appendChild(animationTimeoutElement);
|
|
12
|
+
const style = window.getComputedStyle(animationTimeoutElement);
|
|
13
|
+
const animationTimeout2 = parseInt(style.getPropertyValue(`--animation-duration`), 10);
|
|
14
|
+
if (Number.isInteger(animationTimeout2)) {
|
|
15
|
+
setAnimationTimeout(animationTimeout2);
|
|
16
|
+
}
|
|
17
|
+
document.body.removeChild(animationTimeoutElement);
|
|
18
|
+
}, []);
|
|
19
|
+
return { animationTimeout };
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
export { useAnimationTimeout };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnimationTimeout.js","sources":["src/useAnimationTimeout.ts"],"sourcesContent":["import { useLayoutEffect, useState } from 'react';\n\nimport styles from './animation.less';\n\ninterface UseAnimationTimeoutHook {\n (): { animationTimeout: number };\n}\n\nexport const useAnimationTimeout: UseAnimationTimeoutHook = () => {\n const [animationTimeout, setAnimationTimeout] = useState(0);\n\n useLayoutEffect(() => {\n const animationTimeoutElement = document.createElement('div');\n animationTimeoutElement.classList.add(styles.itemAnimationTimeout);\n document.body.appendChild(animationTimeoutElement);\n const style = window.getComputedStyle(animationTimeoutElement);\n const animationTimeout = parseInt(style.getPropertyValue(`--animation-duration`), 10);\n if (Number.isInteger(animationTimeout)) {\n setAnimationTimeout(animationTimeout);\n }\n document.body.removeChild(animationTimeoutElement);\n }, []);\n\n return { animationTimeout };\n};\n"],"names":[],"mappings":";;;;AAQO,MAAM,
|
|
1
|
+
{"version":3,"file":"useAnimationTimeout.js","sources":["src/useAnimationTimeout.ts"],"sourcesContent":["import { useLayoutEffect, useState } from 'react';\n\nimport styles from './animation.less';\n\ninterface UseAnimationTimeoutHook {\n (): { animationTimeout: number };\n}\n\nexport const useAnimationTimeout: UseAnimationTimeoutHook = () => {\n const [animationTimeout, setAnimationTimeout] = useState(0);\n\n useLayoutEffect(() => {\n const animationTimeoutElement = document.createElement('div');\n animationTimeoutElement.classList.add(styles.itemAnimationTimeout);\n document.body.appendChild(animationTimeoutElement);\n const style = window.getComputedStyle(animationTimeoutElement);\n const animationTimeout = parseInt(style.getPropertyValue(`--animation-duration`), 10);\n if (Number.isInteger(animationTimeout)) {\n setAnimationTimeout(animationTimeout);\n }\n document.body.removeChild(animationTimeoutElement);\n }, []);\n\n return { animationTimeout };\n};\n"],"names":["animationTimeout"],"mappings":";;;;AAQO,MAAM,sBAA+C,MAAM;AAC9D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAS,CAAC,CAAA,CAAA;AAE1D,EAAA,eAAA,CAAgB,MAAM;AAClB,IAAM,MAAA,uBAAA,GAA0B,QAAS,CAAA,aAAA,CAAc,KAAK,CAAA,CAAA;AAC5D,IAAwB,uBAAA,CAAA,SAAA,CAAU,GAAI,CAAA,MAAA,CAAO,oBAAoB,CAAA,CAAA;AACjE,IAAS,QAAA,CAAA,IAAA,CAAK,YAAY,uBAAuB,CAAA,CAAA;AACjD,IAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,gBAAA,CAAiB,uBAAuB,CAAA,CAAA;AAC7D,IAAA,MAAMA,oBAAmB,QAAS,CAAA,KAAA,CAAM,gBAAiB,CAAA,CAAA,oBAAA,CAAsB,GAAG,EAAE,CAAA,CAAA;AACpF,IAAI,IAAA,MAAA,CAAO,SAAUA,CAAAA,iBAAgB,CAAG,EAAA;AACpC,MAAA,mBAAA,CAAoBA,iBAAgB,CAAA,CAAA;AAAA,KACxC;AACA,IAAS,QAAA,CAAA,IAAA,CAAK,YAAY,uBAAuB,CAAA,CAAA;AAAA,GACrD,EAAG,EAAE,CAAA,CAAA;AAEL,EAAA,OAAO,EAAE,gBAAiB,EAAA,CAAA;AAC9B;;;;"}
|
package/useDisabled.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AdditionalDefault } from '
|
|
2
|
-
import { TreeSelectorProps } from '
|
|
1
|
+
import { AdditionalDefault } from './collection/types';
|
|
2
|
+
import { TreeSelectorProps } from './types';
|
|
3
3
|
type UseDisabledHookProps<Additional extends AdditionalDefault> = {
|
|
4
4
|
selected: string[];
|
|
5
5
|
} & Pick<TreeSelectorProps<Additional>, 'disabled' | 'collection' | 'maxSelected'>;
|
package/useDisabled.js
CHANGED
|
@@ -4,16 +4,13 @@ import { getIdsWithNoParentsInSameList } from './collection/treeCollectionHelper
|
|
|
4
4
|
import './collection/treeCollection.js';
|
|
5
5
|
|
|
6
6
|
const useDisabled = ({ selected, disabled, collection, maxSelected }) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
return disabled;
|
|
16
|
-
}, [selected, collection, disabled, maxSelected]);
|
|
7
|
+
return useMemo(() => {
|
|
8
|
+
const valueIds = getIdsWithNoParentsInSameList(collection, selected);
|
|
9
|
+
if (maxSelected && valueIds.length >= maxSelected) {
|
|
10
|
+
return collection.toList().map(({ id }) => id).filter((id) => !selected.includes(id));
|
|
11
|
+
}
|
|
12
|
+
return disabled;
|
|
13
|
+
}, [selected, collection, disabled, maxSelected]);
|
|
17
14
|
};
|
|
18
15
|
|
|
19
16
|
export { useDisabled };
|
package/useDisabled.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDisabled.js","sources":["src/useDisabled.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { getIdsWithNoParentsInSameList } from '@hh.ru/magritte-ui-tree-selector/collection/treeCollectionHelper';\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport { TreeSelectorProps } from '@hh.ru/magritte-ui-tree-selector/types';\n\ntype UseDisabledHookProps<Additional extends AdditionalDefault> = {\n selected: string[];\n} & Pick<TreeSelectorProps<Additional>, 'disabled' | 'collection' | 'maxSelected'>;\ninterface UseDisabledHook {\n <Additional extends AdditionalDefault>(props: UseDisabledHookProps<Additional>): string[] | undefined;\n}\n\nexport const useDisabled: UseDisabledHook = ({ selected, disabled, collection, maxSelected }) => {\n return useMemo(() => {\n const valueIds = getIdsWithNoParentsInSameList(collection, selected);\n if (maxSelected && valueIds.length >= maxSelected) {\n return collection\n .toList()\n .map(({ id }) => id)\n .filter((id) => !selected.includes(id));\n }\n return disabled;\n }, [selected, collection, disabled, maxSelected]);\n};\n"],"names":[],"mappings":";;;;AAaO,MAAM,
|
|
1
|
+
{"version":3,"file":"useDisabled.js","sources":["src/useDisabled.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport { getIdsWithNoParentsInSameList } from '@hh.ru/magritte-ui-tree-selector/collection/treeCollectionHelper';\nimport { AdditionalDefault } from '@hh.ru/magritte-ui-tree-selector/collection/types';\nimport { TreeSelectorProps } from '@hh.ru/magritte-ui-tree-selector/types';\n\ntype UseDisabledHookProps<Additional extends AdditionalDefault> = {\n selected: string[];\n} & Pick<TreeSelectorProps<Additional>, 'disabled' | 'collection' | 'maxSelected'>;\ninterface UseDisabledHook {\n <Additional extends AdditionalDefault>(props: UseDisabledHookProps<Additional>): string[] | undefined;\n}\n\nexport const useDisabled: UseDisabledHook = ({ selected, disabled, collection, maxSelected }) => {\n return useMemo(() => {\n const valueIds = getIdsWithNoParentsInSameList(collection, selected);\n if (maxSelected && valueIds.length >= maxSelected) {\n return collection\n .toList()\n .map(({ id }) => id)\n .filter((id) => !selected.includes(id));\n }\n return disabled;\n }, [selected, collection, disabled, maxSelected]);\n};\n"],"names":[],"mappings":";;;;AAaO,MAAM,cAA+B,CAAC,EAAE,UAAU,QAAU,EAAA,UAAA,EAAY,aAAkB,KAAA;AAC7F,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAM,MAAA,QAAA,GAAW,6BAA8B,CAAA,UAAA,EAAY,QAAQ,CAAA,CAAA;AACnE,IAAI,IAAA,WAAA,IAAe,QAAS,CAAA,MAAA,IAAU,WAAa,EAAA;AAC/C,MAAA,OAAO,WACF,MAAO,EAAA,CACP,GAAI,CAAA,CAAC,EAAE,EAAG,EAAA,KAAM,EAAE,CAAA,CAClB,OAAO,CAAC,EAAA,KAAO,CAAC,QAAS,CAAA,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAAA,KAC9C;AACA,IAAO,OAAA,QAAA,CAAA;AAAA,KACR,CAAC,QAAA,EAAU,UAAY,EAAA,QAAA,EAAU,WAAW,CAAC,CAAA,CAAA;AACpD;;;;"}
|
package/useExpanded.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import TreeCollection from '
|
|
2
|
-
import { AdditionalDefault } from '
|
|
1
|
+
import TreeCollection from './collection/treeCollection';
|
|
2
|
+
import { AdditionalDefault } from './collection/types';
|
|
3
3
|
export declare const areEqualArrays: (arr1: string[], arr2: string[]) => boolean;
|
|
4
4
|
export declare const calculateInitialExpanded: <Additional extends AdditionalDefault>(initialExpanded: string[], selected: string[], expandTreeOnSelected: boolean, collection: TreeCollection<Additional>) => string[];
|
|
5
5
|
interface UseExpandedHookProps<Additional extends AdditionalDefault> {
|
package/useExpanded.js
CHANGED
|
@@ -2,64 +2,75 @@ import './index.css';
|
|
|
2
2
|
import { useMemo, useState, useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
const areEqualArrays = (arr1, arr2) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
.slice()
|
|
11
|
-
.sort()
|
|
12
|
-
.every((item, index) => item === sortArr2[index]);
|
|
5
|
+
if (arr1.length !== arr2.length) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const sortArr2 = arr2.slice().sort();
|
|
9
|
+
return arr1.slice().sort().every((item, index) => item === sortArr2[index]);
|
|
13
10
|
};
|
|
14
11
|
const calculateInitialExpanded = (initialExpanded, selected, expandTreeOnSelected, collection) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
const expanded = initialExpanded.slice();
|
|
13
|
+
if (expandTreeOnSelected) {
|
|
14
|
+
selected.forEach((id) => {
|
|
15
|
+
expanded.push(...collection.getParentIds(id));
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return [...new Set(expanded)];
|
|
22
19
|
};
|
|
23
|
-
const useExpanded = ({
|
|
24
|
-
|
|
20
|
+
const useExpanded = ({
|
|
21
|
+
initialValue,
|
|
22
|
+
selected,
|
|
23
|
+
expandTreeOnSelected,
|
|
24
|
+
collection,
|
|
25
|
+
onExpand
|
|
26
|
+
}) => {
|
|
27
|
+
const calculatedInitialValue = useMemo(
|
|
28
|
+
() => calculateInitialExpanded(initialValue, selected, expandTreeOnSelected, collection),
|
|
25
29
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
26
|
-
[]
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
30
|
+
[]
|
|
31
|
+
);
|
|
32
|
+
const [expanded, setExpanded] = useState(calculatedInitialValue);
|
|
33
|
+
const expandedRef = useRef(calculatedInitialValue);
|
|
34
|
+
const selectedRef = useRef(selected);
|
|
35
|
+
selectedRef.current = selected;
|
|
36
|
+
const handlerRef = useRef(onExpand);
|
|
37
|
+
const handleSetExpanded = useCallback((updatedExpanded) => {
|
|
38
|
+
handlerRef.current?.(updatedExpanded.slice());
|
|
39
|
+
if (!areEqualArrays(expandedRef.current, updatedExpanded)) {
|
|
40
|
+
setExpanded(updatedExpanded);
|
|
41
|
+
}
|
|
42
|
+
}, []);
|
|
43
|
+
const handleExpansion = useCallback(
|
|
44
|
+
(id) => {
|
|
45
|
+
let updatedExpanded;
|
|
46
|
+
if (expandedRef.current.includes(id)) {
|
|
47
|
+
updatedExpanded = expandedRef.current.filter((itemId) => itemId !== id);
|
|
48
|
+
} else {
|
|
49
|
+
updatedExpanded = expandedRef.current.slice();
|
|
50
|
+
updatedExpanded.push(id);
|
|
51
|
+
}
|
|
52
|
+
handleSetExpanded(updatedExpanded);
|
|
53
|
+
},
|
|
54
|
+
[handleSetExpanded]
|
|
55
|
+
);
|
|
56
|
+
const handleResetExpanded = useCallback(() => {
|
|
57
|
+
const calculatedResetValue = calculateInitialExpanded(
|
|
58
|
+
initialValue,
|
|
59
|
+
selectedRef.current,
|
|
60
|
+
expandTreeOnSelected,
|
|
61
|
+
collection
|
|
62
|
+
);
|
|
63
|
+
if (!areEqualArrays(expandedRef.current, calculatedResetValue)) {
|
|
64
|
+
setExpanded(calculatedResetValue);
|
|
65
|
+
}
|
|
66
|
+
}, []);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
handlerRef.current = onExpand;
|
|
69
|
+
}, [onExpand]);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
expandedRef.current = expanded;
|
|
72
|
+
}, [expanded]);
|
|
73
|
+
return { expanded, setExpanded: handleSetExpanded, handleExpansion, handleResetExpanded };
|
|
63
74
|
};
|
|
64
75
|
|
|
65
76
|
export { areEqualArrays, calculateInitialExpanded, useExpanded };
|
package/useExpanded.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useExpanded.js","sources":["src/useExpanded.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState, useMemo } 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';\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\nexport const calculateInitialExpanded = <Additional extends AdditionalDefault>(\n initialExpanded: string[],\n selected: string[],\n expandTreeOnSelected: boolean,\n collection: TreeCollection<Additional>\n): string[] => {\n const expanded: string[] = initialExpanded.slice();\n if (expandTreeOnSelected) {\n selected.forEach((id) => {\n expanded.push(...collection.getParentIds(id));\n });\n }\n return [...new Set(expanded)];\n};\n\ninterface UseExpandedHookProps<Additional extends AdditionalDefault> {\n initialValue: string[];\n onExpand?: (expanded: string[]) => void;\n expandTreeOnSelected: boolean;\n selected: string[];\n collection: TreeCollection<Additional>;\n}\n\ninterface UseExpandedHookReturn {\n expanded: string[];\n setExpanded: (expanded: string[]) => void;\n handleExpansion: (id: string) => void;\n handleResetExpanded: () => void;\n}\ninterface UseExpandedHook {\n <Additional extends AdditionalDefault>(props: UseExpandedHookProps<Additional>): UseExpandedHookReturn;\n}\n\nexport const useExpanded: UseExpandedHook = ({\n initialValue,\n selected,\n expandTreeOnSelected,\n collection,\n onExpand,\n}) => {\n const calculatedInitialValue = useMemo(\n () => calculateInitialExpanded(initialValue, selected, expandTreeOnSelected, collection),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n const [expanded, setExpanded] = useState(calculatedInitialValue);\n const expandedRef = useRef(calculatedInitialValue);\n const selectedRef = useRef(selected);\n selectedRef.current = selected;\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 const handleResetExpanded = useCallback(() => {\n const calculatedResetValue = calculateInitialExpanded(\n initialValue,\n selectedRef.current,\n expandTreeOnSelected,\n collection\n );\n if (!areEqualArrays(expandedRef.current, calculatedResetValue)) {\n setExpanded(calculatedResetValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n handlerRef.current = onExpand;\n }, [onExpand]);\n\n useEffect(() => {\n expandedRef.current = expanded;\n }, [expanded]);\n\n return { expanded, setExpanded: handleSetExpanded, handleExpansion, handleResetExpanded };\n};\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"useExpanded.js","sources":["src/useExpanded.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState, useMemo } 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';\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\nexport const calculateInitialExpanded = <Additional extends AdditionalDefault>(\n initialExpanded: string[],\n selected: string[],\n expandTreeOnSelected: boolean,\n collection: TreeCollection<Additional>\n): string[] => {\n const expanded: string[] = initialExpanded.slice();\n if (expandTreeOnSelected) {\n selected.forEach((id) => {\n expanded.push(...collection.getParentIds(id));\n });\n }\n return [...new Set(expanded)];\n};\n\ninterface UseExpandedHookProps<Additional extends AdditionalDefault> {\n initialValue: string[];\n onExpand?: (expanded: string[]) => void;\n expandTreeOnSelected: boolean;\n selected: string[];\n collection: TreeCollection<Additional>;\n}\n\ninterface UseExpandedHookReturn {\n expanded: string[];\n setExpanded: (expanded: string[]) => void;\n handleExpansion: (id: string) => void;\n handleResetExpanded: () => void;\n}\ninterface UseExpandedHook {\n <Additional extends AdditionalDefault>(props: UseExpandedHookProps<Additional>): UseExpandedHookReturn;\n}\n\nexport const useExpanded: UseExpandedHook = ({\n initialValue,\n selected,\n expandTreeOnSelected,\n collection,\n onExpand,\n}) => {\n const calculatedInitialValue = useMemo(\n () => calculateInitialExpanded(initialValue, selected, expandTreeOnSelected, collection),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n []\n );\n const [expanded, setExpanded] = useState(calculatedInitialValue);\n const expandedRef = useRef(calculatedInitialValue);\n const selectedRef = useRef(selected);\n selectedRef.current = selected;\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 const handleResetExpanded = useCallback(() => {\n const calculatedResetValue = calculateInitialExpanded(\n initialValue,\n selectedRef.current,\n expandTreeOnSelected,\n collection\n );\n if (!areEqualArrays(expandedRef.current, calculatedResetValue)) {\n setExpanded(calculatedResetValue);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n handlerRef.current = onExpand;\n }, [onExpand]);\n\n useEffect(() => {\n expandedRef.current = expanded;\n }, [expanded]);\n\n return { expanded, setExpanded: handleSetExpanded, handleExpansion, handleResetExpanded };\n};\n"],"names":[],"mappings":"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"}
|
package/useIndeterminate.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import TreeCollection from '
|
|
2
|
-
import { AdditionalDefault } from '
|
|
1
|
+
import TreeCollection from './collection/treeCollection';
|
|
2
|
+
import { AdditionalDefault } from './collection/types';
|
|
3
3
|
/**
|
|
4
4
|
* Возвращает массив ID элементов дерева, у которых есть и выбранные, и невыбранные потомки.
|
|
5
5
|
*/
|
package/useIndeterminate.js
CHANGED
|
@@ -2,27 +2,26 @@ import './index.css';
|
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
import { areEqualArrays } from './useExpanded.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Возвращает массив ID элементов дерева, у которых есть и выбранные, и невыбранные потомки.
|
|
7
|
-
*/
|
|
8
5
|
function getIndeterminateParentIds(collection, selected) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
const result = selected.reduce((currentResult, id) => {
|
|
7
|
+
collection.getParentIds(id).forEach((parentId) => {
|
|
8
|
+
if (!selected.includes(parentId)) {
|
|
9
|
+
currentResult.add(parentId);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
return currentResult;
|
|
13
|
+
}, /* @__PURE__ */ new Set());
|
|
14
|
+
return [...result];
|
|
18
15
|
}
|
|
19
16
|
const useIndeterminate = ({ collection, selected }) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
const [indeterminate, setIndeterminate] = useState([]);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const updatedIndeterminateIds = getIndeterminateParentIds(collection, selected);
|
|
20
|
+
setIndeterminate(
|
|
21
|
+
(current) => areEqualArrays(current, updatedIndeterminateIds) ? current : updatedIndeterminateIds
|
|
22
|
+
);
|
|
23
|
+
}, [selected, collection]);
|
|
24
|
+
return { indeterminate };
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
export { getIndeterminateParentIds, useIndeterminate };
|
package/useIndeterminate.js.map
CHANGED
|
@@ -1 +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<Additional extends AdditionalDefault>(\n collection: TreeCollection<Additional>,\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<Additional extends AdditionalDefault> {\n collection: TreeCollection<Additional>;\n selected: string[];\n}\ninterface UseIndeterminateHook {\n <Additional extends AdditionalDefault>(props: UseIndeterminateHookProps<Additional>): { 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":";;;
|
|
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<Additional extends AdditionalDefault>(\n collection: TreeCollection<Additional>,\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<Additional extends AdditionalDefault> {\n collection: TreeCollection<Additional>;\n selected: string[];\n}\ninterface UseIndeterminateHook {\n <Additional extends AdditionalDefault>(props: UseIndeterminateHookProps<Additional>): { 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":";;;AASO,SAAS,yBAAA,CACZ,YACA,QACQ,EAAA;AACR,EAAA,MAAM,MAAS,GAAA,QAAA,CAAS,MAAO,CAAA,CAAC,eAAe,EAAO,KAAA;AAClD,IAAA,UAAA,CAAW,YAAa,CAAA,EAAE,CAAE,CAAA,OAAA,CAAQ,CAAC,QAAa,KAAA;AAC9C,MAAA,IAAI,CAAC,QAAA,CAAS,QAAS,CAAA,QAAQ,CAAG,EAAA;AAC9B,QAAA,aAAA,CAAc,IAAI,QAAQ,CAAA,CAAA;AAAA,OAC9B;AAAA,KACH,CAAA,CAAA;AACD,IAAO,OAAA,aAAA,CAAA;AAAA,GACX,kBAAO,IAAA,GAAA,EAAa,CAAA,CAAA;AACpB,EAAO,OAAA,CAAC,GAAG,MAAM,CAAA,CAAA;AACrB,CAAA;AAUO,MAAM,gBAAyC,GAAA,CAAC,EAAE,UAAA,EAAY,UAAe,KAAA;AAChF,EAAA,MAAM,CAAC,aAAe,EAAA,gBAAgB,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA,CAAA;AAE/D,EAAA,SAAA,CAAU,MAAM;AACZ,IAAM,MAAA,uBAAA,GAA0B,yBAA0B,CAAA,UAAA,EAAY,QAAQ,CAAA,CAAA;AAC9E,IAAA,gBAAA;AAAA,MAAiB,CAAC,OACd,KAAA,cAAA,CAAe,OAAS,EAAA,uBAAuB,IAAI,OAAU,GAAA,uBAAA;AAAA,KACjE,CAAA;AAAA,GACD,EAAA,CAAC,QAAU,EAAA,UAAU,CAAC,CAAA,CAAA;AACzB,EAAA,OAAO,EAAE,aAAc,EAAA,CAAA;AAC3B;;;;"}
|
package/useRenderInput.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactElement, RefObject } from 'react';
|
|
2
|
-
import { SearchInputPropsWithRef } from '
|
|
2
|
+
import { SearchInputPropsWithRef } from './types';
|
|
3
3
|
export interface UseRenderInputHook {
|
|
4
4
|
(inputRef: RefObject<HTMLInputElement>): {
|
|
5
5
|
contentFilterQuery: string;
|
package/useRenderInput.js
CHANGED
|
@@ -8,40 +8,52 @@ import { SearchInput } from '@hh.ru/magritte-ui-input';
|
|
|
8
8
|
import { useAnimationTimeout } from './useAnimationTimeout.js';
|
|
9
9
|
|
|
10
10
|
const WrapperInput = forwardRef(({ parentRef, ...props }, ref) => {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const multiRef = useMultipleRefs(ref, parentRef);
|
|
12
|
+
return /* @__PURE__ */ jsx(SearchInput, { ...props, ref: multiRef, "data-qa": "tree-selector-search-input" });
|
|
13
13
|
});
|
|
14
|
-
WrapperInput.displayName =
|
|
14
|
+
WrapperInput.displayName = "TreeSelectorInput";
|
|
15
15
|
const useRenderInput = (inputRef) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
16
|
+
const [contentFilterQuery, setContentFilterQuery] = useState("");
|
|
17
|
+
const { animationTimeout } = useAnimationTimeout();
|
|
18
|
+
const [value, setValue] = useState("");
|
|
19
|
+
const { isMobile } = useBreakpoint();
|
|
20
|
+
const inputRefCallback = useCallback((node) => {
|
|
21
|
+
if (!node) {
|
|
22
|
+
setValue("");
|
|
23
|
+
setContentFilterQuery("");
|
|
24
|
+
}
|
|
25
|
+
}, []);
|
|
26
|
+
const ref = useMultipleRefs(inputRef, inputRefCallback);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setValue("");
|
|
29
|
+
setContentFilterQuery("");
|
|
30
|
+
}, [isMobile]);
|
|
31
|
+
const debouncedContentFilterQuery = useDebounce(
|
|
32
|
+
useCallback((newValue) => {
|
|
33
|
+
setContentFilterQuery(newValue);
|
|
34
|
+
}, []),
|
|
35
|
+
animationTimeout
|
|
36
|
+
);
|
|
37
|
+
const handleChangeInput = useCallback(
|
|
38
|
+
(newValue) => {
|
|
39
|
+
debouncedContentFilterQuery(newValue);
|
|
40
|
+
setValue(newValue);
|
|
41
|
+
},
|
|
42
|
+
[debouncedContentFilterQuery]
|
|
43
|
+
);
|
|
44
|
+
const setInputValue = useCallback(
|
|
45
|
+
(newValue) => {
|
|
46
|
+
setValue(newValue);
|
|
47
|
+
},
|
|
48
|
+
[setValue]
|
|
49
|
+
);
|
|
50
|
+
const renderInput = useCallback(
|
|
51
|
+
(props) => {
|
|
52
|
+
return /* @__PURE__ */ jsx(WrapperInput, { ...props, value, onChange: handleChangeInput, parentRef: ref });
|
|
53
|
+
},
|
|
54
|
+
[ref, value, handleChangeInput]
|
|
55
|
+
);
|
|
56
|
+
return { contentFilterQuery, setInputValue, handleChangeInput, renderInput };
|
|
45
57
|
};
|
|
46
58
|
|
|
47
59
|
export { useRenderInput };
|
package/useRenderInput.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRenderInput.js","sources":["src/useRenderInput.tsx"],"sourcesContent":["import { ReactElement, RefCallback, useCallback, useEffect, useState, RefObject, forwardRef } from 'react';\n\nimport { useDebounce } from '@hh.ru/magritte-common-func-utils';\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { SearchInput, SearchInputProps } from '@hh.ru/magritte-ui-input';\nimport { SearchInputPropsWithRef } from '@hh.ru/magritte-ui-tree-selector/types';\nimport { useAnimationTimeout } from '@hh.ru/magritte-ui-tree-selector/useAnimationTimeout';\n\ntype WrapperInputProps = SearchInputProps & {\n value: string;\n onChange: (newValue: string) => void;\n parentRef: RefCallback<HTMLInputElement>;\n};\n\nconst WrapperInput = forwardRef<HTMLInputElement, WrapperInputProps>(({ parentRef, ...props }, ref) => {\n const multiRef = useMultipleRefs(ref, parentRef);\n return <SearchInput {...props} ref={multiRef} data-qa=\"tree-selector-search-input\" />;\n});\n\nWrapperInput.displayName = 'TreeSelectorInput';\n\nexport interface UseRenderInputHook {\n (inputRef: RefObject<HTMLInputElement>): {\n contentFilterQuery: string;\n setInputValue: (newValue: string) => void;\n handleChangeInput: (newValue: string) => void;\n renderInput: (props?: SearchInputPropsWithRef) => ReactElement;\n };\n}\n\nexport const useRenderInput: UseRenderInputHook = (inputRef) => {\n const [contentFilterQuery, setContentFilterQuery] = useState('');\n const { animationTimeout } = useAnimationTimeout();\n const [value, setValue] = useState('');\n const { isMobile } = useBreakpoint();\n\n const inputRefCallback: RefCallback<HTMLInputElement> = useCallback((node) => {\n if (!node) {\n setValue('');\n setContentFilterQuery('');\n }\n }, []);\n\n const ref = useMultipleRefs(inputRef, inputRefCallback);\n\n useEffect(() => {\n setValue('');\n setContentFilterQuery('');\n }, [isMobile]);\n\n const debouncedContentFilterQuery = useDebounce(\n useCallback((newValue: string) => {\n setContentFilterQuery(newValue);\n }, []),\n animationTimeout\n );\n\n const handleChangeInput = useCallback(\n (newValue: string) => {\n debouncedContentFilterQuery(newValue);\n setValue(newValue);\n },\n [debouncedContentFilterQuery]\n );\n\n const setInputValue = useCallback(\n (newValue: string) => {\n setValue(newValue);\n },\n [setValue]\n );\n\n const renderInput = useCallback(\n (props?: SearchInputPropsWithRef) => {\n return <WrapperInput {...props} value={value} onChange={handleChangeInput} parentRef={ref} />;\n },\n [ref, value, handleChangeInput]\n );\n\n return { contentFilterQuery, setInputValue, handleChangeInput, renderInput };\n};\n"],"names":[
|
|
1
|
+
{"version":3,"file":"useRenderInput.js","sources":["src/useRenderInput.tsx"],"sourcesContent":["import { ReactElement, RefCallback, useCallback, useEffect, useState, RefObject, forwardRef } from 'react';\n\nimport { useDebounce } from '@hh.ru/magritte-common-func-utils';\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\nimport { SearchInput, SearchInputProps } from '@hh.ru/magritte-ui-input';\nimport { SearchInputPropsWithRef } from '@hh.ru/magritte-ui-tree-selector/types';\nimport { useAnimationTimeout } from '@hh.ru/magritte-ui-tree-selector/useAnimationTimeout';\n\ntype WrapperInputProps = SearchInputProps & {\n value: string;\n onChange: (newValue: string) => void;\n parentRef: RefCallback<HTMLInputElement>;\n};\n\nconst WrapperInput = forwardRef<HTMLInputElement, WrapperInputProps>(({ parentRef, ...props }, ref) => {\n const multiRef = useMultipleRefs(ref, parentRef);\n return <SearchInput {...props} ref={multiRef} data-qa=\"tree-selector-search-input\" />;\n});\n\nWrapperInput.displayName = 'TreeSelectorInput';\n\nexport interface UseRenderInputHook {\n (inputRef: RefObject<HTMLInputElement>): {\n contentFilterQuery: string;\n setInputValue: (newValue: string) => void;\n handleChangeInput: (newValue: string) => void;\n renderInput: (props?: SearchInputPropsWithRef) => ReactElement;\n };\n}\n\nexport const useRenderInput: UseRenderInputHook = (inputRef) => {\n const [contentFilterQuery, setContentFilterQuery] = useState('');\n const { animationTimeout } = useAnimationTimeout();\n const [value, setValue] = useState('');\n const { isMobile } = useBreakpoint();\n\n const inputRefCallback: RefCallback<HTMLInputElement> = useCallback((node) => {\n if (!node) {\n setValue('');\n setContentFilterQuery('');\n }\n }, []);\n\n const ref = useMultipleRefs(inputRef, inputRefCallback);\n\n useEffect(() => {\n setValue('');\n setContentFilterQuery('');\n }, [isMobile]);\n\n const debouncedContentFilterQuery = useDebounce(\n useCallback((newValue: string) => {\n setContentFilterQuery(newValue);\n }, []),\n animationTimeout\n );\n\n const handleChangeInput = useCallback(\n (newValue: string) => {\n debouncedContentFilterQuery(newValue);\n setValue(newValue);\n },\n [debouncedContentFilterQuery]\n );\n\n const setInputValue = useCallback(\n (newValue: string) => {\n setValue(newValue);\n },\n [setValue]\n );\n\n const renderInput = useCallback(\n (props?: SearchInputPropsWithRef) => {\n return <WrapperInput {...props} value={value} onChange={handleChangeInput} parentRef={ref} />;\n },\n [ref, value, handleChangeInput]\n );\n\n return { contentFilterQuery, setInputValue, handleChangeInput, renderInput };\n};\n"],"names":[],"mappings":";;;;;;;;AAeA,MAAM,YAAA,GAAe,WAAgD,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAQ,KAAA;AACnG,EAAM,MAAA,QAAA,GAAW,eAAgB,CAAA,GAAA,EAAK,SAAS,CAAA,CAAA;AAC/C,EAAA,2BAAQ,WAAa,EAAA,EAAA,GAAG,OAAO,GAAK,EAAA,QAAA,EAAU,WAAQ,4BAA6B,EAAA,CAAA,CAAA;AACvF,CAAC,CAAA,CAAA;AAED,YAAA,CAAa,WAAc,GAAA,mBAAA,CAAA;AAWd,MAAA,cAAA,GAAqC,CAAC,QAAa,KAAA;AAC5D,EAAA,MAAM,CAAC,kBAAA,EAAoB,qBAAqB,CAAA,GAAI,SAAS,EAAE,CAAA,CAAA;AAC/D,EAAM,MAAA,EAAE,gBAAiB,EAAA,GAAI,mBAAoB,EAAA,CAAA;AACjD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA,CAAA;AACrC,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,aAAc,EAAA,CAAA;AAEnC,EAAM,MAAA,gBAAA,GAAkD,WAAY,CAAA,CAAC,IAAS,KAAA;AAC1E,IAAA,IAAI,CAAC,IAAM,EAAA;AACP,MAAA,QAAA,CAAS,EAAE,CAAA,CAAA;AACX,MAAA,qBAAA,CAAsB,EAAE,CAAA,CAAA;AAAA,KAC5B;AAAA,GACJ,EAAG,EAAE,CAAA,CAAA;AAEL,EAAM,MAAA,GAAA,GAAM,eAAgB,CAAA,QAAA,EAAU,gBAAgB,CAAA,CAAA;AAEtD,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,QAAA,CAAS,EAAE,CAAA,CAAA;AACX,IAAA,qBAAA,CAAsB,EAAE,CAAA,CAAA;AAAA,GAC5B,EAAG,CAAC,QAAQ,CAAC,CAAA,CAAA;AAEb,EAAA,MAAM,2BAA8B,GAAA,WAAA;AAAA,IAChC,WAAA,CAAY,CAAC,QAAqB,KAAA;AAC9B,MAAA,qBAAA,CAAsB,QAAQ,CAAA,CAAA;AAAA,KAClC,EAAG,EAAE,CAAA;AAAA,IACL,gBAAA;AAAA,GACJ,CAAA;AAEA,EAAA,MAAM,iBAAoB,GAAA,WAAA;AAAA,IACtB,CAAC,QAAqB,KAAA;AAClB,MAAA,2BAAA,CAA4B,QAAQ,CAAA,CAAA;AACpC,MAAA,QAAA,CAAS,QAAQ,CAAA,CAAA;AAAA,KACrB;AAAA,IACA,CAAC,2BAA2B,CAAA;AAAA,GAChC,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IAClB,CAAC,QAAqB,KAAA;AAClB,MAAA,QAAA,CAAS,QAAQ,CAAA,CAAA;AAAA,KACrB;AAAA,IACA,CAAC,QAAQ,CAAA;AAAA,GACb,CAAA;AAEA,EAAA,MAAM,WAAc,GAAA,WAAA;AAAA,IAChB,CAAC,KAAoC,KAAA;AACjC,MAAO,uBAAA,GAAA,CAAC,gBAAc,GAAG,KAAA,EAAO,OAAc,QAAU,EAAA,iBAAA,EAAmB,WAAW,GAAK,EAAA,CAAA,CAAA;AAAA,KAC/F;AAAA,IACA,CAAC,GAAK,EAAA,KAAA,EAAO,iBAAiB,CAAA;AAAA,GAClC,CAAA;AAEA,EAAA,OAAO,EAAE,kBAAA,EAAoB,aAAe,EAAA,iBAAA,EAAmB,WAAY,EAAA,CAAA;AAC/E;;;;"}
|
package/useSelected.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AdditionalDefault } from '
|
|
2
|
-
import ImmutableSelectionStrategy from '
|
|
3
|
-
import { TreeSelectorProps } from '
|
|
1
|
+
import { AdditionalDefault } from './collection/types';
|
|
2
|
+
import ImmutableSelectionStrategy from './strategy/immutableSelectionStrategy';
|
|
3
|
+
import { TreeSelectorProps } from './types';
|
|
4
4
|
type UseSelectedHookProps<Additional extends AdditionalDefault> = {
|
|
5
5
|
strategy: ImmutableSelectionStrategy<Additional>;
|
|
6
6
|
} & Pick<TreeSelectorProps<Additional>, 'value' | 'onChange' | 'collapseToParentId' | 'maxSelected' | 'collection'>;
|
package/useSelected.js
CHANGED
|
@@ -3,38 +3,43 @@ import { useCallback, useState } from 'react';
|
|
|
3
3
|
import { getIdsWithNoParentsInSameList } from './collection/treeCollectionHelper.js';
|
|
4
4
|
import './collection/treeCollection.js';
|
|
5
5
|
|
|
6
|
-
const useSelected = ({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const [prevGetSelectedFromValue, setPrevGetSelectedFromValue] = useState(() => getSelectedFromValue);
|
|
19
|
-
if (prevGetSelectedFromValue !== getSelectedFromValue) {
|
|
20
|
-
setPrevGetSelectedFromValue(() => getSelectedFromValue);
|
|
21
|
-
setSelectedState(getSelectedFromValue());
|
|
6
|
+
const useSelected = ({
|
|
7
|
+
value,
|
|
8
|
+
maxSelected,
|
|
9
|
+
strategy,
|
|
10
|
+
collection,
|
|
11
|
+
collapseToParentId,
|
|
12
|
+
onChange
|
|
13
|
+
}) => {
|
|
14
|
+
const getSelectedFromValue = useCallback(() => {
|
|
15
|
+
let newValue = value.slice();
|
|
16
|
+
if (maxSelected && newValue && newValue.length > maxSelected) {
|
|
17
|
+
newValue = newValue.slice(0, maxSelected);
|
|
22
18
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
return strategy.add([], newValue);
|
|
20
|
+
}, [value, maxSelected, strategy]);
|
|
21
|
+
const [selected, setSelectedState] = useState(getSelectedFromValue);
|
|
22
|
+
const [prevGetSelectedFromValue, setPrevGetSelectedFromValue] = useState(() => getSelectedFromValue);
|
|
23
|
+
if (prevGetSelectedFromValue !== getSelectedFromValue) {
|
|
24
|
+
setPrevGetSelectedFromValue(() => getSelectedFromValue);
|
|
25
|
+
setSelectedState(getSelectedFromValue());
|
|
26
|
+
}
|
|
27
|
+
const setSelected = useCallback(
|
|
28
|
+
(id, isSelected) => {
|
|
29
|
+
const ids = [id];
|
|
30
|
+
const updatedSelected = isSelected ? strategy.add(selected, ids) : strategy.remove(selected, ids);
|
|
31
|
+
const filteredUpdatedSelected = collapseToParentId ? getIdsWithNoParentsInSameList(collection, updatedSelected) : updatedSelected;
|
|
32
|
+
if (maxSelected && filteredUpdatedSelected.length > maxSelected) {
|
|
33
|
+
filteredUpdatedSelected.length = maxSelected;
|
|
34
|
+
}
|
|
35
|
+
onChange(filteredUpdatedSelected, id, isSelected);
|
|
36
|
+
},
|
|
37
|
+
[strategy, selected, collection, collapseToParentId, onChange, maxSelected]
|
|
38
|
+
);
|
|
39
|
+
return {
|
|
40
|
+
selected,
|
|
41
|
+
setSelected
|
|
42
|
+
};
|
|
38
43
|
};
|
|
39
44
|
|
|
40
45
|
export { useSelected };
|