@fluentui/react-tree 9.7.7 → 9.7.9

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +25 -2
  2. package/dist/index.d.ts +54 -84
  3. package/lib/components/FlatTree/useFlatControllableCheckedItems.js +15 -13
  4. package/lib/components/FlatTree/useFlatControllableCheckedItems.js.map +1 -1
  5. package/lib/components/FlatTree/useHeadlessFlatTree.js +4 -2
  6. package/lib/components/FlatTree/useHeadlessFlatTree.js.map +1 -1
  7. package/lib/components/Tree/useNestedControllableCheckedItems.js +1 -1
  8. package/lib/components/Tree/useNestedControllableCheckedItems.js.map +1 -1
  9. package/lib/components/Tree/useTree.js +4 -2
  10. package/lib/components/Tree/useTree.js.map +1 -1
  11. package/lib/hooks/useControllableOpenItems.js +3 -12
  12. package/lib/hooks/useControllableOpenItems.js.map +1 -1
  13. package/lib/hooks/useRootTree.js +5 -4
  14. package/lib/hooks/useRootTree.js.map +1 -1
  15. package/lib/utils/ImmutableMap.js +71 -40
  16. package/lib/utils/ImmutableMap.js.map +1 -1
  17. package/lib/utils/ImmutableSet.js +65 -44
  18. package/lib/utils/ImmutableSet.js.map +1 -1
  19. package/lib/utils/createCheckedItems.js +5 -17
  20. package/lib/utils/createCheckedItems.js.map +1 -1
  21. package/lib-commonjs/components/FlatTree/useFlatControllableCheckedItems.js +15 -13
  22. package/lib-commonjs/components/FlatTree/useFlatControllableCheckedItems.js.map +1 -1
  23. package/lib-commonjs/components/FlatTree/useHeadlessFlatTree.js +4 -2
  24. package/lib-commonjs/components/FlatTree/useHeadlessFlatTree.js.map +1 -1
  25. package/lib-commonjs/components/Tree/useNestedControllableCheckedItems.js +1 -1
  26. package/lib-commonjs/components/Tree/useNestedControllableCheckedItems.js.map +1 -1
  27. package/lib-commonjs/components/Tree/useTree.js +4 -2
  28. package/lib-commonjs/components/Tree/useTree.js.map +1 -1
  29. package/lib-commonjs/hooks/useControllableOpenItems.js +3 -12
  30. package/lib-commonjs/hooks/useControllableOpenItems.js.map +1 -1
  31. package/lib-commonjs/hooks/useRootTree.js +5 -4
  32. package/lib-commonjs/hooks/useRootTree.js.map +1 -1
  33. package/lib-commonjs/utils/ImmutableMap.js +71 -40
  34. package/lib-commonjs/utils/ImmutableMap.js.map +1 -1
  35. package/lib-commonjs/utils/ImmutableSet.js +61 -45
  36. package/lib-commonjs/utils/ImmutableSet.js.map +1 -1
  37. package/lib-commonjs/utils/createCheckedItems.js +5 -17
  38. package/lib-commonjs/utils/createCheckedItems.js.map +1 -1
  39. package/package.json +7 -7
  40. package/lib/utils/createOpenItems.js +0 -10
  41. package/lib/utils/createOpenItems.js.map +0 -1
  42. package/lib-commonjs/utils/createOpenItems.js +0 -20
  43. package/lib-commonjs/utils/createOpenItems.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,12 +1,35 @@
1
1
  # Change Log - @fluentui/react-tree
2
2
 
