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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +2 -40
  3. package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.d.ts +2 -0
  4. package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.d.ts.map +1 -1
  5. package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.js +15 -0
  6. package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.js.map +1 -1
  7. package/lib/esm/presentation-hierarchies-react/stratakit/LocalizationContext.d.ts +10 -0
  8. package/lib/esm/presentation-hierarchies-react/stratakit/LocalizationContext.d.ts.map +1 -1
  9. package/lib/esm/presentation-hierarchies-react/stratakit/LocalizationContext.js +2 -0
  10. package/lib/esm/presentation-hierarchies-react/stratakit/LocalizationContext.js.map +1 -1
  11. package/lib/esm/presentation-hierarchies-react/stratakit/{FilterAction.d.ts → TreeNodeFilterAction.d.ts} +8 -7
  12. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.d.ts.map +1 -0
  13. package/lib/esm/presentation-hierarchies-react/stratakit/{FilterAction.js → TreeNodeFilterAction.js} +8 -2
  14. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js.map +1 -0
  15. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts +57 -0
  16. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts.map +1 -0
  17. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js +71 -0
  18. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js.map +1 -0
  19. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.css +25 -0
  20. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts +6 -6
  21. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts.map +1 -1
  22. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js +56 -49
  23. package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js.map +1 -1
  24. package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts +16 -10
  25. package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts.map +1 -1
  26. package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.js +56 -16
  27. package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.js.map +1 -1
  28. package/lib/esm/presentation-hierarchies-react.d.ts +3 -4
  29. package/lib/esm/presentation-hierarchies-react.d.ts.map +1 -1
  30. package/lib/esm/presentation-hierarchies-react.js +2 -3
  31. package/lib/esm/presentation-hierarchies-react.js.map +1 -1
  32. package/package.json +7 -7
  33. package/lib/esm/presentation-hierarchies-react/stratakit/FilterAction.d.ts.map +0 -1
  34. package/lib/esm/presentation-hierarchies-react/stratakit/FilterAction.js.map +0 -1
  35. package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.d.ts +0 -21
  36. package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.d.ts.map +0 -1
  37. package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.js +0 -36
  38. package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.js.map +0 -1
@@ -3,25 +3,26 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
4
  * See LICENSE.md in the project root for license terms and full copyright notice.
5
5
  *--------------------------------------------------------------------------------------------*/
6
- import { cloneElement, forwardRef, isValidElement, memo, useCallback, useEffect, useMemo, useRef, useState, } from "react";
7
- import { Spinner, TextBox } from "@stratakit/bricks";
6
+ import "./TreeNodeRenderer.css";
7
+ import { cloneElement, forwardRef, isValidElement, memo, useCallback, useEffect, useId, useMemo, useRef, useState, } from "react";
8
+ import { Description, IconButton, Spinner, Text, TextBox } from "@stratakit/bricks";
9
+ import checkmarkSvg from "@stratakit/icons/checkmark.svg";
10
+ import dismissSvg from "@stratakit/icons/dismiss.svg";
8
11
  import refreshSvg from "@stratakit/icons/refresh.svg";
9
- import { DropdownMenu, Tree } from "@stratakit/structures";
12
+ import { DropdownMenu, unstable_Popover as Popover, Tree } from "@stratakit/structures";
10
13
  import { useLocalizationContext } from "./LocalizationContext.js";
11
- import { useRenameContext } from "./RenameAction.js";
12
14
  import { TreeActionBase } from "./TreeAction.js";
15
+ import { useTreeNodeRenameContext } from "./TreeNodeRenameAction.js";
13
16
  /**
14
17
  * A component that renders given `FlatTreeNode` using the `Tree.Item` component from `@itwin/itwinui-react`. The
15
18
  * `FlatTreeNode` objects for this renderer are generally created using the `useFlatTreeNodeList` hook.
16
19
  *
17
- * @see `TreeRenderer`
18
- * @see https://itwinui.bentley.com/docs/tree
19
- * @public
20
+ * @internal
20
21
  */
