@itwin/presentation-hierarchies-react 2.0.0-alpha.47 → 2.0.0-alpha.48

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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # @itwin/presentation-hierarchies-react
2
2
 
3
+ ## 2.0.0-alpha.48
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1159](https://github.com/iTwin/presentation/pull/1159): Introduced `getTreeItemProps` and `treeRootProps` to `StrataKitTreeRenderer`. This allows passing props to underlying `Tree.Item` and `Tree.Root` components.
8
+
9
+ **Breaking changes**
10
+
11
+ `StrataKitTreeNodeRenderer` props changes:
12
+ - `getMenuActions` callback changed to `menuActions` prop (type: `ReactNode[]`)
13
+ - `getInlineActions` callback changed to `inlineActions` prop (type: `ReactNode[]`)
14
+ - `getContextMenuActions` callback changed to `contextMenuActions` prop (type: `ReactNode[]`)
15
+ - `getLabel` callback removed - use `label` prop instead
16
+ - `getSublabel` callback removed - use `description` prop instead
17
+ - `getDecorations` callback removed - use `decorations` prop instead
18
+ - `getClassName` callback removed - use `className` prop instead
19
+ - `onNodeClick` and `onNodeKeyDown` callbacks removed - use `onClick` and `onKeyDown` props instead
20
+
21
+ `StrataKitTreeRenderer` props changes:
22
+ - Props previously passed to `StrataKitTreeNodeRenderer` are no longer accepted
23
+ - Use `getTreeItemProps` callback to provide props to specific `Tree.Item` components
24
+ - Use `getMenuActions`, `getInlineActions`, and `getContextMenuActions` on `StrataKitTreeRenderer` to provide actions for nodes
25
+
26
+ ### Patch Changes
27
+
28
+ - Updated dependencies:
29
+ - @itwin/presentation-hierarchies@2.0.0-alpha.9
30
+
3
31
  ## 2.0.0-alpha.47
4
32
 
5
33
  ### Patch Changes
@@ -626,6 +654,16 @@
626
654
 
627
655
  - [#847](https://github.com/iTwin/presentation/pull/847): Moving tree rendering components to a new design systems.
628
656
 
657
+ ## 1.9.8
658
+
659
+ ### Patch Changes
660
+
661
+ - [#1152](https://github.com/iTwin/presentation/pull/1152): Bump dependencies.
662
+ - Updated dependencies:
663
+ - @itwin/presentation-hierarchies@1.7.7
664
+ - @itwin/presentation-shared@1.2.6
665
+ - @itwin/unified-selection@1.6.4
666
+
629
667
  ## 1.9.7
630
668
 
631
669
  ### Patch Changes
@@ -1,5 +1,8 @@
1
+ import { LegacyRef, MutableRefObject, Ref } from "react";
1
2
  /** @internal */
2
- export declare function useLatest<T>(value: T): import("react").MutableRefObject<T>;
3
+ export declare function useLatest<T>(value: T): MutableRefObject<T>;
3
4
  /** @internal */
4
5
  export declare function useEvent<TCallback extends (...args: any[]) => void>(callback: TCallback): (...args: Parameters<TCallback>) => void;
6
+ /** @internal */
7
+ export declare function useMergedRefs<T>(...refs: ReadonlyArray<Ref<T> | LegacyRef<T> | undefined | null>): (instance: T | null) => void;
5
8
  //# sourceMappingURL=Utils.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"Utils.d.ts","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/Utils.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAA2C,MAAM,OAAO,CAAC;AAElG,gBAAgB;AAChB,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,uBAQpC;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;AAID,gBAAgB;AAChB,wBAAgB,aAAa,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,cAElF,CAAC,GAAG,IAAI,UAWtB"}
@@ -20,4 +20,20 @@ export function useEvent(callback) {
20
20
  }, [latestCallback]);
21
21
  }
22
22
  /* c8 ignore end */
23
+ /* c8 ignore start */
24
+ /** @internal */
25
+ export function useMergedRefs(...refs) {
26
+ return useCallback((instance) => {
27
+ refs.forEach((ref) => {
28
+ if (typeof ref === "function") {
29
+ ref(instance);
30
+ }
31
+ else if (ref) {
32
+ ref.current = instance;
33
+ }
34
+ });
35
+ }, // eslint-disable-next-line react-hooks/exhaustive-deps
36
+ [...refs]);
37
+ }
38
+ /* c8 ignore end */
23
39
  //# sourceMappingURL=Utils.js.map
@@ -1 +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"]}
1
+ {"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../src/presentation-hierarchies-react/Utils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAoC,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAElG,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;AAEnB,qBAAqB;AACrB,gBAAgB;AAChB,MAAM,UAAU,aAAa,CAAI,GAAG,IAA6D;IAC/F,OAAO,WAAW,CAChB,CAAC,QAAkB,EAAE,EAAE;QACrB,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACnB,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;gBAC9B,GAAG,CAAC,QAAQ,CAAC,CAAC;YAChB,CAAC;iBAAM,IAAI,GAAG,EAAE,CAAC;gBACd,GAAkC,CAAC,OAAO,GAAG,QAAQ,CAAC;YACzD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,uDAAuD;IAC1D,CAAC,GAAG,IAAI,CAAC,CACV,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 { LegacyRef, MutableRefObject, Ref, 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\n/* c8 ignore start */\n/** @internal */\nexport function 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/* c8 ignore end */\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TreeErrorRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeErrorRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAqB,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C;;;;GAIG;AACH,UAAU,kBAAkB;IAC1B,iGAAiG;IACjG,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACpF,yEAAyE;IACzE,aAAa,CAAC,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACvE,4FAA4F;IAC5F,eAAe,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;CACjD;AACD;;;;GAIG;AACH,UAAU,yBAAyB;IACjC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,uIAAuI;IACvI,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,YAAY,CAAC;CAC/D;AAED,aAAa;AACb,MAAM,MAAM,sBAAsB,GAAG,yBAAyB,GAAG,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,0BAA0B,CAAC,CAAC;AAE1I;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,WAAW,GACZ,EAAE,sBAAsB,2CA4BxB"}
1
+ {"version":3,"file":"TreeErrorRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeErrorRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAgB,YAAY,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAqB,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C;;;;GAIG;AACH,UAAU,kBAAkB;IAC1B,iGAAiG;IACjG,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACpF,yEAAyE;IACzE,aAAa,CAAC,EAAE,CAAC,qBAAqB,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACvE,4FAA4F;IAC5F,eAAe,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;CACjD;AACD;;;;GAIG;AACH,UAAU,yBAAyB;IACjC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,uIAAuI;IACvI,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,YAAY,CAAC;CAC/D;AAED,aAAa;AACb,MAAM,MAAM,sBAAsB,GAAG,yBAAyB,GAAG,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,0BAA0B,CAAC,CAAC;AAE1I;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,WAAW,GACZ,EAAE,sBAAsB,2CA4BxB"}
@@ -1,4 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ import { cloneElement } from "react";
2
7
  import { unstable_ErrorRegion as ErrorRegion } from "@stratakit/structures";
3
8
  import { ErrorItemRenderer } from "./ErrorItemRenderer.js";
4
9
  import { useLocalizationContext } from "./LocalizationContext.js";
@@ -19,7 +24,7 @@ export function TreeErrorRenderer({ treeLabel, errorList, reloadTree, scrollToEl
19
24
  onFilterClick,
20
25
  };
21
26
  if (renderError) {
22
- return renderError(errorRendererProps);
27
+ return cloneElement(renderError(errorRendererProps), { key: errorItem.errorNode.id });
23
28
  }
24
29
  return _jsx(ErrorItemRenderer, { ...errorRendererProps }, errorItem.errorNode.id);
25
30
  });
