@itwin/presentation-hierarchies-react 2.0.0-alpha.12 → 2.0.0-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/esm/presentation-hierarchies-react/UseTree.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/UseTree.js +1 -7
- package/lib/esm/presentation-hierarchies-react/UseTree.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/Utils.d.ts +5 -0
- package/lib/esm/presentation-hierarchies-react/Utils.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/Utils.js +23 -0
- package/lib/esm/presentation-hierarchies-react/Utils.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts +3 -3
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js +3 -3
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js +6 -4
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js +8 -5
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts +10 -13
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js +22 -24
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts +2 -2
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js +23 -19
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @itwin/presentation-hierarchies-react
|
|
2
2
|
|
|
3
|
+
## 2.0.0-alpha.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#928](https://github.com/iTwin/presentation/pull/928): Memoize tree components to reduce the amount of renders.
|
|
8
|
+
|
|
9
|
+
## 2.0.0-alpha.13
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#924](https://github.com/iTwin/presentation/pull/924): Fix tree error dropdown not applying actions.
|
|
14
|
+
|
|
3
15
|
## 2.0.0-alpha.12
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UseTree.d.ts","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/UseTree.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAClI,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGnF,OAAO,EAA2B,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAE1G,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"UseTree.d.ts","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/UseTree.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import { TreeActions } from "./internal/TreeActions.js";
|
|
|
8
8
|
import { isTreeModelHierarchyNode, isTreeModelInfoNode, TreeModel } from "./internal/TreeModel.js";
|
|
9
9
|
import { useUnifiedTreeSelection } from "./internal/UseUnifiedSelection.js";
|
|
10
10
|
import { safeDispose } from "./internal/Utils.js";
|
|
11
|
+
import { useLatest } from "./Utils.js";
|
|
11
12
|
/**
|
|
12
13
|
* A React hook that creates state for a tree component.
|
|
13
14
|
*
|
|
@@ -232,11 +233,4 @@ function toPresentationHierarchyNodeBase(node) {
|
|
|
232
233
|
extendedData: node.nodeData.extendedData,
|
|
233
234
|
};
|
|
234
235
|
}
|
|
235
|
-
function useLatest(value) {
|
|
236
|
-
const ref = useRef(value);
|
|
237
|
-
useEffect(() => {
|
|
238
|
-
ref.current = value;
|
|
239
|
-
}, [value]);
|
|
240
|
-
return ref;
|
|
241
|
-
}
|
|
242
236
|
//# sourceMappingURL=UseTree.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UseTree.js","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/UseTree.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAiD,aAAa,EAAqB,MAAM,iCAAiC,CAAC;AAElI,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,SAAS,EAA4D,MAAM,yBAAyB,CAAC;AAC7J,OAAO,EAAE,uBAAuB,EAAgC,MAAM,mCAAmC,CAAC;AAC1G,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA6BlD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CAAC,KAAmB;IACzC,MAAM,EAAE,gBAAgB,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,KAAK,EAA+C;IAC7H,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAC7D,OAAO;QACL,GAAG,IAAI;QACP,GAAG,uBAAuB,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;KAC/E,CAAC;AACJ,CAAC;AA8ED,SAAS,eAAe,CAAC,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,GACP;IAGb,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAY;QAC5C,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE,cAAc,EAAE,IAAI,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;QAC3G,SAAS,EAAE,SAAS;KACrB,CAAC,CAAC;IACH,MAAM,wBAAwB,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAClE,MAAM,2BAA2B,GAAG,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACxE,MAAM,uBAAuB,GAAG,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAEhE,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,CACxB,GAAG,EAAE,CACH,IAAI,WAAW,CACb,CAAC,KAAK,EAAE,EAAE;QACR,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1H,QAAQ,CAAC;YACP,KAAK;YACL,SAAS;SACV,CAAC,CAAC;IACL,CAAC,EACD,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,wBAAwB,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAClF,CAAC,KAAK,EAAE,EAAE,CAAC,2BAA2B,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,EACvD,CAAC,KAAK,EAAE,EAAE,CAAC,uBAAuB,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CACpD,CACJ,CAAC;IACF,MAAM,gBAAgB,GAAG,MAAM,EAA4B,CAAC;IAE5D,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,EAAiC,CAAC;IAC5F,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,oBAAoB,EAAE,CAAC;QACxC,QAAQ,CAAC,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,8BAA8B,GAAG,QAAQ,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,mBAAmB,EAAE,EAAE;YACnG,MAAM,kBAAkB,GAAG,mBAAmB,EAAE,YAAY,EAAE,SAAS,KAAK,SAAS,CAAC;YACtF,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QACvC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE;YACV,8BAA8B,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAEpC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,iBAAiB,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;gBAChD,6FAA6F;gBAC7F,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBACtC,cAAc,CAAC,KAAK,CAAC,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,cAAc,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,KAA2C,CAAC;YAChD,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,gBAAgB,EAAE,CAAC;YACnC,CAAC;YAAC,MAAM,CAAC;YACT,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,iBAAiB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBACpE,cAAc,CAAC,KAAK,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,GAAG,EAAE;YACV,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,iBAAiB,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;IAEnD,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,MAAc,EAAE,EAAE;QACjB,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,OAAO,GAAG,WAAW,CACzB,CAAC,MAAc,EAAyC,EAAE;QACxD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,+BAA+B,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC,EACD,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CACvB,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,MAAc,EAAE,UAAmB,EAAE,EAAE;QACtC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,OAAO,EAAE,EAAE;QACV,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,OAAsB,EAAE,UAA+B,EAAE,EAAE;QAC1D,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,cAAc,GAAG,WAAW,CAAkC,CAAC,MAAc,EAAE,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEhJ,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,SAA+C,EAAE,EAAE;QAClD,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC;QACrC,sBAAsB;QACtB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QAED,iBAAiB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC,EACD,CAAC,iBAAiB,CAAC,CACpB,CAAC;IAEF,MAAM,wBAAwB,GAAG,WAAW,CAC1C,CAAC,MAAM,EAAE,EAAE;QACT,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC;QACpC,IAAI,aAAa,IAAI,aAAa,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,CAAC;YACjE,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO;YACL,aAAa;YACb,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE,CACjC,iBAAiB,CAAC,mBAAmB,CAAC;gBACpC,UAAU,EAAE,aAAa;gBACzB,cAAc,EAAE,KAAK,EAAE,cAAc;gBACrC,uBAAuB,EAAE,KAAK,EAAE,uBAAuB;aACxD,CAAC;YACJ,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC;YACxE,SAAS,EAAE,IAAI,CAAC,cAAc;YAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC;SAClE,CAAC;IACJ,CAAC,EACD,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAC7B,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,IAAI,WAAW;QAC1D,UAAU;QACV,UAAU;QACV,WAAW;QACX,cAAc;QACd,gBAAgB;QAChB,OAAO;QACP,wBAAwB;QACxB,YAAY;KACb,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,YAAgC,EAAE,KAAgB;IAC/E,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,eAAe;SACnB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SAC7C,MAAM,CAAC,CAAC,IAAI,EAAyB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAC/C,GAAG,CAAuB,CAAC,IAAI,EAAE,EAAE;QAClC,IAAI,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,+BAA+B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACtC,OAAO;gBACL,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,YAAY;gBACZ,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;aAC5C,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACpC,OAAO;gBACL,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,YAAY;gBACZ,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,YAAY;YACZ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,+BAA+B,CAAC,SAAiC,EAAE,KAAgB;IAC1F,IAAI,QAAiD,CAAC;IACtD,OAAO;QACL,GAAG,+BAA+B,CAAC,SAAS,CAAC;QAC7C,IAAI,QAAQ;YACV,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,qBAAqB,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,+BAA+B,CAAC,IAA4B;IACnE,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS;QAC3B,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU;QAC7B,YAAY,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,IAAI,CAAC,QAAQ;QAChH,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc;QACjC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY;KACzC,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAI,KAAQ;IAC5B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,SAAS,CAAC,GAAG,EAAE;QACb,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { GenericInstanceFilter, HierarchyFilteringPath, HierarchyNode, HierarchyProvider } from \"@itwin/presentation-hierarchies\";\nimport { InstanceKey, IPrimitiveValueFormatter } from \"@itwin/presentation-shared\";\nimport { TreeActions } from \"./internal/TreeActions.js\";\nimport { isTreeModelHierarchyNode, isTreeModelInfoNode, TreeModel, TreeModelHierarchyNode, TreeModelNode, TreeModelRootNode } from \"./internal/TreeModel.js\";\nimport { useUnifiedTreeSelection, UseUnifiedTreeSelectionProps } from \"./internal/UseUnifiedSelection.js\";\nimport { safeDispose } from \"./internal/Utils.js\";\nimport { PresentationHierarchyNode, PresentationTreeNode } from \"./TreeNode.js\";\nimport { SelectionChangeType } from \"./UseSelectionHandler.js\";\n\n/**\n * A data structure that contains information about a single hierarchy level.\n * @public\n */\nexport interface HierarchyLevelDetails {\n /** The parent node whose hierarchy level's information is contained in this data structure */\n hierarchyNode: HierarchyNode | undefined;\n\n /** A function to get instance keys of the hierarchy level. */\n getInstanceKeysIterator: (props?: {\n instanceFilter?: GenericInstanceFilter;\n hierarchyLevelSizeLimit?: number | \"unbounded\";\n }) => AsyncIterableIterator<InstanceKey>;\n\n /** Get the limit of how many nodes can be loaded in this hierarchy level. */\n sizeLimit?: number | \"unbounded\";\n /** Set the limit of how many nodes can be loaded in this hierarchy level. */\n setSizeLimit: (value: undefined | number | \"unbounded\") => void;\n\n /** Get the active instance filter applied to this hierarchy level. */\n instanceFilter?: GenericInstanceFilter;\n /** Set the instance filter to apply to this hierarchy level */\n setInstanceFilter: (filter: GenericInstanceFilter | undefined) => void;\n}\n\n/**\n * A React hook that creates state for a tree component.\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useUnifiedSelectionTree`\n * @see `useIModelTree`\n * @public\n */\nexport function useTree(props: UseTreeProps): UseTreeResult {\n const { getTreeModelNode: _, ...rest } = useTreeInternal(props);\n return rest;\n}\n\n/**\n * A React hook that creates state for a tree component, that is integrated with unified selection\n * through the given selection storage (previously the storage was provided through the, now\n * deprecated, `UnifiedSelectionProvider`).\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useTree`\n * @see `useIModelUnifiedSelectionTree`\n * @see `UnifiedSelectionProvider`\n * @public\n */\nexport function useUnifiedSelectionTree({ sourceName, selectionStorage, ...props }: UseTreeProps & UseUnifiedTreeSelectionProps): UseTreeResult {\n const { getTreeModelNode, ...rest } = useTreeInternal(props);\n return {\n ...rest,\n ...useUnifiedTreeSelection({ sourceName, selectionStorage, getTreeModelNode }),\n };\n}\n\n/** @public */\nexport interface UseTreeProps {\n /** Provides the hierarchy provider for the tree. */\n getHierarchyProvider: () => HierarchyProvider;\n /** Provides paths to filtered nodes. */\n getFilteredPaths?: () => Promise<HierarchyFilteringPath[] | undefined>;\n /**\n * Callback that is called just after a certain action is finished.\n * Can be used for performance tracking.\n */\n onPerformanceMeasured?: (action: \"initial-load\" | \"hierarchy-level-load\" | \"reload\", duration: number) => void;\n /** Action to perform when hierarchy level contains more items that the specified limit. */\n onHierarchyLimitExceeded?: (props: { parentId?: string; filter?: GenericInstanceFilter; limit?: number | \"unbounded\" }) => void;\n /** Action to perform when an error occurs while loading hierarchy. */\n onHierarchyLoadError?: (props: { parentId?: string; type: \"timeout\" | \"unknown\"; error: unknown }) => void;\n}\n\n/**\n * Options for doing either full or a sub tree reload.\n * @public\n */\ninterface ReloadTreeOptions {\n /** Specifies parent node under which sub tree should be reloaded. */\n parentNodeId: string | undefined;\n\n /**\n * Specifies how current tree state should be handled:\n * - `keep` - try to keep current tree state (expanded/collapsed nodes, instance filters, etc.).\n * - `discard` - do not try to keep current tree state. Tree model will be update after nodes are reloaded.\n * - `reset` - remove subtree from the model before reloading and reload nodes ignoring cache.\n *\n * Defaults to `\"keep\"`.\n */\n state?: \"keep\" | \"discard\" | \"reset\";\n}\n\n/** @public */\nexport interface UseTreeResult {\n /**\n * Array containing root tree nodes. It is `undefined` on initial render until any nodes are loaded.\n */\n rootNodes: PresentationTreeNode[] | undefined;\n /**\n * Specifies whether tree is loading or not. It is set to `true` when initial tree load is in progress\n * or tree is reloading.\n */\n isLoading: boolean;\n /**\n * A function that should be called to reload the tree.\n */\n reloadTree: (options?: ReloadTreeOptions) => void;\n /**\n * A function that should be called to either expand or collapse the given node.\n */\n expandNode: (nodeId: string, isExpanded: boolean) => void;\n /**\n * A function that should be called to select nodes in the tree.\n * @param nodeIds Ids of the nodes that are selected.\n * @param changeType Type of change that occurred for the selection.\n */\n selectNodes: (nodeIds: Array<string>, changeType: SelectionChangeType) => void;\n /** Determines whether a given node is selected. */\n isNodeSelected: (nodeId: string) => boolean;\n /** Get a tree node by id */\n getNode: (nodeId: string) => PresentationHierarchyNode | undefined;\n /** Returns hierarchy level details for a given node ID. */\n getHierarchyLevelDetails: (nodeId: string | undefined) => HierarchyLevelDetails | undefined;\n /** Sets a formatter for the primitive values that are displayed in the hierarchy. */\n setFormatter: (formatter: IPrimitiveValueFormatter | undefined) => void;\n}\n\ninterface TreeState {\n model: TreeModel;\n rootNodes: Array<PresentationTreeNode> | undefined;\n}\n\nfunction useTreeInternal({\n getHierarchyProvider,\n getFilteredPaths,\n onPerformanceMeasured,\n onHierarchyLimitExceeded,\n onHierarchyLoadError,\n}: UseTreeProps): UseTreeResult & {\n getTreeModelNode: (nodeId: string) => TreeModelRootNode | TreeModelNode | undefined;\n} {\n const [state, setState] = useState<TreeState>({\n model: { idToNode: new Map(), parentChildMap: new Map(), rootNode: { id: undefined, nodeData: undefined } },\n rootNodes: undefined,\n });\n const onPerformanceMeasuredRef = useLatest(onPerformanceMeasured);\n const onHierarchyLimitExceededRef = useLatest(onHierarchyLimitExceeded);\n const onHierarchyLoadErrorRef = useLatest(onHierarchyLoadError);\n\n const [actions] = useState<TreeActions>(\n () =>\n new TreeActions(\n (model) => {\n const rootNodes = model.parentChildMap.get(undefined) !== undefined ? generateTreeStructure(undefined, model) : undefined;\n setState({\n model,\n rootNodes,\n });\n },\n (actionType, duration) => onPerformanceMeasuredRef.current?.(actionType, duration),\n (props) => onHierarchyLimitExceededRef.current?.(props),\n (props) => onHierarchyLoadErrorRef.current?.(props),\n ),\n );\n const currentFormatter = useRef<IPrimitiveValueFormatter>();\n\n const [hierarchyProvider, setHierarchyProvider] = useState<HierarchyProvider | undefined>();\n useEffect(() => {\n const provider = getHierarchyProvider();\n provider.setFormatter(currentFormatter.current);\n const removeHierarchyChangedListener = provider.hierarchyChanged.addListener((hierarchyChangeArgs) => {\n const shouldDiscardState = hierarchyChangeArgs?.filterChange?.newFilter !== undefined;\n actions.reloadTree({ state: shouldDiscardState ? \"discard\" : \"keep\" });\n });\n actions.setHierarchyProvider(provider);\n setHierarchyProvider(provider);\n return () => {\n removeHierarchyChangedListener();\n actions.reset();\n safeDispose(provider);\n };\n }, [actions, getHierarchyProvider]);\n\n const [isFiltering, setIsFiltering] = useState(false);\n useEffect(() => {\n let disposed = false;\n void (async () => {\n if (!hierarchyProvider) {\n return;\n }\n\n if (!getFilteredPaths) {\n hierarchyProvider.setHierarchyFilter(undefined);\n // reload tree in case hierarchy provider does not use hierarchy filter to load initial nodes\n actions.reloadTree({ state: \"keep\" });\n setIsFiltering(false);\n return;\n }\n\n setIsFiltering(true);\n let paths: HierarchyFilteringPath[] | undefined;\n try {\n paths = await getFilteredPaths();\n } catch {\n } finally {\n if (!disposed) {\n hierarchyProvider.setHierarchyFilter(paths ? { paths } : undefined);\n setIsFiltering(false);\n }\n }\n })();\n return () => {\n disposed = true;\n };\n }, [hierarchyProvider, getFilteredPaths, actions]);\n\n const getTreeModelNode = useCallback<(nodeId: string) => TreeModelRootNode | TreeModelNode | undefined>(\n (nodeId: string) => {\n return actions.getNode(nodeId);\n },\n [actions],\n );\n\n const getNode = useCallback(\n (nodeId: string): PresentationHierarchyNode | undefined => {\n const node = actions.getNode(nodeId);\n if (!node || !isTreeModelHierarchyNode(node)) {\n return undefined;\n }\n return createPresentationHierarchyNode(node, state.model);\n },\n [actions, state.model],\n );\n\n const expandNode = useCallback<UseTreeResult[\"expandNode\"]>(\n (nodeId: string, isExpanded: boolean) => {\n actions.expandNode(nodeId, isExpanded);\n },\n [actions],\n );\n\n const reloadTree = useCallback<UseTreeResult[\"reloadTree\"]>(\n (options) => {\n actions.reloadTree(options);\n },\n [actions],\n );\n\n const selectNodes = useCallback<UseTreeResult[\"selectNodes\"]>(\n (nodeIds: Array<string>, changeType: SelectionChangeType) => {\n actions.selectNodes(nodeIds, changeType);\n },\n [actions],\n );\n\n const isNodeSelected = useCallback<UseTreeResult[\"isNodeSelected\"]>((nodeId: string) => TreeModel.isNodeSelected(state.model, nodeId), [state]);\n\n const setFormatter = useCallback<UseTreeResult[\"setFormatter\"]>(\n (formatter: IPrimitiveValueFormatter | undefined) => {\n currentFormatter.current = formatter;\n /* c8 ignore next 3 */\n if (!hierarchyProvider) {\n return;\n }\n\n hierarchyProvider.setFormatter(formatter);\n },\n [hierarchyProvider],\n );\n\n const getHierarchyLevelDetails = useCallback<UseTreeResult[\"getHierarchyLevelDetails\"]>(\n (nodeId) => {\n const node = actions.getNode(nodeId);\n if (!hierarchyProvider || !node || isTreeModelInfoNode(node)) {\n return undefined;\n }\n const hierarchyNode = node.nodeData;\n if (hierarchyNode && HierarchyNode.isGroupingNode(hierarchyNode)) {\n return undefined;\n }\n\n return {\n hierarchyNode,\n getInstanceKeysIterator: (props) =>\n hierarchyProvider.getNodeInstanceKeys({\n parentNode: hierarchyNode,\n instanceFilter: props?.instanceFilter,\n hierarchyLevelSizeLimit: props?.hierarchyLevelSizeLimit,\n }),\n instanceFilter: node.instanceFilter,\n setInstanceFilter: (filter) => actions.setInstanceFilter(nodeId, filter),\n sizeLimit: node.hierarchyLimit,\n setSizeLimit: (value) => actions.setHierarchyLimit(nodeId, value),\n };\n },\n [actions, hierarchyProvider],\n );\n\n return {\n rootNodes: state.rootNodes,\n isLoading: !!state.model.rootNode.isLoading || isFiltering,\n expandNode,\n reloadTree,\n selectNodes,\n isNodeSelected,\n getTreeModelNode,\n getNode,\n getHierarchyLevelDetails,\n setFormatter,\n };\n}\n\nfunction generateTreeStructure(parentNodeId: string | undefined, model: TreeModel): Array<PresentationTreeNode> | undefined {\n const currentChildren = model.parentChildMap.get(parentNodeId);\n if (!currentChildren) {\n return undefined;\n }\n\n return currentChildren\n .map((childId) => model.idToNode.get(childId))\n .filter((node): node is TreeModelNode => !!node)\n .map<PresentationTreeNode>((node) => {\n if (isTreeModelHierarchyNode(node)) {\n return createPresentationHierarchyNode(node, model);\n }\n\n if (node.type === \"ResultSetTooLarge\") {\n return {\n id: node.id,\n parentNodeId,\n type: node.type,\n resultSetSizeLimit: node.resultSetSizeLimit,\n };\n }\n\n if (node.type === \"NoFilterMatches\") {\n return {\n id: node.id,\n parentNodeId,\n type: node.type,\n };\n }\n\n return {\n id: node.id,\n parentNodeId,\n type: node.type,\n message: node.message,\n };\n });\n}\n\nfunction createPresentationHierarchyNode(modelNode: TreeModelHierarchyNode, model: TreeModel): PresentationHierarchyNode {\n let children: Array<PresentationTreeNode> | undefined;\n return {\n ...toPresentationHierarchyNodeBase(modelNode),\n get children() {\n if (!children) {\n children = generateTreeStructure(modelNode.id, model);\n }\n return children ? children : modelNode.children === true ? true : [];\n },\n };\n}\n\nfunction toPresentationHierarchyNodeBase(node: TreeModelHierarchyNode): Omit<PresentationHierarchyNode, \"children\"> {\n return {\n id: node.id,\n label: node.label,\n nodeData: node.nodeData,\n isLoading: !!node.isLoading,\n isExpanded: !!node.isExpanded,\n isFilterable: !HierarchyNode.isGroupingNode(node.nodeData) && !!node.nodeData.supportsFiltering && node.children,\n isFiltered: !!node.instanceFilter,\n extendedData: node.nodeData.extendedData,\n };\n}\n\nfunction useLatest<T>(value: T) {\n const ref = useRef(value);\n useEffect(() => {\n ref.current = value;\n }, [value]);\n\n return ref;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"UseTree.js","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/UseTree.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { GenericInstanceFilter, HierarchyFilteringPath, HierarchyNode, HierarchyProvider } from \"@itwin/presentation-hierarchies\";\nimport { InstanceKey, IPrimitiveValueFormatter } from \"@itwin/presentation-shared\";\nimport { TreeActions } from \"./internal/TreeActions.js\";\nimport { isTreeModelHierarchyNode, isTreeModelInfoNode, TreeModel, TreeModelHierarchyNode, TreeModelNode, TreeModelRootNode } from \"./internal/TreeModel.js\";\nimport { useUnifiedTreeSelection, UseUnifiedTreeSelectionProps } from \"./internal/UseUnifiedSelection.js\";\nimport { safeDispose } from \"./internal/Utils.js\";\nimport { PresentationHierarchyNode, PresentationTreeNode } from \"./TreeNode.js\";\nimport { SelectionChangeType } from \"./UseSelectionHandler.js\";\nimport { useLatest } from \"./Utils.js\";\n\n/**\n * A data structure that contains information about a single hierarchy level.\n * @public\n */\nexport interface HierarchyLevelDetails {\n /** The parent node whose hierarchy level's information is contained in this data structure */\n hierarchyNode: HierarchyNode | undefined;\n\n /** A function to get instance keys of the hierarchy level. */\n getInstanceKeysIterator: (props?: {\n instanceFilter?: GenericInstanceFilter;\n hierarchyLevelSizeLimit?: number | \"unbounded\";\n }) => AsyncIterableIterator<InstanceKey>;\n\n /** Get the limit of how many nodes can be loaded in this hierarchy level. */\n sizeLimit?: number | \"unbounded\";\n /** Set the limit of how many nodes can be loaded in this hierarchy level. */\n setSizeLimit: (value: undefined | number | \"unbounded\") => void;\n\n /** Get the active instance filter applied to this hierarchy level. */\n instanceFilter?: GenericInstanceFilter;\n /** Set the instance filter to apply to this hierarchy level */\n setInstanceFilter: (filter: GenericInstanceFilter | undefined) => void;\n}\n\n/**\n * A React hook that creates state for a tree component.\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useUnifiedSelectionTree`\n * @see `useIModelTree`\n * @public\n */\nexport function useTree(props: UseTreeProps): UseTreeResult {\n const { getTreeModelNode: _, ...rest } = useTreeInternal(props);\n return rest;\n}\n\n/**\n * A React hook that creates state for a tree component, that is integrated with unified selection\n * through the given selection storage (previously the storage was provided through the, now\n * deprecated, `UnifiedSelectionProvider`).\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useTree`\n * @see `useIModelUnifiedSelectionTree`\n * @see `UnifiedSelectionProvider`\n * @public\n */\nexport function useUnifiedSelectionTree({ sourceName, selectionStorage, ...props }: UseTreeProps & UseUnifiedTreeSelectionProps): UseTreeResult {\n const { getTreeModelNode, ...rest } = useTreeInternal(props);\n return {\n ...rest,\n ...useUnifiedTreeSelection({ sourceName, selectionStorage, getTreeModelNode }),\n };\n}\n\n/** @public */\nexport interface UseTreeProps {\n /** Provides the hierarchy provider for the tree. */\n getHierarchyProvider: () => HierarchyProvider;\n /** Provides paths to filtered nodes. */\n getFilteredPaths?: () => Promise<HierarchyFilteringPath[] | undefined>;\n /**\n * Callback that is called just after a certain action is finished.\n * Can be used for performance tracking.\n */\n onPerformanceMeasured?: (action: \"initial-load\" | \"hierarchy-level-load\" | \"reload\", duration: number) => void;\n /** Action to perform when hierarchy level contains more items that the specified limit. */\n onHierarchyLimitExceeded?: (props: { parentId?: string; filter?: GenericInstanceFilter; limit?: number | \"unbounded\" }) => void;\n /** Action to perform when an error occurs while loading hierarchy. */\n onHierarchyLoadError?: (props: { parentId?: string; type: \"timeout\" | \"unknown\"; error: unknown }) => void;\n}\n\n/**\n * Options for doing either full or a sub tree reload.\n * @public\n */\ninterface ReloadTreeOptions {\n /** Specifies parent node under which sub tree should be reloaded. */\n parentNodeId: string | undefined;\n\n /**\n * Specifies how current tree state should be handled:\n * - `keep` - try to keep current tree state (expanded/collapsed nodes, instance filters, etc.).\n * - `discard` - do not try to keep current tree state. Tree model will be update after nodes are reloaded.\n * - `reset` - remove subtree from the model before reloading and reload nodes ignoring cache.\n *\n * Defaults to `\"keep\"`.\n */\n state?: \"keep\" | \"discard\" | \"reset\";\n}\n\n/** @public */\nexport interface UseTreeResult {\n /**\n * Array containing root tree nodes. It is `undefined` on initial render until any nodes are loaded.\n */\n rootNodes: PresentationTreeNode[] | undefined;\n /**\n * Specifies whether tree is loading or not. It is set to `true` when initial tree load is in progress\n * or tree is reloading.\n */\n isLoading: boolean;\n /**\n * A function that should be called to reload the tree.\n */\n reloadTree: (options?: ReloadTreeOptions) => void;\n /**\n * A function that should be called to either expand or collapse the given node.\n */\n expandNode: (nodeId: string, isExpanded: boolean) => void;\n /**\n * A function that should be called to select nodes in the tree.\n * @param nodeIds Ids of the nodes that are selected.\n * @param changeType Type of change that occurred for the selection.\n */\n selectNodes: (nodeIds: Array<string>, changeType: SelectionChangeType) => void;\n /** Determines whether a given node is selected. */\n isNodeSelected: (nodeId: string) => boolean;\n /** Get a tree node by id */\n getNode: (nodeId: string) => PresentationHierarchyNode | undefined;\n /** Returns hierarchy level details for a given node ID. */\n getHierarchyLevelDetails: (nodeId: string | undefined) => HierarchyLevelDetails | undefined;\n /** Sets a formatter for the primitive values that are displayed in the hierarchy. */\n setFormatter: (formatter: IPrimitiveValueFormatter | undefined) => void;\n}\n\ninterface TreeState {\n model: TreeModel;\n rootNodes: Array<PresentationTreeNode> | undefined;\n}\n\nfunction useTreeInternal({\n getHierarchyProvider,\n getFilteredPaths,\n onPerformanceMeasured,\n onHierarchyLimitExceeded,\n onHierarchyLoadError,\n}: UseTreeProps): UseTreeResult & {\n getTreeModelNode: (nodeId: string) => TreeModelRootNode | TreeModelNode | undefined;\n} {\n const [state, setState] = useState<TreeState>({\n model: { idToNode: new Map(), parentChildMap: new Map(), rootNode: { id: undefined, nodeData: undefined } },\n rootNodes: undefined,\n });\n const onPerformanceMeasuredRef = useLatest(onPerformanceMeasured);\n const onHierarchyLimitExceededRef = useLatest(onHierarchyLimitExceeded);\n const onHierarchyLoadErrorRef = useLatest(onHierarchyLoadError);\n\n const [actions] = useState<TreeActions>(\n () =>\n new TreeActions(\n (model) => {\n const rootNodes = model.parentChildMap.get(undefined) !== undefined ? generateTreeStructure(undefined, model) : undefined;\n setState({\n model,\n rootNodes,\n });\n },\n (actionType, duration) => onPerformanceMeasuredRef.current?.(actionType, duration),\n (props) => onHierarchyLimitExceededRef.current?.(props),\n (props) => onHierarchyLoadErrorRef.current?.(props),\n ),\n );\n const currentFormatter = useRef<IPrimitiveValueFormatter>();\n\n const [hierarchyProvider, setHierarchyProvider] = useState<HierarchyProvider | undefined>();\n useEffect(() => {\n const provider = getHierarchyProvider();\n provider.setFormatter(currentFormatter.current);\n const removeHierarchyChangedListener = provider.hierarchyChanged.addListener((hierarchyChangeArgs) => {\n const shouldDiscardState = hierarchyChangeArgs?.filterChange?.newFilter !== undefined;\n actions.reloadTree({ state: shouldDiscardState ? \"discard\" : \"keep\" });\n });\n actions.setHierarchyProvider(provider);\n setHierarchyProvider(provider);\n return () => {\n removeHierarchyChangedListener();\n actions.reset();\n safeDispose(provider);\n };\n }, [actions, getHierarchyProvider]);\n\n const [isFiltering, setIsFiltering] = useState(false);\n useEffect(() => {\n let disposed = false;\n void (async () => {\n if (!hierarchyProvider) {\n return;\n }\n\n if (!getFilteredPaths) {\n hierarchyProvider.setHierarchyFilter(undefined);\n // reload tree in case hierarchy provider does not use hierarchy filter to load initial nodes\n actions.reloadTree({ state: \"keep\" });\n setIsFiltering(false);\n return;\n }\n\n setIsFiltering(true);\n let paths: HierarchyFilteringPath[] | undefined;\n try {\n paths = await getFilteredPaths();\n } catch {\n } finally {\n if (!disposed) {\n hierarchyProvider.setHierarchyFilter(paths ? { paths } : undefined);\n setIsFiltering(false);\n }\n }\n })();\n return () => {\n disposed = true;\n };\n }, [hierarchyProvider, getFilteredPaths, actions]);\n\n const getTreeModelNode = useCallback<(nodeId: string) => TreeModelRootNode | TreeModelNode | undefined>(\n (nodeId: string) => {\n return actions.getNode(nodeId);\n },\n [actions],\n );\n\n const getNode = useCallback(\n (nodeId: string): PresentationHierarchyNode | undefined => {\n const node = actions.getNode(nodeId);\n if (!node || !isTreeModelHierarchyNode(node)) {\n return undefined;\n }\n return createPresentationHierarchyNode(node, state.model);\n },\n [actions, state.model],\n );\n\n const expandNode = useCallback<UseTreeResult[\"expandNode\"]>(\n (nodeId: string, isExpanded: boolean) => {\n actions.expandNode(nodeId, isExpanded);\n },\n [actions],\n );\n\n const reloadTree = useCallback<UseTreeResult[\"reloadTree\"]>(\n (options) => {\n actions.reloadTree(options);\n },\n [actions],\n );\n\n const selectNodes = useCallback<UseTreeResult[\"selectNodes\"]>(\n (nodeIds: Array<string>, changeType: SelectionChangeType) => {\n actions.selectNodes(nodeIds, changeType);\n },\n [actions],\n );\n\n const isNodeSelected = useCallback<UseTreeResult[\"isNodeSelected\"]>((nodeId: string) => TreeModel.isNodeSelected(state.model, nodeId), [state]);\n\n const setFormatter = useCallback<UseTreeResult[\"setFormatter\"]>(\n (formatter: IPrimitiveValueFormatter | undefined) => {\n currentFormatter.current = formatter;\n /* c8 ignore next 3 */\n if (!hierarchyProvider) {\n return;\n }\n\n hierarchyProvider.setFormatter(formatter);\n },\n [hierarchyProvider],\n );\n\n const getHierarchyLevelDetails = useCallback<UseTreeResult[\"getHierarchyLevelDetails\"]>(\n (nodeId) => {\n const node = actions.getNode(nodeId);\n if (!hierarchyProvider || !node || isTreeModelInfoNode(node)) {\n return undefined;\n }\n const hierarchyNode = node.nodeData;\n if (hierarchyNode && HierarchyNode.isGroupingNode(hierarchyNode)) {\n return undefined;\n }\n\n return {\n hierarchyNode,\n getInstanceKeysIterator: (props) =>\n hierarchyProvider.getNodeInstanceKeys({\n parentNode: hierarchyNode,\n instanceFilter: props?.instanceFilter,\n hierarchyLevelSizeLimit: props?.hierarchyLevelSizeLimit,\n }),\n instanceFilter: node.instanceFilter,\n setInstanceFilter: (filter) => actions.setInstanceFilter(nodeId, filter),\n sizeLimit: node.hierarchyLimit,\n setSizeLimit: (value) => actions.setHierarchyLimit(nodeId, value),\n };\n },\n [actions, hierarchyProvider],\n );\n\n return {\n rootNodes: state.rootNodes,\n isLoading: !!state.model.rootNode.isLoading || isFiltering,\n expandNode,\n reloadTree,\n selectNodes,\n isNodeSelected,\n getTreeModelNode,\n getNode,\n getHierarchyLevelDetails,\n setFormatter,\n };\n}\n\nfunction generateTreeStructure(parentNodeId: string | undefined, model: TreeModel): Array<PresentationTreeNode> | undefined {\n const currentChildren = model.parentChildMap.get(parentNodeId);\n if (!currentChildren) {\n return undefined;\n }\n\n return currentChildren\n .map((childId) => model.idToNode.get(childId))\n .filter((node): node is TreeModelNode => !!node)\n .map<PresentationTreeNode>((node) => {\n if (isTreeModelHierarchyNode(node)) {\n return createPresentationHierarchyNode(node, model);\n }\n\n if (node.type === \"ResultSetTooLarge\") {\n return {\n id: node.id,\n parentNodeId,\n type: node.type,\n resultSetSizeLimit: node.resultSetSizeLimit,\n };\n }\n\n if (node.type === \"NoFilterMatches\") {\n return {\n id: node.id,\n parentNodeId,\n type: node.type,\n };\n }\n\n return {\n id: node.id,\n parentNodeId,\n type: node.type,\n message: node.message,\n };\n });\n}\n\nfunction createPresentationHierarchyNode(modelNode: TreeModelHierarchyNode, model: TreeModel): PresentationHierarchyNode {\n let children: Array<PresentationTreeNode> | undefined;\n return {\n ...toPresentationHierarchyNodeBase(modelNode),\n get children() {\n if (!children) {\n children = generateTreeStructure(modelNode.id, model);\n }\n return children ? children : modelNode.children === true ? true : [];\n },\n };\n}\n\nfunction toPresentationHierarchyNodeBase(node: TreeModelHierarchyNode): Omit<PresentationHierarchyNode, \"children\"> {\n return {\n id: node.id,\n label: node.label,\n nodeData: node.nodeData,\n isLoading: !!node.isLoading,\n isExpanded: !!node.isExpanded,\n isFilterable: !HierarchyNode.isGroupingNode(node.nodeData) && !!node.nodeData.supportsFiltering && node.children,\n isFiltered: !!node.instanceFilter,\n extendedData: node.nodeData.extendedData,\n };\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** @internal */
|
|
2
|
+
export declare function useLatest<T>(value: T): import("react").MutableRefObject<T>;
|
|
3
|
+
/** @internal */
|
|
4
|
+
export declare function useEvent<TCallback extends (...args: any[]) => void>(callback: TCallback): (...args: Parameters<TCallback>) => void;
|
|
5
|
+
//# sourceMappingURL=Utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Utils.d.ts","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/Utils.ts"],"names":[],"mappings":"AAOA,gBAAgB;AAChB,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,uCAQpC;AAGD,gBAAgB;AAChB,wBAAgB,QAAQ,CAAC,SAAS,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,QAAQ,EAAE,SAAS,aAI1E,UAAU,CAAC,SAAS,CAAC,UAKlC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { useCallback, useInsertionEffect, useRef } from "react";
|
|
6
|
+
/** @internal */
|
|
7
|
+
export function useLatest(value) {
|
|
8
|
+
const ref = useRef(value);
|
|
9
|
+
useInsertionEffect(() => {
|
|
10
|
+
ref.current = value;
|
|
11
|
+
}, [value]);
|
|
12
|
+
return ref;
|
|
13
|
+
}
|
|
14
|
+
/* c8 ignore start */
|
|
15
|
+
/** @internal */
|
|
16
|
+
export function useEvent(callback) {
|
|
17
|
+
const latestCallback = useLatest(callback);
|
|
18
|
+
return useCallback((...args) => {
|
|
19
|
+
latestCallback.current(...args);
|
|
20
|
+
}, [latestCallback]);
|
|
21
|
+
}
|
|
22
|
+
/* c8 ignore end */
|
|
23
|
+
//# sourceMappingURL=Utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/Utils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAEhE,gBAAgB;AAChB,MAAM,UAAU,SAAS,CAAI,KAAQ;IACnC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE1B,kBAAkB,CAAC,GAAG,EAAE;QACtB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qBAAqB;AACrB,gBAAgB;AAChB,MAAM,UAAU,QAAQ,CAA6C,QAAmB;IACtF,MAAM,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE3C,OAAO,WAAW,CAChB,CAAC,GAAG,IAA2B,EAAE,EAAE;QACjC,cAAc,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAClC,CAAC,EACD,CAAC,cAAc,CAAC,CACjB,CAAC;AACJ,CAAC;AACD,mBAAmB","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useCallback, useInsertionEffect, useRef } from \"react\";\n\n/** @internal */\nexport function useLatest<T>(value: T) {\n const ref = useRef(value);\n\n useInsertionEffect(() => {\n ref.current = value;\n }, [value]);\n\n return ref;\n}\n\n/* c8 ignore start */\n/** @internal */\nexport function useEvent<TCallback extends (...args: any[]) => void>(callback: TCallback) {\n const latestCallback = useLatest(callback);\n\n return useCallback(\n (...args: Parameters<TCallback>) => {\n latestCallback.current(...args);\n },\n [latestCallback],\n );\n}\n/* c8 ignore end */\n"]}
|
|
@@ -26,7 +26,7 @@ export interface LocalizedStrings {
|
|
|
26
26
|
clearHierarchyLevelFilter: string;
|
|
27
27
|
/**
|
|
28
28
|
* Message displayed when no nodes matching filter are found.
|
|
29
|
-
* Default value: `No matches for current filter for {{node}}
|
|
29
|
+
* Default value: `No matches for current filter for {{node}}.`.
|
|
30
30
|
*/
|
|
31
31
|
noFilteredChildren: string;
|
|
32
32
|
/**
|
|
@@ -36,12 +36,12 @@ export interface LocalizedStrings {
|
|
|
36
36
|
noFilteredChildrenChangeFilter: string;
|
|
37
37
|
/**
|
|
38
38
|
* Message displayed when hierarchy creation for a node failed.
|
|
39
|
-
* Default value: `Failed to create hierarchy for {{node}}
|
|
39
|
+
* Default value: `Failed to create hierarchy for {{node}}.`.
|
|
40
40
|
*/
|
|
41
41
|
failedToCreateHierarchy: string;
|
|
42
42
|
/**
|
|
43
43
|
* Message displayed when result limit exceeds hierarchy size limit.
|
|
44
|
-
* Default value: `The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit
|
|
44
|
+
* Default value: `The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit.`.
|
|
45
45
|
*/
|
|
46
46
|
resultLimitExceeded: string;
|
|
47
47
|
/**
|
|
@@ -9,10 +9,10 @@ const defaultLocalizedStrings = {
|
|
|
9
9
|
filterHierarchyLevel: "Apply filter",
|
|
10
10
|
filterHierarchyLevelActiveDescription: "Filter is applied",
|
|
11
11
|
clearHierarchyLevelFilter: "Clear active filter",
|
|
12
|
-
noFilteredChildren: "No matches for current filter for {{node}}",
|
|
12
|
+
noFilteredChildren: "No matches for current filter for {{node}}.",
|
|
13
13
|
noFilteredChildrenChangeFilter: "Change filter",
|
|
14
|
-
failedToCreateHierarchy: "Failed to create hierarchy for {{node}}",
|
|
15
|
-
resultLimitExceeded: "The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit",
|
|
14
|
+
failedToCreateHierarchy: "Failed to create hierarchy for {{node}}.",
|
|
15
|
+
resultLimitExceeded: "The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit.",
|
|
16
16
|
issuesFound: "issues found",
|
|
17
17
|
increaseHierarchyLimit: "Increase limit to {{limit}}",
|
|
18
18
|
increaseHierarchyLimitWithFiltering: "Add Filter",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalizationContext.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/LocalizationContext.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,aAAa,EAAqB,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AA0E1F,MAAM,uBAAuB,GAAqB;IAChD,OAAO,EAAE,YAAY;IACrB,oBAAoB,EAAE,cAAc;IACpC,qCAAqC,EAAE,mBAAmB;IAC1D,yBAAyB,EAAE,qBAAqB;IAChD,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"LocalizationContext.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/LocalizationContext.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,aAAa,EAAqB,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AA0E1F,MAAM,uBAAuB,GAAqB;IAChD,OAAO,EAAE,YAAY;IACrB,oBAAoB,EAAE,cAAc;IACpC,qCAAqC,EAAE,mBAAmB;IAC1D,yBAAyB,EAAE,qBAAqB;IAChD,kBAAkB,EAAE,6CAA6C;IACjE,8BAA8B,EAAE,eAAe;IAC/C,uBAAuB,EAAE,0CAA0C;IACnE,mBAAmB,EAAE,gGAAgG;IACrH,WAAW,EAAE,cAAc;IAC3B,sBAAsB,EAAE,6BAA6B;IACrD,mCAAmC,EAAE,YAAY;IACjD,KAAK,EAAE,OAAO;CACf,CAAC;AAEF,MAAM,mBAAmB,GAAG,aAAa,CAAsB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAW9G;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAuD;IAC7H,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,gBAAgB,EAAE,EAAE,GAAG,uBAAuB,EAAE,GAAG,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAE9G,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,EAAE,gBAAgB,EAAE,EAAE,GAAG,uBAAuB,EAAE,GAAG,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,OAAO,KAAC,mBAAmB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAgC,CAAC;AAC/F,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,sBAAsB;IACpC,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAC;AACzC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { createContext, PropsWithChildren, useContext, useEffect, useState } from \"react\";\n\n/**\n * Localized strings used in the components.\n * @public\n */\nexport interface LocalizedStrings {\n /**\n * Message displayed when nodes are loading.\n * Default value: `Loading...`.\n */\n loading: string;\n /**\n * Title for apply hierarchy filter button.\n * Default value: `Apply filter`.\n */\n filterHierarchyLevel: string;\n /**\n * Accesible description for applied hierarchy filter button.\n * Default value: `Filter is applied`.\n */\n filterHierarchyLevelActiveDescription: string;\n /**\n * Title for clear hierarchy filter button.\n * Default value: `Clear active filter`.\n */\n clearHierarchyLevelFilter: string;\n /**\n * Message displayed when no nodes matching filter are found.\n * Default value: `No matches for current filter for {{node}}.`.\n */\n noFilteredChildren: string;\n /**\n * Label for change filter action.\n * Default value: `Change filter`.\n */\n noFilteredChildrenChangeFilter: string;\n /**\n * Message displayed when hierarchy creation for a node failed.\n * Default value: `Failed to create hierarchy for {{node}}.`.\n */\n failedToCreateHierarchy: string;\n /**\n * Message displayed when result limit exceeds hierarchy size limit.\n * Default value: `The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit.`.\n */\n resultLimitExceeded: string;\n /**\n * Label displayed on error dropdown.\n * Default value: `issues found`.\n */\n issuesFound: string;\n /**\n * Message displayed when hierarchy size limit can be overridden.\n * Default value: `Increase limit to {{limit}}`.\n */\n increaseHierarchyLimit: string;\n /**\n * Message displayed when hierarchy size limit can be overridden and hierarchy filtering is enabled.\n * Default value: `Add Filter`.\n */\n increaseHierarchyLimitWithFiltering: string;\n /**\n * Label for retry action.\n * Default value: `Retry`.\n */\n retry: string;\n}\n\n/** @internal */\nexport interface LocalizationContext {\n localizedStrings: LocalizedStrings;\n}\n\nconst defaultLocalizedStrings: LocalizedStrings = {\n loading: \"Loading...\",\n filterHierarchyLevel: \"Apply filter\",\n filterHierarchyLevelActiveDescription: \"Filter is applied\",\n clearHierarchyLevelFilter: \"Clear active filter\",\n noFilteredChildren: \"No matches for current filter for {{node}}.\",\n noFilteredChildrenChangeFilter: \"Change filter\",\n failedToCreateHierarchy: \"Failed to create hierarchy for {{node}}.\",\n resultLimitExceeded: \"The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit.\",\n issuesFound: \"issues found\",\n increaseHierarchyLimit: \"Increase limit to {{limit}}\",\n increaseHierarchyLimitWithFiltering: \"Add Filter\",\n retry: \"Retry\",\n};\n\nconst localizationContext = createContext<LocalizationContext>({ localizedStrings: defaultLocalizedStrings });\n\n/**\n * Properties for `LocalizationContextProvider`.\n * @public\n */\ninterface LocalizationContextProviderProps {\n /** Localized strings used in the components. */\n localizedStrings?: Partial<LocalizedStrings>;\n}\n\n/**\n * Context provider for localized strings used in the components.\n * @public\n */\nexport function LocalizationContextProvider({ localizedStrings, children }: PropsWithChildren<LocalizationContextProviderProps>) {\n const [state, setState] = useState({ localizedStrings: { ...defaultLocalizedStrings, ...localizedStrings } });\n\n useEffect(() => {\n setState({ localizedStrings: { ...defaultLocalizedStrings, ...localizedStrings } });\n }, [localizedStrings]);\n\n return <localizationContext.Provider value={state}>{children}</localizationContext.Provider>;\n}\n\n/** @internal */\nexport function useLocalizationContext() {\n return useContext(localizationContext);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeActionButton.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeActionButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TreeActionButton.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeActionButton.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAK/D,aAAa;AACb,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,aAAa;AACb,MAAM,MAAM,iBAAiB,GAAG;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACnE,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC;AAE1E,gBAAgB;AAChB,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,cAAc,2CAEhG;AAED,aAAa;AACb,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE,EAAE,iBAAiB,GAAG,CAAC,IAAI,EAAE,yBAAyB,KAAK,cAAc,CA4B9I"}
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
4
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
5
|
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
import { useCallback } from "react";
|
|
6
7
|
import { Tree } from "@itwin/itwinui-react/bricks";
|
|
7
8
|
import { useLocalizationContext } from "./LocalizationContext.js";
|
|
8
9
|
const filterSvg = new URL("@itwin/itwinui-icons/filter.svg", import.meta.url).href;
|
|
@@ -13,7 +14,8 @@ export function TreeActionButton({ show, label, action, icon, activeDescription
|
|
|
13
14
|
/** @alpha */
|
|
14
15
|
export function useFilterAction({ onFilter, getHierarchyLevelDetails }) {
|
|
15
16
|
const { localizedStrings } = useLocalizationContext();
|
|
16
|
-
|
|
17
|
+
const { filterHierarchyLevel, filterHierarchyLevelActiveDescription } = localizedStrings;
|
|
18
|
+
return useCallback((node) => {
|
|
17
19
|
const handleVisibility = () => {
|
|
18
20
|
if (!onFilter || !node.isFilterable) {
|
|
19
21
|
return false;
|
|
@@ -24,15 +26,15 @@ export function useFilterAction({ onFilter, getHierarchyLevelDetails }) {
|
|
|
24
26
|
return undefined;
|
|
25
27
|
};
|
|
26
28
|
return {
|
|
27
|
-
label:
|
|
29
|
+
label: filterHierarchyLevel,
|
|
28
30
|
action: () => {
|
|
29
31
|
const hierarchyLevelDetails = getHierarchyLevelDetails?.(node.id);
|
|
30
32
|
hierarchyLevelDetails && onFilter?.(hierarchyLevelDetails);
|
|
31
33
|
},
|
|
32
34
|
show: handleVisibility(),
|
|
33
|
-
activeDescription: node.isFiltered ?
|
|
35
|
+
activeDescription: node.isFiltered ? filterHierarchyLevelActiveDescription : undefined,
|
|
34
36
|
icon: filterSvg,
|
|
35
37
|
};
|
|
36
|
-
};
|
|
38
|
+
}, [filterHierarchyLevel, filterHierarchyLevelActiveDescription, onFilter, getHierarchyLevelDetails]);
|
|
37
39
|
}
|
|
38
40
|
//# sourceMappingURL=TreeActionButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeActionButton.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeActionButton.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAGnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,iCAAiC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AA4BnF,gBAAgB;AAChB,MAAM,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAkB;IAC/F,OAAO,KAAC,IAAI,CAAC,UAAU,IAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAI,CAAC;AAC/G,CAAC;AAED,aAAa;AACb,MAAM,UAAU,eAAe,CAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAqB;IACvF,MAAM,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACtD,OAAO,CAAC,IAAI,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"TreeActionButton.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeActionButton.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAGnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,iCAAiC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AA4BnF,gBAAgB;AAChB,MAAM,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAkB;IAC/F,OAAO,KAAC,IAAI,CAAC,UAAU,IAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAI,CAAC;AAC/G,CAAC;AAED,aAAa;AACb,MAAM,UAAU,eAAe,CAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAqB;IACvF,MAAM,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACtD,MAAM,EAAE,oBAAoB,EAAE,qCAAqC,EAAE,GAAG,gBAAgB,CAAC;IACzF,OAAO,WAAW,CAChB,CAAC,IAAI,EAAE,EAAE;QACP,MAAM,gBAAgB,GAAG,GAAG,EAAE;YAC5B,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,OAAO;YACL,KAAK,EAAE,oBAAoB;YAC3B,MAAM,EAAE,GAAG,EAAE;gBACX,MAAM,qBAAqB,GAAG,wBAAwB,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAClE,qBAAqB,IAAI,QAAQ,EAAE,CAAC,qBAAqB,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,EAAE,gBAAgB,EAAE;YACxB,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,SAAS;YACtF,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC,EACD,CAAC,oBAAoB,EAAE,qCAAqC,EAAE,QAAQ,EAAE,wBAAwB,CAAC,CAClG,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useCallback } from \"react\";\nimport { Tree } from \"@itwin/itwinui-react/bricks\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { HierarchyLevelDetails, useTree } from \"../UseTree.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\n\nconst filterSvg = new URL(\"@itwin/itwinui-icons/filter.svg\", import.meta.url).href;\n\n/** @alpha */\nexport interface TreeItemAction {\n label: string;\n action: () => void;\n icon: string;\n /**\n * Determines action items visibility:\n * - `False` - action item is hidden.\n * - `True` - action item is visible at all times.\n * - `Undefined` - action item is visible on hover/focus.\n */\n show?: boolean;\n /**\n * Provide a value when action button is in active state to display a dot above the button.\n * Provided text value is used to set accessible description it should descibe why the action is in active state.\n * If left undefined the action item will be rendered normally.\n */\n activeDescription?: string;\n}\n\n/** @alpha */\nexport type FilterActionProps = {\n /** Action to perform when the filter button is clicked for this node. */\n onFilter?: (hierarchyLevelDetails: HierarchyLevelDetails) => void;\n} & Partial<Pick<ReturnType<typeof useTree>, \"getHierarchyLevelDetails\">>;\n\n/** @internal */\nexport function TreeActionButton({ show, label, action, icon, activeDescription }: TreeItemAction) {\n return <Tree.ItemAction label={label} dot={activeDescription} icon={icon} visible={show} onClick={action} />;\n}\n\n/** @alpha */\nexport function useFilterAction({ onFilter, getHierarchyLevelDetails }: FilterActionProps): (node: PresentationHierarchyNode) => TreeItemAction {\n const { localizedStrings } = useLocalizationContext();\n const { filterHierarchyLevel, filterHierarchyLevelActiveDescription } = localizedStrings;\n return useCallback(\n (node) => {\n const handleVisibility = () => {\n if (!onFilter || !node.isFilterable) {\n return false;\n }\n if (node.isFiltered) {\n return true;\n }\n return undefined;\n };\n\n return {\n label: filterHierarchyLevel,\n action: () => {\n const hierarchyLevelDetails = getHierarchyLevelDetails?.(node.id);\n hierarchyLevelDetails && onFilter?.(hierarchyLevelDetails);\n },\n show: handleVisibility(),\n activeDescription: node.isFiltered ? filterHierarchyLevelActiveDescription : undefined,\n icon: filterSvg,\n };\n },\n [filterHierarchyLevel, filterHierarchyLevelActiveDescription, onFilter, getHierarchyLevelDetails],\n );\n}\n"]}
|
|
@@ -14,7 +14,7 @@ interface TreeErrorRendererOwnProps {
|
|
|
14
14
|
errorList: ErrorNode[];
|
|
15
15
|
}
|
|
16
16
|
type TreeErrorRendererProps = TreeErrorRendererOwnProps & TreeErrorItemProps & Partial<Pick<ReturnType<typeof useTree>, "getHierarchyLevelDetails">> & Pick<LinkedNodeProps, "scrollToElement">;
|
|
17
|
-
export declare function TreeErrorRenderer({ errorList, scrollToElement, getHierarchyLevelDetails, onFilterClick }: TreeErrorRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function TreeErrorRenderer({ errorList, reloadTree, scrollToElement, getHierarchyLevelDetails, onFilterClick }: TreeErrorRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
18
18
|
interface LinkedNodeProps {
|
|
19
19
|
errorNode: ErrorNode;
|
|
20
20
|
scrollToElement: (node: ErrorNode) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeErrorRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeErrorRenderer.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,aAAa;AACb,MAAM,WAAW,kBAAkB;IACjC,iGAAiG;IACjG,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACrF,yEAAyE;IACzE,aAAa,CAAC,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACxE;AAED,UAAU,yBAAyB;IACjC,SAAS,EAAE,SAAS,EAAE,CAAC;CACxB;AAED,KAAK,sBAAsB,GAAG,yBAAyB,GACrD,kBAAkB,GAClB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,EAAE,0BAA0B,CAAC,CAAC,GACrE,IAAI,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;AAE3C,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,wBAAwB,EAAE,aAAa,EAAE,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"TreeErrorRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeErrorRenderer.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,aAAa;AACb,MAAM,WAAW,kBAAkB;IACjC,iGAAiG;IACjG,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACrF,yEAAyE;IACzE,aAAa,CAAC,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACxE;AAED,UAAU,yBAAyB;IACjC,SAAS,EAAE,SAAS,EAAE,CAAC;CACxB;AAED,KAAK,sBAAsB,GAAG,yBAAyB,GACrD,kBAAkB,GAClB,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,EAAE,0BAA0B,CAAC,CAAC,GACrE,IAAI,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;AAE3C,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,wBAAwB,EAAE,aAAa,EAAE,EAAE,sBAAsB,2CAyC5I;AAqDD,UAAU,eAAe;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CAC5C"}
|
|
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
import { Anchor, unstable_ErrorRegion as ErrorRegion, Text } from "@itwin/itwinui-react/bricks";
|
|
7
7
|
import { MAX_LIMIT_OVERRIDE } from "../internal/Utils.js";
|
|
8
8
|
import { useLocalizationContext } from "./LocalizationContext.js";
|
|
9
|
-
export function TreeErrorRenderer({ errorList, scrollToElement, getHierarchyLevelDetails, onFilterClick }) {
|
|
9
|
+
export function TreeErrorRenderer({ errorList, reloadTree, scrollToElement, getHierarchyLevelDetails, onFilterClick }) {
|
|
10
10
|
const { localizedStrings } = useLocalizationContext();
|
|
11
11
|
const errorItems = errorList.map((errorNode) => {
|
|
12
12
|
if (errorNode.error.type === "ResultSetTooLarge") {
|
|
@@ -16,19 +16,22 @@ export function TreeErrorRenderer({ errorList, scrollToElement, getHierarchyLeve
|
|
|
16
16
|
}, onOverrideLimit: getHierarchyLevelDetails ? (limit) => getHierarchyLevelDetails(errorNode.parent?.id)?.setSizeLimit(limit) : undefined, scrollToElement: scrollToElement, limit: errorNode.error.resultSetSizeLimit, errorNode: errorNode }, errorNode.error.id));
|
|
17
17
|
}
|
|
18
18
|
if (errorNode.error.type === "NoFilterMatches") {
|
|
19
|
-
return _jsx(NoFilterMatches, { scrollToElement: scrollToElement,
|
|
19
|
+
return (_jsx(NoFilterMatches, { scrollToElement: scrollToElement, onFilterClick: () => {
|
|
20
|
+
const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.parent?.id);
|
|
21
|
+
hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);
|
|
22
|
+
}, errorNode: errorNode }, errorNode.error.id));
|
|
20
23
|
}
|
|
21
|
-
return _jsx(DefaultErrorContainer, { scrollToElement: scrollToElement, errorNode: errorNode }, errorNode.error.id);
|
|
24
|
+
return _jsx(DefaultErrorContainer, { scrollToElement: scrollToElement, reloadTree: reloadTree, errorNode: errorNode }, errorNode.error.id);
|
|
22
25
|
});
|
|
23
26
|
return (_jsx(ErrorRegion.Root, { style: { width: "100%" }, label: errorList.length !== 0 ? `${errorList.length} ${localizedStrings?.issuesFound}` : undefined, items: errorItems }));
|
|
24
27
|
}
|
|
25
28
|
function NoFilterMatches({ onFilterClick, errorNode, scrollToElement }) {
|
|
26
29
|
const { localizedStrings } = useLocalizationContext();
|
|
27
|
-
return (_jsx(ErrorRegion.Item, { message: _jsx(MessageWithNode, { errorNode: errorNode, scrollToElement: scrollToElement, message: localizedStrings.noFilteredChildren }), actions: _jsx(Anchor, { onClick:
|
|
30
|
+
return (_jsx(ErrorRegion.Item, { message: _jsx(MessageWithNode, { errorNode: errorNode, scrollToElement: scrollToElement, message: localizedStrings.noFilteredChildren }), actions: _jsx(Anchor, { onClick: onFilterClick, children: localizedStrings.noFilteredChildrenChangeFilter }) }));
|
|
28
31
|
}
|
|
29
32
|
function DefaultErrorContainer({ reloadTree, errorNode, scrollToElement }) {
|
|
30
33
|
const { localizedStrings } = useLocalizationContext();
|
|
31
|
-
return (_jsx(ErrorRegion.Item, { message: _jsx(MessageWithNode, { errorNode: errorNode, scrollToElement: scrollToElement, message: localizedStrings.failedToCreateHierarchy }), actions: _jsx(Anchor, { onClick: () => reloadTree, children: localizedStrings.retry }) }));
|
|
34
|
+
return (_jsx(ErrorRegion.Item, { message: _jsx(MessageWithNode, { errorNode: errorNode, scrollToElement: scrollToElement, message: localizedStrings.failedToCreateHierarchy }), actions: _jsx(Anchor, { onClick: () => reloadTree?.({ parentNodeId: errorNode.parent?.id, state: "reset" }), children: localizedStrings.retry }) }));
|
|
32
35
|
}
|
|
33
36
|
function ResultSetTooLarge({ errorNode, onFilterClick, limit, onOverrideLimit, scrollToElement }) {
|
|
34
37
|
const { localizedStrings } = useLocalizationContext();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeErrorRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeErrorRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Anchor, unstable_ErrorRegion as ErrorRegion, Text } from \"@itwin/itwinui-react/bricks\";\nimport { MAX_LIMIT_OVERRIDE } from \"../internal/Utils.js\";\nimport { HierarchyLevelDetails, useTree } from \"../UseTree.js\";\nimport { ErrorNode } from \"./FlatTreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\n\n/** @alpha */\nexport interface TreeErrorItemProps {\n /** A callback to reload a hierarchy level when an error occurs and `retry` button is clicked. */\n reloadTree?: (options: { parentNodeId: string | undefined; state: \"reset\" }) => void;\n /** Action to perform when the filter button is clicked for this node. */\n onFilterClick?: (hierarchyLevelDetails: HierarchyLevelDetails) => void;\n}\n\ninterface TreeErrorRendererOwnProps {\n errorList: ErrorNode[];\n}\n\ntype TreeErrorRendererProps = TreeErrorRendererOwnProps &\n TreeErrorItemProps &\n Partial<Pick<ReturnType<typeof useTree>, \"getHierarchyLevelDetails\">> &\n Pick<LinkedNodeProps, \"scrollToElement\">;\n\nexport function TreeErrorRenderer({ errorList, scrollToElement, getHierarchyLevelDetails, onFilterClick }: TreeErrorRendererProps) {\n const { localizedStrings } = useLocalizationContext();\n const errorItems = errorList.map((errorNode) => {\n if (errorNode.error.type === \"ResultSetTooLarge\") {\n return (\n <ResultSetTooLarge\n key={errorNode.error.id}\n onFilterClick={() => {\n const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.parent?.id);\n hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);\n }}\n onOverrideLimit={getHierarchyLevelDetails ? (limit) => getHierarchyLevelDetails(errorNode.parent?.id)?.setSizeLimit(limit) : undefined}\n scrollToElement={scrollToElement}\n limit={errorNode.error.resultSetSizeLimit}\n errorNode={errorNode}\n />\n );\n }\n if (errorNode.error.type === \"NoFilterMatches\") {\n return <NoFilterMatches key={errorNode.error.id} scrollToElement={scrollToElement} errorNode={errorNode} />;\n }\n return <DefaultErrorContainer key={errorNode.error.id} scrollToElement={scrollToElement} errorNode={errorNode} />;\n });\n\n return (\n <ErrorRegion.Root\n style={{ width: \"100%\" }}\n label={errorList.length !== 0 ? `${errorList.length} ${localizedStrings?.issuesFound}` : undefined}\n items={errorItems}\n />\n );\n}\n\nfunction NoFilterMatches({ onFilterClick, errorNode, scrollToElement }: LinkedNodeProps & Pick<TreeErrorItemProps, \"onFilterClick\">) {\n const { localizedStrings } = useLocalizationContext();\n\n return (\n <ErrorRegion.Item\n message={<MessageWithNode errorNode={errorNode} scrollToElement={scrollToElement} message={localizedStrings.noFilteredChildren} />}\n actions={<Anchor onClick={() => onFilterClick}>{localizedStrings.noFilteredChildrenChangeFilter}</Anchor>}\n />\n );\n}\n\nfunction DefaultErrorContainer({ reloadTree, errorNode, scrollToElement }: LinkedNodeProps & Pick<TreeErrorItemProps, \"reloadTree\">) {\n const { localizedStrings } = useLocalizationContext();\n\n return (\n <ErrorRegion.Item\n message={<MessageWithNode errorNode={errorNode} scrollToElement={scrollToElement} message={localizedStrings.failedToCreateHierarchy} />}\n actions={<Anchor onClick={() => reloadTree}>{localizedStrings.retry}</Anchor>}\n />\n );\n}\n\ntype ResultSetTooLargeProps = {\n limit: number;\n onFilterClick?: () => void;\n onOverrideLimit?: (limit: number) => void;\n} & LinkedNodeProps;\n\nfunction ResultSetTooLarge({ errorNode, onFilterClick, limit, onOverrideLimit, scrollToElement }: ResultSetTooLargeProps) {\n const { localizedStrings } = useLocalizationContext();\n const supportsFiltering = !!onFilterClick;\n const supportsLimitOverride = !!onOverrideLimit && limit < MAX_LIMIT_OVERRIDE;\n const messageWithLimit = localizedStrings.resultLimitExceeded.replace(\"{{limit}}\", limit.toString());\n\n return (\n <ErrorRegion.Item\n message={<MessageWithNode errorNode={errorNode} scrollToElement={scrollToElement} message={messageWithLimit} />}\n actions={\n <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n {supportsLimitOverride && (\n <Anchor onClick={() => onOverrideLimit(MAX_LIMIT_OVERRIDE)}>\n {localizedStrings.increaseHierarchyLimit.replace(\"{{limit}}\", MAX_LIMIT_OVERRIDE.toString())}\n </Anchor>\n )}\n {supportsFiltering && <Anchor onClick={onFilterClick}>{localizedStrings.increaseHierarchyLimitWithFiltering}</Anchor>}\n </div>\n }\n />\n );\n}\n\ninterface LinkedNodeProps {\n errorNode: ErrorNode;\n scrollToElement: (node: ErrorNode) => void;\n}\n\nfunction LinkedNode({ errorNode, scrollToElement }: LinkedNodeProps) {\n return <Anchor onClick={() => scrollToElement(errorNode)}>{errorNode.parent?.label}</Anchor>;\n}\n\nfunction MessageWithNode({ errorNode, scrollToElement, message }: LinkedNodeProps & { message: string }) {\n const splitMessage = message.split(\"{{node}}\", 2);\n return (\n <div style={{ display: \"flex\", whiteSpace: \"pre\", flexWrap: \"wrap\" }}>\n <Text variant={\"body-sm\"}>{splitMessage[0]}</Text>\n <LinkedNode errorNode={errorNode} scrollToElement={scrollToElement} />\n {splitMessage[1] ? <Text variant={\"body-sm\"}>{splitMessage[1]}</Text> : null}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TreeErrorRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeErrorRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Anchor, unstable_ErrorRegion as ErrorRegion, Text } from \"@itwin/itwinui-react/bricks\";\nimport { MAX_LIMIT_OVERRIDE } from \"../internal/Utils.js\";\nimport { HierarchyLevelDetails, useTree } from \"../UseTree.js\";\nimport { ErrorNode } from \"./FlatTreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\n\n/** @alpha */\nexport interface TreeErrorItemProps {\n /** A callback to reload a hierarchy level when an error occurs and `retry` button is clicked. */\n reloadTree?: (options: { parentNodeId: string | undefined; state: \"reset\" }) => void;\n /** Action to perform when the filter button is clicked for this node. */\n onFilterClick?: (hierarchyLevelDetails: HierarchyLevelDetails) => void;\n}\n\ninterface TreeErrorRendererOwnProps {\n errorList: ErrorNode[];\n}\n\ntype TreeErrorRendererProps = TreeErrorRendererOwnProps &\n TreeErrorItemProps &\n Partial<Pick<ReturnType<typeof useTree>, \"getHierarchyLevelDetails\">> &\n Pick<LinkedNodeProps, \"scrollToElement\">;\n\nexport function TreeErrorRenderer({ errorList, reloadTree, scrollToElement, getHierarchyLevelDetails, onFilterClick }: TreeErrorRendererProps) {\n const { localizedStrings } = useLocalizationContext();\n const errorItems = errorList.map((errorNode) => {\n if (errorNode.error.type === \"ResultSetTooLarge\") {\n return (\n <ResultSetTooLarge\n key={errorNode.error.id}\n onFilterClick={() => {\n const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.parent?.id);\n hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);\n }}\n onOverrideLimit={getHierarchyLevelDetails ? (limit) => getHierarchyLevelDetails(errorNode.parent?.id)?.setSizeLimit(limit) : undefined}\n scrollToElement={scrollToElement}\n limit={errorNode.error.resultSetSizeLimit}\n errorNode={errorNode}\n />\n );\n }\n if (errorNode.error.type === \"NoFilterMatches\") {\n return (\n <NoFilterMatches\n key={errorNode.error.id}\n scrollToElement={scrollToElement}\n onFilterClick={() => {\n const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.parent?.id);\n hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);\n }}\n errorNode={errorNode}\n />\n );\n }\n return <DefaultErrorContainer key={errorNode.error.id} scrollToElement={scrollToElement} reloadTree={reloadTree} errorNode={errorNode} />;\n });\n\n return (\n <ErrorRegion.Root\n style={{ width: \"100%\" }}\n label={errorList.length !== 0 ? `${errorList.length} ${localizedStrings?.issuesFound}` : undefined}\n items={errorItems}\n />\n );\n}\n\nfunction NoFilterMatches({ onFilterClick, errorNode, scrollToElement }: LinkedNodeProps & { onFilterClick?: () => void }) {\n const { localizedStrings } = useLocalizationContext();\n\n return (\n <ErrorRegion.Item\n message={<MessageWithNode errorNode={errorNode} scrollToElement={scrollToElement} message={localizedStrings.noFilteredChildren} />}\n actions={<Anchor onClick={onFilterClick}>{localizedStrings.noFilteredChildrenChangeFilter}</Anchor>}\n />\n );\n}\n\nfunction DefaultErrorContainer({ reloadTree, errorNode, scrollToElement }: LinkedNodeProps & Pick<TreeErrorItemProps, \"reloadTree\">) {\n const { localizedStrings } = useLocalizationContext();\n\n return (\n <ErrorRegion.Item\n message={<MessageWithNode errorNode={errorNode} scrollToElement={scrollToElement} message={localizedStrings.failedToCreateHierarchy} />}\n actions={<Anchor onClick={() => reloadTree?.({ parentNodeId: errorNode.parent?.id, state: \"reset\" })}>{localizedStrings.retry}</Anchor>}\n />\n );\n}\n\ntype ResultSetTooLargeProps = {\n limit: number;\n onFilterClick?: () => void;\n onOverrideLimit?: (limit: number) => void;\n} & LinkedNodeProps;\n\nfunction ResultSetTooLarge({ errorNode, onFilterClick, limit, onOverrideLimit, scrollToElement }: ResultSetTooLargeProps) {\n const { localizedStrings } = useLocalizationContext();\n const supportsFiltering = !!onFilterClick;\n const supportsLimitOverride = !!onOverrideLimit && limit < MAX_LIMIT_OVERRIDE;\n const messageWithLimit = localizedStrings.resultLimitExceeded.replace(\"{{limit}}\", limit.toString());\n\n return (\n <ErrorRegion.Item\n message={<MessageWithNode errorNode={errorNode} scrollToElement={scrollToElement} message={messageWithLimit} />}\n actions={\n <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n {supportsLimitOverride && (\n <Anchor onClick={() => onOverrideLimit(MAX_LIMIT_OVERRIDE)}>\n {localizedStrings.increaseHierarchyLimit.replace(\"{{limit}}\", MAX_LIMIT_OVERRIDE.toString())}\n </Anchor>\n )}\n {supportsFiltering && <Anchor onClick={onFilterClick}>{localizedStrings.increaseHierarchyLimitWithFiltering}</Anchor>}\n </div>\n }\n />\n );\n}\n\ninterface LinkedNodeProps {\n errorNode: ErrorNode;\n scrollToElement: (node: ErrorNode) => void;\n}\n\nfunction LinkedNode({ errorNode, scrollToElement }: LinkedNodeProps) {\n return <Anchor onClick={() => scrollToElement(errorNode)}>{errorNode.parent?.label}</Anchor>;\n}\n\nfunction MessageWithNode({ errorNode, scrollToElement, message }: LinkedNodeProps & { message: string }) {\n const splitMessage = message.split(\"{{node}}\", 2);\n return (\n <div style={{ display: \"flex\", whiteSpace: \"pre\", flexWrap: \"wrap\" }}>\n <Text variant={\"body-sm\"}>{splitMessage[0]}</Text>\n <LinkedNode errorNode={errorNode} scrollToElement={scrollToElement} />\n {splitMessage[1] ? <Text variant={\"body-sm\"}>{splitMessage[1]}</Text> : null}\n </div>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentPropsWithoutRef,
|
|
1
|
+
import { ComponentPropsWithoutRef, FC, PropsWithRef, ReactElement, ReactNode, RefAttributes } from "react";
|
|
2
2
|
import { Tree } from "@itwin/itwinui-react/bricks";
|
|
3
3
|
import { PresentationHierarchyNode } from "../TreeNode.js";
|
|
4
4
|
import { useTree, UseTreeResult } from "../UseTree.js";
|
|
@@ -15,26 +15,23 @@ export interface TreeNodeRendererOwnProps {
|
|
|
15
15
|
/** Returns sublabel for a given node. */
|
|
16
16
|
getSublabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;
|
|
17
17
|
/** Action to perform when the node is clicked. */
|
|
18
|
-
onNodeClick?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.MouseEvent<HTMLElement
|
|
18
|
+
onNodeClick?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.MouseEvent<HTMLElement>) => void;
|
|
19
19
|
/** Action to perform when a key is pressed when the node is hovered on. */
|
|
20
20
|
onNodeKeyDown?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.KeyboardEvent<HTMLElement>) => void;
|
|
21
|
-
/**
|
|
22
|
-
* Actions for tree item.
|
|
23
|
-
*/
|
|
24
|
-
actions?: Array<(node: PresentationHierarchyNode) => TreeItemAction>;
|
|
25
21
|
/**
|
|
26
22
|
* Used to render elements between expander and label.
|
|
27
23
|
* E.g. icons, color picker, etc.
|
|
28
24
|
*/
|
|
29
25
|
getDecorations?: (node: PresentationHierarchyNode) => ReactNode;
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
/** Specifies if tree item is selected. */
|
|
27
|
+
selected?: boolean;
|
|
28
|
+
/** Actions for tree item. */
|
|
29
|
+
actions?: Array<(node: PresentationHierarchyNode) => TreeItemAction>;
|
|
30
|
+
/** Specifies if tree item has error. */
|
|
31
|
+
error?: ErrorNode;
|
|
35
32
|
}
|
|
36
33
|
/** @alpha */
|
|
37
|
-
type TreeNodeRendererProps = Pick<ReturnType<typeof useTree>, "expandNode"
|
|
34
|
+
type TreeNodeRendererProps = Pick<ReturnType<typeof useTree>, "expandNode"> & Partial<Pick<ReturnType<typeof useTree>, "getHierarchyLevelDetails">> & Omit<TreeNodeProps, "actions" | "aria-level" | "aria-posinset" | "aria-setsize" | "label" | "icon" | "expanded" | "selected" | "unstable_decorations" | "error"> & Partial<Pick<UseTreeResult, "reloadTree">> & TreeNodeRendererOwnProps;
|
|
38
35
|
/**
|
|
39
36
|
* A component that renders `RenderedTreeNode` using the `TreeNode` component from `@itwin/itwinui-react`.
|
|
40
37
|
*
|
|
@@ -42,6 +39,6 @@ type TreeNodeRendererProps = Pick<ReturnType<typeof useTree>, "expandNode" | "is
|
|
|
42
39
|
* @see https://itwinui.bentley.com/docs/tree
|
|
43
40
|
* @public
|
|
44
41
|
*/
|
|
45
|
-
export declare const TreeNodeRenderer:
|
|
42
|
+
export declare const TreeNodeRenderer: FC<PropsWithRef<TreeNodeRendererProps & RefAttributes<HTMLElement>>>;
|
|
46
43
|
export {};
|
|
47
44
|
//# sourceMappingURL=TreeNodeRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeNodeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeNodeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,wBAAwB,
|
|
1
|
+
{"version":3,"file":"TreeNodeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeNodeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,wBAAwB,EACxB,EAAE,EAKF,YAAY,EACZ,YAAY,EACZ,SAAS,EAET,aAAa,EAId,MAAM,OAAO,CAAC;AACf,OAAO,EAAW,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,SAAS,EAAY,YAAY,EAAqB,MAAM,mBAAmB,CAAC;AAEzF,OAAO,EAAoB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAIzE,aAAa;AACb,KAAK,aAAa,GAAG,wBAAwB,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AAEhE,aAAa;AACb,MAAM,WAAW,wBAAwB;IACvC,6BAA6B;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,YAAY,GAAG,SAAS,CAAC;IACzE,yCAAyC;IACzC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,YAAY,GAAG,SAAS,CAAC;IAC5E,kDAAkD;IAClD,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACnH,2EAA2E;IAC3E,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACxH;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,SAAS,CAAC;IAChE,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,yBAAyB,KAAK,cAAc,CAAC,CAAC;IACrE,wCAAwC;IACxC,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,aAAa;AACb,KAAK,qBAAqB,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,EAAE,YAAY,CAAC,GACzE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,EAAE,0BAA0B,CAAC,CAAC,GACrE,IAAI,CACF,aAAa,EACb,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,sBAAsB,GAAG,OAAO,CAC5I,GACD,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC,GAC1C,wBAAwB,CAAC;AAE3B;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,YAAY,CAAC,qBAAqB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,CA2BjG,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
4
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
5
|
*--------------------------------------------------------------------------------------------*/
|
|
6
|
-
import { forwardRef, useCallback, useMemo, useRef, } from "react";
|
|
6
|
+
import { forwardRef, memo, useCallback, useMemo, useRef, } from "react";
|
|
7
7
|
import { Spinner, Tree } from "@itwin/itwinui-react/bricks";
|
|
8
8
|
import { isPlaceholderNode } from "./FlatTreeNode.js";
|
|
9
9
|
import { useLocalizationContext } from "./LocalizationContext.js";
|
|
@@ -16,48 +16,46 @@ const refreshSvg = new URL("@itwin/itwinui-icons/refresh.svg", import.meta.url).
|
|
|
16
16
|
* @see https://itwinui.bentley.com/docs/tree
|
|
17
17
|
* @public
|
|
18
18
|
*/
|
|
19
|
-
export const TreeNodeRenderer = forwardRef(({ node,
|
|
19
|
+
export const TreeNodeRenderer = memo(forwardRef(function TreeNodeRenderer({ node, selected, actions, error, expandNode, getLabel, getSublabel, getDecorations, reloadTree, onNodeClick, onNodeKeyDown, ...treeItemProps }, forwardedRef) {
|
|
20
|
+
if (isPlaceholderNode(node)) {
|
|
21
|
+
return _jsx(PlaceholderNode, { ...treeItemProps, ref: forwardedRef, level: node.level });
|
|
22
|
+
}
|
|
23
|
+
return (_jsx(HierarchyNode, { ...treeItemProps, ref: forwardedRef, node: node, selected: selected, actions: actions, error: error, expandNode: expandNode, getLabel: getLabel, getSublabel: getSublabel, getDecorations: getDecorations, onNodeKeyDown: onNodeKeyDown, onNodeClick: onNodeClick, reloadTree: reloadTree }));
|
|
24
|
+
}));
|
|
25
|
+
const HierarchyNode = memo(forwardRef(function HierarchyNode({ node, selected, actions, error, expandNode, getLabel, getSublabel, onNodeClick, onNodeKeyDown, getDecorations, reloadTree, ...treeItemProps }, forwardedRef) {
|
|
20
26
|
const nodeRef = useRef(null);
|
|
21
27
|
const ref = useMergedRefs(forwardedRef, nodeRef);
|
|
22
28
|
const { localizedStrings } = useLocalizationContext();
|
|
23
|
-
const
|
|
24
|
-
return !isPlaceholderNode(node) ? hasError?.(node) : false;
|
|
25
|
-
}, [hasError, node]);
|
|
26
|
-
if (isPlaceholderNode(node)) {
|
|
27
|
-
return _jsx(PlaceholderNode, { ...treeItemProps, level: node.level, ref: ref });
|
|
28
|
-
}
|
|
29
|
-
const getActions = () => {
|
|
29
|
+
const nodeActions = useMemo(() => {
|
|
30
30
|
if (!actions || actions.length === 0) {
|
|
31
31
|
return undefined;
|
|
32
32
|
}
|
|
33
33
|
const actionButtons = [];
|
|
34
|
-
if (
|
|
35
|
-
actionButtons.push(_jsx(TreeActionButton, { label: localizedStrings.retry, action: () => reloadTree?.({ parentNodeId: node.id }), show: true, icon: refreshSvg }));
|
|
34
|
+
if (error && error.error.type === "Unknown") {
|
|
35
|
+
actionButtons.push(_jsx(TreeActionButton, { label: localizedStrings.retry, action: () => reloadTree?.({ parentNodeId: node.id, state: "reset" }), show: true, icon: refreshSvg }));
|
|
36
36
|
}
|
|
37
37
|
actionButtons.push(...actions.map((action, index) => {
|
|
38
38
|
const actionInfo = action(node);
|
|
39
39
|
return _jsx(TreeActionButton, { ...actionInfo }, index);
|
|
40
40
|
}));
|
|
41
41
|
return actionButtons;
|
|
42
|
-
};
|
|
43
|
-
const
|
|
44
|
-
return (_jsx(Tree.Item, { ...treeItemProps, ref: ref, "aria-level": node.level, "aria-posinset": node.posInLevel, "aria-setsize": node.levelSize, label: getLabel ? getLabel(node) : node.label, description: getSublabel ? getSublabel(node) : undefined, selected: selected, expanded: node.isExpanded || node.children === true || node.children.length > 0 ? node.isExpanded : undefined, onExpandedChange: (isExpanded) => {
|
|
42
|
+
}, [actions, error, node, reloadTree, localizedStrings]);
|
|
43
|
+
const isDisabled = treeItemProps["aria-disabled"] === true;
|
|
44
|
+
return (_jsx(Tree.Item, { ...treeItemProps, ref: ref, "aria-level": node.level, "aria-posinset": node.posInLevel, "aria-setsize": node.levelSize, label: useMemo(() => (getLabel ? getLabel(node) : node.label), [getLabel, node]), description: useMemo(() => (getSublabel ? getSublabel(node) : undefined), [getSublabel, node]), selected: selected, expanded: node.isExpanded || node.children === true || node.children.length > 0 ? node.isExpanded : undefined, onExpandedChange: useCallback((isExpanded) => {
|
|
45
45
|
expandNode(node.id, isExpanded);
|
|
46
|
-
}, onClick: (event) => {
|
|
47
|
-
!
|
|
48
|
-
}, onKeyDown: (event) => {
|
|
46
|
+
}, [node, expandNode]), onClick: useCallback((event) => {
|
|
47
|
+
!isDisabled && onNodeClick?.(node, !selected, event);
|
|
48
|
+
}, [node, isDisabled, selected, onNodeClick]), onKeyDown: useCallback((event) => {
|
|
49
49
|
// Ignore if it is called on the element inside, e.g. checkbox or expander
|
|
50
|
-
if (!
|
|
50
|
+
if (!isDisabled && event.target === nodeRef.current) {
|
|
51
51
|
onNodeKeyDown?.(node, !selected, event);
|
|
52
52
|
}
|
|
53
|
-
}, actions:
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const PlaceholderNode = forwardRef(({ level, ...props }, forwardedRef) => {
|
|
53
|
+
}, [onNodeKeyDown, selected, isDisabled, node]), actions: nodeActions, unstable_decorations: useMemo(() => getDecorations && getDecorations(node), [getDecorations, node]), error: !!error }));
|
|
54
|
+
}));
|
|
55
|
+
const PlaceholderNode = memo(forwardRef(function PlaceholderNode({ level, ...props }, forwardedRef) {
|
|
57
56
|
const { localizedStrings } = useLocalizationContext();
|
|
58
57
|
return (_jsx(Tree.Item, { ...props, "aria-level": level, "aria-posinset": 1, "aria-setsize": 1, ref: forwardedRef, label: localizedStrings.loading, icon: _jsx(Spinner, { size: "small", title: localizedStrings.loading }) }));
|
|
59
|
-
});
|
|
60
|
-
PlaceholderNode.displayName = "PlaceholderNode";
|
|
58
|
+
}));
|
|
61
59
|
function useMergedRefs(...refs) {
|
|
62
60
|
return useCallback((instance) => {
|
|
63
61
|
refs.forEach((ref) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeNodeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeNodeRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport {\n ComponentPropsWithoutRef,\n forwardRef,\n ForwardRefExoticComponent,\n LegacyRef,\n MutableRefObject,\n ReactElement,\n ReactNode,\n Ref,\n RefAttributes,\n useCallback,\n useMemo,\n useRef,\n} from \"react\";\nimport { Spinner, Tree } from \"@itwin/itwinui-react/bricks\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { useTree, UseTreeResult } from \"../UseTree.js\";\nimport { ErrorNode, FlatTreeNode, isPlaceholderNode } from \"./FlatTreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\nimport { TreeActionButton, TreeItemAction } from \"./TreeActionButton.js\";\n\nconst refreshSvg = new URL(\"@itwin/itwinui-icons/refresh.svg\", import.meta.url).href;\n\n/** @alpha */\ntype TreeNodeProps = ComponentPropsWithoutRef<typeof Tree.Item>;\n\n/** @alpha */\nexport interface TreeNodeRendererOwnProps {\n /** Node that is rendered. */\n node: FlatTreeNode;\n /** Returns a label for a given node. */\n getLabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;\n /** Returns sublabel for a given node. */\n getSublabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;\n /** Action to perform when the node is clicked. */\n onNodeClick?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n /** Action to perform when a key is pressed when the node is hovered on. */\n onNodeKeyDown?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.KeyboardEvent<HTMLElement>) => void;\n /**\n * Actions for tree item.\n */\n actions?: Array<(node: PresentationHierarchyNode) => TreeItemAction>;\n /**\n * Used to render elements between expander and label.\n * E.g. icons, color picker, etc.\n */\n getDecorations?: (node: PresentationHierarchyNode) => ReactNode;\n /**\n * Used to determine if node contains errors.\n * Returns an error if node contains one, otherwise returns undefined.\n */\n hasError?: (node: PresentationHierarchyNode) => ErrorNode | undefined;\n}\n\n/** @alpha */\ntype TreeNodeRendererProps = Pick<ReturnType<typeof useTree>, \"expandNode\" | \"isNodeSelected\"> &\n Partial<Pick<ReturnType<typeof useTree>, \"getHierarchyLevelDetails\">> &\n Omit<TreeNodeProps, \"actions\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\" | \"label\" | \"icon\" | \"expanded\" | \"selected\" | \"unstable_decorations\"> &\n Partial<Pick<UseTreeResult, \"reloadTree\">> &\n TreeNodeRendererOwnProps;\n\n/**\n * A component that renders `RenderedTreeNode` using the `TreeNode` component from `@itwin/itwinui-react`.\n *\n * @see `TreeRenderer`\n * @see https://itwinui.bentley.com/docs/tree\n * @public\n */\nexport const TreeNodeRenderer: ForwardRefExoticComponent<TreeNodeRendererProps & RefAttributes<HTMLElement>> = forwardRef(\n (\n { node, expandNode, getLabel, getSublabel, onNodeClick, onNodeKeyDown, isNodeSelected, actions, getDecorations, hasError, reloadTree, ...treeItemProps },\n forwardedRef,\n ) => {\n const nodeRef = useRef<HTMLElement>(null);\n const ref = useMergedRefs(forwardedRef, nodeRef);\n const { localizedStrings } = useLocalizationContext();\n\n const childErrorNode = useMemo(() => {\n return !isPlaceholderNode(node) ? hasError?.(node) : false;\n }, [hasError, node]);\n\n if (isPlaceholderNode(node)) {\n return <PlaceholderNode {...treeItemProps} level={node.level} ref={ref} />;\n }\n\n const getActions = () => {\n if (!actions || actions.length === 0) {\n return undefined;\n }\n\n const actionButtons: ReactElement[] = [];\n\n if (childErrorNode && childErrorNode.error.type === \"Unknown\") {\n actionButtons.push(\n <TreeActionButton label={localizedStrings.retry} action={() => reloadTree?.({ parentNodeId: node.id })} show={true} icon={refreshSvg} />,\n );\n }\n\n actionButtons.push(\n ...actions.map((action, index) => {\n const actionInfo = action(node);\n return <TreeActionButton key={index} {...actionInfo} />;\n }),\n );\n\n return actionButtons;\n };\n\n const selected = isNodeSelected(node.id);\n return (\n <Tree.Item\n {...treeItemProps}\n ref={ref}\n aria-level={node.level}\n aria-posinset={node.posInLevel}\n aria-setsize={node.levelSize}\n label={getLabel ? getLabel(node) : node.label}\n description={getSublabel ? getSublabel(node) : undefined}\n selected={selected}\n expanded={node.isExpanded || node.children === true || node.children.length > 0 ? node.isExpanded : undefined}\n onExpandedChange={(isExpanded) => {\n expandNode(node.id, isExpanded);\n }}\n onClick={(event) => {\n !treeItemProps[\"aria-disabled\"] && onNodeClick?.(node, !selected, event);\n }}\n onKeyDown={(event) => {\n // Ignore if it is called on the element inside, e.g. checkbox or expander\n if (!treeItemProps[\"aria-disabled\"] && event.target === nodeRef.current) {\n onNodeKeyDown?.(node, !selected, event);\n }\n }}\n actions={getActions()}\n unstable_decorations={getDecorations && getDecorations(node)}\n error={!!childErrorNode}\n />\n );\n },\n);\nTreeNodeRenderer.displayName = \"TreeNodeRenderer\";\n\nconst PlaceholderNode = forwardRef<\n HTMLDivElement,\n Omit<TreeNodeProps, \"onExpanded\" | \"label\" | \"actions\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\" | \"icon\"> & { level: number }\n>(({ level, ...props }, forwardedRef) => {\n const { localizedStrings } = useLocalizationContext();\n return (\n <Tree.Item\n {...props}\n aria-level={level}\n aria-posinset={1}\n aria-setsize={1}\n ref={forwardedRef}\n label={localizedStrings.loading}\n icon={<Spinner size={\"small\"} title={localizedStrings.loading} />}\n />\n );\n});\nPlaceholderNode.displayName = \"PlaceholderNode\";\n\nfunction useMergedRefs<T>(...refs: ReadonlyArray<Ref<T> | LegacyRef<T> | undefined | null>) {\n return useCallback(\n (instance: T | null) => {\n refs.forEach((ref) => {\n if (typeof ref === \"function\") {\n ref(instance);\n } else if (ref) {\n (ref as MutableRefObject<T | null>).current = instance;\n }\n });\n }, // eslint-disable-next-line react-hooks/exhaustive-deps\n [...refs],\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TreeNodeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeNodeRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport {\n ComponentPropsWithoutRef,\n FC,\n forwardRef,\n LegacyRef,\n memo,\n MutableRefObject,\n PropsWithRef,\n ReactElement,\n ReactNode,\n Ref,\n RefAttributes,\n useCallback,\n useMemo,\n useRef,\n} from \"react\";\nimport { Spinner, Tree } from \"@itwin/itwinui-react/bricks\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { useTree, UseTreeResult } from \"../UseTree.js\";\nimport { ErrorNode, FlatNode, FlatTreeNode, isPlaceholderNode } from \"./FlatTreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\nimport { TreeActionButton, TreeItemAction } from \"./TreeActionButton.js\";\n\nconst refreshSvg = new URL(\"@itwin/itwinui-icons/refresh.svg\", import.meta.url).href;\n\n/** @alpha */\ntype TreeNodeProps = ComponentPropsWithoutRef<typeof Tree.Item>;\n\n/** @alpha */\nexport interface TreeNodeRendererOwnProps {\n /** Node that is rendered. */\n node: FlatTreeNode;\n /** Returns a label for a given node. */\n getLabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;\n /** Returns sublabel for a given node. */\n getSublabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;\n /** Action to perform when the node is clicked. */\n onNodeClick?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.MouseEvent<HTMLElement>) => void;\n /** Action to perform when a key is pressed when the node is hovered on. */\n onNodeKeyDown?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.KeyboardEvent<HTMLElement>) => void;\n /**\n * Used to render elements between expander and label.\n * E.g. icons, color picker, etc.\n */\n getDecorations?: (node: PresentationHierarchyNode) => ReactNode;\n /** Specifies if tree item is selected. */\n selected?: boolean;\n /** Actions for tree item. */\n actions?: Array<(node: PresentationHierarchyNode) => TreeItemAction>;\n /** Specifies if tree item has error. */\n error?: ErrorNode;\n}\n\n/** @alpha */\ntype TreeNodeRendererProps = Pick<ReturnType<typeof useTree>, \"expandNode\"> &\n Partial<Pick<ReturnType<typeof useTree>, \"getHierarchyLevelDetails\">> &\n Omit<\n TreeNodeProps,\n \"actions\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\" | \"label\" | \"icon\" | \"expanded\" | \"selected\" | \"unstable_decorations\" | \"error\"\n > &\n Partial<Pick<UseTreeResult, \"reloadTree\">> &\n TreeNodeRendererOwnProps;\n\n/**\n * A component that renders `RenderedTreeNode` using the `TreeNode` component from `@itwin/itwinui-react`.\n *\n * @see `TreeRenderer`\n * @see https://itwinui.bentley.com/docs/tree\n * @public\n */\nexport const TreeNodeRenderer: FC<PropsWithRef<TreeNodeRendererProps & RefAttributes<HTMLElement>>> = memo(\n forwardRef<HTMLElement, TreeNodeRendererProps>(function TreeNodeRenderer(\n { node, selected, actions, error, expandNode, getLabel, getSublabel, getDecorations, reloadTree, onNodeClick, onNodeKeyDown, ...treeItemProps },\n forwardedRef,\n ) {\n if (isPlaceholderNode(node)) {\n return <PlaceholderNode {...treeItemProps} ref={forwardedRef} level={node.level} />;\n }\n\n return (\n <HierarchyNode\n {...treeItemProps}\n ref={forwardedRef}\n node={node}\n selected={selected}\n actions={actions}\n error={error}\n expandNode={expandNode}\n getLabel={getLabel}\n getSublabel={getSublabel}\n getDecorations={getDecorations}\n onNodeKeyDown={onNodeKeyDown}\n onNodeClick={onNodeClick}\n reloadTree={reloadTree}\n />\n );\n }),\n);\n\nconst HierarchyNode = memo(\n forwardRef<HTMLElement, Omit<TreeNodeRendererProps, \"node\"> & { node: FlatNode }>(function HierarchyNode(\n { node, selected, actions, error, expandNode, getLabel, getSublabel, onNodeClick, onNodeKeyDown, getDecorations, reloadTree, ...treeItemProps },\n forwardedRef,\n ) {\n const nodeRef = useRef<HTMLElement>(null);\n const ref = useMergedRefs(forwardedRef, nodeRef);\n const { localizedStrings } = useLocalizationContext();\n\n const nodeActions = useMemo(() => {\n if (!actions || actions.length === 0) {\n return undefined;\n }\n\n const actionButtons: ReactElement[] = [];\n\n if (error && error.error.type === \"Unknown\") {\n actionButtons.push(\n <TreeActionButton\n label={localizedStrings.retry}\n action={() => reloadTree?.({ parentNodeId: node.id, state: \"reset\" })}\n show={true}\n icon={refreshSvg}\n />,\n );\n }\n\n actionButtons.push(\n ...actions.map((action, index) => {\n const actionInfo = action(node);\n return <TreeActionButton key={index} {...actionInfo} />;\n }),\n );\n\n return actionButtons;\n }, [actions, error, node, reloadTree, localizedStrings]);\n\n const isDisabled = treeItemProps[\"aria-disabled\"] === true;\n return (\n <Tree.Item\n {...treeItemProps}\n ref={ref}\n aria-level={node.level}\n aria-posinset={node.posInLevel}\n aria-setsize={node.levelSize}\n label={useMemo(() => (getLabel ? getLabel(node) : node.label), [getLabel, node])}\n description={useMemo(() => (getSublabel ? getSublabel(node) : undefined), [getSublabel, node])}\n selected={selected}\n expanded={node.isExpanded || node.children === true || node.children.length > 0 ? node.isExpanded : undefined}\n onExpandedChange={useCallback(\n (isExpanded: boolean) => {\n expandNode(node.id, isExpanded);\n },\n [node, expandNode],\n )}\n onClick={useCallback<Required<TreeNodeProps>[\"onClick\"]>(\n (event) => {\n !isDisabled && onNodeClick?.(node, !selected, event);\n },\n [node, isDisabled, selected, onNodeClick],\n )}\n onKeyDown={useCallback<Required<TreeNodeProps>[\"onKeyDown\"]>(\n (event) => {\n // Ignore if it is called on the element inside, e.g. checkbox or expander\n if (!isDisabled && event.target === nodeRef.current) {\n onNodeKeyDown?.(node, !selected, event);\n }\n },\n [onNodeKeyDown, selected, isDisabled, node],\n )}\n actions={nodeActions}\n unstable_decorations={useMemo(() => getDecorations && getDecorations(node), [getDecorations, node])}\n error={!!error}\n />\n );\n }),\n);\n\nconst PlaceholderNode = memo(\n forwardRef<\n HTMLElement,\n Omit<TreeNodeProps, \"onExpanded\" | \"label\" | \"actions\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\" | \"icon\"> & { level: number }\n >(function PlaceholderNode({ level, ...props }, forwardedRef) {\n const { localizedStrings } = useLocalizationContext();\n return (\n <Tree.Item\n {...props}\n aria-level={level}\n aria-posinset={1}\n aria-setsize={1}\n ref={forwardedRef}\n label={localizedStrings.loading}\n icon={<Spinner size={\"small\"} title={localizedStrings.loading} />}\n />\n );\n }),\n);\n\nfunction useMergedRefs<T>(...refs: ReadonlyArray<Ref<T> | LegacyRef<T> | undefined | null>) {\n return useCallback(\n (instance: T | null) => {\n refs.forEach((ref) => {\n if (typeof ref === \"function\") {\n ref(instance);\n } else if (ref) {\n (ref as MutableRefObject<T | null>).current = instance;\n }\n });\n }, // eslint-disable-next-line react-hooks/exhaustive-deps\n [...refs],\n );\n}\n"]}
|
|
@@ -18,7 +18,7 @@ interface TreeRendererOwnProps {
|
|
|
18
18
|
selectionMode?: SelectionMode;
|
|
19
19
|
}
|
|
20
20
|
/** @alpha */
|
|
21
|
-
type TreeRendererProps = Pick<ReturnType<typeof useTree>, "expandNode"> & Partial<Pick<ReturnType<typeof useTree>, "selectNodes" | "isNodeSelected" | "getHierarchyLevelDetails" | "reloadTree">> & Pick<TreeErrorItemProps, "onFilterClick"> & Omit<TreeNodeRendererProps, "node" | "reloadTree"> & TreeRendererOwnProps & ComponentPropsWithoutRef<typeof LocalizationContextProvider>;
|
|
21
|
+
type TreeRendererProps = Pick<ReturnType<typeof useTree>, "expandNode"> & Partial<Pick<ReturnType<typeof useTree>, "selectNodes" | "isNodeSelected" | "getHierarchyLevelDetails" | "reloadTree">> & Pick<TreeErrorItemProps, "onFilterClick"> & Omit<TreeNodeRendererProps, "node" | "reloadTree" | "selected" | "error"> & TreeRendererOwnProps & ComponentPropsWithoutRef<typeof LocalizationContextProvider>;
|
|
22
22
|
/**
|
|
23
23
|
* A component that renders a tree using the `Tree` component from `@itwin/itwinui-react`. The tree nodes
|
|
24
24
|
* are rendered using `TreeNodeRenderer` component from this package.
|
|
@@ -26,6 +26,6 @@ type TreeRendererProps = Pick<ReturnType<typeof useTree>, "expandNode"> & Partia
|
|
|
26
26
|
* @see https://itwinui.bentley.com/docs/tree
|
|
27
27
|
* @alpha
|
|
28
28
|
*/
|
|
29
|
-
export declare function TreeRenderer({ rootNodes, expandNode, localizedStrings, selectNodes, selectionMode, getHierarchyLevelDetails, onFilterClick, reloadTree, ...treeProps }: TreeRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export declare function TreeRenderer({ rootNodes, expandNode, localizedStrings, selectNodes, selectionMode, getHierarchyLevelDetails, onFilterClick, reloadTree, isNodeSelected, actions, getDecorations, getLabel, getSublabel, ...treeProps }: TreeRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
30
30
|
export {};
|
|
31
31
|
//# sourceMappingURL=TreeRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"TreeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAA6D,MAAM,OAAO,CAAC;AAC5G,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAEnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAuB,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAqB,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,aAAa;AACb,MAAM,MAAM,SAAS,GAAG,wBAAwB,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AAEnE,aAAa;AACb,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACtF,aAAa;AACb,UAAU,oBAAoB;IAC5B,8BAA8B;IAC9B,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,sEAAsE;IACtE,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,aAAa;AACb,KAAK,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,EAAE,YAAY,CAAC,GACrE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,EAAE,aAAa,GAAG,gBAAgB,GAAG,0BAA0B,GAAG,YAAY,CAAC,CAAC,GACvH,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,GACzC,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC,GACzE,oBAAoB,GACpB,wBAAwB,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,UAAU,EACV,cAAc,EACd,OAAO,EACP,cAAc,EACd,QAAQ,EACR,WAAW,EACX,GAAG,SAAS,EACb,EAAE,iBAAiB,2CA+FnB"}
|
|
@@ -4,10 +4,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
5
5
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
6
6
|
*--------------------------------------------------------------------------------------------*/
|
|
7
|
-
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
7
|
+
import { forwardRef, memo, useCallback, useEffect, useMemo, useRef } from "react";
|
|
8
8
|
import { Tree } from "@itwin/itwinui-react/bricks";
|
|
9
9
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
10
10
|
import { useSelectionHandler } from "../UseSelectionHandler.js";
|
|
11
|
+
import { useEvent } from "../Utils.js";
|
|
11
12
|
import { flattenNodes, getErrors } from "./FlatTreeNode.js";
|
|
12
13
|
import { LocalizationContextProvider } from "./LocalizationContext.js";
|
|
13
14
|
import { TreeErrorRenderer } from "./TreeErrorRenderer.js";
|
|
@@ -19,7 +20,7 @@ import { TreeNodeRenderer } from "./TreeNodeRenderer.js";
|
|
|
19
20
|
* @see https://itwinui.bentley.com/docs/tree
|
|
20
21
|
* @alpha
|
|
21
22
|
*/
|
|
22
|
-
export function TreeRenderer({ rootNodes, expandNode, localizedStrings, selectNodes, selectionMode, getHierarchyLevelDetails, onFilterClick, reloadTree, ...treeProps }) {
|
|
23
|
+
export function TreeRenderer({ rootNodes, expandNode, localizedStrings, selectNodes, selectionMode, getHierarchyLevelDetails, onFilterClick, reloadTree, isNodeSelected, actions, getDecorations, getLabel, getSublabel, ...treeProps }) {
|
|
23
24
|
const { onNodeClick, onNodeKeyDown } = useSelectionHandler({
|
|
24
25
|
rootNodes,
|
|
25
26
|
selectNodes: selectNodes ?? noopSelectNodes,
|
|
@@ -29,22 +30,20 @@ export function TreeRenderer({ rootNodes, expandNode, localizedStrings, selectNo
|
|
|
29
30
|
const parentRef = useRef(null);
|
|
30
31
|
const flatNodes = useMemo(() => flattenNodes(rootNodes), [rootNodes]);
|
|
31
32
|
const errorList = useMemo(() => getErrors(rootNodes), [rootNodes]);
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const error = errorList.find((errorNode) => errorNode.parent?.id === node.id);
|
|
37
|
-
return error;
|
|
33
|
+
const handleNodeClick = useEvent(onNodeClick);
|
|
34
|
+
const handleKeyDown = useEvent(onNodeKeyDown);
|
|
35
|
+
const hasError = useCallback((nodeId) => {
|
|
36
|
+
return errorList.find((errorNode) => errorNode.parent?.id === nodeId);
|
|
38
37
|
}, [errorList]);
|
|
39
38
|
const virtualizer = useVirtualizer({
|
|
40
39
|
count: flatNodes.length,
|
|
41
40
|
getScrollElement: () => parentRef.current,
|
|
42
41
|
getItemKey: (index) => flatNodes[index].id,
|
|
43
42
|
estimateSize: () => 28,
|
|
44
|
-
overscan:
|
|
43
|
+
overscan: 10,
|
|
45
44
|
});
|
|
46
45
|
const items = virtualizer.getVirtualItems();
|
|
47
|
-
const scrollToElement = (errorNode) => {
|
|
46
|
+
const scrollToElement = useCallback((errorNode) => {
|
|
48
47
|
const index = flatNodes.findIndex((flatNode) => flatNode.id === errorNode.parent?.id);
|
|
49
48
|
if (index === -1) {
|
|
50
49
|
errorNode.expandTo((nodeId) => expandNode(nodeId, true));
|
|
@@ -52,7 +51,7 @@ export function TreeRenderer({ rootNodes, expandNode, localizedStrings, selectNo
|
|
|
52
51
|
return;
|
|
53
52
|
}
|
|
54
53
|
virtualizer.scrollToIndex(index, { align: "end" });
|
|
55
|
-
};
|
|
54
|
+
}, [expandNode, flatNodes, virtualizer]);
|
|
56
55
|
useEffect(() => {
|
|
57
56
|
if (scrollToNode.current === undefined) {
|
|
58
57
|
return;
|
|
@@ -65,15 +64,20 @@ export function TreeRenderer({ rootNodes, expandNode, localizedStrings, selectNo
|
|
|
65
64
|
scrollToNode.current = undefined;
|
|
66
65
|
}, [flatNodes, virtualizer]);
|
|
67
66
|
return (_jsxs(LocalizationContextProvider, { localizedStrings: localizedStrings, children: [_jsx(TreeErrorRenderer, { errorList: errorList, scrollToElement: scrollToElement, getHierarchyLevelDetails: getHierarchyLevelDetails, onFilterClick: onFilterClick, reloadTree: reloadTree }), _jsx("div", { style: { height: "100%", width: "100%", overflowY: "auto" }, ref: parentRef, children: _jsx(Tree.Root, { style: { height: virtualizer.getTotalSize(), minHeight: "100%", width: "100%", position: "relative", overflow: "hidden" }, children: items.map((virtualizedItem) => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
left: 0,
|
|
72
|
-
width: "100%",
|
|
73
|
-
transform: `translateY(${virtualizedItem.start}px)`,
|
|
74
|
-
willChange: "transform",
|
|
75
|
-
}, expandNode: expandNode, onNodeClick: onNodeClick, onNodeKeyDown: onNodeKeyDown, hasError: hasError, node: flatNodes[virtualizedItem.index], key: virtualizedItem.key, "data-index": virtualizedItem.index, reloadTree: reloadTree }));
|
|
67
|
+
const selected = isNodeSelected?.(flatNodes[virtualizedItem.index].id) ?? false;
|
|
68
|
+
const error = hasError(flatNodes[virtualizedItem.index].id);
|
|
69
|
+
return (_createElement(VirtualTreeItem, { ...treeProps, ref: virtualizer.measureElement, start: virtualizedItem.start, expandNode: expandNode, onNodeClick: handleNodeClick, onNodeKeyDown: handleKeyDown, error: error, node: flatNodes[virtualizedItem.index], key: virtualizedItem.key, "data-index": virtualizedItem.index, reloadTree: reloadTree, selected: selected, actions: actions, getDecorations: getDecorations, getLabel: getLabel, getSublabel: getSublabel }));
|
|
76
70
|
}) }) })] }));
|
|
77
71
|
}
|
|
72
|
+
const VirtualTreeItem = memo(forwardRef(function VirtualTreeItem({ start, ...props }, forwardedRef) {
|
|
73
|
+
return (_jsx(TreeNodeRenderer, { ...props, ref: forwardedRef, style: useMemo(() => ({
|
|
74
|
+
position: "absolute",
|
|
75
|
+
top: 0,
|
|
76
|
+
left: 0,
|
|
77
|
+
width: "100%",
|
|
78
|
+
transform: `translateY(${start}px)`,
|
|
79
|
+
willChange: "transform",
|
|
80
|
+
}), [start]) }));
|
|
81
|
+
}));
|
|
78
82
|
function noopSelectNodes() { }
|
|
79
83
|
//# sourceMappingURL=TreeRenderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ComponentPropsWithoutRef, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { Tree } from \"@itwin/itwinui-react/bricks\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { PresentationHierarchyNode, PresentationTreeNode } from \"../TreeNode.js\";\nimport { SelectionMode, useSelectionHandler } from \"../UseSelectionHandler.js\";\nimport { useTree } from \"../UseTree.js\";\nimport { ErrorNode, flattenNodes, getErrors } from \"./FlatTreeNode.js\";\nimport { LocalizationContextProvider } from \"./LocalizationContext.js\";\nimport { TreeErrorItemProps, TreeErrorRenderer } from \"./TreeErrorRenderer.js\";\nimport { TreeNodeRenderer } from \"./TreeNodeRenderer.js\";\n\n/** @alpha */\nexport type TreeProps = ComponentPropsWithoutRef<typeof Tree.Root>;\n\n/** @alpha */\nexport type TreeNodeRendererProps = ComponentPropsWithoutRef<typeof TreeNodeRenderer>;\n/** @alpha */\ninterface TreeRendererOwnProps {\n /** Root nodes of the tree. */\n rootNodes: PresentationTreeNode[];\n /** Active selection mode used by the tree. Defaults to `\"single\"`. */\n selectionMode?: SelectionMode;\n}\n\n/** @alpha */\ntype TreeRendererProps = Pick<ReturnType<typeof useTree>, \"expandNode\"> &\n Partial<Pick<ReturnType<typeof useTree>, \"selectNodes\" | \"isNodeSelected\" | \"getHierarchyLevelDetails\" | \"reloadTree\">> &\n Pick<TreeErrorItemProps, \"onFilterClick\"> &\n Omit<TreeNodeRendererProps, \"node\" | \"reloadTree\"> &\n TreeRendererOwnProps &\n ComponentPropsWithoutRef<typeof LocalizationContextProvider>;\n\n/**\n * A component that renders a tree using the `Tree` component from `@itwin/itwinui-react`. The tree nodes\n * are rendered using `TreeNodeRenderer` component from this package.\n *\n * @see https://itwinui.bentley.com/docs/tree\n * @alpha\n */\nexport function TreeRenderer({\n rootNodes,\n expandNode,\n localizedStrings,\n selectNodes,\n selectionMode,\n getHierarchyLevelDetails,\n onFilterClick,\n reloadTree,\n ...treeProps\n}: TreeRendererProps) {\n const { onNodeClick, onNodeKeyDown } = useSelectionHandler({\n rootNodes,\n selectNodes: selectNodes ?? noopSelectNodes,\n selectionMode: selectionMode ?? \"single\",\n });\n const scrollToNode = useRef<string | undefined>(undefined);\n const parentRef = useRef<HTMLDivElement>(null);\n const flatNodes = useMemo(() => flattenNodes(rootNodes), [rootNodes]);\n const errorList = useMemo(() => getErrors(rootNodes), [rootNodes]);\n\n const hasError = useCallback(\n (node: PresentationHierarchyNode) => {\n if (node.children === true) {\n return undefined;\n }\n\n const error = errorList.find((errorNode) => errorNode.parent?.id === node.id);\n return error;\n },\n [errorList],\n );\n\n const virtualizer = useVirtualizer({\n count: flatNodes.length,\n getScrollElement: () => parentRef.current,\n getItemKey: (index) => flatNodes[index].id,\n estimateSize: () => 28,\n overscan: 5,\n });\n\n const items = virtualizer.getVirtualItems();\n\n const scrollToElement = (errorNode: ErrorNode) => {\n const index = flatNodes.findIndex((flatNode) => flatNode.id === errorNode.parent?.id);\n if (index === -1) {\n errorNode.expandTo((nodeId) => expandNode(nodeId, true));\n scrollToNode.current = errorNode.parent?.id;\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n };\n\n useEffect(() => {\n if (scrollToNode.current === undefined) {\n return;\n }\n const index = flatNodes.findIndex((flatNode) => flatNode.id === scrollToNode.current);\n if (index === -1) {\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n scrollToNode.current = undefined;\n }, [flatNodes, virtualizer]);\n\n return (\n <LocalizationContextProvider localizedStrings={localizedStrings}>\n <TreeErrorRenderer\n errorList={errorList}\n scrollToElement={scrollToElement}\n getHierarchyLevelDetails={getHierarchyLevelDetails}\n onFilterClick={onFilterClick}\n reloadTree={reloadTree}\n />\n <div style={{ height: \"100%\", width: \"100%\", overflowY: \"auto\" }} ref={parentRef}>\n <Tree.Root style={{ height: virtualizer.getTotalSize(), minHeight: \"100%\", width: \"100%\", position: \"relative\", overflow: \"hidden\" }}>\n {items.map((virtualizedItem) => {\n return (\n <TreeNodeRenderer\n {...treeProps}\n ref={virtualizer.measureElement}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${virtualizedItem.start}px)`,\n willChange: \"transform\",\n }}\n expandNode={expandNode}\n onNodeClick={onNodeClick}\n onNodeKeyDown={onNodeKeyDown}\n hasError={hasError}\n node={flatNodes[virtualizedItem.index]}\n key={virtualizedItem.key}\n data-index={virtualizedItem.index}\n reloadTree={reloadTree}\n />\n );\n })}\n </Tree.Root>\n </div>\n </LocalizationContextProvider>\n );\n}\n\nfunction noopSelectNodes() {}\n"]}
|
|
1
|
+
{"version":3,"file":"TreeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/itwinui/TreeRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ComponentPropsWithoutRef, forwardRef, memo, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { Tree } from \"@itwin/itwinui-react/bricks\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { PresentationTreeNode } from \"../TreeNode.js\";\nimport { SelectionMode, useSelectionHandler } from \"../UseSelectionHandler.js\";\nimport { useTree } from \"../UseTree.js\";\nimport { useEvent } from \"../Utils.js\";\nimport { ErrorNode, flattenNodes, getErrors } from \"./FlatTreeNode.js\";\nimport { LocalizationContextProvider } from \"./LocalizationContext.js\";\nimport { TreeErrorItemProps, TreeErrorRenderer } from \"./TreeErrorRenderer.js\";\nimport { TreeNodeRenderer } from \"./TreeNodeRenderer.js\";\n\n/** @alpha */\nexport type TreeProps = ComponentPropsWithoutRef<typeof Tree.Root>;\n\n/** @alpha */\nexport type TreeNodeRendererProps = ComponentPropsWithoutRef<typeof TreeNodeRenderer>;\n/** @alpha */\ninterface TreeRendererOwnProps {\n /** Root nodes of the tree. */\n rootNodes: PresentationTreeNode[];\n /** Active selection mode used by the tree. Defaults to `\"single\"`. */\n selectionMode?: SelectionMode;\n}\n\n/** @alpha */\ntype TreeRendererProps = Pick<ReturnType<typeof useTree>, \"expandNode\"> &\n Partial<Pick<ReturnType<typeof useTree>, \"selectNodes\" | \"isNodeSelected\" | \"getHierarchyLevelDetails\" | \"reloadTree\">> &\n Pick<TreeErrorItemProps, \"onFilterClick\"> &\n Omit<TreeNodeRendererProps, \"node\" | \"reloadTree\" | \"selected\" | \"error\"> &\n TreeRendererOwnProps &\n ComponentPropsWithoutRef<typeof LocalizationContextProvider>;\n\n/**\n * A component that renders a tree using the `Tree` component from `@itwin/itwinui-react`. The tree nodes\n * are rendered using `TreeNodeRenderer` component from this package.\n *\n * @see https://itwinui.bentley.com/docs/tree\n * @alpha\n */\nexport function TreeRenderer({\n rootNodes,\n expandNode,\n localizedStrings,\n selectNodes,\n selectionMode,\n getHierarchyLevelDetails,\n onFilterClick,\n reloadTree,\n isNodeSelected,\n actions,\n getDecorations,\n getLabel,\n getSublabel,\n ...treeProps\n}: TreeRendererProps) {\n const { onNodeClick, onNodeKeyDown } = useSelectionHandler({\n rootNodes,\n selectNodes: selectNodes ?? noopSelectNodes,\n selectionMode: selectionMode ?? \"single\",\n });\n const scrollToNode = useRef<string | undefined>(undefined);\n const parentRef = useRef<HTMLDivElement>(null);\n const flatNodes = useMemo(() => flattenNodes(rootNodes), [rootNodes]);\n const errorList = useMemo(() => getErrors(rootNodes), [rootNodes]);\n\n const handleNodeClick = useEvent(onNodeClick);\n const handleKeyDown = useEvent(onNodeKeyDown);\n\n const hasError = useCallback(\n (nodeId: string) => {\n return errorList.find((errorNode) => errorNode.parent?.id === nodeId);\n },\n [errorList],\n );\n\n const virtualizer = useVirtualizer({\n count: flatNodes.length,\n getScrollElement: () => parentRef.current,\n getItemKey: (index) => flatNodes[index].id,\n estimateSize: () => 28,\n overscan: 10,\n });\n\n const items = virtualizer.getVirtualItems();\n\n const scrollToElement = useCallback(\n (errorNode: ErrorNode) => {\n const index = flatNodes.findIndex((flatNode) => flatNode.id === errorNode.parent?.id);\n if (index === -1) {\n errorNode.expandTo((nodeId) => expandNode(nodeId, true));\n scrollToNode.current = errorNode.parent?.id;\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n },\n [expandNode, flatNodes, virtualizer],\n );\n\n useEffect(() => {\n if (scrollToNode.current === undefined) {\n return;\n }\n const index = flatNodes.findIndex((flatNode) => flatNode.id === scrollToNode.current);\n if (index === -1) {\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n scrollToNode.current = undefined;\n }, [flatNodes, virtualizer]);\n\n return (\n <LocalizationContextProvider localizedStrings={localizedStrings}>\n <TreeErrorRenderer\n errorList={errorList}\n scrollToElement={scrollToElement}\n getHierarchyLevelDetails={getHierarchyLevelDetails}\n onFilterClick={onFilterClick}\n reloadTree={reloadTree}\n />\n <div style={{ height: \"100%\", width: \"100%\", overflowY: \"auto\" }} ref={parentRef}>\n <Tree.Root style={{ height: virtualizer.getTotalSize(), minHeight: \"100%\", width: \"100%\", position: \"relative\", overflow: \"hidden\" }}>\n {items.map((virtualizedItem) => {\n const selected = isNodeSelected?.(flatNodes[virtualizedItem.index].id) ?? false;\n const error = hasError(flatNodes[virtualizedItem.index].id);\n return (\n <VirtualTreeItem\n {...treeProps}\n ref={virtualizer.measureElement}\n start={virtualizedItem.start}\n expandNode={expandNode}\n onNodeClick={handleNodeClick}\n onNodeKeyDown={handleKeyDown}\n error={error}\n node={flatNodes[virtualizedItem.index]}\n key={virtualizedItem.key}\n data-index={virtualizedItem.index}\n reloadTree={reloadTree}\n selected={selected}\n actions={actions}\n getDecorations={getDecorations}\n getLabel={getLabel}\n getSublabel={getSublabel}\n />\n );\n })}\n </Tree.Root>\n </div>\n </LocalizationContextProvider>\n );\n}\n\nconst VirtualTreeItem = memo(\n forwardRef<HTMLElement, TreeNodeRendererProps & { start: number }>(function VirtualTreeItem({ start, ...props }, forwardedRef) {\n return (\n <TreeNodeRenderer\n {...props}\n ref={forwardedRef}\n style={useMemo(\n () => ({\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${start}px)`,\n willChange: \"transform\",\n }),\n [start],\n )}\n />\n );\n }),\n);\n\nfunction noopSelectNodes() {}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/presentation-hierarchies-react",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.14",
|
|
4
4
|
"description": "React components based on `@itwin/presentation-hierarchies`",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"immer": "^10.1.1",
|
|
45
45
|
"react-error-boundary": "^4.0.13",
|
|
46
46
|
"rxjs": "^7.8.1",
|
|
47
|
-
"@itwin/presentation-hierarchies": "^1.4.2",
|
|
48
47
|
"@itwin/presentation-shared": "^1.2.1",
|
|
48
|
+
"@itwin/presentation-hierarchies": "^1.4.2",
|
|
49
49
|
"@itwin/unified-selection": "^1.4.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|