21
22
  export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode(props, forwardedRef) {
22
23
  const { node, decorations, inlineActions, menuActions, contextMenuActions, expandNode, reloadTree, ...treeItemProps } = props;
23
24
  const { localizedStrings } = useLocalizationContext();
24
- const renameContext = useRenameContext();
25
+ const renameContext = useTreeNodeRenameContext();
25
26
  const [contextMenuProps, setContextMenuProps] = useState(undefined);
26
27
  const label = treeItemProps.label ?? node.label;
27
28
  const inlineActionItems = useMemo(() => {
@@ -50,35 +51,30 @@ export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode(
50
51
  }
51
52
  return undefined;
52
53
  }, [node.children, node.error, node.isExpanded]);
53
- const { onLabelChanged, setIsRenaming, isRenaming } = renameContext ?? {};
54
- const labelEditor = isRenaming ? (_jsx(LabelEditor, { initialLabel: node.label, onChange: (newLabel) => {
55
- onLabelChanged?.(newLabel);
56
- setIsRenaming?.(false);
57
- }, onCancel: () => {
58
- setIsRenaming?.(false);
59
- } })) : undefined;
60
- return (_jsxs(_Fragment, { children: [_jsx(Tree.Item, { ...treeItemProps, ref: forwardedRef, label: labelEditor ?? label, expanded: expanded, onExpandedChange: useCallback((isExpanded) => {
61
- expandNode(node.id, isExpanded);
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);
65
- }
66
- if (!contextMenuActions) {
67
- return;
68
- }
69
- e.preventDefault();
70
- const actions = injectActionVariant(contextMenuActions, "context-menu");
71
- if (actions.length === 0) {
72
- return;
73
- }
74
- setContextMenuProps({
75
- position: {
76
- x: e.clientX,
77
- y: e.clientY,
78
- },
79
- actions,
80
- });
81
- } }), _jsxs(DropdownMenu.Provider, { open: contextMenuProps !== undefined, setOpen: (open) => {
54
+ const { renameParameters, cancelRename } = renameContext ?? {};
55
+ const labelEditor = (_jsx(LabelEditor, { initialLabel: node.label, onChange: renameParameters?.commit, onCancel: cancelRename, labelValidationHint: renameParameters?.labelValidationHint, validate: renameParameters?.validate }));
56
+ return (_jsxs(_Fragment, { children: [_jsx(Popover, { content: labelEditor, placement: "bottom", open: renameParameters?.nodeId === node.id, setOpen: cancelRename, unmountOnHide: true, children: _jsx(Tree.Item, { ...treeItemProps, ref: forwardedRef, label: label, expanded: expanded, onExpandedChange: useCallback((isExpanded) => {
57
+ expandNode(node.id, isExpanded);
58
+ }, [node, expandNode]), inlineActions: inlineActionItems, actions: menuActionItems, unstable_decorations: decorations, error: node.error ? node.error.id : undefined, onContextMenu: (e) => {
59
+ if (treeItemProps.onContextMenu) {
60
+ treeItemProps.onContextMenu(e);
61
+ }
62
+ if (!contextMenuActions) {
63
+ return;
64
+ }
65
+ e.preventDefault();
66
+ const actions = injectActionVariant(contextMenuActions, "context-menu");
67
+ if (actions.length === 0) {
68
+ return;
69
+ }
70
+ setContextMenuProps({
71
+ position: {
72
+ x: e.clientX,
73
+ y: e.clientY,
74
+ },
75
+ actions,
76
+ });
77
+ } }) }), _jsxs(DropdownMenu.Provider, { open: contextMenuProps !== undefined, setOpen: (open) => {
82
78
  if (!open) {
83
79
  setContextMenuProps(undefined);
84
80
  }
@@ -88,19 +84,25 @@ export const PlaceholderNode = memo(forwardRef(function PlaceholderNode({ ...pro
88
84
  const { localizedStrings } = useLocalizationContext();
89
85
  return (_jsx(Tree.Item, { ...props, ref: forwardedRef, label: localizedStrings.loading, unstable_decorations: _jsx(Spinner, { size: "small", title: localizedStrings.loading }) }));
90
86
  }));
91
- function LabelEditor({ initialLabel, onChange, onCancel }) {
87
+ function LabelEditor({ initialLabel, labelValidationHint, onChange, onCancel, validate, }) {
88
+ const { localizedStrings } = useLocalizationContext();
92
89
  const inputRef = useRef(null);
93
90
  const [newLabelValue, setNewLabelValue] = useState(initialLabel);
91
+ const [hasError, setHasError] = useState(false);
94
92
  const handleLabelChange = () => {
93
+ if (validate && !validate(newLabelValue)) {
94
+ setHasError(true);
95
+ return;
96
+ }
95
97
  if (initialLabel !== newLabelValue) {
96
- onChange(newLabelValue);
98
+ onChange?.(newLabelValue);
97
99
  return;
98
100
  }
99
- onCancel();
101
+ onCancel?.();
100
102
  };
101
103
  const cancelLabelChange = () => {
102
104
  setNewLabelValue(initialLabel);
103
- onCancel();
105
+ onCancel?.();
104
106
  };
105
107
  useEffect(() => {
106
108
  if (inputRef.current) {
@@ -108,14 +110,19 @@ function LabelEditor({ initialLabel, onChange, onCancel }) {
108
110
  inputRef.current.select();
109
111
  }
110
112
  }, []);
111
- return (_jsx(TextBox.Root, { children: _jsx(TextBox.Input, { ref: inputRef, value: newLabelValue, onChange: (event) => setNewLabelValue(event.target.value), onBlur: handleLabelChange, onKeyDown: (event) => {
112
- if (event.key === "Enter") {
113
- handleLabelChange();
114
- }
115
- else if (event.key === "Escape") {
116
- cancelLabelChange();
117
- }
118
- } }) }));
113
+ const canRename = newLabelValue && newLabelValue !== initialLabel && !hasError;
114
+ const inputId = useId();
115
+ return (_jsxs("div", { className: "phr-node-label-editor", children: [_jsxs("div", { className: "phr-node-label-editor-input-row", children: [_jsx(TextBox.Root, { style: { width: "100%" }, className: hasError ? "with-error" : undefined, children: _jsx(TextBox.Input, { id: inputId, ref: inputRef, value: newLabelValue, onChange: (event) => {
116
+ setNewLabelValue(event.target.value);
117
+ setHasError(false);
118
+ }, onKeyDown: (event) => {
119
+ if (event.key === "Enter") {
120
+ handleLabelChange();
121
+ }
122
+ else if (event.key === "Escape") {
123
+ cancelLabelChange();
124
+ }
125
+ } }) }), _jsx(IconButton, { icon: dismissSvg, label: localizedStrings.cancel, onClick: cancelLabelChange }), _jsx(IconButton, { icon: checkmarkSvg, label: localizedStrings.confirm, onClick: handleLabelChange, disabled: !canRename })] }), labelValidationHint !== undefined ? (_jsx(Description, { id: inputId, tone: hasError ? "critical" : "neutral", style: { display: "flex" }, children: _jsx(Text, { variant: "caption-lg", children: labelValidationHint }) })) : undefined] }, initialLabel));
119
126
  }
120
127
  function injectActionVariant(actions, variant) {
121
128
  return actions
@@ -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 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
+ {"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 \"./TreeNodeRenderer.css\";\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 useId,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Description, IconButton, Spinner, Text, TextBox } from \"@stratakit/bricks\";\nimport checkmarkSvg from \"@stratakit/icons/checkmark.svg\";\nimport dismissSvg from \"@stratakit/icons/dismiss.svg\";\nimport refreshSvg from \"@stratakit/icons/refresh.svg\";\nimport { DropdownMenu, unstable_Popover as Popover, Tree } from \"@stratakit/structures\";\nimport { TreeRendererProps } from \"../Renderers.js\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\nimport { TreeActionBase, TreeActionBaseAttributes } from \"./TreeAction.js\";\nimport { useTreeNodeRenameContext } from \"./TreeNodeRenameAction.js\";\n\n/** @internal */\ninterface 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/** @internal */\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 * @internal\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 = useTreeNodeRenameContext();\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 { renameParameters, cancelRename } = renameContext ?? {};\n const labelEditor = (\n <LabelEditor\n initialLabel={node.label}\n onChange={renameParameters?.commit}\n onCancel={cancelRename}\n labelValidationHint={renameParameters?.labelValidationHint}\n validate={renameParameters?.validate}\n />\n );\n\n return (\n <>\n <Popover content={labelEditor} placement=\"bottom\" open={renameParameters?.nodeId === node.id} setOpen={cancelRename} unmountOnHide>\n <Tree.Item\n {...treeItemProps}\n ref={forwardedRef}\n label={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 </Popover>\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({\n initialLabel,\n labelValidationHint,\n onChange,\n onCancel,\n validate,\n}: {\n initialLabel: string;\n labelValidationHint?: string;\n onChange?: (newLabel: string) => void;\n onCancel?: () => void;\n validate?: (newLabel: string) => boolean;\n}) {\n const { localizedStrings } = useLocalizationContext();\n const inputRef = useRef<HTMLInputElement>(null);\n const [newLabelValue, setNewLabelValue] = useState(initialLabel);\n const [hasError, setHasError] = useState<boolean>(false);\n const handleLabelChange = () => {\n if (validate && !validate(newLabelValue)) {\n setHasError(true);\n return;\n }\n\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 const canRename = newLabelValue && newLabelValue !== initialLabel && !hasError;\n const inputId = useId();\n\n return (\n <div key={initialLabel} className=\"phr-node-label-editor\">\n <div className=\"phr-node-label-editor-input-row\">\n <TextBox.Root style={{ width: \"100%\" }} className={hasError ? \"with-error\" : undefined}>\n <TextBox.Input\n id={inputId}\n ref={inputRef}\n value={newLabelValue}\n onChange={(event) => {\n setNewLabelValue(event.target.value);\n setHasError(false);\n }}\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 <IconButton icon={dismissSvg} label={localizedStrings.cancel} onClick={cancelLabelChange} />\n <IconButton icon={checkmarkSvg} label={localizedStrings.confirm} onClick={handleLabelChange} disabled={!canRename} />\n </div>\n {labelValidationHint !== undefined ? (\n <Description id={inputId} tone={hasError ? \"critical\" : \"neutral\"} style={{ display: \"flex\" }}>\n <Text variant=\"caption-lg\">{labelValidationHint}</Text>\n </Description>\n ) : undefined}\n </div>\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,10 +1,11 @@
1
- import { ComponentProps, ComponentPropsWithoutRef, ReactElement, ReactNode } from "react";
1
+ import { ComponentProps, ComponentPropsWithoutRef, FC, PropsWithoutRef, ReactElement, 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
  import { SelectionMode } from "../UseSelectionHandler.js";
6
6
  import { LocalizationContextProvider } from "./LocalizationContext.js";
7
7
  import { TreeErrorRendererProps } from "./TreeErrorRenderer.js";
8
+ import { TreeNodeEditingProps } from "./TreeNodeRenameAction.js";
8
9
  import { StrataKitTreeItemProps } from "./TreeNodeRenderer.js";
9
10
  /** @alpha */
10
11
  interface TreeRendererOwnProps {
@@ -19,15 +20,10 @@ interface TreeRendererOwnProps {
19
20
  /** A render function for errors' display component. Defaults to `<TreeErrorRenderer />`. */
20
21
  errorRenderer?: (props: TreeErrorRendererProps) => ReactElement;
21
22
  /** Props that defines if current node supports editing. */
22
- getEditingProps?: (node: PresentationHierarchyNode) => {
23
- /**
24
- * A callback that is invoked when node label is changed. Should be used together
25
- * with `<RenameAction />` to enter label editing mode. Node label is not editable
26
- * when this is not supplied.
27
- */
28
- onLabelChanged?: (newLabel: string) => void;
29
- };
23
+ getEditingProps?: (node: PresentationHierarchyNode) => TreeNodeEditingProps | undefined;
24
+ /** Custom props for the root Tree component. */
30
25
  treeRootProps?: Partial<Omit<ComponentProps<typeof Tree.Root>, "style">>;
26
+ /** A callback that returns tree item props for specific node. */
31
27
  getTreeItemProps?: (node: PresentationHierarchyNode) => Partial<Omit<StrataKitTreeItemProps, "selected" | "aria-level" | "aria-posinset" | "aria-setsize">>;
32
28
  /**
33
29
  * Callback that returns menu actions for tree item.
@@ -56,6 +52,16 @@ interface TreeRendererOwnProps {
56
52
  }) => ReactNode[];
57
53
  }
58
54
  /** @alpha */
55
+ export interface StrataKitTreeRendererAttributes {
56
+ /**
57
+ * Opens rename mode for the first node that matches the given predicate. Node must be already loaded in the tree.
58
+ * If the node is not visible (because its parent is collapsed), all parents will be expanded to make it visible and node will be scrolled into view.
59
+ *
60
+ * Returns "node-not-found" if no node matches the predicate, "success" if rename was initiated.
61
+ */
62
+ renameNode: (predicate: (node: PresentationHierarchyNode) => boolean) => "node-not-found" | "success";
63
+ }
64
+ /** @alpha */
59
65
  type StrataKitTreeRendererProps = TreeRendererProps & Pick<TreeErrorRendererProps, "onFilterClick"> & TreeRendererOwnProps & ComponentPropsWithoutRef<typeof LocalizationContextProvider>;
60
66
  /**
61
67
  * A component that renders a tree using the `Tree` component from `@itwin/itwinui-react`. The tree nodes
@@ -64,6 +70,6 @@ type StrataKitTreeRendererProps = TreeRendererProps & Pick<TreeErrorRendererProp
64
70
  * @see https://itwinui.bentley.com/docs/tree
65
71
  * @alpha
66
72
  */
67
- export declare function StrataKitTreeRenderer(props: StrataKitTreeRendererProps): import("react/jsx-runtime").JSX.Element;
73
+ export declare const StrataKitTreeRenderer: FC<PropsWithoutRef<StrataKitTreeRendererProps> & RefAttributes<StrataKitTreeRendererAttributes>>;
68
74
  export {};
69
75
  //# 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,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
+ {"version":3,"file":"TreeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,cAAc,EACd,wBAAwB,EAExB,EAAE,EAGF,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EAMd,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;AACvE,OAAO,EAAqB,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAgE,MAAM,2BAA2B,CAAC;AAC/H,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,oBAAoB,GAAG,SAAS,CAAC;IAExF,gDAAgD;IAChD,aAAa,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAEzE,iEAAiE;IACjE,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,MAAM,WAAW,+BAA+B;IAC9C;;;;;OAKG;IACH,UAAU,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,yBAAyB,KAAK,OAAO,KAAK,gBAAgB,GAAG,SAAS,CAAC;CACvG;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,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,eAAe,CAAC,0BAA0B,CAAC,GAAG,aAAa,CAAC,+BAA+B,CAAC,CA+KjI,CAAC"}
@@ -3,15 +3,15 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
4
  * See LICENSE.md in the project root for license terms and full copyright notice.
5
5
  *--------------------------------------------------------------------------------------------*/
6
- import { forwardRef, memo, useCallback, useEffect, useMemo, useRef, } from "react";
6
+ import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, } from "react";
7
7
  import { Tree } from "@stratakit/structures";
8
8
  import { useVirtualizer } from "@tanstack/react-virtual";
9
9
  import { useSelectionHandler } from "../UseSelectionHandler.js";
10
10
  import { useEvent, useMergedRefs } from "../Utils.js";
11
- import { isPlaceholderItem, useErrorList, useFlatTreeItems } from "./FlatTreeNode.js";
11
+ import { findPathToNode, isPlaceholderItem, useErrorList, useFlatTreeItems } from "./FlatTreeNode.js";
12
12
  import { LocalizationContextProvider } from "./LocalizationContext.js";
13
- import { RenameContextProvider } from "./RenameAction.js";
14
13
  import { TreeErrorRenderer } from "./TreeErrorRenderer.js";
14
+ import { TreeNodeRenameContextProvider, useTreeNodeRenameContextValue } from "./TreeNodeRenameAction.js";
15
15
  import { PlaceholderNode, StrataKitTreeNodeRenderer } from "./TreeNodeRenderer.js";
16
16
  /**
17
17
  * A component that renders a tree using the `Tree` component from `@itwin/itwinui-react`. The tree nodes
@@ -20,7 +20,7 @@ import { PlaceholderNode, StrataKitTreeNodeRenderer } from "./TreeNodeRenderer.j
20
20
  * @see https://itwinui.bentley.com/docs/tree
21
21
  * @alpha
22
22
  */
23
- export function StrataKitTreeRenderer(props) {
23
+ export const StrataKitTreeRenderer = forwardRef(function StrataKitTreeRenderer(props, forwardedRef) {
24
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,
@@ -39,11 +39,14 @@ export function StrataKitTreeRenderer(props) {
39
39
  overscan: 10,
40
40
  });
41
41
  const items = virtualizer.getVirtualItems();
42
+ const renameContext = useTreeNodeRenameContextValue({
43
+ getEditingProps,
44
+ });
42
45
  const scrollToElement = useCallback(({ errorNode, expandTo }) => {
43
46
  const index = flatItems.findIndex((flatItem) => flatItem.id === errorNode.id);
44
47
  if (index === -1) {
45
48
  expandTo((nodeId) => expandNode(nodeId, true));
46
- scrollToNode.current = errorNode.id;
49
+ scrollToNode.current = { id: errorNode.id };
47
50
  return;
48
51
  }
49
52
  virtualizer.scrollToIndex(index, { align: "end" });
@@ -52,13 +55,51 @@ export function StrataKitTreeRenderer(props) {
52
55
  if (scrollToNode.current === undefined) {
53
56
  return;
54
57
  }
55
- const index = flatItems.findIndex((flatItem) => flatItem.id === scrollToNode.current);
58
+ const targetNodeId = scrollToNode.current.id;
59
+ const index = flatItems.findIndex((flatItem) => flatItem.id === targetNodeId);
56
60
  if (index === -1) {
57
61
  return;
58
62
  }
59
- virtualizer.scrollToIndex(index, { align: "end" });
63
+ virtualizer.scrollToIndex(index, { align: "auto" });
64
+ scrollToNode.current.action?.();
60
65
  scrollToNode.current = undefined;
61
66
  }, [flatItems, virtualizer]);
67
+ useImperativeHandle(forwardedRef, () => ({
68
+ renameNode: (predicate) => {
69
+ const pathToNode = findPathToNode(rootNodes, predicate);
70
+ if (!pathToNode) {
71
+ return "node-not-found";
72
+ }
73
+ const targetNode = pathToNode.pop();
74
+ const collapsedNodes = pathToNode.filter((pathNode) => !pathNode.isExpanded);
75
+ const handleRename = () => {
76
+ // give time to scroll node into view before starting rename
77
+ requestAnimationFrame(() => {
78
+ renameContext.startRename(targetNode);
79
+ });
80
+ };
81
+ if (collapsedNodes.length > 0) {
82
+ collapsedNodes.forEach((node) => expandNode(node.id, true));
83
+ scrollToNode.current = {
84
+ id: targetNode.id,
85
+ action: handleRename,
86
+ };
87
+ return "success";
88
+ }
89
+ const index = flatItems.findIndex((flatItem) => flatItem.id === targetNode.id);
90
+ virtualizer.scrollToIndex(index, { align: "auto" });
91
+ handleRename();
92
+ return "success";
93
+ },
94
+ }));
95
+ const cancelRename = renameContext.cancelRename;
96
+ const isScrolling = virtualizer.isScrolling;
97
+ useEffect(() => {
98
+ if (isScrolling) {
99
+ // cancel rename when scroll is initiated
100
+ cancelRename();
101
+ }
102
+ }, [isScrolling, cancelRename]);
62
103
  const errorRendererProps = {
63
104
  treeLabel,
64
105
  errorList,
@@ -78,12 +119,12 @@ export function StrataKitTreeRenderer(props) {
78
119
  return calculatedSelectedNodes;
79
120
  };
80
121
  }, [flatItems, isNodeSelected]);
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) => {
82
- const item = flatItems[virtualizedItem.index];
83
- const selected = isNodeSelected?.(item.id) ?? false;
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));
85
- }) }) })] }));
86
- }
122
+ 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: _jsx(TreeNodeRenameContextProvider, { value: renameContext, children: items.map((virtualizedItem) => {
123
+ const item = flatItems[virtualizedItem.index];
124
+ const selected = isNodeSelected?.(item.id) ?? false;
125
+ 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, getInlineActions: getInlineActions, getMenuActions: getMenuActions, getTreeItemProps: getTreeItemProps }, virtualizedItem.key));
126
+ }) }) }) })] }));
127
+ });
87
128
  const VirtualTreeItem = memo(forwardRef(function VirtualTreeItem({ start, item, ...props }, forwardedRef) {
88
129
  const style = useMemo(() => ({
89
130
  position: "absolute",
@@ -98,7 +139,7 @@ const VirtualTreeItem = memo(forwardRef(function VirtualTreeItem({ start, item,
98
139
  }
99
140
  return _jsx(HierarchyNodeItem, { ...props, ref: forwardedRef, style: style, item: item });
100
141
  }));
101
- const HierarchyNodeItem = memo(forwardRef(function HierarchyNodeItem({ item, selected, getEditingProps, getTreeItemProps, onNodeClick, onNodeKeyDown, getSelectedNodes, getMenuActions, getInlineActions, getContextMenuActions, ...rest }, forwardedRef) {
142
+ const HierarchyNodeItem = memo(forwardRef(function HierarchyNodeItem({ item, selected, getTreeItemProps, onNodeClick, onNodeKeyDown, getSelectedNodes, getMenuActions, getInlineActions, getContextMenuActions, ...rest }, forwardedRef) {
102
143
  const nodeRef = useRef(null);
103
144
  const node = item.node;
104
145
  const treeItemProps = getTreeItemProps?.(node);
@@ -127,9 +168,8 @@ const HierarchyNodeItem = memo(forwardRef(function HierarchyNodeItem({ item, sel
127
168
  }
128
169
  onNodeKeyDown?.(node, !selected, e);
129
170
  });
130
- const editingProps = getEditingProps?.(item.node);
131
171
  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 }) }));
172
+ return (_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 }));
133
173
  }));
134
174
  function noopSelectNodes() { }
135
175
  //# 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 {\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"]}
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 FC,\n forwardRef,\n memo,\n PropsWithoutRef,\n ReactElement,\n ReactNode,\n RefAttributes,\n useCallback,\n useEffect,\n useImperativeHandle,\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, findPathToNode, FlatTreeItem, FlatTreeNodeItem, isPlaceholderItem, useErrorList, useFlatTreeItems } from \"./FlatTreeNode.js\";\nimport { LocalizationContextProvider } from \"./LocalizationContext.js\";\nimport { TreeErrorRenderer, TreeErrorRendererProps } from \"./TreeErrorRenderer.js\";\nimport { TreeNodeEditingProps, TreeNodeRenameContextProvider, useTreeNodeRenameContextValue } from \"./TreeNodeRenameAction.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) => TreeNodeEditingProps | undefined;\n\n /** Custom props for the root Tree component. */\n treeRootProps?: Partial<Omit<ComponentProps<typeof Tree.Root>, \"style\">>;\n\n /** A callback that returns tree item props for specific node. */\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 */\nexport interface StrataKitTreeRendererAttributes {\n /**\n * Opens rename mode for the first node that matches the given predicate. Node must be already loaded in the tree.\n * If the node is not visible (because its parent is collapsed), all parents will be expanded to make it visible and node will be scrolled into view.\n *\n * Returns \"node-not-found\" if no node matches the predicate, \"success\" if rename was initiated.\n */\n renameNode: (predicate: (node: PresentationHierarchyNode) => boolean) => \"node-not-found\" | \"success\";\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 const StrataKitTreeRenderer: FC<PropsWithoutRef<StrataKitTreeRendererProps> & RefAttributes<StrataKitTreeRendererAttributes>> = forwardRef<\n StrataKitTreeRendererAttributes,\n StrataKitTreeRendererProps\n>(function StrataKitTreeRenderer(props, forwardedRef) {\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<{ id: string; action?: () => void } | 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 renameContext = useTreeNodeRenameContextValue({\n getEditingProps,\n });\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 = { id: 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 targetNodeId = scrollToNode.current.id;\n const index = flatItems.findIndex((flatItem) => flatItem.id === targetNodeId);\n if (index === -1) {\n return;\n }\n virtualizer.scrollToIndex(index, { align: \"auto\" });\n scrollToNode.current.action?.();\n scrollToNode.current = undefined;\n }, [flatItems, virtualizer]);\n\n useImperativeHandle(forwardedRef, () => ({\n renameNode: (predicate) => {\n const pathToNode = findPathToNode(rootNodes, predicate);\n if (!pathToNode) {\n return \"node-not-found\";\n }\n const targetNode = pathToNode.pop()!;\n const collapsedNodes = pathToNode.filter((pathNode) => !pathNode.isExpanded);\n\n const handleRename = () => {\n // give time to scroll node into view before starting rename\n requestAnimationFrame(() => {\n renameContext.startRename(targetNode);\n });\n };\n\n if (collapsedNodes.length > 0) {\n collapsedNodes.forEach((node) => expandNode(node.id, true));\n scrollToNode.current = {\n id: targetNode.id,\n action: handleRename,\n };\n return \"success\";\n }\n\n const index = flatItems.findIndex((flatItem) => flatItem.id === targetNode.id);\n virtualizer.scrollToIndex(index, { align: \"auto\" });\n handleRename();\n return \"success\";\n },\n }));\n\n const cancelRename = renameContext.cancelRename;\n const isScrolling = virtualizer.isScrolling;\n useEffect(() => {\n if (isScrolling) {\n // cancel rename when scroll is initiated\n cancelRename();\n }\n }, [isScrolling, cancelRename]);\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 <TreeNodeRenameContextProvider value={renameContext}>\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 getInlineActions={getInlineActions}\n getMenuActions={getMenuActions}\n getTreeItemProps={getTreeItemProps}\n />\n );\n })}\n </TreeNodeRenameContextProvider>\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\"> &\n Pick<ReturnType<typeof useSelectionHandler>, \"onNodeClick\" | \"onNodeKeyDown\">;\n\nconst HierarchyNodeItem = memo(\n forwardRef<HTMLElement, HierarchyNodeItemProps>(function HierarchyNodeItem(\n { item, selected, getTreeItemProps, onNodeClick, onNodeKeyDown, getSelectedNodes, getMenuActions, getInlineActions, getContextMenuActions, ...rest },\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 ref = useMergedRefs(forwardedRef, nodeRef);\n return (\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 );\n }),\n);\n\nfunction noopSelectNodes() {}\n"]}
@@ -4,11 +4,10 @@ export { useTree, useUnifiedSelectionTree } from "./presentation-hierarchies-rea
4
4
  export { useNodeHighlighting } from "./presentation-hierarchies-react/UseNodeHighlighting.js";