@@ -1 +1 @@
1
- {"version":3,"file":"TreeErrorRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeErrorRenderer.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAE,oBAAoB,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAA0B,MAAM,wBAAwB,CAAC;AAEnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAmClE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,WAAW,GACY;IACvB,MAAM,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;QAC7C,MAAM,kBAAkB,GAA2B;YACjD,SAAS;YACT,eAAe,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC;YACjD,UAAU;YACV,wBAAwB;YACxB,aAAa;SACd,CAAC;QAEF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,WAAW,CAAC,kBAAkB,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,KAAC,iBAAiB,OAAkC,kBAAkB,IAA9C,SAAS,CAAC,SAAS,CAAC,EAAE,CAA4B,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,WAAW,CAAC,IAAI,IACf,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBACZ,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,CAAC,EAC/E,KAAK,EACH,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,OAAO,CAAC,sBAAsB,EAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAErJ,KAAK,EAAE,UAAU,GACjB,CACH,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 { ReactElement } from \"react\";\nimport { unstable_ErrorRegion as ErrorRegion } from \"@stratakit/structures\";\nimport { HierarchyLevelDetails, TreeRendererProps } from \"../Renderers.js\";\nimport { ErrorItemRenderer, ErrorItemRendererProps } from \"./ErrorItemRenderer.js\";\nimport { ErrorItem } from \"./FlatTreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\n\n/**\n * Interface containing error item related actions.\n *\n * @alpha\n */\ninterface 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 /** Action to perform when an error occurs and node label is clicked in the error message */\n scrollToElement: (errorNode: ErrorItem) => void;\n}\n/**\n * Interface containing building blocks for `TreeErrorRenderer`.\n *\n * @alpha\n */\ninterface TreeErrorRendererOwnProps {\n /**\n * A user friendly display label of the tree. Should be unique within the consuming application,\n * as it's used for creating a unique accessible label for the error region.\n */\n treeLabel: string;\n /** List of errors to be displayed */\n errorList: ErrorItem[];\n /** Callback to render custom error messages. Component should be wrapped in `ErrorRegion.Item` from `@itwin/itwinui-react` package. */\n renderError?: (props: ErrorItemRendererProps) => ReactElement;\n}\n\n/** @alpha */\nexport type TreeErrorRendererProps = TreeErrorRendererOwnProps & TreeErrorItemProps & Pick<TreeRendererProps, \"getHierarchyLevelDetails\">;\n\n/**\n * A component that renders error display dropdown using the `unstable_ErrorRegion` component from `@itwin/itwinui-react`.\n * As input, the component uses a list of `ErrorNode` objects, which are generally created using the `useErrorList` hook.\n *\n * @alpha\n */\nexport function TreeErrorRenderer({\n treeLabel,\n errorList,\n reloadTree,\n scrollToElement,\n getHierarchyLevelDetails,\n onFilterClick,\n renderError,\n}: TreeErrorRendererProps) {\n const { localizedStrings } = useLocalizationContext();\n const errorItems = errorList.map((errorItem) => {\n const errorRendererProps: ErrorItemRendererProps = {\n errorItem,\n scrollToElement: () => scrollToElement(errorItem),\n reloadTree,\n getHierarchyLevelDetails,\n onFilterClick,\n };\n\n if (renderError) {\n return renderError(errorRendererProps);\n }\n\n return <ErrorItemRenderer key={errorItem.errorNode.id} {...errorRendererProps} />;\n });\n\n return (\n <ErrorRegion.Root\n style={{ width: \"100%\" }}\n aria-label={localizedStrings.issuesForTree.replace(\"{{tree_label}}\", treeLabel)}\n label={\n errorList.length === 0 ? localizedStrings.noIssuesFound : localizedStrings.issuesFound.replace(\"{{number_of_issues}}\", errorList.length.toString())\n }\n items={errorItems}\n />\n );\n}\n"]}
1
+ {"version":3,"file":"TreeErrorRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeErrorRenderer.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,YAAY,EAAgB,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,oBAAoB,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAA0B,MAAM,wBAAwB,CAAC;AAEnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAmClE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,WAAW,GACY;IACvB,MAAM,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;QAC7C,MAAM,kBAAkB,GAA2B;YACjD,SAAS;YACT,eAAe,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC;YACjD,UAAU;YACV,wBAAwB;YACxB,aAAa;SACd,CAAC;QAEF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,YAAY,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,EAAE,GAAG,EAAE,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;QAED,OAAO,KAAC,iBAAiB,OAAkC,kBAAkB,IAA9C,SAAS,CAAC,SAAS,CAAC,EAAE,CAA4B,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,WAAW,CAAC,IAAI,IACf,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBACZ,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,CAAC,EAC/E,KAAK,EACH,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,OAAO,CAAC,sBAAsB,EAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAErJ,KAAK,EAAE,UAAU,GACjB,CACH,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 { cloneElement, ReactElement } from \"react\";\nimport { unstable_ErrorRegion as ErrorRegion } from \"@stratakit/structures\";\nimport { HierarchyLevelDetails, TreeRendererProps } from \"../Renderers.js\";\nimport { ErrorItemRenderer, ErrorItemRendererProps } from \"./ErrorItemRenderer.js\";\nimport { ErrorItem } from \"./FlatTreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\n\n/**\n * Interface containing error item related actions.\n *\n * @alpha\n */\ninterface 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 /** Action to perform when an error occurs and node label is clicked in the error message */\n scrollToElement: (errorNode: ErrorItem) => void;\n}\n/**\n * Interface containing building blocks for `TreeErrorRenderer`.\n *\n * @alpha\n */\ninterface TreeErrorRendererOwnProps {\n /**\n * A user friendly display label of the tree. Should be unique within the consuming application,\n * as it's used for creating a unique accessible label for the error region.\n */\n treeLabel: string;\n /** List of errors to be displayed */\n errorList: ErrorItem[];\n /** Callback to render custom error messages. Component should be wrapped in `ErrorRegion.Item` from `@itwin/itwinui-react` package. */\n renderError?: (props: ErrorItemRendererProps) => ReactElement;\n}\n\n/** @alpha */\nexport type TreeErrorRendererProps = TreeErrorRendererOwnProps & TreeErrorItemProps & Pick<TreeRendererProps, \"getHierarchyLevelDetails\">;\n\n/**\n * A component that renders error display dropdown using the `unstable_ErrorRegion` component from `@itwin/itwinui-react`.\n * As input, the component uses a list of `ErrorNode` objects, which are generally created using the `useErrorList` hook.\n *\n * @alpha\n */\nexport function TreeErrorRenderer({\n treeLabel,\n errorList,\n reloadTree,\n scrollToElement,\n getHierarchyLevelDetails,\n onFilterClick,\n renderError,\n}: TreeErrorRendererProps) {\n const { localizedStrings } = useLocalizationContext();\n const errorItems = errorList.map((errorItem) => {\n const errorRendererProps: ErrorItemRendererProps = {\n errorItem,\n scrollToElement: () => scrollToElement(errorItem),\n reloadTree,\n getHierarchyLevelDetails,\n onFilterClick,\n };\n\n if (renderError) {\n return cloneElement(renderError(errorRendererProps), { key: errorItem.errorNode.id });\n }\n\n return <ErrorItemRenderer key={errorItem.errorNode.id} {...errorRendererProps} />;\n });\n\n return (\n <ErrorRegion.Root\n style={{ width: \"100%\" }}\n aria-label={localizedStrings.issuesForTree.replace(\"{{tree_label}}\", treeLabel)}\n label={\n errorList.length === 0 ? localizedStrings.noIssuesFound : localizedStrings.issuesFound.replace(\"{{number_of_issues}}\", errorList.length.toString())\n }\n items={errorItems}\n />\n );\n}\n"]}
@@ -1,47 +1,38 @@
1
- import { ComponentPropsWithoutRef, FC, PropsWithRef, ReactElement, ReactNode, RefAttributes } from "react";
1
+ import { ComponentPropsWithoutRef, FC, PropsWithRef, ReactNode, RefAttributes } from "react";
2
2
  import { Tree } from "@stratakit/structures";
3
3
  import { TreeRendererProps } from "../Renderers.js";
4
4
  import { PresentationHierarchyNode } from "../TreeNode.js";
5
5
  /** @alpha */
6
- type TreeNodeProps = ComponentPropsWithoutRef<typeof Tree.Item>;
7
- /** @alpha */
8
- export interface TreeNodeRendererOwnProps {
6
+ export interface TreeNodeRendererOwnProps extends Pick<TreeRendererProps, "expandNode" | "reloadTree"> {
9
7
  /** Node that is rendered. */
10
8
  node: PresentationHierarchyNode;
11
- /** Returns the class name for a given node. */
12
- getClassName?: (node: PresentationHierarchyNode) => string | undefined;
13
- /** Returns a label for a given node. */
14
- getLabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;
15
- /** Returns sublabel for a given node. */
16
- getSublabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;
17
- /** Action to perform when the node is clicked. */
18
- onNodeClick?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.MouseEvent<HTMLElement>) => void;
19
- /** Action to perform when a key is pressed when the node is hovered on. */
20
- onNodeKeyDown?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.KeyboardEvent<HTMLElement>) => void;
21
- /**
22
- * Used to render elements between expander and label.
23
- * E.g. icons, color picker, etc.
24
- */
25
- getDecorations?: (node: PresentationHierarchyNode) => ReactNode;
26
9
  /**
27
- * Callback that returns menu actions for tree item.
28
- * Must return an array of `<TreeActionBase />` or `<Divider />` elements.
10
+ * Menu actions for tree item.
11
+ * Must be an array of `<TreeActionBase />` or `<Divider />` elements.
29
12
  */
30
- getMenuActions?: (node: PresentationHierarchyNode) => ReactNode[];
13
+ menuActions?: ReactNode[];
31
14
  /**
32
- * Callback that returns inline actions for tree item.
33
- * Must return an array of `<TreeActionBase />` elements.
15
+ * Inline actions for tree item.
16
+ * Must be an array of `<TreeActionBase />` elements.
34
17
  * Max 2 items.
35
18
  */
36
- getInlineActions?: (node: PresentationHierarchyNode) => ReactNode[];
19
+ inlineActions?: ReactNode[];
37
20
  /**
38
- * Callback that returns actions for tree item context menu.
39
- * Must return an array of `<TreeActionBase />` or `<Divider />` elements.
21
+ * Context menu actions for tree item.
22
+ * Must be an array of `<TreeActionBase />` or `<Divider />` elements.
40
23
  */
41
- getContextMenuActions?: (node: PresentationHierarchyNode) => ReactNode[];
24
+ contextMenuActions?: ReactNode[];
42
25
  }
43
26
  /** @alpha */
44
- type TreeNodeRendererProps = Pick<TreeRendererProps, "expandNode" | "reloadTree"> & Omit<TreeNodeProps, "actions" | "label" | "expanded" | "unstable_decorations" | "error"> & TreeNodeRendererOwnProps;
27
+ export type StrataKitTreeItemProps = Omit<ComponentPropsWithoutRef<typeof Tree.Item>, "actions" | "inlineActions" | "expanded" | "onExpandedChange" | "icon" | "unstable_decorations" | "error"> & {
28
+ /**
29
+ * Used to render elements between expander and label.
30
+ * E.g. icons, color picker, etc.
31
+ */
32
+ decorations?: ReactNode;
33
+ };
34
+ /** @alpha */
35
+ export type TreeNodeRendererProps = StrataKitTreeItemProps & TreeNodeRendererOwnProps;
45
36
  /**
46
37
  * A component that renders given `FlatTreeNode` using the `Tree.Item` component from `@itwin/itwinui-react`. The
47
38
  * `FlatTreeNode` objects for this renderer are generally created using the `useFlatTreeNodeList` hook.
@@ -51,6 +42,5 @@ type TreeNodeRendererProps = Pick<TreeRendererProps, "expandNode" | "reloadTree"
51
42
  * @public
52
43
  */
53
44
  export declare const StrataKitTreeNodeRenderer: FC<PropsWithRef<TreeNodeRendererProps & RefAttributes<HTMLElement>>>;
54
- export declare const PlaceholderNode: FC<PropsWithRef<Omit<TreeNodeProps, "onExpanded" | "label" | "actions" | "icon" | "error"> & RefAttributes<HTMLElement>>>;
55
- export {};
45
+ export declare const PlaceholderNode: FC<PropsWithRef<Pick<StrataKitTreeItemProps, "style" | "aria-level" | "aria-posinset" | "aria-setsize"> & RefAttributes<HTMLElement>>>;
56
46
  //# sourceMappingURL=TreeNodeRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TreeNodeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeNodeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEL,wBAAwB,EACxB,EAAE,EAMF,YAAY,EACZ,YAAY,EACZ,SAAS,EAET,aAAa,EAMd,MAAM,OAAO,CAAC;AAGf,OAAO,EAAgB,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAK3D,aAAa;AACb,KAAK,aAAa,GAAG,wBAAwB,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AAEhE,aAAa;AACb,MAAM,WAAW,wBAAwB;IACvC,6BAA6B;IAC7B,IAAI,EAAE,yBAAyB,CAAC;IAChC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,MAAM,GAAG,SAAS,CAAC;IACvE,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;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,SAAS,EAAE,CAAC;IAClE;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,SAAS,EAAE,CAAC;IACpE;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,SAAS,EAAE,CAAC;CAC1E;AAED,aAAa;AACb,KAAK,qBAAqB,GAAG,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,YAAY,CAAC,GAC/E,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,sBAAsB,GAAG,OAAO,CAAC,GACxF,wBAAwB,CAAC;AAE3B;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,YAAY,CAAC,qBAAqB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,CAsK1G,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,CAKrJ,CAAC"}