3
- This log was last generated on Mon, 05 Aug 2024 22:31:39 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 15 Aug 2024 08:18:59 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.7.9](https://github.com/microsoft/fluentui/tree/@fluentui/react-tree_v9.7.9)
8
+
9
+ Thu, 15 Aug 2024 08:18:59 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-tree_v9.7.8..@fluentui/react-tree_v9.7.9)
11
+
12
+ ### Patches
13
+
14
+ - Bump @fluentui/react-aria to v9.13.3 ([PR #31885](https://github.com/microsoft/fluentui/pull/31885) by beachball)
15
+ - Bump @fluentui/react-avatar to v9.6.36 ([PR #31885](https://github.com/microsoft/fluentui/pull/31885) by beachball)
16
+ - Bump @fluentui/react-button to v9.3.88 ([PR #31885](https://github.com/microsoft/fluentui/pull/31885) by beachball)
17
+ - Bump @fluentui/react-checkbox to v9.2.34 ([PR #31885](https://github.com/microsoft/fluentui/pull/31885) by beachball)
18
+ - Bump @fluentui/react-radio to v9.2.29 ([PR #31885](https://github.com/microsoft/fluentui/pull/31885) by beachball)
19
+ - Bump @fluentui/react-tabster to v9.22.4 ([PR #31885](https://github.com/microsoft/fluentui/pull/31885) by beachball)
20
+
21
+ ## [9.7.8](https://github.com/microsoft/fluentui/tree/@fluentui/react-tree_v9.7.8)
22
+
23
+ Tue, 06 Aug 2024 21:40:45 GMT
24
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-tree_v9.7.7..@fluentui/react-tree_v9.7.8)
25
+
26
+ ### Patches
27
+
28
+ - chore: improve ImmutableSet and ImmutableMap internal implementation ([PR #32167](https://github.com/microsoft/fluentui/pull/32167) by bernardo.sunderhus@gmail.com)
29
+
7
30
  ## [9.7.7](https://github.com/microsoft/fluentui/tree/@fluentui/react-tree_v9.7.7)
8
31
 
9
- Mon, 05 Aug 2024 22:31:39 GMT
32
+ Mon, 05 Aug 2024 22:33:04 GMT
10
33
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-tree_v9.7.6..@fluentui/react-tree_v9.7.7)
11
34
 
12
35
  ### Patches
package/dist/index.d.ts CHANGED
@@ -28,28 +28,6 @@ import type { SelectionMode as SelectionMode_2 } from '@fluentui/react-utilities
28
28
  import type { Slot } from '@fluentui/react-utilities';
29
29
  import type { SlotClassNames } from '@fluentui/react-utilities';
30
30
 
31
- /**
32
- * properly creates an ImmutableMap instance from an iterable
33
- */
34
- declare function createImmutableMap<Key, Value>(iterable?: Iterable<[Key, Value]>): ImmutableMap<Key, Value>;
35
-
36
- /**
37
- * properly creates an ImmutableSet instance from an iterable
38
- */
39
- declare function createImmutableSet<Value>(iterable?: Iterable<Value>): ImmutableSet<Value>;
40
-
41
- /**
42
- * Avoid using *dangerouslyCreateImmutableMap*, since this method will expose internally used set, use createImmutableMap instead,
43
- * @param internalMap - a set that is used internally to store values.
44
- */
45
- declare function dangerouslyCreateImmutableMap<Key, Value>(internalMap: Map<Key, Value>): ImmutableMap<Key, Value>;
46
-
47
- /**
48
- * Avoid using *dangerouslyCreateImmutableSet*, since this method will expose internally used set, use createImmutableSet instead,
49
- * @param internalSet - a set that is used internally to store values.
50
- */
51
- declare function dangerouslyCreateImmutableSet<Value>(internalSet: Set<Value>): ImmutableSet<Value>;
52
-
53
31
  declare type FlattenedTreeItem<Props extends TreeItemProps> = HeadlessFlatTreeItemProps & Props;
54
32
 
55
33
  /**
@@ -297,85 +275,77 @@ declare type HeadlessTreeItemProps = Omit<TreeItemProps, 'itemType' | 'value'> &
297
275
  parentValue?: TreeItemValue;
298
276
  };
299
277
 
300
- declare interface ImmutableMap<Key, Value> {
301
- clear(): ImmutableMap<Key, Value>;
302
- delete(key: Key): ImmutableMap<Key, Value>;
278
+ declare class ImmutableMap<Key, Value> implements Iterable<[Key, Value]> {
279
+ static empty: ImmutableMap<never, never>;
280
+ readonly size: number;
281
+ private [internalMapSymbol];
282
+ static dangerouslyGetInternalMap<Key, Value>(immutableMap: ImmutableMap<Key, Value>): Map<Key, Value>;
283
+ static copy<Key, Value>(immutableMap: ImmutableMap<Key, Value>): ImmutableMap<Key, Value>;
303
284
  /**
304
- * Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
305
- * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
285
+ * Creates a new {@link ImmutableMap} from an iterable.
286
+ * If the iterable is undefined, {@link ImmutableMap.empty} will be returned.
287
+ * If the iterable is already an {@link ImmutableMap}, it will be returned as is no copy will be made.
306
288
  */
307
- get(key: Key): Value | undefined;
289
+ static from<T extends [unknown, unknown]>(iterable?: Iterable<T>): ImmutableMap<T[0], T[1]>;
308
290
  /**
309
- * @returns boolean indicating whether an element with the specified key exists or not.
291
+ * Creates a new {@link ImmutableMap} from an iterable with an auxiliary map function to modify the iterable.
292
+ * If the iterable is undefined, {@link ImmutableMap.empty} will be returned.
293
+ * If the iterable is already an {@link ImmutableMap}, it will be returned as is no copy will be made.
294
+ * The map function will be called for each element in the iterable.
310
295
  */
311
- has(key: Key): boolean;
296
+ static from<T, U extends [unknown, unknown]>(iterable: Iterable<T> | undefined, mapFn: (value: T) => U): ImmutableMap<U[0], U[1]>;
297
+ static [Symbol.hasInstance](instance: unknown): boolean;
312
298
  /**
313
- * Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
299
+ * Do not use this constructor directly, use {@link ImmutableMap.from} instead.
300
+ * {@link ImmutableMap.from} handles instance verification (which might be problematic on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_realms | multiple realms}),
301
+ * avoid unnecessary copies, supports iterables and ensures that the internal map is never exposed.
302
+ *
303
+ *⚠️⚠️ _By using this constructor directly, you might end up with a mutable map, as it is not guaranteed that the internal map is not exposed._ ⚠️⚠️
314
304
  */
305
+ constructor(internalMap: Map<Key, Value>);
306
+ delete(key: Key): ImmutableMap<Key, Value>;
307
+ get(key: Key): Value | undefined;
308
+ has(key: Key): boolean;
315
309
  set(key: Key, value: Value): ImmutableMap<Key, Value>;
316
- /**
317
- * @returns the number of elements in the Map.
318
- */
319
- readonly size: number;
320
- /** Iterates over entries in the Map. */
321
- [Symbol.iterator](): IterableIterator<[Key, Value]>;
322
- /**
323
- * @internal
324
- * Exposes the internal map used to store values.
325
- * This is an internal API and should not be used directly.
326
- */
327
- dangerouslyGetInternalMap_unstable(): Map<Key, Value>;
310
+ [Symbol.iterator](): Iterator<[Key, Value]>;
328
311
  }
329
312
 
330
- declare const ImmutableMap: {
331
- empty: ImmutableMap<never, never>;
332
- create: typeof createImmutableMap;
333
- isImmutableMap: typeof isImmutableMap;
334
- dangerouslyCreate_unstable: typeof dangerouslyCreateImmutableMap;
335
- };
336
-
337
- declare interface ImmutableSet<Value> {
338
- /**
339
- * The number of (unique) elements in a ImmutableSet.
340
- */
313
+ /**
314
+ * @public
315
+ *
316
+ * Small immutable wrapper around the native Set implementation.
317
+ * Every operation that would modify the set returns a new copy instance.
318
+ */
319
+ declare class ImmutableSet<T> implements Iterable<T> {
320
+ static empty: ImmutableSet<never>;
341
321
  readonly size: number;
322
+ private [internalSetSymbol];
323
+ static dangerouslyGetInternalSet<Value>(set: ImmutableSet<Value>): Set<Value>;
324
+ static copy<T>(immutableSet: ImmutableSet<T>): ImmutableSet<T>;
342
325
  /**
343
- * Creates a new ImmutableSet containing all previous element plus the one provided as argument
344
- * @param value - new value to be included in the new ImmutableSet instance
345
- */
346
- add(value: Value): ImmutableSet<Value>;
347
- /**
348
- * Returns a reference to ImmutableSet.emptySet
349
- */
350
- clear(): ImmutableSet<Value>;
351
- /**
352
- * Creates a new ImmutableSet with the original items and removes a specified value from the new ImmutableSet.
326
+ * Creates a new {@link ImmutableSet} from an iterable.
327
+ * If the iterable is undefined, {@link ImmutableSet.empty} will be returned.
328
+ * If the iterable is already an {@link ImmutableSet}, it will be returned as is no copy will be made.
353
329
  */
354
- delete(value: Value): ImmutableSet<Value>;
330
+ static from<Value>(iterable?: Iterable<Value>): ImmutableSet<Value>;
331
+ static [Symbol.hasInstance](instance: unknown): boolean;
355
332
  /**
356
- * @returns a boolean indicating whether an element with the specified value exists in the ImmutableSet or not.
357
- */
358
- has(value: Value): boolean;
359
- /** Iterates over values in the ImmutableSet. */
360
- [Symbol.iterator](): IterableIterator<Value>;
361
- /**
362
- * @internal
363
- * Exposes the internal set used to store values.
364
- * This is an internal API and should not be used directly.
333
+ * Do not use this constructor directly, use {@link ImmutableSet.from} instead.
334
+ * {@link ImmutableSet.from} handles instance verification (which might be problematic on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_realms | multiple realms}),
335
+ * avoid unnecessary copies, supports iterables and ensures that the internal set is never exposed.
336
+ *
337
+ *⚠️⚠️ _By using this constructor directly, you might end up with a mutable set, as it is not guaranteed that the internal set is not exposed._ ⚠️⚠️
365
338
  */
366
- dangerouslyGetInternalSet_unstable(): Set<Value>;
339
+ constructor(internalSet: Set<T>);
340
+ add(value: T): ImmutableSet<T>;
341
+ delete(value: T): ImmutableSet<T>;
342
+ has(value: T): boolean;
343
+ [Symbol.iterator](): Iterator<T>;
367
344
  }
368
345
 
369
- declare const ImmutableSet: {
370
- empty: ImmutableSet<never>;
371
- create: typeof createImmutableSet;
372
- isImmutableSet: typeof isImmutableSet;
373
- dangerouslyCreate_unstable: typeof dangerouslyCreateImmutableSet;
374
- };
375
-
376
- declare function isImmutableMap<Key, Value>(value: unknown): value is ImmutableMap<Key, Value>;
346
+ declare const internalMapSymbol: unique symbol;
377
347
 
378
- declare function isImmutableSet<Value>(value: unknown): value is ImmutableSet<Value>;
348
+ declare const internalSetSymbol: unique symbol;
379
349
 
380
350
  declare type MultiSelectValue = NonNullable<CheckboxProps['checked']>;
381
351
 
@@ -14,7 +14,7 @@ export function useFlatControllableCheckedItems(props, headlessTree) {
14
14
  }
15
15
  export function createNextFlatCheckedItems(data, previousCheckedItems, headlessTree) {
16
16
  if (data.selectionMode === 'single') {
17
- return ImmutableMap.create([
17
+ return ImmutableMap.from([
18
18
  [
19
19
  data.value,
20
20
  data.checked
@@ -30,40 +30,42 @@ Tree item ${data.value} not found.`);
30
30
  }
31
31
  return previousCheckedItems;
32
32
  }
33
- const nextCheckedItems = new Map(previousCheckedItems);
33
+ let nextCheckedItems = previousCheckedItems;
34
34
  for (const children of headlessTree.subtree(data.value)){
35
- nextCheckedItems.set(children.value, data.checked);
35
+ nextCheckedItems = nextCheckedItems.set(children.value, data.checked);
36
36
  }
37
- nextCheckedItems.set(data.value, data.checked);
37
+ nextCheckedItems = nextCheckedItems.set(data.value, data.checked);
38
38
  let isAncestorsMixed = false;
39
39
  for (const parent of headlessTree.ancestors(treeItem.value)){
40
40
  // if one parent is mixed, all ancestors are mixed
41
41
  if (isAncestorsMixed) {
42
- nextCheckedItems.set(parent.value, 'mixed');
42
+ nextCheckedItems = nextCheckedItems.set(parent.value, 'mixed');
43
43
  continue;
44
44
  }
45
- const checkedChildren = [];
45
+ let checkedChildrenAmount = 0;
46
46
  for (const child of headlessTree.children(parent.value)){
47
- var _nextCheckedItems_get;
48
- if (((_nextCheckedItems_get = nextCheckedItems.get(child.value)) !== null && _nextCheckedItems_get !== void 0 ? _nextCheckedItems_get : false) === data.checked) {
49
- checkedChildren.push(child);
47
+ if ((nextCheckedItems.get(child.value) || false) === data.checked) {
48
+ checkedChildrenAmount++;
50
49
  }
51
50
  }
52
- if (checkedChildren.length === parent.childrenValues.length) {
53
- nextCheckedItems.set(parent.value, data.checked);
51
+ // if all children are checked, parent is checked
52
+ if (checkedChildrenAmount === parent.childrenValues.length) {
53
+ nextCheckedItems = nextCheckedItems.set(parent.value, data.checked);
54
54
  } else {
55
55
  // if one parent is mixed, all ancestors are mixed
56
56
  isAncestorsMixed = true;
57
- nextCheckedItems.set(parent.value, 'mixed');
57
+ nextCheckedItems = nextCheckedItems.set(parent.value, 'mixed');
58
58
  }
59
59
  }
60
- return ImmutableMap.dangerouslyCreate_unstable(nextCheckedItems);
60
+ return nextCheckedItems;
61
61
  }
62
62
  function initializeCheckedItems(props, headlessTree) {
63
63
  if (!props.selectionMode) {
64
64
  return ImmutableMap.empty;
65
65
  }
66
66
  let state = createCheckedItems(props.defaultCheckedItems);
67
+ // if selectionMode is multiselect, we need to calculate the checked state of all children
68
+ // and ancestors of the defaultCheckedItems
67
69
  if (props.selectionMode === 'multiselect') {
68
70
  for (const [value, checked] of state){
69
71
  state = createNextFlatCheckedItems({
@@ -1 +1 @@
1
- {"version":3,"sources":["useFlatControllableCheckedItems.ts"],"sourcesContent":["import { useControllableState } from '@fluentui/react-utilities';\nimport { TreeItemValue } from '../../TreeItem';\nimport { ImmutableMap } from '../../utils/ImmutableMap';\nimport * as React from 'react';\nimport type { HeadlessTree, HeadlessTreeItemProps } from '../../utils/createHeadlessTree';\nimport { createCheckedItems } from '../../utils/createCheckedItems';\nimport type { TreeCheckedChangeData } from '../Tree/Tree.types';\nimport { HeadlessFlatTreeOptions } from './useHeadlessFlatTree';\n\nexport function useFlatControllableCheckedItems<Props extends HeadlessTreeItemProps>(\n props: Pick<HeadlessFlatTreeOptions, 'checkedItems' | 'defaultCheckedItems' | 'selectionMode'>,\n headlessTree: HeadlessTree<Props>,\n) {\n return useControllableState({\n initialState: ImmutableMap.empty,\n state: React.useMemo(\n () => (props.selectionMode ? props.checkedItems && createCheckedItems(props.checkedItems) : undefined),\n [props.checkedItems, props.selectionMode],\n ),\n defaultState: props.defaultCheckedItems ? () => initializeCheckedItems(props, headlessTree) : undefined,\n });\n}\n\nexport function createNextFlatCheckedItems(\n data: Pick<TreeCheckedChangeData, 'value' | 'checked' | 'selectionMode'>,\n previousCheckedItems: ImmutableMap<TreeItemValue, 'mixed' | boolean>,\n headlessTree: HeadlessTree<HeadlessTreeItemProps>,\n): ImmutableMap<TreeItemValue, 'mixed' | boolean> {\n if (data.selectionMode === 'single') {\n return ImmutableMap.create([[data.value, data.checked]]);\n }\n const treeItem = headlessTree.get(data.value);\n if (!treeItem) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [useHeadlessFlatTree]:\n Tree item ${data.value} not found.\n `);\n }\n return previousCheckedItems;\n }\n const nextCheckedItems = new Map(previousCheckedItems);\n for (const children of headlessTree.subtree(data.value)) {\n nextCheckedItems.set(children.value, data.checked);\n }\n nextCheckedItems.set(data.value, data.checked);\n\n let isAncestorsMixed = false;\n for (const parent of headlessTree.ancestors(treeItem.value)) {\n // if one parent is mixed, all ancestors are mixed\n if (isAncestorsMixed) {\n nextCheckedItems.set(parent.value, 'mixed');\n continue;\n }\n const checkedChildren = [];\n for (const child of headlessTree.children(parent.value)) {\n if ((nextCheckedItems.get(child.value) ?? false) === data.checked) {\n checkedChildren.push(child);\n }\n }\n if (checkedChildren.length === parent.childrenValues.length) {\n nextCheckedItems.set(parent.value, data.checked);\n } else {\n // if one parent is mixed, all ancestors are mixed\n isAncestorsMixed = true;\n nextCheckedItems.set(parent.value, 'mixed');\n }\n }\n return ImmutableMap.dangerouslyCreate_unstable(nextCheckedItems);\n}\n\nfunction initializeCheckedItems(\n props: Pick<HeadlessFlatTreeOptions, 'selectionMode' | 'defaultCheckedItems'>,\n headlessTree: HeadlessTree<HeadlessTreeItemProps>,\n) {\n if (!props.selectionMode) {\n return ImmutableMap.empty;\n }\n let state = createCheckedItems(props.defaultCheckedItems);\n if (props.selectionMode === 'multiselect') {\n for (const [value, checked] of state) {\n state = createNextFlatCheckedItems({ value, checked, selectionMode: props.selectionMode }, state, headlessTree);\n }\n }\n return state;\n}\n"],"names":["useControllableState","ImmutableMap","React","createCheckedItems","useFlatControllableCheckedItems","props","headlessTree","initialState","empty","state","useMemo","selectionMode","checkedItems","undefined","defaultState","defaultCheckedItems","initializeCheckedItems","createNextFlatCheckedItems","data","previousCheckedItems","create","value","checked","treeItem","get","process","env","NODE_ENV","console","error","nextCheckedItems","Map","children","subtree","set","isAncestorsMixed","parent","ancestors","checkedChildren","child","push","length","childrenValues","dangerouslyCreate_unstable"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,oBAAoB,QAAQ,4BAA4B;AAEjE,SAASC,YAAY,QAAQ,2BAA2B;AACxD,YAAYC,WAAW,QAAQ;AAE/B,SAASC,kBAAkB,QAAQ,iCAAiC;AAIpE,OAAO,SAASC,gCACdC,KAA8F,EAC9FC,YAAiC;IAEjC,OAAON,qBAAqB;QAC1BO,cAAcN,aAAaO,KAAK;QAChCC,OAAOP,MAAMQ,OAAO,CAClB,IAAOL,MAAMM,aAAa,GAAGN,MAAMO,YAAY,IAAIT,mBAAmBE,MAAMO,YAAY,IAAIC,WAC5F;YAACR,MAAMO,YAAY;YAAEP,MAAMM,aAAa;SAAC;QAE3CG,cAAcT,MAAMU,mBAAmB,GAAG,IAAMC,uBAAuBX,OAAOC,gBAAgBO;IAChG;AACF;AAEA,OAAO,SAASI,2BACdC,IAAwE,EACxEC,oBAAoE,EACpEb,YAAiD;IAEjD,IAAIY,KAAKP,aAAa,KAAK,UAAU;QACnC,OAAOV,aAAamB,MAAM,CAAC;YAAC;gBAACF,KAAKG,KAAK;gBAAEH,KAAKI,OAAO;aAAC;SAAC;IACzD;IACA,MAAMC,WAAWjB,aAAakB,GAAG,CAACN,KAAKG,KAAK;IAC5C,IAAI,CAACE,UAAU;QACb,IAAIE,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,sCAAsC;YACtCC,QAAQC,KAAK,CAAsB,CAAC;UAExB,EAAEX,KAAKG,KAAK,CAAC,WACzB,CAAC;QACH;QACA,OAAOF;IACT;IACA,MAAMW,mBAAmB,IAAIC,IAAIZ;IACjC,KAAK,MAAMa,YAAY1B,aAAa2B,OAAO,CAACf,KAAKG,KAAK,EAAG;QACvDS,iBAAiBI,GAAG,CAACF,SAASX,KAAK,EAAEH,KAAKI,OAAO;IACnD;IACAQ,iBAAiBI,GAAG,CAAChB,KAAKG,KAAK,EAAEH,KAAKI,OAAO;IAE7C,IAAIa,mBAAmB;IACvB,KAAK,MAAMC,UAAU9B,aAAa+B,SAAS,CAACd,SAASF,KAAK,EAAG;QAC3D,kDAAkD;QAClD,IAAIc,kBAAkB;YACpBL,iBAAiBI,GAAG,CAACE,OAAOf,KAAK,EAAE;YACnC;QACF;QACA,MAAMiB,kBAAkB,EAAE;QAC1B,KAAK,MAAMC,SAASjC,aAAa0B,QAAQ,CAACI,OAAOf,KAAK,EAAG;gBAClDS;YAAL,IAAI,AAACA,CAAAA,CAAAA,wBAAAA,iBAAiBN,GAAG,CAACe,MAAMlB,KAAK,eAAhCS,mCAAAA,wBAAqC,KAAI,MAAOZ,KAAKI,OAAO,EAAE;gBACjEgB,gBAAgBE,IAAI,CAACD;YACvB;QACF;QACA,IAAID,gBAAgBG,MAAM,KAAKL,OAAOM,cAAc,CAACD,MAAM,EAAE;YAC3DX,iBAAiBI,GAAG,CAACE,OAAOf,KAAK,EAAEH,KAAKI,OAAO;QACjD,OAAO;YACL,kDAAkD;YAClDa,mBAAmB;YACnBL,iBAAiBI,GAAG,CAACE,OAAOf,KAAK,EAAE;QACrC;IACF;IACA,OAAOpB,aAAa0C,0BAA0B,CAACb;AACjD;AAEA,SAASd,uBACPX,KAA6E,EAC7EC,YAAiD;IAEjD,IAAI,CAACD,MAAMM,aAAa,EAAE;QACxB,OAAOV,aAAaO,KAAK;IAC3B;IACA,IAAIC,QAAQN,mBAAmBE,MAAMU,mBAAmB;IACxD,IAAIV,MAAMM,aAAa,KAAK,eAAe;QACzC,KAAK,MAAM,CAACU,OAAOC,QAAQ,IAAIb,MAAO;YACpCA,QAAQQ,2BAA2B;gBAAEI;gBAAOC;gBAASX,eAAeN,MAAMM,aAAa;YAAC,GAAGF,OAAOH;QACpG;IACF;IACA,OAAOG;AACT"}
1
+ {"version":3,"sources":["useFlatControllableCheckedItems.ts"],"sourcesContent":["import { useControllableState } from '@fluentui/react-utilities';\nimport { TreeItemValue } from '../../TreeItem';\nimport { ImmutableMap } from '../../utils/ImmutableMap';\nimport * as React from 'react';\nimport type { HeadlessTree, HeadlessTreeItemProps } from '../../utils/createHeadlessTree';\nimport { createCheckedItems } from '../../utils/createCheckedItems';\nimport type { TreeCheckedChangeData } from '../Tree/Tree.types';\nimport { HeadlessFlatTreeOptions } from './useHeadlessFlatTree';\n\nexport function useFlatControllableCheckedItems<Props extends HeadlessTreeItemProps>(\n props: Pick<HeadlessFlatTreeOptions, 'checkedItems' | 'defaultCheckedItems' | 'selectionMode'>,\n headlessTree: HeadlessTree<Props>,\n) {\n return useControllableState({\n initialState: ImmutableMap.empty,\n state: React.useMemo(\n () => (props.selectionMode ? props.checkedItems && createCheckedItems(props.checkedItems) : undefined),\n [props.checkedItems, props.selectionMode],\n ),\n defaultState: props.defaultCheckedItems ? () => initializeCheckedItems(props, headlessTree) : undefined,\n });\n}\n\nexport function createNextFlatCheckedItems(\n data: Pick<TreeCheckedChangeData, 'value' | 'checked' | 'selectionMode'>,\n previousCheckedItems: ImmutableMap<TreeItemValue, 'mixed' | boolean>,\n headlessTree: HeadlessTree<HeadlessTreeItemProps>,\n): ImmutableMap<TreeItemValue, 'mixed' | boolean> {\n if (data.selectionMode === 'single') {\n return ImmutableMap.from([[data.value, data.checked]]);\n }\n const treeItem = headlessTree.get(data.value);\n if (!treeItem) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [useHeadlessFlatTree]:\n Tree item ${data.value} not found.\n `);\n }\n return previousCheckedItems;\n }\n let nextCheckedItems = previousCheckedItems;\n for (const children of headlessTree.subtree(data.value)) {\n nextCheckedItems = nextCheckedItems.set(children.value, data.checked);\n }\n nextCheckedItems = nextCheckedItems.set(data.value, data.checked);\n\n let isAncestorsMixed = false;\n for (const parent of headlessTree.ancestors(treeItem.value)) {\n // if one parent is mixed, all ancestors are mixed\n if (isAncestorsMixed) {\n nextCheckedItems = nextCheckedItems.set(parent.value, 'mixed');\n continue;\n }\n let checkedChildrenAmount = 0;\n for (const child of headlessTree.children(parent.value)) {\n if ((nextCheckedItems.get(child.value) || false) === data.checked) {\n checkedChildrenAmount++;\n }\n }\n // if all children are checked, parent is checked\n if (checkedChildrenAmount === parent.childrenValues.length) {\n nextCheckedItems = nextCheckedItems.set(parent.value, data.checked);\n } else {\n // if one parent is mixed, all ancestors are mixed\n isAncestorsMixed = true;\n nextCheckedItems = nextCheckedItems.set(parent.value, 'mixed');\n }\n }\n return nextCheckedItems;\n}\n\nfunction initializeCheckedItems(\n props: Pick<HeadlessFlatTreeOptions, 'selectionMode' | 'defaultCheckedItems'>,\n headlessTree: HeadlessTree<HeadlessTreeItemProps>,\n) {\n if (!props.selectionMode) {\n return ImmutableMap.empty;\n }\n let state = createCheckedItems(props.defaultCheckedItems);\n // if selectionMode is multiselect, we need to calculate the checked state of all children\n // and ancestors of the defaultCheckedItems\n if (props.selectionMode === 'multiselect') {\n for (const [value, checked] of state) {\n state = createNextFlatCheckedItems({ value, checked, selectionMode: props.selectionMode }, state, headlessTree);\n }\n }\n return state;\n}\n"],"names":["useControllableState","ImmutableMap","React","createCheckedItems","useFlatControllableCheckedItems","props","headlessTree","initialState","empty","state","useMemo","selectionMode","checkedItems","undefined","defaultState","defaultCheckedItems","initializeCheckedItems","createNextFlatCheckedItems","data","previousCheckedItems","from","value","checked","treeItem","get","process","env","NODE_ENV","console","error","nextCheckedItems","children","subtree","set","isAncestorsMixed","parent","ancestors","checkedChildrenAmount","child","childrenValues","length"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,oBAAoB,QAAQ,4BAA4B;AAEjE,SAASC,YAAY,QAAQ,2BAA2B;AACxD,YAAYC,WAAW,QAAQ;AAE/B,SAASC,kBAAkB,QAAQ,iCAAiC;AAIpE,OAAO,SAASC,gCACdC,KAA8F,EAC9FC,YAAiC;IAEjC,OAAON,qBAAqB;QAC1BO,cAAcN,aAAaO,KAAK;QAChCC,OAAOP,MAAMQ,OAAO,CAClB,IAAOL,MAAMM,aAAa,GAAGN,MAAMO,YAAY,IAAIT,mBAAmBE,MAAMO,YAAY,IAAIC,WAC5F;YAACR,MAAMO,YAAY;YAAEP,MAAMM,aAAa;SAAC;QAE3CG,cAAcT,MAAMU,mBAAmB,GAAG,IAAMC,uBAAuBX,OAAOC,gBAAgBO;IAChG;AACF;AAEA,OAAO,SAASI,2BACdC,IAAwE,EACxEC,oBAAoE,EACpEb,YAAiD;IAEjD,IAAIY,KAAKP,aAAa,KAAK,UAAU;QACnC,OAAOV,aAAamB,IAAI,CAAC;YAAC;gBAACF,KAAKG,KAAK;gBAAEH,KAAKI,OAAO;aAAC;SAAC;IACvD;IACA,MAAMC,WAAWjB,aAAakB,GAAG,CAACN,KAAKG,KAAK;IAC5C,IAAI,CAACE,UAAU;QACb,IAAIE,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;YACzC,sCAAsC;YACtCC,QAAQC,KAAK,CAAsB,CAAC;UAExB,EAAEX,KAAKG,KAAK,CAAC,WACzB,CAAC;QACH;QACA,OAAOF;IACT;IACA,IAAIW,mBAAmBX;IACvB,KAAK,MAAMY,YAAYzB,aAAa0B,OAAO,CAACd,KAAKG,KAAK,EAAG;QACvDS,mBAAmBA,iBAAiBG,GAAG,CAACF,SAASV,KAAK,EAAEH,KAAKI,OAAO;IACtE;IACAQ,mBAAmBA,iBAAiBG,GAAG,CAACf,KAAKG,KAAK,EAAEH,KAAKI,OAAO;IAEhE,IAAIY,mBAAmB;IACvB,KAAK,MAAMC,UAAU7B,aAAa8B,SAAS,CAACb,SAASF,KAAK,EAAG;QAC3D,kDAAkD;QAClD,IAAIa,kBAAkB;YACpBJ,mBAAmBA,iBAAiBG,GAAG,CAACE,OAAOd,KAAK,EAAE;YACtD;QACF;QACA,IAAIgB,wBAAwB;QAC5B,KAAK,MAAMC,SAAShC,aAAayB,QAAQ,CAACI,OAAOd,KAAK,EAAG;YACvD,IAAI,AAACS,CAAAA,iBAAiBN,GAAG,CAACc,MAAMjB,KAAK,KAAK,KAAI,MAAOH,KAAKI,OAAO,EAAE;gBACjEe;YACF;QACF;QACA,iDAAiD;QACjD,IAAIA,0BAA0BF,OAAOI,cAAc,CAACC,MAAM,EAAE;YAC1DV,mBAAmBA,iBAAiBG,GAAG,CAACE,OAAOd,KAAK,EAAEH,KAAKI,OAAO;QACpE,OAAO;YACL,kDAAkD;YAClDY,mBAAmB;YACnBJ,mBAAmBA,iBAAiBG,GAAG,CAACE,OAAOd,KAAK,EAAE;QACxD;IACF;IACA,OAAOS;AACT;AAEA,SAASd,uBACPX,KAA6E,EAC7EC,YAAiD;IAEjD,IAAI,CAACD,MAAMM,aAAa,EAAE;QACxB,OAAOV,aAAaO,KAAK;IAC3B;IACA,IAAIC,QAAQN,mBAAmBE,MAAMU,mBAAmB;IACxD,0FAA0F;IAC1F,2CAA2C;IAC3C,IAAIV,MAAMM,aAAa,KAAK,eAAe;QACzC,KAAK,MAAM,CAACU,OAAOC,QAAQ,IAAIb,MAAO;YACpCA,QAAQQ,2BAA2B;gBAAEI;gBAAOC;gBAASX,eAAeN,MAAMM,aAAa;YAAC,GAAGF,OAAOH;QACpG;IACF;IACA,OAAOG;AACT"}
@@ -5,7 +5,9 @@ import { treeDataTypes } from '../../utils/tokens';
5
5
  import { useFlatTreeNavigation } from '../../hooks/useFlatTreeNavigation';
6
6
  import { createNextOpenItems, useControllableOpenItems } from '../../hooks/useControllableOpenItems';
7
7
  import { dataTreeItemValueAttrName } from '../../utils/getTreeItemValueFromElement';
8
+ import { ImmutableSet } from '../../utils/ImmutableSet';
8
9
  import { createNextFlatCheckedItems, useFlatControllableCheckedItems } from './useFlatControllableCheckedItems';
10
+ import { ImmutableMap } from '../../utils/ImmutableMap';
9
11
  /**
10
12
  * this hook provides FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems
11
13
  * in multiple scenarios including virtualization.
@@ -31,7 +33,7 @@ import { createNextFlatCheckedItems, useFlatControllableCheckedItems } from './u
31
33
  const nextOpenItems = createNextOpenItems(data, openItems);
32
34
  (_options_onOpenChange = options.onOpenChange) === null || _options_onOpenChange === void 0 ? void 0 : _options_onOpenChange.call(options, event, {
33
35
  ...data,
34
- openItems: nextOpenItems.dangerouslyGetInternalSet_unstable()
36
+ openItems: ImmutableSet.dangerouslyGetInternalSet(nextOpenItems)
35
37
  });
36
38
  setOpenItems(nextOpenItems);
37
39
  });
@@ -40,7 +42,7 @@ import { createNextFlatCheckedItems, useFlatControllableCheckedItems } from './u
40
42
  const nextCheckedItems = createNextFlatCheckedItems(data, checkedItems, headlessTree);
41
43
  (_options_onCheckedChange = options.onCheckedChange) === null || _options_onCheckedChange === void 0 ? void 0 : _options_onCheckedChange.call(options, event, {
42
44
  ...data,
43
- checkedItems: nextCheckedItems.dangerouslyGetInternalMap_unstable()
45
+ checkedItems: ImmutableMap.dangerouslyGetInternalMap(nextCheckedItems)
44
46
  });
45
47
  setCheckedItems(nextCheckedItems);
46
48
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["useHeadlessFlatTree.ts"],"sourcesContent":["import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { HeadlessTreeItem, HeadlessTreeItemProps, createHeadlessTree } from '../../utils/createHeadlessTree';\nimport { treeDataTypes } from '../../utils/tokens';\nimport { useFlatTreeNavigation } from '../../hooks/useFlatTreeNavigation';\nimport { createNextOpenItems, useControllableOpenItems } from '../../hooks/useControllableOpenItems';\nimport type { TreeItemValue } from '../../TreeItem';\nimport { dataTreeItemValueAttrName } from '../../utils/getTreeItemValueFromElement';\nimport { ImmutableSet } from '../../utils/ImmutableSet';\nimport { createNextFlatCheckedItems, useFlatControllableCheckedItems } from './useFlatControllableCheckedItems';\nimport { FlatTreeProps } from './FlatTree.types';\nimport {\n TreeCheckedChangeData,\n TreeCheckedChangeEvent,\n TreeNavigationData_unstable,\n TreeOpenChangeData,\n TreeOpenChangeEvent,\n TreeProps,\n} from '../Tree/Tree.types';\n\nexport type HeadlessFlatTreeItemProps = HeadlessTreeItemProps;\nexport type HeadlessFlatTreeItem<Props extends HeadlessFlatTreeItemProps> = HeadlessTreeItem<Props>;\n\n/**\n * FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n *\n * On simple scenarios it is advised to simply use a nested structure instead.\n */\nexport type HeadlessFlatTree<Props extends HeadlessFlatTreeItemProps> = {\n /**\n * returns the properties required for the Tree component to work properly.\n * That includes:\n * `openItems`, `onOpenChange`, `onNavigation_unstable` and `ref`\n */\n getTreeProps(): Required<\n Pick<FlatTreeProps, 'openItems' | 'onOpenChange' | 'onNavigation' | 'checkedItems' | 'onCheckedChange'>\n > & {\n ref: React.Ref<HTMLDivElement>;\n openItems: ImmutableSet<TreeItemValue>;\n };\n /**\n * internal method used to react to an `onNavigation` event.\n * This method ensures proper navigation on keyboard and mouse interaction.\n * In case of virtualization it might be required to cancel default provided `onNavigation`\n * event and then call this method manually.\n *\n * @example\n * ```ts\n * // react-window\n * const handleNavigation = (event, data) => {\n * event.preventDefault();\n * const nextItem = tree.getNextNavigableItem(data);\n * // scroll to item using virtualization scroll mechanism\n * if (nextItem && tree.getElementFromItem(nextItem)) {\n * listRef.current.scrollToItem(nextItem.index);\n * }\n * // wait for scrolling to happen and then invoke navigate method\n * requestAnimationFrame(() => {\n * tree.navigate(data);\n * });\n * };\n *```\n */\n navigate(data: TreeNavigationData_unstable): void;\n /**\n * returns next item to be focused on a navigation.\n * This method is provided to decouple the element that needs to be focused from\n * the action of focusing it itself.\n *\n * On the case of TypeAhead navigation this method returns the current item.\n */\n getNextNavigableItem(\n visibleItems: HeadlessTreeItem<Props>[],\n data: TreeNavigationData_unstable,\n ): HeadlessTreeItem<Props> | undefined;\n /**\n * similar to getElementById but for FlatTreeItems\n */\n getElementFromItem(item: HeadlessTreeItem<Props>): HTMLElement | null;\n /**\n * an iterable containing all visually available flat tree items\n */\n items(): IterableIterator<HeadlessTreeItem<Props>>;\n};\n\nexport type HeadlessFlatTreeOptions = Pick<\n FlatTreeProps,\n 'onOpenChange' | 'onNavigation' | 'selectionMode' | 'onCheckedChange'\n> &\n Pick<TreeProps, 'defaultOpenItems' | 'openItems' | 'checkedItems'> & {\n defaultCheckedItems?: TreeProps['checkedItems'];\n };\n\n/**\n * @internal\n */\ntype HeadlessFlatTreeReturn<Props extends HeadlessFlatTreeItemProps> = HeadlessFlatTree<Props> & {\n getItem(value: TreeItemValue): HeadlessTreeItem<Props> | undefined;\n};\n\n/**\n * this hook provides FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n * On simple scenarios it is advised to simply use a nested structure instead.\n *\n * @param props - a list of tree items\n * @param options - in case control over the internal openItems is required\n */\nexport function useHeadlessFlatTree_unstable<Props extends HeadlessTreeItemProps>(\n props: Props[],\n options: HeadlessFlatTreeOptions = {},\n): HeadlessFlatTreeReturn<Props> {\n 'use no memo';\n\n const headlessTree = React.useMemo(() => createHeadlessTree(props), [props]);\n const [openItems, setOpenItems] = useControllableOpenItems(options);\n const [checkedItems, setCheckedItems] = useFlatControllableCheckedItems(options, headlessTree);\n const navigation = useFlatTreeNavigation();\n\n const treeRef = React.useRef<HTMLDivElement>(null);\n const handleOpenChange = useEventCallback((event: TreeOpenChangeEvent, data: TreeOpenChangeData) => {\n const nextOpenItems = createNextOpenItems(data, openItems);\n options.onOpenChange?.(event, {\n ...data,\n openItems: nextOpenItems.dangerouslyGetInternalSet_unstable(),\n });\n setOpenItems(nextOpenItems);\n });\n\n const handleCheckedChange = useEventCallback((event: TreeCheckedChangeEvent, data: TreeCheckedChangeData) => {\n const nextCheckedItems = createNextFlatCheckedItems(data, checkedItems, headlessTree);\n options.onCheckedChange?.(event, {\n ...data,\n checkedItems: nextCheckedItems.dangerouslyGetInternalMap_unstable(),\n });\n setCheckedItems(nextCheckedItems);\n });\n\n const getNextNavigableItem = useEventCallback(\n (visibleItems: HeadlessTreeItem<Props>[], data: TreeNavigationData_unstable) => {\n const item = headlessTree.get(data.value);\n if (item) {\n switch (data.type) {\n case treeDataTypes.TypeAhead:\n return item;\n case treeDataTypes.ArrowLeft:\n return headlessTree.get(item.parentValue!);\n case treeDataTypes.ArrowRight:\n return visibleItems[item.index + 1];\n case treeDataTypes.End:\n return visibleItems[visibleItems.length - 1];\n case treeDataTypes.Home:\n return visibleItems[0];\n case treeDataTypes.ArrowDown:\n return visibleItems[item.index + 1];\n case treeDataTypes.ArrowUp:\n return visibleItems[item.index - 1];\n }\n }\n },\n );\n\n const getElementFromItem = React.useCallback((item: HeadlessTreeItem<Props>) => {\n return treeRef.current?.querySelector(`[${dataTreeItemValueAttrName}=\"${item.value}\"]`) as HTMLElement | null;\n }, []);\n\n const ref = useMergedRefs<HTMLDivElement>(treeRef, navigation.rootRef);\n\n const getTreeProps = React.useCallback(\n () => ({\n ref,\n openItems,\n selectionMode: options.selectionMode,\n checkedItems,\n onOpenChange: handleOpenChange,\n onCheckedChange: handleCheckedChange,\n onNavigation: options.onNavigation ?? noop,\n }),\n // ref, handleOpenChange - useEventCallback, handleCheckedChange - useEventCallback\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [openItems, checkedItems, options.selectionMode, options.onNavigation],\n );\n\n const items = React.useCallback(() => headlessTree.visibleItems(openItems), [openItems, headlessTree]);\n\n const getItem = React.useCallback((value: TreeItemValue) => headlessTree.get(value), [headlessTree]);\n\n return React.useMemo<HeadlessFlatTreeReturn<Props>>(\n () => ({\n navigate: navigation.navigate,\n getTreeProps,\n getNextNavigableItem,\n getElementFromItem,\n items,\n getItem,\n }),\n [navigation.navigate, getTreeProps, getNextNavigableItem, getElementFromItem, items, getItem],\n );\n}\n\n/** @internal */\nfunction noop() {\n /* noop */\n}\n"],"names":["useEventCallback","useMergedRefs","React","createHeadlessTree","treeDataTypes","useFlatTreeNavigation","createNextOpenItems","useControllableOpenItems","dataTreeItemValueAttrName","createNextFlatCheckedItems","useFlatControllableCheckedItems","useHeadlessFlatTree_unstable","props","options","headlessTree","useMemo","openItems","setOpenItems","checkedItems","setCheckedItems","navigation","treeRef","useRef","handleOpenChange","event","data","nextOpenItems","onOpenChange","dangerouslyGetInternalSet_unstable","handleCheckedChange","nextCheckedItems","onCheckedChange","dangerouslyGetInternalMap_unstable","getNextNavigableItem","visibleItems","item","get","value","type","TypeAhead","ArrowLeft","parentValue","ArrowRight","index","End","length","Home","ArrowDown","ArrowUp","getElementFromItem","useCallback","current","querySelector","ref","rootRef","getTreeProps","selectionMode","onNavigation","noop","items","getItem","navigate"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["useHeadlessFlatTree.ts"],"sourcesContent":["import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { HeadlessTreeItem, HeadlessTreeItemProps, createHeadlessTree } from '../../utils/createHeadlessTree';\nimport { treeDataTypes } from '../../utils/tokens';\nimport { useFlatTreeNavigation } from '../../hooks/useFlatTreeNavigation';\nimport { createNextOpenItems, useControllableOpenItems } from '../../hooks/useControllableOpenItems';\nimport type { TreeItemValue } from '../../TreeItem';\nimport { dataTreeItemValueAttrName } from '../../utils/getTreeItemValueFromElement';\nimport { ImmutableSet } from '../../utils/ImmutableSet';\nimport { createNextFlatCheckedItems, useFlatControllableCheckedItems } from './useFlatControllableCheckedItems';\nimport { FlatTreeProps } from './FlatTree.types';\nimport {\n TreeCheckedChangeData,\n TreeCheckedChangeEvent,\n TreeNavigationData_unstable,\n TreeOpenChangeData,\n TreeOpenChangeEvent,\n TreeProps,\n} from '../Tree/Tree.types';\nimport { ImmutableMap } from '../../utils/ImmutableMap';\n\nexport type HeadlessFlatTreeItemProps = HeadlessTreeItemProps;\nexport type HeadlessFlatTreeItem<Props extends HeadlessFlatTreeItemProps> = HeadlessTreeItem<Props>;\n\n/**\n * FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n *\n * On simple scenarios it is advised to simply use a nested structure instead.\n */\nexport type HeadlessFlatTree<Props extends HeadlessFlatTreeItemProps> = {\n /**\n * returns the properties required for the Tree component to work properly.\n * That includes:\n * `openItems`, `onOpenChange`, `onNavigation_unstable` and `ref`\n */\n getTreeProps(): Required<\n Pick<FlatTreeProps, 'openItems' | 'onOpenChange' | 'onNavigation' | 'checkedItems' | 'onCheckedChange'>\n > & {\n ref: React.Ref<HTMLDivElement>;\n openItems: ImmutableSet<TreeItemValue>;\n };\n /**\n * internal method used to react to an `onNavigation` event.\n * This method ensures proper navigation on keyboard and mouse interaction.\n * In case of virtualization it might be required to cancel default provided `onNavigation`\n * event and then call this method manually.\n *\n * @example\n * ```ts\n * // react-window\n * const handleNavigation = (event, data) => {\n * event.preventDefault();\n * const nextItem = tree.getNextNavigableItem(data);\n * // scroll to item using virtualization scroll mechanism\n * if (nextItem && tree.getElementFromItem(nextItem)) {\n * listRef.current.scrollToItem(nextItem.index);\n * }\n * // wait for scrolling to happen and then invoke navigate method\n * requestAnimationFrame(() => {\n * tree.navigate(data);\n * });\n * };\n *```\n */\n navigate(data: TreeNavigationData_unstable): void;\n /**\n * returns next item to be focused on a navigation.\n * This method is provided to decouple the element that needs to be focused from\n * the action of focusing it itself.\n *\n * On the case of TypeAhead navigation this method returns the current item.\n */\n getNextNavigableItem(\n visibleItems: HeadlessTreeItem<Props>[],\n data: TreeNavigationData_unstable,\n ): HeadlessTreeItem<Props> | undefined;\n /**\n * similar to getElementById but for FlatTreeItems\n */\n getElementFromItem(item: HeadlessTreeItem<Props>): HTMLElement | null;\n /**\n * an iterable containing all visually available flat tree items\n */\n items(): IterableIterator<HeadlessTreeItem<Props>>;\n};\n\nexport type HeadlessFlatTreeOptions = Pick<\n FlatTreeProps,\n 'onOpenChange' | 'onNavigation' | 'selectionMode' | 'onCheckedChange'\n> &\n Pick<TreeProps, 'defaultOpenItems' | 'openItems' | 'checkedItems'> & {\n defaultCheckedItems?: TreeProps['checkedItems'];\n };\n\n/**\n * @internal\n */\ntype HeadlessFlatTreeReturn<Props extends HeadlessFlatTreeItemProps> = HeadlessFlatTree<Props> & {\n getItem(value: TreeItemValue): HeadlessTreeItem<Props> | undefined;\n};\n\n/**\n * this hook provides FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n * On simple scenarios it is advised to simply use a nested structure instead.\n *\n * @param props - a list of tree items\n * @param options - in case control over the internal openItems is required\n */\nexport function useHeadlessFlatTree_unstable<Props extends HeadlessTreeItemProps>(\n props: Props[],\n options: HeadlessFlatTreeOptions = {},\n): HeadlessFlatTreeReturn<Props> {\n 'use no memo';\n\n const headlessTree = React.useMemo(() => createHeadlessTree(props), [props]);\n const [openItems, setOpenItems] = useControllableOpenItems(options);\n const [checkedItems, setCheckedItems] = useFlatControllableCheckedItems(options, headlessTree);\n const navigation = useFlatTreeNavigation();\n\n const treeRef = React.useRef<HTMLDivElement>(null);\n const handleOpenChange = useEventCallback((event: TreeOpenChangeEvent, data: TreeOpenChangeData) => {\n const nextOpenItems = createNextOpenItems(data, openItems);\n options.onOpenChange?.(event, {\n ...data,\n openItems: ImmutableSet.dangerouslyGetInternalSet(nextOpenItems),\n });\n setOpenItems(nextOpenItems);\n });\n\n const handleCheckedChange = useEventCallback((event: TreeCheckedChangeEvent, data: TreeCheckedChangeData) => {\n const nextCheckedItems = createNextFlatCheckedItems(data, checkedItems, headlessTree);\n options.onCheckedChange?.(event, {\n ...data,\n checkedItems: ImmutableMap.dangerouslyGetInternalMap(nextCheckedItems),\n });\n setCheckedItems(nextCheckedItems);\n });\n\n const getNextNavigableItem = useEventCallback(\n (visibleItems: HeadlessTreeItem<Props>[], data: TreeNavigationData_unstable) => {\n const item = headlessTree.get(data.value);\n if (item) {\n switch (data.type) {\n case treeDataTypes.TypeAhead:\n return item;\n case treeDataTypes.ArrowLeft:\n return headlessTree.get(item.parentValue!);\n case treeDataTypes.ArrowRight:\n return visibleItems[item.index + 1];\n case treeDataTypes.End:\n return visibleItems[visibleItems.length - 1];\n case treeDataTypes.Home:\n return visibleItems[0];\n case treeDataTypes.ArrowDown:\n return visibleItems[item.index + 1];\n case treeDataTypes.ArrowUp:\n return visibleItems[item.index - 1];\n }\n }\n },\n );\n\n const getElementFromItem = React.useCallback((item: HeadlessTreeItem<Props>) => {\n return treeRef.current?.querySelector(`[${dataTreeItemValueAttrName}=\"${item.value}\"]`) as HTMLElement | null;\n }, []);\n\n const ref = useMergedRefs<HTMLDivElement>(treeRef, navigation.rootRef);\n\n const getTreeProps = React.useCallback(\n () => ({\n ref,\n openItems,\n selectionMode: options.selectionMode,\n checkedItems,\n onOpenChange: handleOpenChange,\n onCheckedChange: handleCheckedChange,\n onNavigation: options.onNavigation ?? noop,\n }),\n // ref, handleOpenChange - useEventCallback, handleCheckedChange - useEventCallback\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [openItems, checkedItems, options.selectionMode, options.onNavigation],\n );\n\n const items = React.useCallback(() => headlessTree.visibleItems(openItems), [openItems, headlessTree]);\n\n const getItem = React.useCallback((value: TreeItemValue) => headlessTree.get(value), [headlessTree]);\n\n return React.useMemo<HeadlessFlatTreeReturn<Props>>(\n () => ({\n navigate: navigation.navigate,\n getTreeProps,\n getNextNavigableItem,\n getElementFromItem,\n items,\n getItem,\n }),\n [navigation.navigate, getTreeProps, getNextNavigableItem, getElementFromItem, items, getItem],\n );\n}\n\n/** @internal */\nfunction noop() {\n /* noop */\n}\n"],"names":["useEventCallback","useMergedRefs","React","createHeadlessTree","treeDataTypes","useFlatTreeNavigation","createNextOpenItems","useControllableOpenItems","dataTreeItemValueAttrName","ImmutableSet","createNextFlatCheckedItems","useFlatControllableCheckedItems","ImmutableMap","useHeadlessFlatTree_unstable","props","options","headlessTree","useMemo","openItems","setOpenItems","checkedItems","setCheckedItems","navigation","treeRef","useRef","handleOpenChange","event","data","nextOpenItems","onOpenChange","dangerouslyGetInternalSet","handleCheckedChange","nextCheckedItems","onCheckedChange","dangerouslyGetInternalMap","getNextNavigableItem","visibleItems","item","get","value","type","TypeAhead","ArrowLeft","parentValue","ArrowRight","index","End","length","Home","ArrowDown","ArrowUp","getElementFromItem","useCallback","current","querySelector","ref","rootRef","getTreeProps","selectionMode","onNavigation","noop","items","getItem","navigate"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -8,7 +8,7 @@ export function useNestedCheckedItems(props) {
8
8
  }
9
9
  export function createNextNestedCheckedItems(data, previousCheckedItems) {
10
10
  if (data.selectionMode === 'single') {
11
- return ImmutableMap.create([
11
+ return ImmutableMap.from([
12
12
  [
13
13
  data.value,
14
14
  data.checked
@@ -1 +1 @@
1
- {"version":3,"sources":["useNestedControllableCheckedItems.ts"],"sourcesContent":["import * as React from 'react';\nimport type { TreeCheckedChangeData, TreeProps } from './Tree.types';\nimport { ImmutableMap } from '../../utils/ImmutableMap';\nimport { createCheckedItems } from '../../utils/createCheckedItems';\nimport { TreeItemValue } from '../TreeItem/TreeItem.types';\n\nexport function useNestedCheckedItems(props: Pick<TreeProps, 'checkedItems'>) {\n return React.useMemo(() => createCheckedItems(props.checkedItems), [props.checkedItems]);\n}\n\nexport function createNextNestedCheckedItems(\n data: Pick<TreeCheckedChangeData, 'selectionMode' | 'value' | 'checked'>,\n previousCheckedItems: ImmutableMap<TreeItemValue, 'mixed' | boolean>,\n): ImmutableMap<TreeItemValue, 'mixed' | boolean> {\n if (data.selectionMode === 'single') {\n return ImmutableMap.create([[data.value, data.checked]]);\n }\n if (data.selectionMode === 'multiselect') {\n return previousCheckedItems.set(data.value, data.checked);\n }\n return previousCheckedItems;\n}\n"],"names":["React","ImmutableMap","createCheckedItems","useNestedCheckedItems","props","useMemo","checkedItems","createNextNestedCheckedItems","data","previousCheckedItems","selectionMode","create","value","checked","set"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,kBAAkB,QAAQ,iCAAiC;AAGpE,OAAO,SAASC,sBAAsBC,KAAsC;IAC1E,OAAOJ,MAAMK,OAAO,CAAC,IAAMH,mBAAmBE,MAAME,YAAY,GAAG;QAACF,MAAME,YAAY;KAAC;AACzF;AAEA,OAAO,SAASC,6BACdC,IAAwE,EACxEC,oBAAoE;IAEpE,IAAID,KAAKE,aAAa,KAAK,UAAU;QACnC,OAAOT,aAAaU,MAAM,CAAC;YAAC;gBAACH,KAAKI,KAAK;gBAAEJ,KAAKK,OAAO;aAAC;SAAC;IACzD;IACA,IAAIL,KAAKE,aAAa,KAAK,eAAe;QACxC,OAAOD,qBAAqBK,GAAG,CAACN,KAAKI,KAAK,EAAEJ,KAAKK,OAAO;IAC1D;IACA,OAAOJ;AACT"}
1
+ {"version":3,"sources":["useNestedControllableCheckedItems.ts"],"sourcesContent":["import * as React from 'react';\nimport type { TreeCheckedChangeData, TreeProps } from './Tree.types';\nimport { ImmutableMap } from '../../utils/ImmutableMap';\nimport { createCheckedItems } from '../../utils/createCheckedItems';\nimport { TreeItemValue } from '../TreeItem/TreeItem.types';\n\nexport function useNestedCheckedItems(props: Pick<TreeProps, 'checkedItems'>) {\n return React.useMemo(() => createCheckedItems(props.checkedItems), [props.checkedItems]);\n}\n\nexport function createNextNestedCheckedItems(\n data: Pick<TreeCheckedChangeData, 'selectionMode' | 'value' | 'checked'>,\n previousCheckedItems: ImmutableMap<TreeItemValue, 'mixed' | boolean>,\n): ImmutableMap<TreeItemValue, 'mixed' | boolean> {\n if (data.selectionMode === 'single') {\n return ImmutableMap.from([[data.value, data.checked]]);\n }\n if (data.selectionMode === 'multiselect') {\n return previousCheckedItems.set(data.value, data.checked);\n }\n return previousCheckedItems;\n}\n"],"names":["React","ImmutableMap","createCheckedItems","useNestedCheckedItems","props","useMemo","checkedItems","createNextNestedCheckedItems","data","previousCheckedItems","selectionMode","from","value","checked","set"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,kBAAkB,QAAQ,iCAAiC;AAGpE,OAAO,SAASC,sBAAsBC,KAAsC;IAC1E,OAAOJ,MAAMK,OAAO,CAAC,IAAMH,mBAAmBE,MAAME,YAAY,GAAG;QAACF,MAAME,YAAY;KAAC;AACzF;AAEA,OAAO,SAASC,6BACdC,IAAwE,EACxEC,oBAAoE;IAEpE,IAAID,KAAKE,aAAa,KAAK,UAAU;QACnC,OAAOT,aAAaU,IAAI,CAAC;YAAC;gBAACH,KAAKI,KAAK;gBAAEJ,KAAKK,OAAO;aAAC;SAAC;IACvD;IACA,IAAIL,KAAKE,aAAa,KAAK,eAAe;QACxC,OAAOD,qBAAqBK,GAAG,CAACN,KAAKI,KAAK,EAAEJ,KAAKK,OAAO;IAC1D;IACA,OAAOJ;AACT"}
@@ -7,6 +7,8 @@ import { useRootTree } from '../../hooks/useRootTree';
7
7
  import { useSubtree } from '../../hooks/useSubtree';
8
8
  import { useTreeNavigation } from '../../hooks/useTreeNavigation';
9
9
  import { useTreeContext_unstable } from '../../contexts/treeContext';
10
+ import { ImmutableSet } from '../../utils/ImmutableSet';
11
+ import { ImmutableMap } from '../../utils/ImmutableMap';
10
12
  export const useTree_unstable = (props, ref)=>{
11
13
  'use no memo';
12
14
  const isRoot = React.useContext(SubtreeContext) === undefined;
@@ -29,7 +31,7 @@ function useNestedRootTree(props, ref) {
29
31
  const nextOpenItems = createNextOpenItems(data, openItems);
30
32
  (_props_onOpenChange = props.onOpenChange) === null || _props_onOpenChange === void 0 ? void 0 : _props_onOpenChange.call(props, event, {
31
33
  ...data,
32
- openItems: nextOpenItems.dangerouslyGetInternalSet_unstable()
34
+ openItems: ImmutableSet.dangerouslyGetInternalSet(nextOpenItems)
33
35
  });
34
36
  setOpenItems(nextOpenItems);
35
37
  }),
@@ -47,7 +49,7 @@ function useNestedRootTree(props, ref) {
47
49
  const nextCheckedItems = createNextNestedCheckedItems(data, checkedItems);
48
50
  (_props_onCheckedChange = props.onCheckedChange) === null || _props_onCheckedChange === void 0 ? void 0 : _props_onCheckedChange.call(props, event, {
49
51
  ...data,
50
- checkedItems: nextCheckedItems.dangerouslyGetInternalMap_unstable()
52
+ checkedItems: ImmutableMap.dangerouslyGetInternalMap(nextCheckedItems)
51
53
  });
52
54
  })
53
55
  }, useMergedRefs(ref, navigation.treeRef)), {
@@ -1 +1 @@
1
- {"version":3,"sources":["useTree.ts"],"sourcesContent":["import * as React from 'react';\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport type { TreeProps, TreeState } from './Tree.types';\nimport { createNextOpenItems, useControllableOpenItems } from '../../hooks/useControllableOpenItems';\nimport { createNextNestedCheckedItems, useNestedCheckedItems } from './useNestedControllableCheckedItems';\nimport { SubtreeContext } from '../../contexts/subtreeContext';\nimport { useRootTree } from '../../hooks/useRootTree';\nimport { useSubtree } from '../../hooks/useSubtree';\nimport { useTreeNavigation } from '../../hooks/useTreeNavigation';\nimport { useTreeContext_unstable } from '../../contexts/treeContext';\n\nexport const useTree_unstable = (props: TreeProps, ref: React.Ref<HTMLElement>): TreeState => {\n 'use no memo';\n\n const isRoot = React.useContext(SubtreeContext) === undefined;\n // as level is static, this doesn't break rule of hooks\n // and if this becomes an issue later on, this can be easily converted\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return isRoot ? useNestedRootTree(props, ref) : useNestedSubtree(props, ref);\n};\n\nfunction useNestedRootTree(props: TreeProps, ref: React.Ref<HTMLElement>): TreeState {\n 'use no memo';\n\n const [openItems, setOpenItems] = useControllableOpenItems(props);\n const checkedItems = useNestedCheckedItems(props);\n const navigation = useTreeNavigation();\n\n return Object.assign(\n useRootTree(\n {\n ...props,\n openItems,\n checkedItems,\n onOpenChange: useEventCallback((event, data) => {\n const nextOpenItems = createNextOpenItems(data, openItems);\n props.onOpenChange?.(event, {\n ...data,\n openItems: nextOpenItems.dangerouslyGetInternalSet_unstable(),\n });\n setOpenItems(nextOpenItems);\n }),\n onNavigation: useEventCallback((event, data) => {\n props.onNavigation?.(event, data);\n if (!event.isDefaultPrevented()) {\n navigation.navigate(data, {\n preventScroll: data.isScrollPrevented(),\n });\n }\n }),\n onCheckedChange: useEventCallback((event, data) => {\n const nextCheckedItems = createNextNestedCheckedItems(data, checkedItems);\n props.onCheckedChange?.(event, {\n ...data,\n checkedItems: nextCheckedItems.dangerouslyGetInternalMap_unstable(),\n });\n }),\n },\n useMergedRefs(ref, navigation.treeRef),\n ),\n { treeType: 'nested' } as const,\n );\n}\n\nfunction useNestedSubtree(props: TreeProps, ref: React.Ref<HTMLElement>): TreeState {\n 'use no memo';\n\n if (process.env.NODE_ENV === 'development') {\n // this doesn't break rule of hooks, as environment is a static value\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const treeType = useTreeContext_unstable(ctx => ctx.treeType);\n if (treeType === 'flat') {\n throw new Error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [useTree]:\n Subtrees are not allowed in a FlatTree!\n You cannot use a <Tree> component inside of a <FlatTree> component!\n `);\n }\n }\n return useSubtree(props, ref);\n}\n"],"names":["React","useEventCallback","useMergedRefs","createNextOpenItems","useControllableOpenItems","createNextNestedCheckedItems","useNestedCheckedItems","SubtreeContext","useRootTree","useSubtree","useTreeNavigation","useTreeContext_unstable","useTree_unstable","props","ref","isRoot","useContext","undefined","useNestedRootTree","useNestedSubtree","openItems","setOpenItems","checkedItems","navigation","Object","assign","onOpenChange","event","data","nextOpenItems","dangerouslyGetInternalSet_unstable","onNavigation","isDefaultPrevented","navigate","preventScroll","isScrollPrevented","onCheckedChange","nextCheckedItems","dangerouslyGetInternalMap_unstable","treeRef","treeType","process","env","NODE_ENV","ctx","Error"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,gBAAgB,EAAEC,aAAa,QAAQ,4BAA4B;AAE5E,SAASC,mBAAmB,EAAEC,wBAAwB,QAAQ,uCAAuC;AACrG,SAASC,4BAA4B,EAAEC,qBAAqB,QAAQ,sCAAsC;AAC1G,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SAASC,UAAU,QAAQ,yBAAyB;AACpD,SAASC,iBAAiB,QAAQ,gCAAgC;AAClE,SAASC,uBAAuB,QAAQ,6BAA6B;AAErE,OAAO,MAAMC,mBAAmB,CAACC,OAAkBC;IACjD;IAEA,MAAMC,SAASf,MAAMgB,UAAU,CAACT,oBAAoBU;IACpD,uDAAuD;IACvD,sEAAsE;IACtE,sDAAsD;IACtD,OAAOF,SAASG,kBAAkBL,OAAOC,OAAOK,iBAAiBN,OAAOC;AAC1E,EAAE;AAEF,SAASI,kBAAkBL,KAAgB,EAAEC,GAA2B;IACtE;IAEA,MAAM,CAACM,WAAWC,aAAa,GAAGjB,yBAAyBS;IAC3D,MAAMS,eAAehB,sBAAsBO;IAC3C,MAAMU,aAAab;IAEnB,OAAOc,OAAOC,MAAM,CAClBjB,YACE;QACE,GAAGK,KAAK;QACRO;QACAE;QACAI,cAAczB,iBAAiB,CAAC0B,OAAOC;gBAErCf;YADA,MAAMgB,gBAAgB1B,oBAAoByB,MAAMR;aAChDP,sBAAAA,MAAMa,YAAY,cAAlBb,0CAAAA,yBAAAA,OAAqBc,OAAO;gBAC1B,GAAGC,IAAI;gBACPR,WAAWS,cAAcC,kCAAkC;YAC7D;YACAT,aAAaQ;QACf;QACAE,cAAc9B,iBAAiB,CAAC0B,OAAOC;gBACrCf;aAAAA,sBAAAA,MAAMkB,YAAY,cAAlBlB,0CAAAA,yBAAAA,OAAqBc,OAAOC;YAC5B,IAAI,CAACD,MAAMK,kBAAkB,IAAI;gBAC/BT,WAAWU,QAAQ,CAACL,MAAM;oBACxBM,eAAeN,KAAKO,iBAAiB;gBACvC;YACF;QACF;QACAC,iBAAiBnC,iBAAiB,CAAC0B,OAAOC;gBAExCf;YADA,MAAMwB,mBAAmBhC,6BAA6BuB,MAAMN;aAC5DT,yBAAAA,MAAMuB,eAAe,cAArBvB,6CAAAA,4BAAAA,OAAwBc,OAAO;gBAC7B,GAAGC,IAAI;gBACPN,cAAce,iBAAiBC,kCAAkC;YACnE;QACF;IACF,GACApC,cAAcY,KAAKS,WAAWgB,OAAO,IAEvC;QAAEC,UAAU;IAAS;AAEzB;AAEA,SAASrB,iBAAiBN,KAAgB,EAAEC,GAA2B;IACrE;IAEA,IAAI2B,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1C,qEAAqE;QACrE,sDAAsD;QACtD,MAAMH,WAAW7B,wBAAwBiC,CAAAA,MAAOA,IAAIJ,QAAQ;QAC5D,IAAIA,aAAa,QAAQ;YACvB,MAAM,IAAIK,MAA2B,CAAC;;mEAItC,CAAC;QACH;IACF;IACA,OAAOpC,WAAWI,OAAOC;AAC3B"}
1
+ {"version":3,"sources":["useTree.ts"],"sourcesContent":["import * as React from 'react';\nimport { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport type { TreeProps, TreeState } from './Tree.types';\nimport { createNextOpenItems, useControllableOpenItems } from '../../hooks/useControllableOpenItems';\nimport { createNextNestedCheckedItems, useNestedCheckedItems } from './useNestedControllableCheckedItems';\nimport { SubtreeContext } from '../../contexts/subtreeContext';\nimport { useRootTree } from '../../hooks/useRootTree';\nimport { useSubtree } from '../../hooks/useSubtree';\nimport { useTreeNavigation } from '../../hooks/useTreeNavigation';\nimport { useTreeContext_unstable } from '../../contexts/treeContext';\nimport { ImmutableSet } from '../../utils/ImmutableSet';\nimport { ImmutableMap } from '../../utils/ImmutableMap';\n\nexport const useTree_unstable = (props: TreeProps, ref: React.Ref<HTMLElement>): TreeState => {\n 'use no memo';\n\n const isRoot = React.useContext(SubtreeContext) === undefined;\n // as level is static, this doesn't break rule of hooks\n // and if this becomes an issue later on, this can be easily converted\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return isRoot ? useNestedRootTree(props, ref) : useNestedSubtree(props, ref);\n};\n\nfunction useNestedRootTree(props: TreeProps, ref: React.Ref<HTMLElement>): TreeState {\n 'use no memo';\n\n const [openItems, setOpenItems] = useControllableOpenItems(props);\n const checkedItems = useNestedCheckedItems(props);\n const navigation = useTreeNavigation();\n\n return Object.assign(\n useRootTree(\n {\n ...props,\n openItems,\n checkedItems,\n onOpenChange: useEventCallback((event, data) => {\n const nextOpenItems = createNextOpenItems(data, openItems);\n props.onOpenChange?.(event, {\n ...data,\n openItems: ImmutableSet.dangerouslyGetInternalSet(nextOpenItems),\n });\n setOpenItems(nextOpenItems);\n }),\n onNavigation: useEventCallback((event, data) => {\n props.onNavigation?.(event, data);\n if (!event.isDefaultPrevented()) {\n navigation.navigate(data, {\n preventScroll: data.isScrollPrevented(),\n });\n }\n }),\n onCheckedChange: useEventCallback((event, data) => {\n const nextCheckedItems = createNextNestedCheckedItems(data, checkedItems);\n props.onCheckedChange?.(event, {\n ...data,\n checkedItems: ImmutableMap.dangerouslyGetInternalMap(nextCheckedItems),\n });\n }),\n },\n useMergedRefs(ref, navigation.treeRef),\n ),\n { treeType: 'nested' } as const,\n );\n}\n\nfunction useNestedSubtree(props: TreeProps, ref: React.Ref<HTMLElement>): TreeState {\n 'use no memo';\n\n if (process.env.NODE_ENV === 'development') {\n // this doesn't break rule of hooks, as environment is a static value\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const treeType = useTreeContext_unstable(ctx => ctx.treeType);\n if (treeType === 'flat') {\n throw new Error(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [useTree]:\n Subtrees are not allowed in a FlatTree!\n You cannot use a <Tree> component inside of a <FlatTree> component!\n `);\n }\n }\n return useSubtree(props, ref);\n}\n"],"names":["React","useEventCallback","useMergedRefs","createNextOpenItems","useControllableOpenItems","createNextNestedCheckedItems","useNestedCheckedItems","SubtreeContext","useRootTree","useSubtree","useTreeNavigation","useTreeContext_unstable","ImmutableSet","ImmutableMap","useTree_unstable","props","ref","isRoot","useContext","undefined","useNestedRootTree","useNestedSubtree","openItems","setOpenItems","checkedItems","navigation","Object","assign","onOpenChange","event","data","nextOpenItems","dangerouslyGetInternalSet","onNavigation","isDefaultPrevented","navigate","preventScroll","isScrollPrevented","onCheckedChange","nextCheckedItems","dangerouslyGetInternalMap","treeRef","treeType","process","env","NODE_ENV","ctx","Error"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,gBAAgB,EAAEC,aAAa,QAAQ,4BAA4B;AAE5E,SAASC,mBAAmB,EAAEC,wBAAwB,QAAQ,uCAAuC;AACrG,SAASC,4BAA4B,EAAEC,qBAAqB,QAAQ,sCAAsC;AAC1G,SAASC,cAAc,QAAQ,gCAAgC;AAC/D,SAASC,WAAW,QAAQ,0BAA0B;AACtD,SAASC,UAAU,QAAQ,yBAAyB;AACpD,SAASC,iBAAiB,QAAQ,gCAAgC;AAClE,SAASC,uBAAuB,QAAQ,6BAA6B;AACrE,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,YAAY,QAAQ,2BAA2B;AAExD,OAAO,MAAMC,mBAAmB,CAACC,OAAkBC;IACjD;IAEA,MAAMC,SAASjB,MAAMkB,UAAU,CAACX,oBAAoBY;IACpD,uDAAuD;IACvD,sEAAsE;IACtE,sDAAsD;IACtD,OAAOF,SAASG,kBAAkBL,OAAOC,OAAOK,iBAAiBN,OAAOC;AAC1E,EAAE;AAEF,SAASI,kBAAkBL,KAAgB,EAAEC,GAA2B;IACtE;IAEA,MAAM,CAACM,WAAWC,aAAa,GAAGnB,yBAAyBW;IAC3D,MAAMS,eAAelB,sBAAsBS;IAC3C,MAAMU,aAAaf;IAEnB,OAAOgB,OAAOC,MAAM,CAClBnB,YACE;QACE,GAAGO,KAAK;QACRO;QACAE;QACAI,cAAc3B,iBAAiB,CAAC4B,OAAOC;gBAErCf;YADA,MAAMgB,gBAAgB5B,oBAAoB2B,MAAMR;aAChDP,sBAAAA,MAAMa,YAAY,cAAlBb,0CAAAA,yBAAAA,OAAqBc,OAAO;gBAC1B,GAAGC,IAAI;gBACPR,WAAWV,aAAaoB,yBAAyB,CAACD;YACpD;YACAR,aAAaQ;QACf;QACAE,cAAchC,iBAAiB,CAAC4B,OAAOC;gBACrCf;aAAAA,sBAAAA,MAAMkB,YAAY,cAAlBlB,0CAAAA,yBAAAA,OAAqBc,OAAOC;YAC5B,IAAI,CAACD,MAAMK,kBAAkB,IAAI;gBAC/BT,WAAWU,QAAQ,CAACL,MAAM;oBACxBM,eAAeN,KAAKO,iBAAiB;gBACvC;YACF;QACF;QACAC,iBAAiBrC,iBAAiB,CAAC4B,OAAOC;gBAExCf;YADA,MAAMwB,mBAAmBlC,6BAA6ByB,MAAMN;aAC5DT,yBAAAA,MAAMuB,eAAe,cAArBvB,6CAAAA,4BAAAA,OAAwBc,OAAO;gBAC7B,GAAGC,IAAI;gBACPN,cAAcX,aAAa2B,yBAAyB,CAACD;YACvD;QACF;IACF,GACArC,cAAcc,KAAKS,WAAWgB,OAAO,IAEvC;QAAEC,UAAU;IAAS;AAEzB;AAEA,SAASrB,iBAAiBN,KAAgB,EAAEC,GAA2B;IACrE;IAEA,IAAI2B,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1C,qEAAqE;QACrE,sDAAsD;QACtD,MAAMH,WAAW/B,wBAAwBmC,CAAAA,MAAOA,IAAIJ,QAAQ;QAC5D,IAAIA,aAAa,QAAQ;YACvB,MAAM,IAAIK,MAA2B,CAAC;;mEAItC,CAAC;QACH;IACF;IACA,OAAOtC,WAAWM,OAAOC;AAC3B"}
@@ -1,28 +1,19 @@
1
1
  import { useControllableState } from '@fluentui/react-utilities';
2
2
  import * as React from 'react';
3
3
  import { ImmutableSet } from '../utils/ImmutableSet';
4
- import { createOpenItems } from '../utils/createOpenItems';
5
4
  /**
6
5
  * @internal
7
6
  */ export function useControllableOpenItems(props) {
8
7
  return useControllableState({
9
- state: React.useMemo(()=>props.openItems && createOpenItems(props.openItems), [
8
+ state: React.useMemo(()=>props.openItems && ImmutableSet.from(props.openItems), [
10
9
  props.openItems
11
10
  ]),
12
- defaultState: props.defaultOpenItems && (()=>createOpenItems(props.defaultOpenItems)),
11
+ defaultState: props.defaultOpenItems && (()=>ImmutableSet.from(props.defaultOpenItems)),
13
12
  initialState: ImmutableSet.empty
14
13
  });
15
14
  }
16
15
  /**
17
16
  * @internal
18
17
  */ export function createNextOpenItems(data, previousOpenItems) {
19
- if (data.value === null) {
20
- return previousOpenItems;
21
- }
22
- const previousOpenItemsHasId = previousOpenItems.has(data.value);
23
- if (data.open ? previousOpenItemsHasId : !previousOpenItemsHasId) {
24
- return previousOpenItems;
25
- }
26
- const nextOpenItems = ImmutableSet.create(previousOpenItems);
27
- return data.open ? nextOpenItems.add(data.value) : nextOpenItems.delete(data.value);
18
+ return data.open ? previousOpenItems.add(data.value) : previousOpenItems.delete(data.value);
28
19
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["useControllableOpenItems.ts"],"sourcesContent":["import { useControllableState } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport type { TreeItemValue } from '../components/TreeItem/TreeItem.types';\nimport { createOpenItems } from '../utils/createOpenItems';\nimport { TreeOpenChangeData, TreeProps } from '../Tree';\n\n/**\n * @internal\n */\nexport function useControllableOpenItems(props: Pick<TreeProps, 'openItems' | 'defaultOpenItems'>) {\n return useControllableState({\n state: React.useMemo(() => props.openItems && createOpenItems(props.openItems), [props.openItems]),\n defaultState: props.defaultOpenItems && (() => createOpenItems(props.defaultOpenItems)),\n initialState: ImmutableSet.empty,\n });\n}\n\n/**\n * @internal\n */\nexport function createNextOpenItems(\n data: Pick<TreeOpenChangeData, 'value' | 'open'>,\n previousOpenItems: ImmutableSet<TreeItemValue>,\n): ImmutableSet<TreeItemValue> {\n if (data.value === null) {\n return previousOpenItems;\n }\n const previousOpenItemsHasId = previousOpenItems.has(data.value);\n if (data.open ? previousOpenItemsHasId : !previousOpenItemsHasId) {\n return previousOpenItems;\n }\n const nextOpenItems = ImmutableSet.create(previousOpenItems);\n return data.open ? nextOpenItems.add(data.value) : nextOpenItems.delete(data.value);\n}\n"],"names":["useControllableState","React","ImmutableSet","createOpenItems","useControllableOpenItems","props","state","useMemo","openItems","defaultState","defaultOpenItems","initialState","empty","createNextOpenItems","data","previousOpenItems","value","previousOpenItemsHasId","has","open","nextOpenItems","create","add","delete"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,oBAAoB,QAAQ,4BAA4B;AACjE,YAAYC,WAAW,QAAQ;AAC/B,SAASC,YAAY,QAAQ,wBAAwB;AAErD,SAASC,eAAe,QAAQ,2BAA2B;AAG3D;;CAEC,GACD,OAAO,SAASC,yBAAyBC,KAAwD;IAC/F,OAAOL,qBAAqB;QAC1BM,OAAOL,MAAMM,OAAO,CAAC,IAAMF,MAAMG,SAAS,IAAIL,gBAAgBE,MAAMG,SAAS,GAAG;YAACH,MAAMG,SAAS;SAAC;QACjGC,cAAcJ,MAAMK,gBAAgB,IAAK,CAAA,IAAMP,gBAAgBE,MAAMK,gBAAgB,CAAA;QACrFC,cAAcT,aAAaU,KAAK;IAClC;AACF;AAEA;;CAEC,GACD,OAAO,SAASC,oBACdC,IAAgD,EAChDC,iBAA8C;IAE9C,IAAID,KAAKE,KAAK,KAAK,MAAM;QACvB,OAAOD;IACT;IACA,MAAME,yBAAyBF,kBAAkBG,GAAG,CAACJ,KAAKE,KAAK;IAC/D,IAAIF,KAAKK,IAAI,GAAGF,yBAAyB,CAACA,wBAAwB;QAChE,OAAOF;IACT;IACA,MAAMK,gBAAgBlB,aAAamB,MAAM,CAACN;IAC1C,OAAOD,KAAKK,IAAI,GAAGC,cAAcE,GAAG,CAACR,KAAKE,KAAK,IAAII,cAAcG,MAAM,CAACT,KAAKE,KAAK;AACpF"}
1
+ {"version":3,"sources":["useControllableOpenItems.ts"],"sourcesContent":["import { useControllableState } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport type { TreeItemValue } from '../components/TreeItem/TreeItem.types';\nimport { TreeOpenChangeData, TreeProps } from '../Tree';\n\n/**\n * @internal\n */\nexport function useControllableOpenItems(props: Pick<TreeProps, 'openItems' | 'defaultOpenItems'>) {\n return useControllableState({\n state: React.useMemo(() => props.openItems && ImmutableSet.from(props.openItems), [props.openItems]),\n defaultState: props.defaultOpenItems && (() => ImmutableSet.from(props.defaultOpenItems)),\n initialState: ImmutableSet.empty,\n });\n}\n\n/**\n * @internal\n */\nexport function createNextOpenItems(\n data: Pick<TreeOpenChangeData, 'value' | 'open'>,\n previousOpenItems: ImmutableSet<TreeItemValue>,\n): ImmutableSet<TreeItemValue> {\n return data.open ? previousOpenItems.add(data.value) : previousOpenItems.delete(data.value);\n}\n"],"names":["useControllableState","React","ImmutableSet","useControllableOpenItems","props","state","useMemo","openItems","from","defaultState","defaultOpenItems","initialState","empty","createNextOpenItems","data","previousOpenItems","open","add","value","delete"],"rangeMappings":";;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,oBAAoB,QAAQ,4BAA4B;AACjE,YAAYC,WAAW,QAAQ;AAC/B,SAASC,YAAY,QAAQ,wBAAwB;AAIrD;;CAEC,GACD,OAAO,SAASC,yBAAyBC,KAAwD;IAC/F,OAAOJ,qBAAqB;QAC1BK,OAAOJ,MAAMK,OAAO,CAAC,IAAMF,MAAMG,SAAS,IAAIL,aAAaM,IAAI,CAACJ,MAAMG,SAAS,GAAG;YAACH,MAAMG,SAAS;SAAC;QACnGE,cAAcL,MAAMM,gBAAgB,IAAK,CAAA,IAAMR,aAAaM,IAAI,CAACJ,MAAMM,gBAAgB,CAAA;QACvFC,cAAcT,aAAaU,KAAK;IAClC;AACF;AAEA;;CAEC,GACD,OAAO,SAASC,oBACdC,IAAgD,EAChDC,iBAA8C;IAE9C,OAAOD,KAAKE,IAAI,GAAGD,kBAAkBE,GAAG,CAACH,KAAKI,KAAK,IAAIH,kBAAkBI,MAAM,CAACL,KAAKI,KAAK;AAC5F"}
@@ -1,10 +1,11 @@
1
1
  import { getIntrinsicElementProps, useEventCallback, slot } from '@fluentui/react-utilities';
2
2
  import * as React from 'react';
3
3
  import { Collapse } from '@fluentui/react-motion-components-preview';
4
- import { createOpenItems } from '../utils/createOpenItems';
5
4
  import { createCheckedItems } from '../utils/createCheckedItems';
6
5
  import { treeDataTypes } from '../utils/tokens';
7
6
  import { createNextOpenItems } from './useControllableOpenItems';
7
+ import { ImmutableSet } from '../utils/ImmutableSet';
8
+ import { ImmutableMap } from '../utils/ImmutableMap';
8
9
  /**
9
10
  * Create the state required to render the root level tree.
10
11
  *
@@ -13,7 +14,7 @@ import { createNextOpenItems } from './useControllableOpenItems';
13
14
  */ export function useRootTree(props, ref) {
14
15
  warnIfNoProperPropsRootTree(props);
15
16
  const { appearance = 'subtle', size = 'medium', selectionMode = 'none' } = props;
16
- const openItems = React.useMemo(()=>createOpenItems(props.openItems), [
17
+ const openItems = React.useMemo(()=>ImmutableSet.from(props.openItems), [
17
18
  props.openItems
18
19
  ]);
19
20
  const checkedItems = React.useMemo(()=>createCheckedItems(props.checkedItems), [
@@ -23,7 +24,7 @@ import { createNextOpenItems } from './useControllableOpenItems';
23
24
  var _props_onOpenChange;
24
25
  (_props_onOpenChange = props.onOpenChange) === null || _props_onOpenChange === void 0 ? void 0 : _props_onOpenChange.call(props, request.event, {
25
26
  ...request,
26
- openItems: createNextOpenItems(request, openItems).dangerouslyGetInternalSet_unstable()
27
+ openItems: ImmutableSet.dangerouslyGetInternalSet(createNextOpenItems(request, openItems))
27
28
  });
28
29
  };
29
30
  const requestCheckedChange = (request)=>{
@@ -34,7 +35,7 @@ import { createNextOpenItems } from './useControllableOpenItems';
34
35
  (_props_onCheckedChange = props.onCheckedChange) === null || _props_onCheckedChange === void 0 ? void 0 : _props_onCheckedChange.call(props, request.event, {
35
36
  ...request,
36
37
  selectionMode,
37
- checkedItems: checkedItems.dangerouslyGetInternalMap_unstable()
38
+ checkedItems: ImmutableMap.dangerouslyGetInternalMap(checkedItems)
38
39
  });
39
40
  };
40
41
  const requestNavigation = (request)=>{