5
5
  export { HierarchyLevelDetails, TreeRendererProps } from "./presentation-hierarchies-react/Renderers.js";
6
6
  export { useIModelTree, useIModelUnifiedSelectionTree } from "./presentation-hierarchies-react/UseIModelTree.js";
7
- export { StrataKitTreeNodeRenderer } from "./presentation-hierarchies-react/stratakit/TreeNodeRenderer.js";
8
7
  export { TreeActionBase, TreeActionBaseAttributes } from "./presentation-hierarchies-react/stratakit/TreeAction.js";
9
- export { FilterAction } from "./presentation-hierarchies-react/stratakit/FilterAction.js";
10
- export { RenameAction, RenameContextProvider } from "./presentation-hierarchies-react/stratakit/RenameAction.js";
11
- export { StrataKitTreeRenderer } from "./presentation-hierarchies-react/stratakit/TreeRenderer.js";
8
+ export { TreeNodeFilterAction } from "./presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js";
9
+ export { TreeNodeRenameAction } from "./presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js";
10
+ export { StrataKitTreeRenderer, StrataKitTreeRendererAttributes } from "./presentation-hierarchies-react/stratakit/TreeRenderer.js";
12
11
  export { StrataKitRootErrorRenderer } from "./presentation-hierarchies-react/stratakit/RootErrorRenderer.js";