1
+ {"version":3,"file":"TreeNodeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeNodeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEL,wBAAwB,EACxB,EAAE,EAIF,YAAY,EACZ,SAAS,EACT,aAAa,EAMd,MAAM,OAAO,CAAC;AAGf,OAAO,EAAgB,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAK3D,aAAa;AACb,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,YAAY,CAAC;IACpG,6BAA6B;IAC7B,IAAI,EAAE,yBAAyB,CAAC;IAChC;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,SAAS,EAAE,CAAC;CAClC;AAED,aAAa;AACb,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,wBAAwB,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,EAC1C,SAAS,GAAG,eAAe,GAAG,UAAU,GAAG,kBAAkB,GAAG,MAAM,GAAG,sBAAsB,GAAG,OAAO,CAC1G,GAAG;IACF;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,CAAC;AAEF,aAAa;AACb,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;AAEtF;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,YAAY,CAAC,qBAAqB,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,CA4H1G,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAC9B,YAAY,CAAC,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,YAAY,GAAG,eAAe,GAAG,cAAc,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC,CAgBnI,CAAC"}
@@ -18,33 +18,29 @@ import { TreeActionBase } from "./TreeAction.js";
18
18
  * @see https://itwinui.bentley.com/docs/tree
19
19
  * @public
20
20
  */
21
- export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode({ node, selected, expandNode, onNodeClick, onNodeKeyDown, reloadTree, getClassName, getLabel, getSublabel, getMenuActions, getInlineActions, getDecorations, getContextMenuActions, ...treeItemProps }, forwardedRef) {
22
- const nodeRef = useRef(null);
23
- const ref = useMergedRefs(forwardedRef, nodeRef);
21
+ export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode(props, forwardedRef) {
22
+ const { node, decorations, inlineActions, menuActions, contextMenuActions, expandNode, reloadTree, ...treeItemProps } = props;
24
23
  const { localizedStrings } = useLocalizationContext();
25
24
  const renameContext = useRenameContext();
26
25
  const [contextMenuProps, setContextMenuProps] = useState(undefined);
27
- const className = useMemo(() => getClassName?.(node), [getClassName, node]);
28
- const label = useMemo(() => (getLabel ? getLabel(node) : node.label), [getLabel, node]);
29
- const description = useMemo(() => (getSublabel ? getSublabel(node) : undefined), [getSublabel, node]);
30
- const decorations = useMemo(() => getDecorations?.(node), [getDecorations, node]);
31
- const inlineActions = useMemo(() => {
26
+ const label = treeItemProps.label ?? node.label;
27
+ const inlineActionItems = useMemo(() => {
32
28
  if (node.error !== undefined && node.error.type === "ChildrenLoad") {
33
29
  return [
34
30
  _jsx(TreeActionBase, { label: localizedStrings.retry, onClick: () => reloadTree({ parentNodeId: node.id, state: "reset" }), visible: true, icon: refreshSvg, variant: "inline" }, "retry"),
35
31
  ];
36
32
  }
37
- if (!getInlineActions) {
38
- return [];
33
+ if (!inlineActions) {
34
+ return undefined;
39
35
  }
40
- return injectActionVariant(getInlineActions(node), "inline");
41
- }, [node, getInlineActions, localizedStrings.retry, reloadTree]);
42
- const menuItems = useMemo(() => {
43
- if (!getMenuActions) {
36
+ return injectActionVariant(inlineActions, "inline");
37
+ }, [node, inlineActions, localizedStrings.retry, reloadTree]);
38
+ const menuActionItems = useMemo(() => {
39
+ if (!menuActions) {
44
40
  return undefined;
45
41
  }
46
- return injectActionVariant(getMenuActions(node), "default");
47
- }, [getMenuActions, node]);
42
+ return injectActionVariant(menuActions, "default");
43
+ }, [menuActions]);
48
44
  const expanded = useMemo(() => {
49
45
  if (node.error) {
50
46
  return undefined;
@@ -54,7 +50,6 @@ export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode(
54
50
  }
55
51
  return undefined;
56
52
  }, [node.children, node.error, node.isExpanded]);
57
- const isDisabled = treeItemProps["aria-disabled"] === true;
58
53
  const { onLabelChanged, setIsRenaming, isRenaming } = renameContext ?? {};
59
54
  const labelEditor = isRenaming ? (_jsx(LabelEditor, { initialLabel: node.label, onChange: (newLabel) => {
60
55
  onLabelChanged?.(newLabel);
@@ -62,25 +57,18 @@ export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode(
62
57
  }, onCancel: () => {
63
58
  setIsRenaming?.(false);
64
59
  } })) : undefined;
65
- return (_jsxs(_Fragment, { children: [_jsx(Tree.Item, { ...treeItemProps, ref: ref, className: className, label: labelEditor ?? label, description: description, selected: selected, expanded: expanded, onExpandedChange: useCallback((isExpanded) => {
60
+ return (_jsxs(_Fragment, { children: [_jsx(Tree.Item, { ...treeItemProps, ref: forwardedRef, label: labelEditor ?? label, expanded: expanded, onExpandedChange: useCallback((isExpanded) => {
66
61
  expandNode(node.id, isExpanded);
67
- }, [node, expandNode]), onClick: useCallback((event) => {
68
- if (isDisabled) {
69
- return;
62
+ }, [node, expandNode]), inlineActions: inlineActionItems, actions: menuActionItems, unstable_decorations: decorations, error: node.error ? node.error.id : undefined, onContextMenu: (e) => {
63
+ if (treeItemProps.onContextMenu) {
64
+ treeItemProps.onContextMenu(e);
70
65
  }
71
- onNodeClick?.(node, !selected, event);
72
- }, [node, isDisabled, selected, onNodeClick]), onKeyDown: useCallback((event) => {
73
- // Ignore if it is called on the element inside, e.g. checkbox or expander
74
- if (!isDisabled && event.target === nodeRef.current) {
75
- onNodeKeyDown?.(node, !selected, event);
76
- }
77
- }, [onNodeKeyDown, selected, isDisabled, node]), inlineActions: inlineActions, actions: menuItems, unstable_decorations: decorations, error: node.error ? node.error.id : undefined, onContextMenu: (e) => {
78
- if (!getContextMenuActions) {
66
+ if (!contextMenuActions) {
79
67
  return;
80
68
  }
81
69
  e.preventDefault();
82
- const contextMenuActions = injectActionVariant(getContextMenuActions(node), "context-menu");
83
- if (contextMenuActions.length === 0) {
70
+ const actions = injectActionVariant(contextMenuActions, "context-menu");
71
+ if (actions.length === 0) {
84
72
  return;
85
73
  }
86
74
  setContextMenuProps({
@@ -88,7 +76,7 @@ export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode(
88
76
  x: e.clientX,
89
77
  y: e.clientY,
90
78
  },
91
- actions: contextMenuActions,
79
+ actions,
92
80
  });
93
81
  } }), _jsxs(DropdownMenu.Provider, { open: contextMenuProps !== undefined, setOpen: (open) => {
94
82
  if (!open) {
@@ -98,7 +86,7 @@ export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode(
98
86
  }));
99
87
  export const PlaceholderNode = memo(forwardRef(function PlaceholderNode({ ...props }, forwardedRef) {
100
88
  const { localizedStrings } = useLocalizationContext();
101
- return _jsx(Tree.Item, { ...props, ref: forwardedRef, label: localizedStrings.loading, icon: _jsx(Spinner, { size: "small", title: localizedStrings.loading }) });
89
+ return (_jsx(Tree.Item, { ...props, ref: forwardedRef, label: localizedStrings.loading, unstable_decorations: _jsx(Spinner, { size: "small", title: localizedStrings.loading }) }));
102
90
  }));
103
91
  function LabelEditor({ initialLabel, onChange, onCancel }) {
104
92
  const inputRef = useRef(null);
@@ -134,17 +122,4 @@ function injectActionVariant(actions, variant) {
134
122
  .filter((action) => isValidElement(action))
135
123
  .map((action) => cloneElement(action, { variant }));
136
124
  }
137
- function useMergedRefs(...refs) {
138
- return useCallback((instance) => {
139
- refs.forEach((ref) => {
140
- if (typeof ref === "function") {
141
- ref(instance);
142
- }
143
- else if (ref) {
144
- ref.current = instance;
145
- }
146
- });
147
- }, // eslint-disable-next-line react-hooks/exhaustive-deps
148
- [...refs]);
149
- }
150
125
  //# sourceMappingURL=TreeNodeRenderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TreeNodeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/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 cloneElement,\n ComponentPropsWithoutRef,\n FC,\n forwardRef,\n isValidElement,\n LegacyRef,\n memo,\n MutableRefObject,\n PropsWithRef,\n ReactElement,\n ReactNode,\n Ref,\n RefAttributes,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Spinner, TextBox } from \"@stratakit/bricks\";\nimport refreshSvg from \"@stratakit/icons/refresh.svg\";\nimport { DropdownMenu, Tree } from \"@stratakit/structures\";\nimport { TreeRendererProps } from \"../Renderers.js\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\nimport { useRenameContext } from \"./RenameAction.js\";\nimport { TreeActionBase, TreeActionBaseAttributes } from \"./TreeAction.js\";\n\n/** @alpha */\ntype TreeNodeProps = ComponentPropsWithoutRef<typeof Tree.Item>;\n\n/** @alpha */\nexport interface TreeNodeRendererOwnProps {\n /** Node that is rendered. */\n node: PresentationHierarchyNode;\n /** Returns the class name for a given node. */\n getClassName?: (node: PresentationHierarchyNode) => string | undefined;\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 /**\n * Callback that returns menu actions for tree item.\n * Must return an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n getMenuActions?: (node: PresentationHierarchyNode) => ReactNode[];\n /**\n * Callback that returns inline actions for tree item.\n * Must return an array of `<TreeActionBase />` elements.\n * Max 2 items.\n */\n getInlineActions?: (node: PresentationHierarchyNode) => ReactNode[];\n /**\n * Callback that returns actions for tree item context menu.\n * Must return an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n getContextMenuActions?: (node: PresentationHierarchyNode) => ReactNode[];\n}\n\n/** @alpha */\ntype TreeNodeRendererProps = Pick<TreeRendererProps, \"expandNode\" | \"reloadTree\"> &\n Omit<TreeNodeProps, \"actions\" | \"label\" | \"expanded\" | \"unstable_decorations\" | \"error\"> &\n TreeNodeRendererOwnProps;\n\n/**\n * A component that renders given `FlatTreeNode` using the `Tree.Item` component from `@itwin/itwinui-react`. The\n * `FlatTreeNode` objects for this renderer are generally created using the `useFlatTreeNodeList` hook.\n *\n * @see `TreeRenderer`\n * @see https://itwinui.bentley.com/docs/tree\n * @public\n */\nexport const StrataKitTreeNodeRenderer: FC<PropsWithRef<TreeNodeRendererProps & RefAttributes<HTMLElement>>> = memo(\n forwardRef<HTMLElement, TreeNodeRendererProps>(function HierarchyNode(\n {\n node,\n selected,\n expandNode,\n onNodeClick,\n onNodeKeyDown,\n reloadTree,\n getClassName,\n getLabel,\n getSublabel,\n getMenuActions,\n getInlineActions,\n getDecorations,\n getContextMenuActions,\n ...treeItemProps\n },\n forwardedRef,\n ) {\n const nodeRef = useRef<HTMLElement>(null);\n const ref = useMergedRefs(forwardedRef, nodeRef);\n const { localizedStrings } = useLocalizationContext();\n const renameContext = useRenameContext();\n const [contextMenuProps, setContextMenuProps] = useState<{ position: { x: number; y: number }; actions: ReactNode[] } | undefined>(undefined);\n\n const className = useMemo(() => getClassName?.(node), [getClassName, node]);\n const label = useMemo(() => (getLabel ? getLabel(node) : node.label), [getLabel, node]);\n const description = useMemo(() => (getSublabel ? getSublabel(node) : undefined), [getSublabel, node]);\n const decorations = useMemo(() => getDecorations?.(node), [getDecorations, node]);\n const inlineActions = useMemo(() => {\n if (node.error !== undefined && node.error.type === \"ChildrenLoad\") {\n return [\n <TreeActionBase\n key=\"retry\"\n label={localizedStrings.retry}\n onClick={() => reloadTree({ parentNodeId: node.id, state: \"reset\" })}\n visible={true}\n icon={refreshSvg}\n variant=\"inline\"\n />,\n ];\n }\n if (!getInlineActions) {\n return [];\n }\n return injectActionVariant(getInlineActions(node), \"inline\");\n }, [node, getInlineActions, localizedStrings.retry, reloadTree]);\n\n const menuItems = useMemo(() => {\n if (!getMenuActions) {\n return undefined;\n }\n return injectActionVariant(getMenuActions(node), \"default\");\n }, [getMenuActions, node]);\n\n const expanded = useMemo(() => {\n if (node.error) {\n return undefined;\n }\n\n if (node.isExpanded || node.children === true || node.children.length > 0) {\n return node.isExpanded;\n }\n\n return undefined;\n }, [node.children, node.error, node.isExpanded]);\n\n const isDisabled = treeItemProps[\"aria-disabled\"] === true;\n\n const { onLabelChanged, setIsRenaming, isRenaming } = renameContext ?? {};\n const labelEditor = isRenaming ? (\n <LabelEditor\n initialLabel={node.label}\n onChange={(newLabel) => {\n onLabelChanged?.(newLabel);\n setIsRenaming?.(false);\n }}\n onCancel={() => {\n setIsRenaming?.(false);\n }}\n />\n ) : undefined;\n\n return (\n <>\n <Tree.Item\n {...treeItemProps}\n ref={ref}\n className={className}\n label={labelEditor ?? label}\n description={description}\n selected={selected}\n expanded={expanded}\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 if (isDisabled) {\n return;\n }\n\n 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 inlineActions={inlineActions}\n actions={menuItems}\n unstable_decorations={decorations}\n error={node.error ? node.error.id : undefined}\n onContextMenu={(e) => {\n if (!getContextMenuActions) {\n return;\n }\n\n e.preventDefault();\n const contextMenuActions = injectActionVariant(getContextMenuActions(node), \"context-menu\");\n if (contextMenuActions.length === 0) {\n return;\n }\n\n setContextMenuProps({\n position: {\n x: e.clientX,\n y: e.clientY,\n },\n actions: contextMenuActions,\n });\n }}\n />\n <DropdownMenu.Provider\n open={contextMenuProps !== undefined}\n setOpen={(open) => {\n if (!open) {\n setContextMenuProps(undefined);\n }\n }}\n key={`${node.id}-${contextMenuProps?.position.x ?? \"\"}-${contextMenuProps?.position.y ?? \"\"}`}\n >\n {contextMenuProps ? (\n <DropdownMenu.Button style={{ position: \"fixed\", top: contextMenuProps.position.y, left: contextMenuProps.position.x }} render={<div />} />\n ) : null}\n {/* `autoFocus` prop is coming from ariakit and is not native HTML `autoFocus` prop. */}\n {/* `focusable` is needed for `autoFocus` to work. StrataKit exposes only `autoFocus` and does not set `focusable` internally. */}\n {/* eslint-disable jsx-a11y/no-autofocus */}\n {/* @ts-expect-error focusable is passed through */}\n <DropdownMenu.Content focusable autoFocus={true}>\n {contextMenuProps?.actions}\n </DropdownMenu.Content>\n </DropdownMenu.Provider>\n </>\n );\n }),\n);\n\nexport const PlaceholderNode: FC<PropsWithRef<Omit<TreeNodeProps, \"onExpanded\" | \"label\" | \"actions\" | \"icon\" | \"error\"> & RefAttributes<HTMLElement>>> = memo(\n forwardRef<HTMLElement, Omit<TreeNodeProps, \"onExpanded\" | \"label\" | \"actions\" | \"icon\" | \"error\">>(function PlaceholderNode({ ...props }, forwardedRef) {\n const { localizedStrings } = useLocalizationContext();\n return <Tree.Item {...props} ref={forwardedRef} label={localizedStrings.loading} icon={<Spinner size={\"small\"} title={localizedStrings.loading} />} />;\n }),\n);\n\nfunction LabelEditor({ initialLabel, onChange, onCancel }: { initialLabel: string; onChange: (newLabel: string) => void; onCancel: () => void }) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [newLabelValue, setNewLabelValue] = useState(initialLabel);\n const handleLabelChange = () => {\n if (initialLabel !== newLabelValue) {\n onChange(newLabelValue);\n return;\n }\n onCancel();\n };\n\n const cancelLabelChange = () => {\n setNewLabelValue(initialLabel);\n onCancel();\n };\n\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, []);\n\n return (\n <TextBox.Root>\n <TextBox.Input\n ref={inputRef}\n value={newLabelValue}\n onChange={(event) => setNewLabelValue(event.target.value)}\n onBlur={handleLabelChange}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n handleLabelChange();\n } else if (event.key === \"Escape\") {\n cancelLabelChange();\n }\n }}\n />\n </TextBox.Root>\n );\n}\n\nfunction injectActionVariant(actions: ReactNode[], variant: TreeActionBaseAttributes[\"variant\"]) {\n return actions\n .filter((action) => isValidElement<TreeActionBaseAttributes>(action))\n .map((action) => cloneElement<TreeActionBaseAttributes>(action, { variant }));\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"]}
1
+ {"version":3,"file":"TreeNodeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/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 cloneElement,\n ComponentPropsWithoutRef,\n FC,\n forwardRef,\n isValidElement,\n memo,\n PropsWithRef,\n ReactNode,\n RefAttributes,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Spinner, TextBox } from \"@stratakit/bricks\";\nimport refreshSvg from \"@stratakit/icons/refresh.svg\";\nimport { DropdownMenu, Tree } from \"@stratakit/structures\";\nimport { TreeRendererProps } from \"../Renderers.js\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\nimport { useRenameContext } from \"./RenameAction.js\";\nimport { TreeActionBase, TreeActionBaseAttributes } from \"./TreeAction.js\";\n\n/** @alpha */\nexport interface TreeNodeRendererOwnProps extends Pick<TreeRendererProps, \"expandNode\" | \"reloadTree\"> {\n /** Node that is rendered. */\n node: PresentationHierarchyNode;\n /**\n * Menu actions for tree item.\n * Must be an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n menuActions?: ReactNode[];\n /**\n * Inline actions for tree item.\n * Must be an array of `<TreeActionBase />` elements.\n * Max 2 items.\n */\n inlineActions?: ReactNode[];\n /**\n * Context menu actions for tree item.\n * Must be an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n contextMenuActions?: ReactNode[];\n}\n\n/** @alpha */\nexport type StrataKitTreeItemProps = Omit<\n ComponentPropsWithoutRef<typeof Tree.Item>,\n \"actions\" | \"inlineActions\" | \"expanded\" | \"onExpandedChange\" | \"icon\" | \"unstable_decorations\" | \"error\"\n> & {\n /**\n * Used to render elements between expander and label.\n * E.g. icons, color picker, etc.\n */\n decorations?: ReactNode;\n};\n\n/** @alpha */\nexport type TreeNodeRendererProps = StrataKitTreeItemProps & TreeNodeRendererOwnProps;\n\n/**\n * A component that renders given `FlatTreeNode` using the `Tree.Item` component from `@itwin/itwinui-react`. The\n * `FlatTreeNode` objects for this renderer are generally created using the `useFlatTreeNodeList` hook.\n *\n * @see `TreeRenderer`\n * @see https://itwinui.bentley.com/docs/tree\n * @public\n */\nexport const StrataKitTreeNodeRenderer: FC<PropsWithRef<TreeNodeRendererProps & RefAttributes<HTMLElement>>> = memo(\n forwardRef<HTMLElement, TreeNodeRendererProps>(function HierarchyNode(props, forwardedRef) {\n const { node, decorations, inlineActions, menuActions, contextMenuActions, expandNode, reloadTree, ...treeItemProps } = props;\n const { localizedStrings } = useLocalizationContext();\n const renameContext = useRenameContext();\n const [contextMenuProps, setContextMenuProps] = useState<{ position: { x: number; y: number }; actions: ReactNode[] } | undefined>(undefined);\n\n const label = treeItemProps.label ?? node.label;\n const inlineActionItems = useMemo(() => {\n if (node.error !== undefined && node.error.type === \"ChildrenLoad\") {\n return [\n <TreeActionBase\n key=\"retry\"\n label={localizedStrings.retry}\n onClick={() => reloadTree({ parentNodeId: node.id, state: \"reset\" })}\n visible={true}\n icon={refreshSvg}\n variant=\"inline\"\n />,\n ];\n }\n if (!inlineActions) {\n return undefined;\n }\n return injectActionVariant(inlineActions, \"inline\");\n }, [node, inlineActions, localizedStrings.retry, reloadTree]);\n\n const menuActionItems = useMemo(() => {\n if (!menuActions) {\n return undefined;\n }\n return injectActionVariant(menuActions, \"default\");\n }, [menuActions]);\n\n const expanded = useMemo(() => {\n if (node.error) {\n return undefined;\n }\n\n if (node.isExpanded || node.children === true || node.children.length > 0) {\n return node.isExpanded;\n }\n\n return undefined;\n }, [node.children, node.error, node.isExpanded]);\n\n const { onLabelChanged, setIsRenaming, isRenaming } = renameContext ?? {};\n const labelEditor = isRenaming ? (\n <LabelEditor\n initialLabel={node.label}\n onChange={(newLabel) => {\n onLabelChanged?.(newLabel);\n setIsRenaming?.(false);\n }}\n onCancel={() => {\n setIsRenaming?.(false);\n }}\n />\n ) : undefined;\n\n return (\n <>\n <Tree.Item\n {...treeItemProps}\n ref={forwardedRef}\n label={labelEditor ?? label}\n expanded={expanded}\n onExpandedChange={useCallback(\n (isExpanded: boolean) => {\n expandNode(node.id, isExpanded);\n },\n [node, expandNode],\n )}\n inlineActions={inlineActionItems}\n actions={menuActionItems}\n unstable_decorations={decorations}\n error={node.error ? node.error.id : undefined}\n onContextMenu={(e) => {\n if (treeItemProps.onContextMenu) {\n treeItemProps.onContextMenu(e);\n }\n\n if (!contextMenuActions) {\n return;\n }\n\n e.preventDefault();\n const actions = injectActionVariant(contextMenuActions, \"context-menu\");\n if (actions.length === 0) {\n return;\n }\n\n setContextMenuProps({\n position: {\n x: e.clientX,\n y: e.clientY,\n },\n actions,\n });\n }}\n />\n <DropdownMenu.Provider\n open={contextMenuProps !== undefined}\n setOpen={(open) => {\n if (!open) {\n setContextMenuProps(undefined);\n }\n }}\n key={`${node.id}-${contextMenuProps?.position.x ?? \"\"}-${contextMenuProps?.position.y ?? \"\"}`}\n >\n {contextMenuProps ? (\n <DropdownMenu.Button style={{ position: \"fixed\", top: contextMenuProps.position.y, left: contextMenuProps.position.x }} render={<div />} />\n ) : null}\n {/* `autoFocus` prop is coming from ariakit and is not native HTML `autoFocus` prop. */}\n {/* `focusable` is needed for `autoFocus` to work. StrataKit exposes only `autoFocus` and does not set `focusable` internally. */}\n {/* eslint-disable jsx-a11y/no-autofocus */}\n {/* @ts-expect-error focusable is passed through */}\n <DropdownMenu.Content focusable autoFocus={true}>\n {contextMenuProps?.actions}\n </DropdownMenu.Content>\n </DropdownMenu.Provider>\n </>\n );\n }),\n);\n\nexport const PlaceholderNode: FC<\n PropsWithRef<Pick<StrataKitTreeItemProps, \"style\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\"> & RefAttributes<HTMLElement>>\n> = memo(\n forwardRef<HTMLElement, Pick<StrataKitTreeItemProps, \"style\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\">>(function PlaceholderNode(\n { ...props },\n forwardedRef,\n ) {\n const { localizedStrings } = useLocalizationContext();\n return (\n <Tree.Item\n {...props}\n ref={forwardedRef}\n label={localizedStrings.loading}\n unstable_decorations={<Spinner size={\"small\"} title={localizedStrings.loading} />}\n />\n );\n }),\n);\n\nfunction LabelEditor({ initialLabel, onChange, onCancel }: { initialLabel: string; onChange: (newLabel: string) => void; onCancel: () => void }) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [newLabelValue, setNewLabelValue] = useState(initialLabel);\n const handleLabelChange = () => {\n if (initialLabel !== newLabelValue) {\n onChange(newLabelValue);\n return;\n }\n onCancel();\n };\n\n const cancelLabelChange = () => {\n setNewLabelValue(initialLabel);\n onCancel();\n };\n\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, []);\n\n return (\n <TextBox.Root>\n <TextBox.Input\n ref={inputRef}\n value={newLabelValue}\n onChange={(event) => setNewLabelValue(event.target.value)}\n onBlur={handleLabelChange}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n handleLabelChange();\n } else if (event.key === \"Escape\") {\n cancelLabelChange();\n }\n }}\n />\n </TextBox.Root>\n );\n}\n\nfunction injectActionVariant(actions: ReactNode[], variant: TreeActionBaseAttributes[\"variant\"]) {\n return actions\n .filter((action) => isValidElement<TreeActionBaseAttributes>(action))\n .map((action) => cloneElement<TreeActionBaseAttributes>(action, { variant }));\n}\n"]}
@@ -1,17 +1,14 @@
1
- import { ComponentPropsWithoutRef, ReactElement, ReactNode } from "react";
1
+ import { ComponentProps, ComponentPropsWithoutRef, ReactElement, ReactNode } from "react";
2
2
  import { Tree } from "@stratakit/structures";
3
3
  import { TreeRendererProps } from "../Renderers.js";
4
4
  import { PresentationHierarchyNode } from "../TreeNode.js";
5
5
  import { SelectionMode } from "../UseSelectionHandler.js";
6
6
  import { LocalizationContextProvider } from "./LocalizationContext.js";
7
7
  import { TreeErrorRendererProps } from "./TreeErrorRenderer.js";
8
- import { StrataKitTreeNodeRenderer } from "./TreeNodeRenderer.js";
9
- /** @alpha */
10
- export type TreeProps = ComponentPropsWithoutRef<typeof Tree.Root>;
11
- /** @alpha */
12
- export type TreeNodeRendererProps = ComponentPropsWithoutRef<typeof StrataKitTreeNodeRenderer>;
8
+ import { StrataKitTreeItemProps } from "./TreeNodeRenderer.js";
13
9
  /** @alpha */
14
10
  interface TreeRendererOwnProps {
11
+ id?: string;
15
12
  /**
16
13
  * A user friendly display label of the tree. Should be unique within the consuming application,
17
14
  * as it's used for accessibility purposes.
@@ -30,6 +27,8 @@ interface TreeRendererOwnProps {
30
27
  */
31
28
  onLabelChanged?: (newLabel: string) => void;
32
29
  };
30
+ treeRootProps?: Partial<Omit<ComponentProps<typeof Tree.Root>, "style">>;
31
+ getTreeItemProps?: (node: PresentationHierarchyNode) => Partial<Omit<StrataKitTreeItemProps, "selected" | "aria-level" | "aria-posinset" | "aria-setsize">>;
33
32
  /**
34
33
  * Callback that returns menu actions for tree item.
35
34
  * Must return an array of `<TreeActionBase />` or `<Divider />` elements.
@@ -57,7 +56,7 @@ interface TreeRendererOwnProps {
57
56
  }) => ReactNode[];
58
57
  }
59
58
  /** @alpha */
60
- type StrataKitTreeRendererProps = TreeRendererProps & Pick<TreeErrorRendererProps, "onFilterClick"> & Omit<TreeNodeRendererProps, "node" | "aria-level" | "aria-posinset" | "aria-setsize" | "reloadTree" | "selected" | "error" | "getMenuActions" | "getInlineActions" | "getContextMenuActions"> & TreeRendererOwnProps & ComponentPropsWithoutRef<typeof LocalizationContextProvider>;
59
+ type StrataKitTreeRendererProps = TreeRendererProps & Pick<TreeErrorRendererProps, "onFilterClick"> & TreeRendererOwnProps & ComponentPropsWithoutRef<typeof LocalizationContextProvider>;
61
60
  /**
62
61
  * A component that renders a tree using the `Tree` component from `@itwin/itwinui-react`. The tree nodes
63
62
  * are rendered using `TreeNodeRenderer` component from this package.
@@ -65,6 +64,6 @@ type StrataKitTreeRendererProps = TreeRendererProps & Pick<TreeErrorRendererProp
65
64
  * @see https://itwinui.bentley.com/docs/tree
66
65
  * @alpha
67
66
  */
68
- export declare function StrataKitTreeRenderer({ rootNodes, selectNodes, selectionMode, expandNode, treeLabel, localizedStrings, getHierarchyLevelDetails, onFilterClick, reloadTree, isNodeSelected, errorRenderer, onNodeClick: onNodeClickOverride, onNodeKeyDown: onNodeKeyDownOverride, getEditingProps, id, getInlineActions, getMenuActions, getContextMenuActions, ...treeProps }: StrataKitTreeRendererProps): import("react/jsx-runtime").JSX.Element;
67
+ export declare function StrataKitTreeRenderer(props: StrataKitTreeRendererProps): import("react/jsx-runtime").JSX.Element;
69
68
  export {};
70
69
  //# sourceMappingURL=TreeRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TreeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,wBAAwB,EAAmC,YAAY,EAAE,SAAS,EAA2C,MAAM,OAAO,CAAC;AACpJ,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAuB,MAAM,2BAA2B,CAAC;AAG/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EAAqB,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAmB,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAEnF,aAAa;AACb,MAAM,MAAM,SAAS,GAAG,wBAAwB,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AAEnE,aAAa;AACb,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE/F,aAAa;AACb,UAAU,oBAAoB;IAC5B;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,4FAA4F;IAC5F,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,YAAY,CAAC;IAChE,2DAA2D;IAC3D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK;QACrD;;;;WAIG;QACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7C,CAAC;IAEF;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,yBAAyB,CAAC;QAAC,aAAa,EAAE,yBAAyB,EAAE,CAAA;KAAE,KAAK,SAAS,EAAE,CAAC;IAC/H;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,yBAAyB,CAAC;QAAC,aAAa,EAAE,yBAAyB,EAAE,CAAA;KAAE,KAAK,SAAS,EAAE,CAAC;IACjI;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,yBAAyB,CAAC;QAAC,aAAa,EAAE,yBAAyB,EAAE,CAAA;KAAE,KAAK,SAAS,EAAE,CAAC;CACvI;AAED,aAAa;AACb,KAAK,0BAA0B,GAAG,iBAAiB,GACjD,IAAI,CAAC,sBAAsB,EAAE,eAAe,CAAC,GAC7C,IAAI,CACF,qBAAqB,EACnB,MAAM,GACN,YAAY,GACZ,eAAe,GACf,cAAc,GACd,YAAY,GACZ,UAAU,GACV,OAAO,GACP,gBAAgB,GAChB,kBAAkB,GAClB,uBAAuB,CAC1B,GACD,oBAAoB,GACpB,wBAAwB,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EAAE,mBAAmB,EAChC,aAAa,EAAE,qBAAqB,EACpC,eAAe,EACf,EAAE,EACF,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,GAAG,SAAS,EACb,EAAE,0BAA0B,2CAgH5B"}
1
+ {"version":3,"file":"TreeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,cAAc,EACd,wBAAwB,EAIxB,YAAY,EACZ,SAAS,EAKV,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAuB,MAAM,2BAA2B,CAAC;AAG/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EAAqB,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAmB,sBAAsB,EAAoD,MAAM,uBAAuB,CAAC;AAElI,aAAa;AACb,UAAU,oBAAoB;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,4FAA4F;IAC5F,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,YAAY,CAAC;IAChE,2DAA2D;IAC3D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK;QACrD;;;;WAIG;QACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7C,CAAC;IAEF,aAAa,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAEzE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,UAAU,GAAG,YAAY,GAAG,eAAe,GAAG,cAAc,CAAC,CAAC,CAAC;IAE5J;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,yBAAyB,CAAC;QAAC,aAAa,EAAE,yBAAyB,EAAE,CAAA;KAAE,KAAK,SAAS,EAAE,CAAC;IAC/H;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,yBAAyB,CAAC;QAAC,aAAa,EAAE,yBAAyB,EAAE,CAAA;KAAE,KAAK,SAAS,EAAE,CAAC;IACjI;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,yBAAyB,CAAC;QAAC,aAAa,EAAE,yBAAyB,EAAE,CAAA;KAAE,KAAK,SAAS,EAAE,CAAC;CACvI;AAED,aAAa;AACb,KAAK,0BAA0B,GAAG,iBAAiB,GACjD,IAAI,CAAC,sBAAsB,EAAE,eAAe,CAAC,GAC7C,oBAAoB,GACpB,wBAAwB,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,2CA4HtE"}
@@ -1,14 +1,13 @@
1
- import { createElement as _createElement } from "react";
2
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
2
  /*---------------------------------------------------------------------------------------------
4
3
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
5
4
  * See LICENSE.md in the project root for license terms and full copyright notice.
6
5
  *--------------------------------------------------------------------------------------------*/
7
- import { forwardRef, memo, useCallback, useEffect, useMemo, useRef } from "react";
6
+ import { forwardRef, memo, useCallback, useEffect, useMemo, useRef, } from "react";
8
7
  import { Tree } from "@stratakit/structures";
9
8
  import { useVirtualizer } from "@tanstack/react-virtual";
10
9
  import { useSelectionHandler } from "../UseSelectionHandler.js";
11
- import { useEvent } from "../Utils.js";
10
+ import { useEvent, useMergedRefs } from "../Utils.js";
12
11
  import { isPlaceholderItem, useErrorList, useFlatTreeItems } from "./FlatTreeNode.js";
13
12
  import { LocalizationContextProvider } from "./LocalizationContext.js";
14
13
  import { RenameContextProvider } from "./RenameAction.js";
@@ -21,14 +20,13 @@ import { PlaceholderNode, StrataKitTreeNodeRenderer } from "./TreeNodeRenderer.j
21
20
  * @see https://itwinui.bentley.com/docs/tree
22
21
  * @alpha
23
22
  */
24
- export function StrataKitTreeRenderer({ rootNodes, selectNodes, selectionMode, expandNode, treeLabel, localizedStrings, getHierarchyLevelDetails, onFilterClick, reloadTree, isNodeSelected, errorRenderer, onNodeClick: onNodeClickOverride, onNodeKeyDown: onNodeKeyDownOverride, getEditingProps, id, getInlineActions, getMenuActions, getContextMenuActions, ...treeProps }) {
23
+ export function StrataKitTreeRenderer(props) {
24
+ const { id, rootNodes, selectNodes, selectionMode, expandNode, treeLabel, localizedStrings, getHierarchyLevelDetails, onFilterClick, reloadTree, isNodeSelected, errorRenderer, treeRootProps, getContextMenuActions, getEditingProps, getInlineActions, getMenuActions, getTreeItemProps, } = props;
25
25
  const { onNodeClick, onNodeKeyDown } = useSelectionHandler({
26
26
  rootNodes,
27
27
  selectNodes: selectNodes ?? noopSelectNodes,
28
28
  selectionMode: selectionMode ?? "single",
29
29
  });
30
- const handleNodeClick = useEvent(onNodeClickOverride ?? onNodeClick);
31
- const handleKeyDown = useEvent(onNodeKeyDownOverride ?? onNodeKeyDown);
32
30
  const flatItems = useFlatTreeItems(rootNodes);
33
31
  const errorList = useErrorList(rootNodes);
34
32
  const scrollToNode = useRef(undefined);
@@ -80,24 +78,13 @@ export function StrataKitTreeRenderer({ rootNodes, selectNodes, selectionMode, e
80
78
  return calculatedSelectedNodes;
81
79
  };
82
80
  }, [flatItems, isNodeSelected]);
83
- const nodeActions = useMemo(() => {
84
- return {
85
- getMenuActions: getMenuActions ? (node) => getMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,
86
- getInlineActions: getInlineActions
87
- ? (node) => getInlineActions({ targetNode: node, selectedNodes: getSelectedNodes() })
88
- : undefined,
89
- getContextMenuActions: getContextMenuActions
90
- ? (node) => getContextMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() })
91
- : undefined,
92
- };
93
- }, [getMenuActions, getInlineActions, getContextMenuActions, getSelectedNodes]);
94
- return (_jsxs(LocalizationContextProvider, { localizedStrings: localizedStrings, children: [errorRenderer ? errorRenderer(errorRendererProps) : _jsx(TreeErrorRenderer, { ...errorRendererProps }), _jsx("div", { id: id, 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) => {
81
+ return (_jsxs(LocalizationContextProvider, { localizedStrings: localizedStrings, children: [errorRenderer ? errorRenderer(errorRendererProps) : _jsx(TreeErrorRenderer, { ...errorRendererProps }), _jsx("div", { id: id, style: { height: "100%", width: "100%", overflowY: "auto" }, ref: parentRef, children: _jsx(Tree.Root, { ...treeRootProps, style: { height: virtualizer.getTotalSize(), minHeight: "100%", width: "100%", position: "relative", overflow: "hidden" }, children: items.map((virtualizedItem) => {
95
82
  const item = flatItems[virtualizedItem.index];
96
83
  const selected = isNodeSelected?.(item.id) ?? false;
97
- return (_createElement(VirtualTreeItem, { ...treeProps, ...nodeActions, onNodeClick: handleNodeClick, onNodeKeyDown: handleKeyDown, ref: virtualizer.measureElement, start: virtualizedItem.start, expandNode: expandNode, item: item, key: virtualizedItem.key, "data-index": virtualizedItem.index, reloadTree: reloadTree, selected: selected, getEditingProps: getEditingProps }));
84
+ return (_jsx(VirtualTreeItem, { ref: virtualizer.measureElement, "data-index": virtualizedItem.index, start: virtualizedItem.start, item: item, selected: selected, expandNode: expandNode, reloadTree: reloadTree, onNodeClick: onNodeClick, onNodeKeyDown: onNodeKeyDown, getSelectedNodes: getSelectedNodes, getContextMenuActions: getContextMenuActions, getEditingProps: getEditingProps, getInlineActions: getInlineActions, getMenuActions: getMenuActions, getTreeItemProps: getTreeItemProps }, virtualizedItem.key));
98
85
  }) }) })] }));
99
86
  }
100
- const VirtualTreeItem = memo(forwardRef(function VirtualTreeItem({ start, item, getDecorations, getMenuActions, getInlineActions, getContextMenuActions, getClassName, getLabel, getSublabel, expandNode, reloadTree, onNodeClick, onNodeKeyDown, getEditingProps, ...props }, forwardedRef) {
87
+ const VirtualTreeItem = memo(forwardRef(function VirtualTreeItem({ start, item, ...props }, forwardedRef) {
101
88
  const style = useMemo(() => ({
102
89
  position: "absolute",
103
90
  top: 0,
@@ -107,10 +94,42 @@ const VirtualTreeItem = memo(forwardRef(function VirtualTreeItem({ start, item,
107
94
  willChange: "transform",
108
95
  }), [start]);
109
96
  if (isPlaceholderItem(item)) {
110
- return _jsx(PlaceholderNode, { ...props, ref: forwardedRef, style: style, "aria-level": item.level, "aria-posinset": 1, "aria-setsize": 1 });
97
+ return _jsx(PlaceholderNode, { ref: forwardedRef, "data-index": props["data-index"], style: style, "aria-level": item.level, "aria-posinset": 1, "aria-setsize": 1 });
111
98
  }
99
+ return _jsx(HierarchyNodeItem, { ...props, ref: forwardedRef, style: style, item: item });
100
+ }));
101
+ const HierarchyNodeItem = memo(forwardRef(function HierarchyNodeItem({ item, selected, getEditingProps, getTreeItemProps, onNodeClick, onNodeKeyDown, getSelectedNodes, getMenuActions, getInlineActions, getContextMenuActions, ...rest }, forwardedRef) {
102
+ const nodeRef = useRef(null);
103
+ const node = item.node;
104
+ const treeItemProps = getTreeItemProps?.(node);
105
+ const isDisabled = treeItemProps?.["aria-disabled"] === true;
106
+ const nodeActions = useMemo(() => ({
107
+ menuActions: getMenuActions ? getMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,
108
+ inlineActions: getInlineActions ? getInlineActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,
109
+ contextMenuActions: getContextMenuActions ? getContextMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,
110
+ }), [node, getMenuActions, getInlineActions, getContextMenuActions, getSelectedNodes]);
111
+ const onClick = useEvent((e) => {
112
+ if (treeItemProps?.onClick) {
113
+ treeItemProps.onClick(e);
114
+ }
115
+ if (isDisabled) {
116
+ return;
117
+ }
118
+ onNodeClick?.(node, !selected, e);
119
+ });
120
+ const onKeyDown = useEvent((e) => {
121
+ if (treeItemProps?.onKeyDown) {
122
+ treeItemProps.onKeyDown(e);
123
+ }
124
+ // Ignore if it is called on the element inside, e.g. checkbox or expander
125
+ if (isDisabled || e.target !== nodeRef.current) {
126
+ return;
127
+ }
128
+ onNodeKeyDown?.(node, !selected, e);
129
+ });
112
130
  const editingProps = getEditingProps?.(item.node);
113
- return (_jsx(RenameContextProvider, { onLabelChanged: editingProps?.onLabelChanged, children: _jsx(StrataKitTreeNodeRenderer, { ...props, ref: forwardedRef, style: style, "aria-level": item.level, "aria-posinset": item.posInLevel, "aria-setsize": item.levelSize, node: item.node, expandNode: expandNode, reloadTree: reloadTree, getDecorations: getDecorations, getMenuActions: getMenuActions, getInlineActions: getInlineActions, getContextMenuActions: getContextMenuActions, getClassName: getClassName, getLabel: getLabel, getSublabel: getSublabel, onNodeClick: onNodeClick, onNodeKeyDown: onNodeKeyDown }) }));
131
+ const ref = useMergedRefs(forwardedRef, nodeRef);
132
+ return (_jsx(RenameContextProvider, { onLabelChanged: editingProps?.onLabelChanged, children: _jsx(StrataKitTreeNodeRenderer, { ...treeItemProps, ...rest, ...nodeActions, ref: ref, "aria-level": item.level, "aria-posinset": item.posInLevel, "aria-setsize": item.levelSize, node: item.node, selected: selected, onClick: onClick, onKeyDown: onKeyDown }) }));
114
133
  }));
115
134
  function noopSelectNodes() { }
116
135
  //# sourceMappingURL=TreeRenderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TreeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/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, CSSProperties, forwardRef, memo, ReactElement, ReactNode, useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { Tree } from \"@stratakit/structures\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { TreeRendererProps } from \"../Renderers.js\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { SelectionMode, useSelectionHandler } from \"../UseSelectionHandler.js\";\nimport { useEvent } from \"../Utils.js\";\nimport { ErrorItem, FlatTreeItem, FlatTreeNodeItem, isPlaceholderItem, useErrorList, useFlatTreeItems } from \"./FlatTreeNode.js\";\nimport { LocalizationContextProvider } from \"./LocalizationContext.js\";\nimport { RenameContextProvider } from \"./RenameAction.js\";\nimport { TreeErrorRenderer, TreeErrorRendererProps } from \"./TreeErrorRenderer.js\";\nimport { PlaceholderNode, StrataKitTreeNodeRenderer } from \"./TreeNodeRenderer.js\";\n\n/** @alpha */\nexport type TreeProps = ComponentPropsWithoutRef<typeof Tree.Root>;\n\n/** @alpha */\nexport type TreeNodeRendererProps = ComponentPropsWithoutRef<typeof StrataKitTreeNodeRenderer>;\n\n/** @alpha */\ninterface TreeRendererOwnProps {\n /**\n * A user friendly display label of the tree. Should be unique within the consuming application,\n * as it's used for accessibility purposes.\n */\n treeLabel: string;\n /** Active selection mode used by the tree. Defaults to `\"single\"`. */\n selectionMode?: SelectionMode;\n /** A render function for errors' display component. Defaults to `<TreeErrorRenderer />`. */\n errorRenderer?: (props: TreeErrorRendererProps) => ReactElement;\n /** Props that defines if current node supports editing. */\n getEditingProps?: (node: PresentationHierarchyNode) => {\n /**\n * A callback that is invoked when node label is changed. Should be used together\n * with `<RenameAction />` to enter label editing mode. Node label is not editable\n * when this is not supplied.\n */\n onLabelChanged?: (newLabel: string) => void;\n };\n\n /**\n * Callback that returns menu actions for tree item.\n * Must return an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n getMenuActions?: (props: { targetNode: PresentationHierarchyNode; selectedNodes: PresentationHierarchyNode[] }) => ReactNode[];\n /**\n * Callback that returns inline actions for tree item.\n * Must return an array of `<TreeActionBase />` elements.\n * Max 2 items.\n */\n getInlineActions?: (props: { targetNode: PresentationHierarchyNode; selectedNodes: PresentationHierarchyNode[] }) => ReactNode[];\n /**\n * Callback that returns actions for tree item context menu.\n * Must return an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n getContextMenuActions?: (props: { targetNode: PresentationHierarchyNode; selectedNodes: PresentationHierarchyNode[] }) => ReactNode[];\n}\n\n/** @alpha */\ntype StrataKitTreeRendererProps = TreeRendererProps &\n Pick<TreeErrorRendererProps, \"onFilterClick\"> &\n Omit<\n TreeNodeRendererProps,\n | \"node\"\n | \"aria-level\"\n | \"aria-posinset\"\n | \"aria-setsize\"\n | \"reloadTree\"\n | \"selected\"\n | \"error\"\n | \"getMenuActions\"\n | \"getInlineActions\"\n | \"getContextMenuActions\"\n > &\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 StrataKitTreeRenderer({\n rootNodes,\n selectNodes,\n selectionMode,\n expandNode,\n treeLabel,\n localizedStrings,\n getHierarchyLevelDetails,\n onFilterClick,\n reloadTree,\n isNodeSelected,\n errorRenderer,\n onNodeClick: onNodeClickOverride,\n onNodeKeyDown: onNodeKeyDownOverride,\n getEditingProps,\n id,\n getInlineActions,\n getMenuActions,\n getContextMenuActions,\n ...treeProps\n}: StrataKitTreeRendererProps) {\n const { onNodeClick, onNodeKeyDown } = useSelectionHandler({\n rootNodes,\n selectNodes: selectNodes ?? noopSelectNodes,\n selectionMode: selectionMode ?? \"single\",\n });\n const handleNodeClick = useEvent(onNodeClickOverride ?? onNodeClick);\n const handleKeyDown = useEvent(onNodeKeyDownOverride ?? onNodeKeyDown);\n const flatItems = useFlatTreeItems(rootNodes);\n const errorList = useErrorList(rootNodes);\n\n const scrollToNode = useRef<string | undefined>(undefined);\n const parentRef = useRef<HTMLDivElement>(null);\n\n const virtualizer = useVirtualizer({\n count: flatItems.length,\n getScrollElement: () => parentRef.current,\n getItemKey: useCallback((index: number) => flatItems[index].id, [flatItems]),\n estimateSize: () => 28,\n overscan: 10,\n });\n\n const items = virtualizer.getVirtualItems();\n\n const scrollToElement = useCallback(\n ({ errorNode, expandTo }: ErrorItem) => {\n const index = flatItems.findIndex((flatItem) => flatItem.id === errorNode.id);\n if (index === -1) {\n expandTo((nodeId) => expandNode(nodeId, true));\n scrollToNode.current = errorNode.id;\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n },\n [expandNode, flatItems, virtualizer],\n );\n\n useEffect(() => {\n if (scrollToNode.current === undefined) {\n return;\n }\n const index = flatItems.findIndex((flatItem) => flatItem.id === scrollToNode.current);\n if (index === -1) {\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n scrollToNode.current = undefined;\n }, [flatItems, virtualizer]);\n\n const errorRendererProps: TreeErrorRendererProps = {\n treeLabel,\n errorList,\n scrollToElement,\n getHierarchyLevelDetails,\n onFilterClick,\n reloadTree,\n };\n\n const getSelectedNodes = useMemo(() => {\n let calculatedSelectedNodes: PresentationHierarchyNode[];\n return () => {\n if (calculatedSelectedNodes === undefined) {\n calculatedSelectedNodes = flatItems\n .filter((item): item is FlatTreeNodeItem => !isPlaceholderItem(item) && isNodeSelected?.(item.id))\n .map((item) => item.node);\n }\n return calculatedSelectedNodes;\n };\n }, [flatItems, isNodeSelected]);\n\n const nodeActions = useMemo(() => {\n return {\n getMenuActions: getMenuActions ? (node: PresentationHierarchyNode) => getMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,\n getInlineActions: getInlineActions\n ? (node: PresentationHierarchyNode) => getInlineActions({ targetNode: node, selectedNodes: getSelectedNodes() })\n : undefined,\n getContextMenuActions: getContextMenuActions\n ? (node: PresentationHierarchyNode) => getContextMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() })\n : undefined,\n };\n }, [getMenuActions, getInlineActions, getContextMenuActions, getSelectedNodes]);\n\n return (\n <LocalizationContextProvider localizedStrings={localizedStrings}>\n {errorRenderer ? errorRenderer(errorRendererProps) : <TreeErrorRenderer {...errorRendererProps} />}\n <div id={id} 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 item = flatItems[virtualizedItem.index];\n const selected = isNodeSelected?.(item.id) ?? false;\n return (\n <VirtualTreeItem\n {...treeProps}\n {...nodeActions}\n onNodeClick={handleNodeClick}\n onNodeKeyDown={handleKeyDown}\n ref={virtualizer.measureElement}\n start={virtualizedItem.start}\n expandNode={expandNode}\n item={item}\n key={virtualizedItem.key}\n data-index={virtualizedItem.index}\n reloadTree={reloadTree}\n selected={selected}\n getEditingProps={getEditingProps}\n />\n );\n })}\n </Tree.Root>\n </div>\n </LocalizationContextProvider>\n );\n}\n\ntype VirtualTreeItemProps = Omit<TreeNodeRendererProps, \"node\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\"> & {\n start: number;\n item: FlatTreeItem;\n getEditingProps?: TreeRendererOwnProps[\"getEditingProps\"];\n};\n\nconst VirtualTreeItem = memo(\n forwardRef<HTMLElement, VirtualTreeItemProps>(function VirtualTreeItem(\n {\n start,\n item,\n getDecorations,\n getMenuActions,\n getInlineActions,\n getContextMenuActions,\n getClassName,\n getLabel,\n getSublabel,\n expandNode,\n reloadTree,\n onNodeClick,\n onNodeKeyDown,\n getEditingProps,\n ...props\n },\n forwardedRef,\n ) {\n const style: CSSProperties = 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 if (isPlaceholderItem(item)) {\n return <PlaceholderNode {...props} ref={forwardedRef} style={style} aria-level={item.level} aria-posinset={1} aria-setsize={1} />;\n }\n\n const editingProps = getEditingProps?.(item.node);\n return (\n <RenameContextProvider onLabelChanged={editingProps?.onLabelChanged}>\n <StrataKitTreeNodeRenderer\n {...props}\n ref={forwardedRef}\n style={style}\n aria-level={item.level}\n aria-posinset={item.posInLevel}\n aria-setsize={item.levelSize}\n node={item.node}\n expandNode={expandNode}\n reloadTree={reloadTree}\n getDecorations={getDecorations}\n getMenuActions={getMenuActions}\n getInlineActions={getInlineActions}\n getContextMenuActions={getContextMenuActions}\n getClassName={getClassName}\n getLabel={getLabel}\n getSublabel={getSublabel}\n onNodeClick={onNodeClick}\n onNodeKeyDown={onNodeKeyDown}\n />\n </RenameContextProvider>\n );\n }),\n);\n\nfunction noopSelectNodes() {}\n"]}
1
+ {"version":3,"file":"TreeRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/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 {\n ComponentProps,\n ComponentPropsWithoutRef,\n CSSProperties,\n forwardRef,\n memo,\n ReactElement,\n ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { Tree } from \"@stratakit/structures\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { TreeRendererProps } from \"../Renderers.js\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { SelectionMode, useSelectionHandler } from \"../UseSelectionHandler.js\";\nimport { useEvent, useMergedRefs } from \"../Utils.js\";\nimport { ErrorItem, FlatTreeItem, FlatTreeNodeItem, isPlaceholderItem, useErrorList, useFlatTreeItems } from \"./FlatTreeNode.js\";\nimport { LocalizationContextProvider } from \"./LocalizationContext.js\";\nimport { RenameContextProvider } from \"./RenameAction.js\";\nimport { TreeErrorRenderer, TreeErrorRendererProps } from \"./TreeErrorRenderer.js\";\nimport { PlaceholderNode, StrataKitTreeItemProps, StrataKitTreeNodeRenderer, TreeNodeRendererProps } from \"./TreeNodeRenderer.js\";\n\n/** @alpha */\ninterface TreeRendererOwnProps {\n id?: string;\n /**\n * A user friendly display label of the tree. Should be unique within the consuming application,\n * as it's used for accessibility purposes.\n */\n treeLabel: string;\n /** Active selection mode used by the tree. Defaults to `\"single\"`. */\n selectionMode?: SelectionMode;\n /** A render function for errors' display component. Defaults to `<TreeErrorRenderer />`. */\n errorRenderer?: (props: TreeErrorRendererProps) => ReactElement;\n /** Props that defines if current node supports editing. */\n getEditingProps?: (node: PresentationHierarchyNode) => {\n /**\n * A callback that is invoked when node label is changed. Should be used together\n * with `<RenameAction />` to enter label editing mode. Node label is not editable\n * when this is not supplied.\n */\n onLabelChanged?: (newLabel: string) => void;\n };\n\n treeRootProps?: Partial<Omit<ComponentProps<typeof Tree.Root>, \"style\">>;\n\n getTreeItemProps?: (node: PresentationHierarchyNode) => Partial<Omit<StrataKitTreeItemProps, \"selected\" | \"aria-level\" | \"aria-posinset\" | \"aria-setsize\">>;\n\n /**\n * Callback that returns menu actions for tree item.\n * Must return an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n getMenuActions?: (props: { targetNode: PresentationHierarchyNode; selectedNodes: PresentationHierarchyNode[] }) => ReactNode[];\n /**\n * Callback that returns inline actions for tree item.\n * Must return an array of `<TreeActionBase />` elements.\n * Max 2 items.\n */\n getInlineActions?: (props: { targetNode: PresentationHierarchyNode; selectedNodes: PresentationHierarchyNode[] }) => ReactNode[];\n /**\n * Callback that returns actions for tree item context menu.\n * Must return an array of `<TreeActionBase />` or `<Divider />` elements.\n */\n getContextMenuActions?: (props: { targetNode: PresentationHierarchyNode; selectedNodes: PresentationHierarchyNode[] }) => ReactNode[];\n}\n\n/** @alpha */\ntype StrataKitTreeRendererProps = TreeRendererProps &\n Pick<TreeErrorRendererProps, \"onFilterClick\"> &\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 StrataKitTreeRenderer(props: StrataKitTreeRendererProps) {\n const {\n id,\n rootNodes,\n selectNodes,\n selectionMode,\n expandNode,\n treeLabel,\n localizedStrings,\n getHierarchyLevelDetails,\n onFilterClick,\n reloadTree,\n isNodeSelected,\n errorRenderer,\n treeRootProps,\n getContextMenuActions,\n getEditingProps,\n getInlineActions,\n getMenuActions,\n getTreeItemProps,\n } = props;\n const { onNodeClick, onNodeKeyDown } = useSelectionHandler({\n rootNodes,\n selectNodes: selectNodes ?? noopSelectNodes,\n selectionMode: selectionMode ?? \"single\",\n });\n const flatItems = useFlatTreeItems(rootNodes);\n const errorList = useErrorList(rootNodes);\n\n const scrollToNode = useRef<string | undefined>(undefined);\n const parentRef = useRef<HTMLDivElement>(null);\n\n const virtualizer = useVirtualizer({\n count: flatItems.length,\n getScrollElement: () => parentRef.current,\n getItemKey: useCallback((index: number) => flatItems[index].id, [flatItems]),\n estimateSize: () => 28,\n overscan: 10,\n });\n\n const items = virtualizer.getVirtualItems();\n\n const scrollToElement = useCallback(\n ({ errorNode, expandTo }: ErrorItem) => {\n const index = flatItems.findIndex((flatItem) => flatItem.id === errorNode.id);\n if (index === -1) {\n expandTo((nodeId) => expandNode(nodeId, true));\n scrollToNode.current = errorNode.id;\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n },\n [expandNode, flatItems, virtualizer],\n );\n\n useEffect(() => {\n if (scrollToNode.current === undefined) {\n return;\n }\n const index = flatItems.findIndex((flatItem) => flatItem.id === scrollToNode.current);\n if (index === -1) {\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"end\" });\n scrollToNode.current = undefined;\n }, [flatItems, virtualizer]);\n\n const errorRendererProps: TreeErrorRendererProps = {\n treeLabel,\n errorList,\n scrollToElement,\n getHierarchyLevelDetails,\n onFilterClick,\n reloadTree,\n };\n\n const getSelectedNodes = useMemo(() => {\n let calculatedSelectedNodes: PresentationHierarchyNode[];\n return () => {\n if (calculatedSelectedNodes === undefined) {\n calculatedSelectedNodes = flatItems\n .filter((item): item is FlatTreeNodeItem => !isPlaceholderItem(item) && isNodeSelected?.(item.id))\n .map((item) => item.node);\n }\n return calculatedSelectedNodes;\n };\n }, [flatItems, isNodeSelected]);\n\n return (\n <LocalizationContextProvider localizedStrings={localizedStrings}>\n {errorRenderer ? errorRenderer(errorRendererProps) : <TreeErrorRenderer {...errorRendererProps} />}\n <div id={id} style={{ height: \"100%\", width: \"100%\", overflowY: \"auto\" }} ref={parentRef}>\n <Tree.Root\n {...treeRootProps}\n style={{ height: virtualizer.getTotalSize(), minHeight: \"100%\", width: \"100%\", position: \"relative\", overflow: \"hidden\" }}\n >\n {items.map((virtualizedItem) => {\n const item = flatItems[virtualizedItem.index];\n const selected = isNodeSelected?.(item.id) ?? false;\n return (\n <VirtualTreeItem\n ref={virtualizer.measureElement}\n key={virtualizedItem.key}\n data-index={virtualizedItem.index}\n start={virtualizedItem.start}\n item={item}\n selected={selected}\n expandNode={expandNode}\n reloadTree={reloadTree}\n onNodeClick={onNodeClick}\n onNodeKeyDown={onNodeKeyDown}\n getSelectedNodes={getSelectedNodes}\n getContextMenuActions={getContextMenuActions}\n getEditingProps={getEditingProps}\n getInlineActions={getInlineActions}\n getMenuActions={getMenuActions}\n getTreeItemProps={getTreeItemProps}\n />\n );\n })}\n </Tree.Root>\n </div>\n </LocalizationContextProvider>\n );\n}\n\ntype VirtualTreeItemProps = Omit<HierarchyNodeItemProps, \"item\"> & {\n start: number;\n \"data-index\": number;\n item: FlatTreeItem;\n};\n\nconst VirtualTreeItem = memo(\n forwardRef<HTMLElement, VirtualTreeItemProps>(function VirtualTreeItem({ start, item, ...props }, forwardedRef) {\n const style: CSSProperties = 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 if (isPlaceholderItem(item)) {\n return <PlaceholderNode ref={forwardedRef} data-index={props[\"data-index\"]} style={style} aria-level={item.level} aria-posinset={1} aria-setsize={1} />;\n }\n\n return <HierarchyNodeItem {...props} ref={forwardedRef} style={style} item={item} />;\n }),\n);\n\ntype HierarchyNodeItemProps = {\n item: FlatTreeNodeItem;\n style?: CSSProperties;\n getSelectedNodes: () => PresentationHierarchyNode[];\n} & Pick<TreeNodeRendererProps, \"expandNode\" | \"reloadTree\" | \"selected\"> &\n Pick<TreeRendererOwnProps, \"getContextMenuActions\" | \"getInlineActions\" | \"getMenuActions\" | \"getTreeItemProps\" | \"getEditingProps\"> &\n Pick<ReturnType<typeof useSelectionHandler>, \"onNodeClick\" | \"onNodeKeyDown\">;\n\nconst HierarchyNodeItem = memo(\n forwardRef<HTMLElement, HierarchyNodeItemProps>(function HierarchyNodeItem(\n {\n item,\n selected,\n getEditingProps,\n getTreeItemProps,\n onNodeClick,\n onNodeKeyDown,\n getSelectedNodes,\n getMenuActions,\n getInlineActions,\n getContextMenuActions,\n ...rest\n },\n forwardedRef,\n ) {\n const nodeRef = useRef<HTMLElement>(null);\n const node = item.node;\n const treeItemProps = getTreeItemProps?.(node);\n\n const isDisabled = treeItemProps?.[\"aria-disabled\"] === true;\n const nodeActions = useMemo(\n () => ({\n menuActions: getMenuActions ? getMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,\n inlineActions: getInlineActions ? getInlineActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,\n contextMenuActions: getContextMenuActions ? getContextMenuActions({ targetNode: node, selectedNodes: getSelectedNodes() }) : undefined,\n }),\n [node, getMenuActions, getInlineActions, getContextMenuActions, getSelectedNodes],\n );\n\n const onClick = useEvent<Required<TreeNodeRendererProps>[\"onClick\"]>((e) => {\n if (treeItemProps?.onClick) {\n treeItemProps.onClick(e);\n }\n if (isDisabled) {\n return;\n }\n onNodeClick?.(node, !selected, e);\n });\n const onKeyDown = useEvent<Required<TreeNodeRendererProps>[\"onKeyDown\"]>((e) => {\n if (treeItemProps?.onKeyDown) {\n treeItemProps.onKeyDown(e);\n }\n // Ignore if it is called on the element inside, e.g. checkbox or expander\n if (isDisabled || e.target !== nodeRef.current) {\n return;\n }\n onNodeKeyDown?.(node, !selected, e);\n });\n\n const editingProps = getEditingProps?.(item.node);\n const ref = useMergedRefs(forwardedRef, nodeRef);\n return (\n <RenameContextProvider onLabelChanged={editingProps?.onLabelChanged}>\n <StrataKitTreeNodeRenderer\n {...treeItemProps}\n {...rest}\n {...nodeActions}\n ref={ref}\n aria-level={item.level}\n aria-posinset={item.posInLevel}\n aria-setsize={item.levelSize}\n node={item.node}\n selected={selected}\n onClick={onClick}\n onKeyDown={onKeyDown}\n />\n </RenameContextProvider>\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.47",
3
+ "version": "2.0.0-alpha.48",
4
4
  "description": "React components based on `@itwin/presentation-hierarchies`",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -37,15 +37,15 @@
37
37
  "./package.json": "./package.json"
38
38
  },
39
39
  "dependencies": {
40
- "@itwin/core-bentley": "^5.4.1",
40
+ "@itwin/core-bentley": "^5.4.2",
41
41
  "@tanstack/react-virtual": "^3.13.13",
42
42
  "classnames": "^2.5.1",
43
43
  "immer": "^10.2.0",
44
44
  "react-error-boundary": "^4.1.2",
45
45
  "rxjs": "^7.8.2",
46
- "@itwin/unified-selection": "^1.6.3",
46
+ "@itwin/presentation-hierarchies": "^2.0.0-alpha.9",
47
47
  "@itwin/presentation-shared": "^2.0.0-alpha.5",
48
- "@itwin/presentation-hierarchies": "^2.0.0-alpha.8"
48
+ "@itwin/unified-selection": "^1.6.4"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@stratakit/bricks": "^0.5",
@@ -70,20 +70,20 @@
70
70
  }
71
71
  },
72
72
  "devDependencies": {
73
- "@itwin/build-tools": "^5.4.1",
73
+ "@itwin/build-tools": "^5.4.2",
74
74
  "@itwin/eslint-plugin": "5.1.0",
75
75
  "@stratakit/bricks": "^0.5.3",
76
76
  "@stratakit/foundations": "^0.4.3",
77
77
  "@stratakit/icons": "^0.2.2",
78
78
  "@stratakit/structures": "^0.5.3",
79
79
  "@testing-library/dom": "^10.4.1",
80
- "@testing-library/react": "^16.3.0",
80
+ "@testing-library/react": "^16.3.1",
81
81
  "@testing-library/user-event": "^14.6.1",
82
82
  "@types/chai": "^5.2.3",
83
83
  "@types/chai-as-promised": "^8.0.2",
84
84
  "@types/jsdom": "^21.1.7",
85
85
  "@types/mocha": "^10.0.10",
86
- "@types/node": "^22.19.2",
86
+ "@types/node": "^22.19.3",
87
87
  "@types/react": "^18.3.27",
88
88
  "@types/react-dom": "^18.3.7",
89
89
  "@types/sinon": "^17.0.4",
@@ -93,7 +93,7 @@
93
93
  "chai-as-promised": "^8.0.2",
94
94
  "cpx2": "^7.0.2",
95
95
  "cross-env": "^7.0.3",
96
- "eslint": "^9.39.1",
96
+ "eslint": "^9.39.2",
97
97
  "eslint-plugin-react": "^7.37.5",
98
98
  "global-jsdom": "^26.0.0",
99
99
  "ignore-styles": "^5.0.1",