13
12
  export { TreeErrorRenderer } from "./presentation-hierarchies-react/stratakit/TreeErrorRenderer.js";
14
13
  export { ErrorItemRenderer } from "./presentation-hierarchies-react/stratakit/ErrorItemRenderer.js";
@@ -1 +1 @@
1
- {"version":3,"file":"presentation-hierarchies-react.d.ts","sourceRoot":"","sources":["../../src/presentation-hierarchies-react.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,SAAS,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AAClJ,OAAO,EAAE,mBAAmB,EAAE,MAAM,yDAAyD,CAAC;AAC9F,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,yDAAyD,CAAC;AAC9F,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,6BAA6B,EAAE,MAAM,mDAAmD,CAAC;AACjH,OAAO,EAAE,yBAAyB,EAAE,MAAM,gEAAgE,CAAC;AAC3G,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,YAAY,EAAE,MAAM,4DAA4D,CAAC;AAC1F,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4DAA4D,CAAC;AACjH,OAAO,EAAE,qBAAqB,EAAE,MAAM,4DAA4D,CAAC;AACnG,OAAO,EAAE,0BAA0B,EAAE,MAAM,iEAAiE,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,iEAAiE,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iEAAiE,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,4DAA4D,CAAC;AAC1H,OAAO,EAAE,2BAA2B,EAAE,MAAM,mEAAmE,CAAC;AAEhH,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAChI,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"presentation-hierarchies-react.d.ts","sourceRoot":"","sources":["../../src/presentation-hierarchies-react.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,SAAS,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AAClJ,OAAO,EAAE,mBAAmB,EAAE,MAAM,yDAAyD,CAAC;AAC9F,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,yDAAyD,CAAC;AAC9F,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACzG,OAAO,EAAE,aAAa,EAAE,6BAA6B,EAAE,MAAM,mDAAmD,CAAC;AACjH,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oEAAoE,CAAC;AAC1G,OAAO,EAAE,oBAAoB,EAAE,MAAM,oEAAoE,CAAC;AAC1G,OAAO,EAAE,qBAAqB,EAAE,+BAA+B,EAAE,MAAM,4DAA4D,CAAC;AACpI,OAAO,EAAE,0BAA0B,EAAE,MAAM,iEAAiE,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,iEAAiE,CAAC;AACpG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iEAAiE,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,4DAA4D,CAAC;AAC1H,OAAO,EAAE,2BAA2B,EAAE,MAAM,mEAAmE,CAAC;AAEhH,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAChI,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -6,10 +6,9 @@ export { useSelectionHandler } from "./presentation-hierarchies-react/UseSelecti
6
6
  export { useTree, useUnifiedSelectionTree } from "./presentation-hierarchies-react/UseTree.js";
7
7
  export { useNodeHighlighting } from "./presentation-hierarchies-react/UseNodeHighlighting.js";
8
8
  export { useIModelTree, useIModelUnifiedSelectionTree } from "./presentation-hierarchies-react/UseIModelTree.js";
9
- export { StrataKitTreeNodeRenderer } from "./presentation-hierarchies-react/stratakit/TreeNodeRenderer.js";
10
9
  export { TreeActionBase } from "./presentation-hierarchies-react/stratakit/TreeAction.js";
11
- export { FilterAction } from "./presentation-hierarchies-react/stratakit/FilterAction.js";
12
- export { RenameAction, RenameContextProvider } from "./presentation-hierarchies-react/stratakit/RenameAction.js";
10
+ export { TreeNodeFilterAction } from "./presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js";
11
+ export { TreeNodeRenameAction } from "./presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js";
13
12
  export { StrataKitTreeRenderer } from "./presentation-hierarchies-react/stratakit/TreeRenderer.js";
14
13
  export { StrataKitRootErrorRenderer } from "./presentation-hierarchies-react/stratakit/RootErrorRenderer.js";
15
14
  export { TreeErrorRenderer } from "./presentation-hierarchies-react/stratakit/TreeErrorRenderer.js";