@itwin/presentation-hierarchies-react 2.0.0-alpha.3 → 2.0.0-alpha.31
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 +559 -0
- package/README.md +24 -24
- package/lib/esm/presentation-hierarchies-react/Renderers.d.ts +85 -0
- package/lib/esm/presentation-hierarchies-react/Renderers.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/{itwinui/TreeActionButton.css → Renderers.js} +2 -4
- package/lib/esm/presentation-hierarchies-react/Renderers.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts +14 -29
- package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/TreeNode.js +1 -7
- package/lib/esm/presentation-hierarchies-react/TreeNode.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.d.ts +2 -0
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.js +1 -1
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/UseNodeHighlighting.d.ts +24 -0
- package/lib/esm/presentation-hierarchies-react/UseNodeHighlighting.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/UseNodeHighlighting.js +39 -0
- package/lib/esm/presentation-hierarchies-react/UseNodeHighlighting.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts +3 -3
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js +1 -8
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/UseTree.d.ts +32 -70
- package/lib/esm/presentation-hierarchies-react/UseTree.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/UseTree.js +48 -49
- package/lib/esm/presentation-hierarchies-react/UseTree.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/Utils.d.ts +5 -0
- package/lib/esm/presentation-hierarchies-react/Utils.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/Utils.js +23 -0
- package/lib/esm/presentation-hierarchies-react/Utils.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts +2 -2
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js +31 -16
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts +24 -6
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js +28 -32
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts +6 -29
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js +31 -27
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts +23 -9
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js +16 -29
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +1 -1
- package/lib/esm/presentation-hierarchies-react/stratakit/FilterAction.d.ts +34 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/FilterAction.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/FilterAction.js +26 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/FilterAction.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.d.ts +58 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.js +74 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/FlatTreeNode.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/{itwinui → stratakit}/LocalizationContext.d.ts +47 -7
- package/lib/esm/presentation-hierarchies-react/stratakit/LocalizationContext.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/{itwinui → stratakit}/LocalizationContext.js +13 -5
- package/lib/esm/presentation-hierarchies-react/stratakit/LocalizationContext.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.d.ts +33 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.js +39 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RenameAction.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts +16 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RootErrorRenderer.js +42 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/RootErrorRenderer.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts +43 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js +70 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts +49 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js +116 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts +40 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts.map +1 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.js +93 -0
- package/lib/esm/presentation-hierarchies-react/stratakit/TreeRenderer.js.map +1 -0
- package/lib/esm/presentation-hierarchies-react.d.ts +13 -10
- package/lib/esm/presentation-hierarchies-react.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies-react.js +10 -9
- package/lib/esm/presentation-hierarchies-react.js.map +1 -1
- package/package.json +46 -38
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts +0 -15
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js +0 -22
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts +0 -21
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js +0 -29
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts +0 -12
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js +0 -72
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeLevelRenderer.d.ts +0 -12
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeLevelRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeLevelRenderer.js +0 -10
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeLevelRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts +0 -45
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js +0 -71
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts +0 -30
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js +0 -22
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalizationContext.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/LocalizationContext.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,aAAa,EAAqB,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAmG1F,MAAM,uBAAuB,GAAqB;IAChD,OAAO,EAAE,YAAY;IACrB,oBAAoB,EAAE,cAAc;IACpC,qCAAqC,EAAE,mBAAmB;IAC1D,yBAAyB,EAAE,qBAAqB;IAChD,kBAAkB,EAAE,6CAA6C;IACjE,8BAA8B,EAAE,eAAe;IAC/C,uBAAuB,EAAE,0CAA0C;IACnE,2BAA2B,EAAE,sBAAsB;IACnD,mBAAmB,EAAE,gGAAgG;IACrH,uBAAuB,EAAE,8EAA8E;IACvG,WAAW,EAAE,cAAc;IAC3B,sBAAsB,EAAE,6BAA6B;IACrD,iCAAiC,EAAE,cAAc;IACjD,mCAAmC,EAAE,YAAY;IACjD,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,MAAM,mBAAmB,GAAG,aAAa,CAAsB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,CAAC,CAAC;AAW9G;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAuD;IAC7H,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,gBAAgB,EAAE,EAAE,GAAG,uBAAuB,EAAE,GAAG,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAE9G,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,EAAE,gBAAgB,EAAE,EAAE,GAAG,uBAAuB,EAAE,GAAG,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEvB,OAAO,KAAC,mBAAmB,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAgC,CAAC;AAC/F,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,sBAAsB;IACpC,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAC;AACzC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { createContext, PropsWithChildren, useContext, useEffect, useState } from \"react\";\n\n/**\n * Localized strings used in the components.\n * @public\n */\nexport interface LocalizedStrings {\n /**\n * Message displayed when nodes are loading.\n * Default value: `Loading...`.\n */\n loading: string;\n /**\n * Title for apply hierarchy filter button.\n * Default value: `Apply filter`.\n */\n filterHierarchyLevel: string;\n /**\n * Accesible description for applied hierarchy filter button.\n * Default value: `Filter is applied`.\n */\n filterHierarchyLevelActiveDescription: string;\n /**\n * Title for clear hierarchy filter button.\n * Default value: `Clear active filter`.\n */\n clearHierarchyLevelFilter: string;\n /**\n * Message displayed when no nodes matching filter are found.\n * Default value: `No matches for current filter for {{node}}.`.\n */\n noFilteredChildren: string;\n /**\n * Label for change filter action.\n * Default value: `Change filter`.\n */\n noFilteredChildrenChangeFilter: string;\n /**\n * Message displayed when hierarchy creation for a node failed.\n * Default value: `Failed to create hierarchy for {{node}}.`.\n */\n failedToCreateHierarchy: string;\n /**\n * Message displayed when hierarchy creation for a node failed.\n * Default value: `Failed to load tree.`.\n */\n failedToCreateRootHierarchy: string;\n /**\n * Message displayed when result limit exceeds hierarchy size limit.\n * Default value: `The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit.`.\n */\n resultLimitExceeded: string;\n /**\n * Message displayed when result limit exceeds hierarchy size limit.\n * Default value: `The root item hierarchy contains {{limit}}+ items. Try increasing the limit.`.\n */\n rootResultLimitExceeded: string;\n /**\n * Label displayed on error dropdown.\n * Default value: `issues found`.\n */\n issuesFound: string;\n /**\n * Message displayed when hierarchy size limit can be overridden.\n * Default value: `Increase limit to {{limit}}`.\n */\n increaseHierarchyLimit: string;\n /**\n * Message displayed when hierarchy size limit can be overridden.\n * Default value: `Remove limit`.\n */\n increaseHierarchyLimitToUnlimited: string;\n /**\n * Message displayed when hierarchy size limit can be overridden and hierarchy filtering is enabled.\n * Default value: `Add Filter`.\n */\n increaseHierarchyLimitWithFiltering: string;\n /**\n * Label for retry action.\n * Default value: `Retry`.\n */\n retry: string;\n /**\n * Label for rename action.\n * Default value: `Rename`.\n */\n rename: string;\n /**\n * Label for more actions button.\n * Default value: `More`.\n */\n more: string;\n}\n\n/** @internal */\nexport interface LocalizationContext {\n localizedStrings: LocalizedStrings;\n}\n\nconst defaultLocalizedStrings: LocalizedStrings = {\n loading: \"Loading...\",\n filterHierarchyLevel: \"Apply filter\",\n filterHierarchyLevelActiveDescription: \"Filter is applied\",\n clearHierarchyLevelFilter: \"Clear active filter\",\n noFilteredChildren: \"No matches for current filter for {{node}}.\",\n noFilteredChildrenChangeFilter: \"Change filter\",\n failedToCreateHierarchy: \"Failed to create hierarchy for {{node}}.\",\n failedToCreateRootHierarchy: \"Failed to load tree.\",\n resultLimitExceeded: \"The hierarchy for {{node}} contains {{limit}}+ items. Try using filters or increase the limit.\",\n rootResultLimitExceeded: \"The root item hierarchy contains {{limit}}+ items. Try increasing the limit.\",\n issuesFound: \"issues found\",\n increaseHierarchyLimit: \"Increase limit to {{limit}}\",\n increaseHierarchyLimitToUnlimited: \"Remove limit\",\n increaseHierarchyLimitWithFiltering: \"Add Filter\",\n retry: \"Retry\",\n rename: \"Rename\",\n more: \"More\",\n};\n\nconst localizationContext = createContext<LocalizationContext>({ localizedStrings: defaultLocalizedStrings });\n\n/**\n * Properties for `LocalizationContextProvider`.\n * @public\n */\ninterface LocalizationContextProviderProps {\n /** Localized strings used in the components. */\n localizedStrings?: Partial<LocalizedStrings>;\n}\n\n/**\n * Context provider for localized strings used in the components.\n * @public\n */\nexport function LocalizationContextProvider({ localizedStrings, children }: PropsWithChildren<LocalizationContextProviderProps>) {\n const [state, setState] = useState({ localizedStrings: { ...defaultLocalizedStrings, ...localizedStrings } });\n\n useEffect(() => {\n setState({ localizedStrings: { ...defaultLocalizedStrings, ...localizedStrings } });\n }, [localizedStrings]);\n\n return <localizationContext.Provider value={state}>{children}</localizationContext.Provider>;\n}\n\n/** @internal */\nexport function useLocalizationContext() {\n return useContext(localizationContext);\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PropsWithChildren } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* @alpha
|
|
4
|
+
*/
|
|
5
|
+
interface RenameActionProps {
|
|
6
|
+
/**
|
|
7
|
+
* Indicates that space for this action button should be reserved, even when the action is not available.
|
|
8
|
+
* For nodes that don't support renaming, `<RenameAction reserveSpace />` renders:
|
|
9
|
+
*
|
|
10
|
+
* - Blank space when the action is used as an inline action. It's recommended to set this prop to keep all action buttons of the same kind vertically aligned.
|
|
11
|
+
* - Disabled menu item when the action is used as a menu action.
|
|
12
|
+
*/
|
|
13
|
+
reserveSpace?: true;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* React component that renders a rename action for a tree item.
|
|
17
|
+
* The tree component must have `getEditingProps.onLabelChanged` prop set to enable renaming functionality. When the rename is completed, the `onLabelChanged` function is called to make the actual data update.
|
|
18
|
+
* @alpha
|
|
19
|
+
*/
|
|
20
|
+
export declare const RenameAction: import("react").NamedExoticComponent<RenameActionProps>;
|
|
21
|
+
interface RenameContext {
|
|
22
|
+
isRenaming: boolean;
|
|
23
|
+
setIsRenaming: (isRenaming: boolean) => void;
|
|
24
|
+
onLabelChanged?: (newLabel: string) => void;
|
|
25
|
+
}
|
|
26
|
+
/** @internal */
|
|
27
|
+
export declare const useRenameContext: () => RenameContext | undefined;
|
|
28
|
+
/** @alpha */
|
|
29
|
+
export declare function RenameContextProvider({ onLabelChanged, children }: PropsWithChildren<{
|
|
30
|
+
onLabelChanged?: (newLabel: string) => void;
|
|
31
|
+
}>): import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=RenameAction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameAction.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/RenameAction.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAuB,iBAAiB,EAA8C,MAAM,OAAO,CAAC;AAK3G;;GAEG;AACH,UAAU,iBAAiB;IACzB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,yDAevB,CAAC;AAEH,UAAU,aAAa;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAID,gBAAgB;AAChB,eAAO,MAAM,gBAAgB,iCAE5B,CAAC;AAEF,aAAa;AACb,wBAAgB,qBAAqB,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC;IAAE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC,2CAKrI"}
|
|
@@ -0,0 +1,39 @@
|
|
|
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 { createContext, memo, useCallback, useContext, useMemo, useState } from "react";
|
|
7
|
+
import renameSvg from "@stratakit/icons/rename.svg";
|
|
8
|
+
import { Tree } from "@stratakit/structures";
|
|
9
|
+
import { useLocalizationContext } from "./LocalizationContext.js";
|
|
10
|
+
/**
|
|
11
|
+
* React component that renders a rename action for a tree item.
|
|
12
|
+
* The tree component must have `getEditingProps.onLabelChanged` prop set to enable renaming functionality. When the rename is completed, the `onLabelChanged` function is called to make the actual data update.
|
|
13
|
+
* @alpha
|
|
14
|
+
*/
|
|
15
|
+
export const RenameAction = memo(function RenameAction({ reserveSpace }) {
|
|
16
|
+
const { localizedStrings } = useLocalizationContext();
|
|
17
|
+
const context = useRenameContext();
|
|
18
|
+
const { rename } = localizedStrings;
|
|
19
|
+
const setIsRenaming = context?.setIsRenaming;
|
|
20
|
+
const handleClick = useCallback(() => {
|
|
21
|
+
setIsRenaming?.(true);
|
|
22
|
+
}, [setIsRenaming]);
|
|
23
|
+
if (!context?.onLabelChanged) {
|
|
24
|
+
return reserveSpace ? _jsx(Tree.ItemAction, { label: rename, icon: renameSvg, visible: false, disabled: true }) : undefined;
|
|
25
|
+
}
|
|
26
|
+
return _jsx(Tree.ItemAction, { label: rename, onClick: handleClick, icon: renameSvg });
|
|
27
|
+
});
|
|
28
|
+
const renameContext = createContext(undefined);
|
|
29
|
+
/** @internal */
|
|
30
|
+
export const useRenameContext = () => {
|
|
31
|
+
return useContext(renameContext);
|
|
32
|
+
};
|
|
33
|
+
/** @alpha */
|
|
34
|
+
export function RenameContextProvider({ onLabelChanged, children }) {
|
|
35
|
+
const [isRenaming, setIsRenaming] = useState(false);
|
|
36
|
+
const value = useMemo(() => ({ isRenaming, setIsRenaming, onLabelChanged }), [isRenaming, onLabelChanged]);
|
|
37
|
+
return _jsx(renameContext.Provider, { value: value, children: children });
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=RenameAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenameAction.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/RenameAction.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,aAAa,EAAE,IAAI,EAAqB,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC3G,OAAO,SAAS,MAAM,6BAA6B,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAgBlE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,YAAY,CAAC,EAAE,YAAY,EAAqB;IACxF,MAAM,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IACtD,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC;IAEpC,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,CAAC;IAC7C,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;QAC7B,OAAO,YAAY,CAAC,CAAC,CAAC,KAAC,IAAI,CAAC,UAAU,IAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,SAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACjH,CAAC;IAED,OAAO,KAAC,IAAI,CAAC,UAAU,IAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,GAAI,CAAC;AACnF,CAAC,CAAC,CAAC;AAQH,MAAM,aAAa,GAAG,aAAa,CAA4B,SAAS,CAAC,CAAC;AAE1E,gBAAgB;AAChB,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IACnC,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,aAAa;AACb,MAAM,UAAU,qBAAqB,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAsE;IACpI,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;IAE3G,OAAO,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA0B,CAAC;AACnF,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { createContext, memo, PropsWithChildren, useCallback, useContext, useMemo, useState } from \"react\";\nimport renameSvg from \"@stratakit/icons/rename.svg\";\nimport { Tree } from \"@stratakit/structures\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\n\n/**\n * @alpha\n */\ninterface RenameActionProps {\n /**\n * Indicates that space for this action button should be reserved, even when the action is not available.\n * For nodes that don't support renaming, `<RenameAction reserveSpace />` renders:\n *\n * - Blank space when the action is used as an inline action. It's recommended to set this prop to keep all action buttons of the same kind vertically aligned.\n * - Disabled menu item when the action is used as a menu action.\n */\n reserveSpace?: true;\n}\n\n/**\n * React component that renders a rename action for a tree item.\n * The tree component must have `getEditingProps.onLabelChanged` prop set to enable renaming functionality. When the rename is completed, the `onLabelChanged` function is called to make the actual data update.\n * @alpha\n */\nexport const RenameAction = memo(function RenameAction({ reserveSpace }: RenameActionProps) {\n const { localizedStrings } = useLocalizationContext();\n const context = useRenameContext();\n const { rename } = localizedStrings;\n\n const setIsRenaming = context?.setIsRenaming;\n const handleClick = useCallback(() => {\n setIsRenaming?.(true);\n }, [setIsRenaming]);\n\n if (!context?.onLabelChanged) {\n return reserveSpace ? <Tree.ItemAction label={rename} icon={renameSvg} visible={false} disabled /> : undefined;\n }\n\n return <Tree.ItemAction label={rename} onClick={handleClick} icon={renameSvg} />;\n});\n\ninterface RenameContext {\n isRenaming: boolean;\n setIsRenaming: (isRenaming: boolean) => void;\n onLabelChanged?: (newLabel: string) => void;\n}\n\nconst renameContext = createContext<RenameContext | undefined>(undefined);\n\n/** @internal */\nexport const useRenameContext = () => {\n return useContext(renameContext);\n};\n\n/** @alpha */\nexport function RenameContextProvider({ onLabelChanged, children }: PropsWithChildren<{ onLabelChanged?: (newLabel: string) => void }>) {\n const [isRenaming, setIsRenaming] = useState(false);\n const value = useMemo(() => ({ isRenaming, setIsRenaming, onLabelChanged }), [isRenaming, onLabelChanged]);\n\n return <renameContext.Provider value={value}>{children}</renameContext.Provider>;\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RootErrorRendererProps } from "../Renderers.js";
|
|
2
|
+
import { ErrorInfo } from "../TreeNode.js";
|
|
3
|
+
/**
|
|
4
|
+
* @alpha
|
|
5
|
+
*/
|
|
6
|
+
export type StrataKitRootErrorRendererProps = {
|
|
7
|
+
/** Root error to be displayed */
|
|
8
|
+
error: ErrorInfo;
|
|
9
|
+
} & RootErrorRendererProps;
|
|
10
|
+
/**
|
|
11
|
+
* A component that renders root node error state.
|
|
12
|
+
*
|
|
13
|
+
* @alpha
|
|
14
|
+
*/
|
|
15
|
+
export declare function StrataKitRootErrorRenderer({ error, getHierarchyLevelDetails, reloadTree }: StrataKitRootErrorRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=RootErrorRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RootErrorRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/RootErrorRenderer.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C;;GAEG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,iCAAiC;IACjC,KAAK,EAAE,SAAS,CAAC;CAClB,GAAG,sBAAsB,CAAC;AAE3B;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAE,EAAE,+BAA+B,2CA+B1H"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } 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 { Button, Text } from "@stratakit/bricks";
|
|
7
|
+
import { Icon } from "@stratakit/foundations";
|
|
8
|
+
import errorSvg from "@stratakit/icons/status-error.svg";
|
|
9
|
+
import { useLocalizationContext } from "./LocalizationContext.js";
|
|
10
|
+
/**
|
|
11
|
+
* A component that renders root node error state.
|
|
12
|
+
*
|
|
13
|
+
* @alpha
|
|
14
|
+
*/
|
|
15
|
+
export function StrataKitRootErrorRenderer({ error, getHierarchyLevelDetails, reloadTree }) {
|
|
16
|
+
const { localizedStrings } = useLocalizationContext();
|
|
17
|
+
if (error.type === "ResultSetTooLarge") {
|
|
18
|
+
const onOverrideLimit = () => getHierarchyLevelDetails(undefined)?.setSizeLimit("unbounded");
|
|
19
|
+
return (_jsx(RootErrorContainer, { message: localizedStrings.rootResultLimitExceeded.replace("{{limit}}", error.resultSetSizeLimit.toString()), actions: [
|
|
20
|
+
{
|
|
21
|
+
action: onOverrideLimit,
|
|
22
|
+
label: localizedStrings.increaseHierarchyLimitToUnlimited,
|
|
23
|
+
condition: () => true,
|
|
24
|
+
},
|
|
25
|
+
] }));
|
|
26
|
+
}
|
|
27
|
+
return (_jsx(RootErrorContainer, { message: localizedStrings.failedToCreateRootHierarchy, actions: [
|
|
28
|
+
{
|
|
29
|
+
action: () => reloadTree({ parentNodeId: undefined, state: "reset" }),
|
|
30
|
+
label: localizedStrings.retry,
|
|
31
|
+
condition: () => true,
|
|
32
|
+
},
|
|
33
|
+
] }));
|
|
34
|
+
}
|
|
35
|
+
function RootErrorContainer({ actions, message }) {
|
|
36
|
+
return (_jsxs("div", { style: { height: "100%", display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", gap: "0.5rem" }, children: [_jsx(Icon, { href: errorSvg, size: "large" }), _jsx(Text, { variant: "body-sm", style: { textAlign: "center" }, children: message }), actions
|
|
37
|
+
?.filter(({ condition }) => condition())
|
|
38
|
+
.map((action) => {
|
|
39
|
+
return (_jsx(Button, { onClick: () => action.action(), children: action.label }, action.label));
|
|
40
|
+
})] }));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=RootErrorRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RootErrorRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/RootErrorRenderer.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,QAAQ,MAAM,mCAAmC,CAAC;AAGzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAUlE;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAmC;IACzH,MAAM,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,EAAE,CAAC;IAEtD,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACvC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;QAC7F,OAAO,CACL,KAAC,kBAAkB,IACjB,OAAO,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC,EAC3G,OAAO,EAAE;gBACP;oBACE,MAAM,EAAE,eAAe;oBACvB,KAAK,EAAE,gBAAgB,CAAC,iCAAiC;oBACzD,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI;iBACtB;aACF,GACD,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,KAAC,kBAAkB,IACjB,OAAO,EAAE,gBAAgB,CAAC,2BAA2B,EACrD,OAAO,EAAE;YACP;gBACE,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;gBACrE,KAAK,EAAE,gBAAgB,CAAC,KAAK;gBAC7B,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI;aACtB;SACF,GACD,CACH,CAAC;AACJ,CAAC;AAOD,SAAS,kBAAkB,CAAC,EAAE,OAAO,EAAE,OAAO,EAA2B;IACvE,OAAO,CACL,eAAK,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,aACrI,KAAC,IAAI,IAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAC,OAAO,GAAG,EACrC,KAAC,IAAI,IAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,YACrD,OAAO,GACH,EACN,OAAO;gBACN,EAAE,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC;iBACvC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACd,OAAO,CACL,KAAC,MAAM,IAAoB,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,YACtD,MAAM,CAAC,KAAK,IADF,MAAM,CAAC,KAAK,CAEhB,CACV,CAAC;YACJ,CAAC,CAAC,IACA,CACP,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 { Button, Text } from \"@stratakit/bricks\";\nimport { Icon } from \"@stratakit/foundations\";\nimport errorSvg from \"@stratakit/icons/status-error.svg\";\nimport { RootErrorRendererProps } from \"../Renderers.js\";\nimport { ErrorInfo } from \"../TreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\n\n/**\n * @alpha\n */\nexport type StrataKitRootErrorRendererProps = {\n /** Root error to be displayed */\n error: ErrorInfo;\n} & RootErrorRendererProps;\n\n/**\n * A component that renders root node error state.\n *\n * @alpha\n */\nexport function StrataKitRootErrorRenderer({ error, getHierarchyLevelDetails, reloadTree }: StrataKitRootErrorRendererProps) {\n const { localizedStrings } = useLocalizationContext();\n\n if (error.type === \"ResultSetTooLarge\") {\n const onOverrideLimit = () => getHierarchyLevelDetails(undefined)?.setSizeLimit(\"unbounded\");\n return (\n <RootErrorContainer\n message={localizedStrings.rootResultLimitExceeded.replace(\"{{limit}}\", error.resultSetSizeLimit.toString())}\n actions={[\n {\n action: onOverrideLimit,\n label: localizedStrings.increaseHierarchyLimitToUnlimited,\n condition: () => true,\n },\n ]}\n />\n );\n }\n\n return (\n <RootErrorContainer\n message={localizedStrings.failedToCreateRootHierarchy}\n actions={[\n {\n action: () => reloadTree({ parentNodeId: undefined, state: \"reset\" }),\n label: localizedStrings.retry,\n condition: () => true,\n },\n ]}\n />\n );\n}\n\ninterface RootErrorContainerProps {\n message: string;\n actions?: { action: () => void; label: string; condition: () => boolean }[];\n}\n\nfunction RootErrorContainer({ actions, message }: RootErrorContainerProps) {\n return (\n <div style={{ height: \"100%\", display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", alignItems: \"center\", gap: \"0.5rem\" }}>\n <Icon href={errorSvg} size=\"large\" />\n <Text variant={\"body-sm\"} style={{ textAlign: \"center\" }}>\n {message}\n </Text>\n {actions\n ?.filter(({ condition }) => condition())\n .map((action) => {\n return (\n <Button key={action.label} onClick={() => action.action()}>\n {action.label}\n </Button>\n );\n })}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { HierarchyLevelDetails, TreeRendererProps } from "../Renderers.js";
|
|
3
|
+
import { ErrorItem } from "./FlatTreeNode.js";
|
|
4
|
+
/**
|
|
5
|
+
* Interface containing error item related actions.
|
|
6
|
+
*
|
|
7
|
+
* @alpha
|
|
8
|
+
*/
|
|
9
|
+
interface TreeErrorItemProps {
|
|
10
|
+
/** A callback to reload a hierarchy level when an error occurs and `retry` button is clicked. */
|
|
11
|
+
reloadTree: (options: {
|
|
12
|
+
parentNodeId: string | undefined;
|
|
13
|
+
state: "reset";
|
|
14
|
+
}) => void;
|
|
15
|
+
/** Action to perform when the filter button is clicked for this node. */
|
|
16
|
+
onFilterClick?: (hierarchyLevelDetails: HierarchyLevelDetails) => void;
|
|
17
|
+
/** Action to perform when an error accurs and node label is clicked in the error message */
|
|
18
|
+
scrollToElement: (errorNode: ErrorItem) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Interface containing building blocks for `TreeErrorRenderer`.
|
|
22
|
+
*
|
|
23
|
+
* @alpha
|
|
24
|
+
*/
|
|
25
|
+
interface TreeErrorRendererOwnProps {
|
|
26
|
+
/** List of errors to be displayed */
|
|
27
|
+
errorList: ErrorItem[];
|
|
28
|
+
renderError?: ({ errorItem, scrollToElement }: {
|
|
29
|
+
errorItem: ErrorItem;
|
|
30
|
+
scrollToElement: () => void;
|
|
31
|
+
}) => ReactElement;
|
|
32
|
+
}
|
|
33
|
+
/** @alpha */
|
|
34
|
+
export type TreeErrorRendererProps = TreeErrorRendererOwnProps & TreeErrorItemProps & Pick<TreeRendererProps, "getHierarchyLevelDetails">;
|
|
35
|
+
/**
|
|
36
|
+
* A component that renders error display dropdown using the `unstable_ErrorRegion` component from `@itwin/itwinui-react`.
|
|
37
|
+
* As input, the component uses a list of `ErrorNode` objects, which are generally created using the `useErrorList` hook.
|
|
38
|
+
*
|
|
39
|
+
* @alpha
|
|
40
|
+
*/
|
|
41
|
+
export declare function TreeErrorRenderer({ errorList, reloadTree, scrollToElement, getHierarchyLevelDetails, onFilterClick, renderError }: TreeErrorRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=TreeErrorRenderer.d.ts.map
|
|
@@ -0,0 +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;AAIrC,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE3E,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,qCAAqC;IACrC,SAAS,EAAE,SAAS,EAAE,CAAC;IAEvB,WAAW,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE;QAAE,SAAS,EAAE,SAAS,CAAC;QAAC,eAAe,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,YAAY,CAAC;CACvH;AAED,aAAa;AACb,MAAM,MAAM,sBAAsB,GAAG,yBAAyB,GAAG,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,0BAA0B,CAAC,CAAC;AAE1I;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,wBAAwB,EAAE,aAAa,EAAE,WAAW,EAAE,EAAE,sBAAsB,2CAgFzJ"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Anchor, Text } from "@stratakit/bricks";
|
|
3
|
+
import { unstable_ErrorRegion as ErrorRegion } from "@stratakit/structures";
|
|
4
|
+
import { MAX_LIMIT_OVERRIDE } from "../internal/Utils.js";
|
|
5
|
+
import { useLocalizationContext } from "./LocalizationContext.js";
|
|
6
|
+
/**
|
|
7
|
+
* A component that renders error display dropdown using the `unstable_ErrorRegion` component from `@itwin/itwinui-react`.
|
|
8
|
+
* As input, the component uses a list of `ErrorNode` objects, which are generally created using the `useErrorList` hook.
|
|
9
|
+
*
|
|
10
|
+
* @alpha
|
|
11
|
+
*/
|
|
12
|
+
export function TreeErrorRenderer({ errorList, reloadTree, scrollToElement, getHierarchyLevelDetails, onFilterClick, renderError }) {
|
|
13
|
+
const { localizedStrings } = useLocalizationContext();
|
|
14
|
+
const errorItems = errorList.map(({ errorNode, expandTo }) => {
|
|
15
|
+
if (renderError) {
|
|
16
|
+
return renderError({ errorItem: { errorNode, expandTo }, scrollToElement: () => scrollToElement({ errorNode, expandTo }) });
|
|
17
|
+
}
|
|
18
|
+
if (errorNode.error?.type === "ResultSetTooLarge") {
|
|
19
|
+
const limit = errorNode.error.resultSetSizeLimit;
|
|
20
|
+
const onOverrideLimit = getHierarchyLevelDetails ? () => getHierarchyLevelDetails(errorNode.id)?.setSizeLimit(MAX_LIMIT_OVERRIDE) : undefined;
|
|
21
|
+
return (_jsx(ErrorItemContainer, { errorNode: errorNode, actions: [
|
|
22
|
+
{
|
|
23
|
+
action: () => {
|
|
24
|
+
onOverrideLimit?.();
|
|
25
|
+
},
|
|
26
|
+
label: localizedStrings.increaseHierarchyLimit.replace("{{limit}}", MAX_LIMIT_OVERRIDE.toString()),
|
|
27
|
+
condition: () => !!onOverrideLimit && limit < MAX_LIMIT_OVERRIDE,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
action: () => {
|
|
31
|
+
const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.id);
|
|
32
|
+
hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);
|
|
33
|
+
},
|
|
34
|
+
label: localizedStrings.increaseHierarchyLimitWithFiltering,
|
|
35
|
+
condition: () => !!onFilterClick && !!errorNode?.isFilterable,
|
|
36
|
+
},
|
|
37
|
+
], message: localizedStrings.resultLimitExceeded.replace("{{limit}}", limit.toString()), scrollToElement: () => scrollToElement({ errorNode, expandTo }) }, errorNode.error.id));
|
|
38
|
+
}
|
|
39
|
+
if (errorNode.error?.type === "NoFilterMatches") {
|
|
40
|
+
return (_jsx(ErrorItemContainer, { errorNode: errorNode, actions: [
|
|
41
|
+
{
|
|
42
|
+
action: () => {
|
|
43
|
+
const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.id);
|
|
44
|
+
hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);
|
|
45
|
+
},
|
|
46
|
+
label: localizedStrings.noFilteredChildrenChangeFilter,
|
|
47
|
+
condition: () => true,
|
|
48
|
+
},
|
|
49
|
+
], message: localizedStrings.noFilteredChildren, scrollToElement: () => scrollToElement({ errorNode, expandTo }) }, errorNode.error.id));
|
|
50
|
+
}
|
|
51
|
+
return (_jsx(ErrorItemContainer, { errorNode: errorNode, actions: [
|
|
52
|
+
{
|
|
53
|
+
action: () => reloadTree({ parentNodeId: errorNode.id, state: "reset" }),
|
|
54
|
+
label: localizedStrings.retry,
|
|
55
|
+
condition: () => true,
|
|
56
|
+
},
|
|
57
|
+
], message: localizedStrings.failedToCreateHierarchy, scrollToElement: () => scrollToElement({ errorNode, expandTo }) }, errorNode.id));
|
|
58
|
+
});
|
|
59
|
+
return (_jsx(ErrorRegion.Root, { style: { width: "100%" }, label: errorList.length !== 0 ? `${errorList.length} ${localizedStrings?.issuesFound}` : undefined, items: errorItems }));
|
|
60
|
+
}
|
|
61
|
+
function ErrorItemContainer({ errorNode, message, actions, scrollToElement }) {
|
|
62
|
+
return (_jsx(ErrorRegion.Item, { message: _jsx(MessageWithLink, { linkLabel: errorNode.label, scrollToElement: scrollToElement, message: message }), messageId: errorNode.id, actions: _jsx("div", { style: { display: "flex", flexDirection: "column" }, children: actions
|
|
63
|
+
?.filter(({ condition }) => condition())
|
|
64
|
+
.map(({ label, action }) => (_jsx(Anchor, { onClick: action, children: label }, label))) }) }));
|
|
65
|
+
}
|
|
66
|
+
function MessageWithLink({ linkLabel, scrollToElement, message }) {
|
|
67
|
+
const splitMessage = message.split("{{node}}", 2);
|
|
68
|
+
return (_jsxs("div", { style: { display: "flex", whiteSpace: "pre", flexWrap: "wrap" }, children: [_jsx(Text, { variant: "body-sm", children: splitMessage[0] }), _jsx(Anchor, { onClick: scrollToElement, children: linkLabel }), splitMessage[1] ? _jsx(Text, { variant: "body-sm", children: splitMessage[1] }) : null] }));
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=TreeErrorRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeErrorRenderer.js","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeErrorRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ReactElement } from \"react\";\nimport { Anchor, Text } from \"@stratakit/bricks\";\nimport { unstable_ErrorRegion as ErrorRegion } from \"@stratakit/structures\";\nimport { MAX_LIMIT_OVERRIDE } from \"../internal/Utils.js\";\nimport { HierarchyLevelDetails, TreeRendererProps } from \"../Renderers.js\";\nimport { PresentationHierarchyNode } from \"../TreeNode.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 accurs 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 /** 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?: ({ errorItem, scrollToElement }: { errorItem: ErrorItem; scrollToElement: () => void }) => 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({ errorList, reloadTree, scrollToElement, getHierarchyLevelDetails, onFilterClick, renderError }: TreeErrorRendererProps) {\n const { localizedStrings } = useLocalizationContext();\n const errorItems = errorList.map(({ errorNode, expandTo }) => {\n if (renderError) {\n return renderError({ errorItem: { errorNode, expandTo }, scrollToElement: () => scrollToElement({ errorNode, expandTo }) });\n }\n\n if (errorNode.error?.type === \"ResultSetTooLarge\") {\n const limit = errorNode.error.resultSetSizeLimit;\n const onOverrideLimit = getHierarchyLevelDetails ? () => getHierarchyLevelDetails(errorNode.id)?.setSizeLimit(MAX_LIMIT_OVERRIDE) : undefined;\n return (\n <ErrorItemContainer\n key={errorNode.error.id}\n errorNode={errorNode}\n actions={[\n {\n action: () => {\n onOverrideLimit?.();\n },\n label: localizedStrings.increaseHierarchyLimit.replace(\"{{limit}}\", MAX_LIMIT_OVERRIDE.toString()),\n condition: () => !!onOverrideLimit && limit < MAX_LIMIT_OVERRIDE,\n },\n {\n action: () => {\n const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.id);\n hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);\n },\n label: localizedStrings.increaseHierarchyLimitWithFiltering,\n condition: () => !!onFilterClick && !!errorNode?.isFilterable,\n },\n ]}\n message={localizedStrings.resultLimitExceeded.replace(\"{{limit}}\", limit.toString())}\n scrollToElement={() => scrollToElement({ errorNode, expandTo })}\n />\n );\n }\n if (errorNode.error?.type === \"NoFilterMatches\") {\n return (\n <ErrorItemContainer\n key={errorNode.error.id}\n errorNode={errorNode}\n actions={[\n {\n action: () => {\n const hierarchyLevelDetails = getHierarchyLevelDetails?.(errorNode.id);\n hierarchyLevelDetails && onFilterClick?.(hierarchyLevelDetails);\n },\n label: localizedStrings.noFilteredChildrenChangeFilter,\n condition: () => true,\n },\n ]}\n message={localizedStrings.noFilteredChildren}\n scrollToElement={() => scrollToElement({ errorNode, expandTo })}\n />\n );\n }\n return (\n <ErrorItemContainer\n key={errorNode.id}\n errorNode={errorNode}\n actions={[\n {\n action: () => reloadTree({ parentNodeId: errorNode.id, state: \"reset\" }),\n label: localizedStrings.retry,\n condition: () => true,\n },\n ]}\n message={localizedStrings.failedToCreateHierarchy}\n scrollToElement={() => scrollToElement({ errorNode, expandTo })}\n />\n );\n });\n\n return (\n <ErrorRegion.Root\n style={{ width: \"100%\" }}\n label={errorList.length !== 0 ? `${errorList.length} ${localizedStrings?.issuesFound}` : undefined}\n items={errorItems}\n />\n );\n}\n\ntype ErrorItemContainerProps = {\n errorNode: PresentationHierarchyNode;\n message: string;\n actions?: { action: () => void; label: string; condition: () => boolean }[];\n} & Pick<MessageWithLinkProps, \"scrollToElement\">;\n\nfunction ErrorItemContainer({ errorNode, message, actions, scrollToElement }: ErrorItemContainerProps) {\n return (\n <ErrorRegion.Item\n message={<MessageWithLink linkLabel={errorNode.label} scrollToElement={scrollToElement} message={message} />}\n messageId={errorNode.id}\n actions={\n <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n {actions\n ?.filter(({ condition }) => condition())\n .map(({ label, action }) => (\n <Anchor key={label} onClick={action}>\n {label}\n </Anchor>\n ))}\n </div>\n }\n />\n );\n}\n\ninterface MessageWithLinkProps {\n scrollToElement: () => void;\n message: string;\n linkLabel?: string;\n}\n\nfunction MessageWithLink({ linkLabel, scrollToElement, message }: MessageWithLinkProps) {\n const splitMessage = message.split(\"{{node}}\", 2);\n return (\n <div style={{ display: \"flex\", whiteSpace: \"pre\", flexWrap: \"wrap\" }}>\n <Text variant={\"body-sm\"}>{splitMessage[0]}</Text>\n <Anchor onClick={scrollToElement}>{linkLabel}</Anchor>\n {splitMessage[1] ? <Text variant={\"body-sm\"}>{splitMessage[1]}</Text> : null}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, FC, PropsWithRef, ReactElement, ReactNode, RefAttributes } from "react";
|
|
2
|
+
import { Tree } from "@stratakit/structures";
|
|
3
|
+
import { TreeRendererProps } from "../Renderers.js";
|
|
4
|
+
import { PresentationHierarchyNode } from "../TreeNode.js";
|
|
5
|
+
/** @alpha */
|
|
6
|
+
type TreeNodeProps = ComponentPropsWithoutRef<typeof Tree.Item>;
|
|
7
|
+
/** @alpha */
|
|
8
|
+
export interface TreeNodeRendererOwnProps {
|
|
9
|
+
/** Node that is rendered. */
|
|
10
|
+
node: PresentationHierarchyNode;
|
|
11
|
+
/** Returns a label for a given node. */
|
|
12
|
+
getLabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;
|
|
13
|
+
/** Returns sublabel for a given node. */
|
|
14
|
+
getSublabel?: (node: PresentationHierarchyNode) => ReactElement | undefined;
|
|
15
|
+
/** Action to perform when the node is clicked. */
|
|
16
|
+
onNodeClick?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.MouseEvent<HTMLElement>) => void;
|
|
17
|
+
/** Action to perform when a key is pressed when the node is hovered on. */
|
|
18
|
+
onNodeKeyDown?: (node: PresentationHierarchyNode, isSelected: boolean, event: React.KeyboardEvent<HTMLElement>) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Used to render elements between expander and label.
|
|
21
|
+
* E.g. icons, color picker, etc.
|
|
22
|
+
*/
|
|
23
|
+
getDecorations?: (node: PresentationHierarchyNode) => ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* Callback that returns menu actions for tree item.
|
|
26
|
+
* Must return an array of `Tree.ItemAction` elements.
|
|
27
|
+
*/
|
|
28
|
+
getMenuActions?: (node: PresentationHierarchyNode) => ReactNode[];
|
|
29
|
+
/**
|
|
30
|
+
* Callback that returns inline actions for tree item.
|
|
31
|
+
* Must return an array of `Tree.ItemAction` elements.
|
|
32
|
+
* Max 2 items.
|
|
33
|
+
*/
|
|
34
|
+
getInlineActions?: (node: PresentationHierarchyNode) => ReactNode[];
|
|
35
|
+
}
|
|
36
|
+
/** @alpha */
|
|
37
|
+
type TreeNodeRendererProps = Pick<TreeRendererProps, "expandNode" | "reloadTree"> & Omit<TreeNodeProps, "actions" | "label" | "expanded" | "unstable_decorations" | "error"> & TreeNodeRendererOwnProps;
|
|
38
|
+
/**
|
|
39
|
+
* A component that renders given `FlatTreeNode` using the `Tree.Item` component from `@itwin/itwinui-react`. The
|
|
40
|
+
* `FlatTreeNode` objects for this renderer are generally created using the `useFlatTreeNodeList` hook.
|
|
41
|
+
*
|
|
42
|
+
* @see `TreeRenderer`
|
|
43
|
+
* @see https://itwinui.bentley.com/docs/tree
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare const StrataKitTreeNodeRenderer: FC<PropsWithRef<TreeNodeRendererProps & RefAttributes<HTMLElement>>>;
|
|
47
|
+
export declare const PlaceholderNode: FC<PropsWithRef<Omit<TreeNodeProps, "onExpanded" | "label" | "actions" | "icon" | "error"> & RefAttributes<HTMLElement>>>;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=TreeNodeRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeNodeRenderer.d.ts","sourceRoot":"","sources":["../../../../src/presentation-hierarchies-react/stratakit/TreeNodeRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EACL,wBAAwB,EACxB,EAAE,EAKF,YAAY,EACZ,YAAY,EACZ,SAAS,EAET,aAAa,EAMd,MAAM,OAAO,CAAC;AAGf,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAI3D,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,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;CACrE;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,CAgH1G,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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
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 { forwardRef, memo, useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
7
|
+
import { Spinner, TextBox } from "@stratakit/bricks";
|
|
8
|
+
import refreshSvg from "@stratakit/icons/refresh.svg";
|
|
9
|
+
import { Tree } from "@stratakit/structures";
|
|
10
|
+
import { useLocalizationContext } from "./LocalizationContext.js";
|
|
11
|
+
import { useRenameContext } from "./RenameAction.js";
|
|
12
|
+
/**
|
|
13
|
+
* A component that renders given `FlatTreeNode` using the `Tree.Item` component from `@itwin/itwinui-react`. The
|
|
14
|
+
* `FlatTreeNode` objects for this renderer are generally created using the `useFlatTreeNodeList` hook.
|
|
15
|
+
*
|
|
16
|
+
* @see `TreeRenderer`
|
|
17
|
+
* @see https://itwinui.bentley.com/docs/tree
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export const StrataKitTreeNodeRenderer = memo(forwardRef(function HierarchyNode({ node, selected, expandNode, onNodeClick, onNodeKeyDown, reloadTree, getLabel, getSublabel, getMenuActions, getInlineActions, getDecorations, ...treeItemProps }, forwardedRef) {
|
|
21
|
+
const nodeRef = useRef(null);
|
|
22
|
+
const ref = useMergedRefs(forwardedRef, nodeRef);
|
|
23
|
+
const { localizedStrings } = useLocalizationContext();
|
|
24
|
+
const renameContext = useRenameContext();
|
|
25
|
+
const label = useMemo(() => (getLabel ? getLabel(node) : node.label), [getLabel, node]);
|
|
26
|
+
const description = useMemo(() => (getSublabel ? getSublabel(node) : undefined), [getSublabel, node]);
|
|
27
|
+
const decorations = useMemo(() => getDecorations?.(node), [getDecorations, node]);
|
|
28
|
+
const inlineActions = useMemo(() => {
|
|
29
|
+
if (node.error !== undefined && node.error.type === "Unknown") {
|
|
30
|
+
return [
|
|
31
|
+
_jsx(Tree.ItemAction, { label: localizedStrings.retry, onClick: () => reloadTree({ parentNodeId: node.id, state: "reset" }), visible: true, icon: refreshSvg }, "retry"),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
if (!getInlineActions) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
return getInlineActions(node);
|
|
38
|
+
}, [node, getInlineActions, localizedStrings.retry, reloadTree]);
|
|
39
|
+
const expanded = useMemo(() => {
|
|
40
|
+
if (node.error) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
if (node.isExpanded || node.children === true || node.children.length > 0) {
|
|
44
|
+
return node.isExpanded;
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}, [node.children, node.error, node.isExpanded]);
|
|
48
|
+
const isDisabled = treeItemProps["aria-disabled"] === true;
|
|
49
|
+
const { onLabelChanged, setIsRenaming, isRenaming } = renameContext ?? {};
|
|
50
|
+
const labelEditor = isRenaming ? (_jsx(LabelEditor, { initialLabel: node.label, onChange: (newLabel) => {
|
|
51
|
+
onLabelChanged?.(newLabel);
|
|
52
|
+
setIsRenaming?.(false);
|
|
53
|
+
}, onCancel: () => {
|
|
54
|
+
setIsRenaming?.(false);
|
|
55
|
+
} })) : undefined;
|
|
56
|
+
return (_jsx(Tree.Item, { ...treeItemProps, ref: ref, label: labelEditor ?? label, description: description, selected: selected, expanded: expanded, onExpandedChange: useCallback((isExpanded) => {
|
|
57
|
+
expandNode(node.id, isExpanded);
|
|
58
|
+
}, [node, expandNode]), onClick: useCallback((event) => {
|
|
59
|
+
if (isDisabled) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
onNodeClick?.(node, !selected, event);
|
|
63
|
+
}, [node, isDisabled, selected, onNodeClick]), onKeyDown: useCallback((event) => {
|
|
64
|
+
// Ignore if it is called on the element inside, e.g. checkbox or expander
|
|
65
|
+
if (!isDisabled && event.target === nodeRef.current) {
|
|
66
|
+
onNodeKeyDown?.(node, !selected, event);
|
|
67
|
+
}
|
|
68
|
+
}, [onNodeKeyDown, selected, isDisabled, node]), inlineActions: inlineActions, actions: useMemo(() => (node.error === undefined && getMenuActions ? getMenuActions(node) : []), [getMenuActions, node]), unstable_decorations: decorations, error: node.error ? node.error.id : undefined }));
|
|
69
|
+
}));
|
|
70
|
+
export const PlaceholderNode = memo(forwardRef(function PlaceholderNode({ ...props }, forwardedRef) {
|
|
71
|
+
const { localizedStrings } = useLocalizationContext();
|
|
72
|
+
return _jsx(Tree.Item, { ...props, ref: forwardedRef, label: localizedStrings.loading, icon: _jsx(Spinner, { size: "small", title: localizedStrings.loading }) });
|
|
73
|
+
}));
|
|
74
|
+
function LabelEditor({ initialLabel, onChange, onCancel }) {
|
|
75
|
+
const inputRef = useRef(null);
|
|
76
|
+
const [newLabelValue, setNewLabelValue] = useState(initialLabel);
|
|
77
|
+
const handleLabelChange = () => {
|
|
78
|
+
if (initialLabel !== newLabelValue) {
|
|
79
|
+
onChange(newLabelValue);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
onCancel();
|
|
83
|
+
};
|
|
84
|
+
const cancelLabelChange = () => {
|
|
85
|
+
setNewLabelValue(initialLabel);
|
|
86
|
+
onCancel();
|
|
87
|
+
};
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (inputRef.current) {
|
|
90
|
+
inputRef.current.focus();
|
|
91
|
+
inputRef.current.select();
|
|
92
|
+
}
|
|
93
|
+
}, []);
|
|
94
|
+
return (_jsx(TextBox.Root, { children: _jsx(TextBox.Input, { ref: inputRef, value: newLabelValue, onChange: (event) => setNewLabelValue(event.target.value), onBlur: handleLabelChange, onKeyDown: (event) => {
|
|
95
|
+
if (event.key === "Enter") {
|
|
96
|
+
handleLabelChange();
|
|
97
|
+
}
|
|
98
|
+
else if (event.key === "Escape") {
|
|
99
|
+
cancelLabelChange();
|
|
100
|
+
}
|
|
101
|
+
} }) }));
|
|
102
|
+
}
|
|
103
|
+
function useMergedRefs(...refs) {
|
|
104
|
+
return useCallback((instance) => {
|
|
105
|
+
refs.forEach((ref) => {
|
|
106
|
+
if (typeof ref === "function") {
|
|
107
|
+
ref(instance);
|
|
108
|
+
}
|
|
109
|
+
else if (ref) {
|
|
110
|
+
ref.current = instance;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}, // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
114
|
+
[...refs]);
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=TreeNodeRenderer.js.map
|
|
@@ -0,0 +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 ComponentPropsWithoutRef,\n FC,\n forwardRef,\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 { Tree } from \"@stratakit/structures\";\nimport { TreeRendererProps } from \"../Renderers.js\";\nimport { PresentationHierarchyNode } from \"../TreeNode.js\";\nimport { useLocalizationContext } from \"./LocalizationContext.js\";\nimport { useRenameContext } from \"./RenameAction.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 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 `Tree.ItemAction` elements.\n */\n getMenuActions?: (node: PresentationHierarchyNode) => ReactNode[];\n /**\n * Callback that returns inline actions for tree item.\n * Must return an array of `Tree.ItemAction` elements.\n * Max 2 items.\n */\n getInlineActions?: (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 getLabel,\n getSublabel,\n getMenuActions,\n getInlineActions,\n getDecorations,\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\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 === \"Unknown\") {\n return [\n <Tree.ItemAction\n key=\"retry\"\n label={localizedStrings.retry}\n onClick={() => reloadTree({ parentNodeId: node.id, state: \"reset\" })}\n visible={true}\n icon={refreshSvg}\n />,\n ];\n }\n if (!getInlineActions) {\n return [];\n }\n return getInlineActions(node);\n }, [node, getInlineActions, localizedStrings.retry, reloadTree]);\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 <Tree.Item\n {...treeItemProps}\n ref={ref}\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={useMemo(() => (node.error === undefined && getMenuActions ? getMenuActions(node) : []), [getMenuActions, node])}\n unstable_decorations={decorations}\n error={node.error ? node.error.id : undefined}\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 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"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, ReactElement } from "react";
|
|
2
|
+
import { Tree } from "@stratakit/structures";
|
|
3
|
+
import { TreeRendererProps } from "../Renderers.js";
|
|
4
|
+
import { PresentationHierarchyNode } from "../TreeNode.js";
|
|
5
|
+
import { SelectionMode } from "../UseSelectionHandler.js";
|
|
6
|
+
import { LocalizationContextProvider } from "./LocalizationContext.js";
|
|
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>;
|
|
13
|
+
/** @alpha */
|
|
14
|
+
interface TreeRendererOwnProps {
|
|
15
|
+
/** Active selection mode used by the tree. Defaults to `"single"`. */
|
|
16
|
+
selectionMode?: SelectionMode;
|
|
17
|
+
/** A render function for errors' display component. Defaults to `<TreeErrorRenderer />`. */
|
|
18
|
+
errorRenderer?: (props: TreeErrorRendererProps) => ReactElement;
|
|
19
|
+
/** Props that defines if current node supports editing. */
|
|
20
|
+
getEditingProps?: (node: PresentationHierarchyNode) => {
|
|
21
|
+
/**
|
|
22
|
+
* A callback that is invoked when node label is changed. Should be used together
|
|
23
|
+
* with `<RenameAction />` to enter label editing mode. Node label is not editable
|
|
24
|
+
* when this is not supplied.
|
|
25
|
+
*/
|
|
26
|
+
onLabelChanged?: (newLabel: string) => void;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** @alpha */
|
|
30
|
+
type StrataKitTreeRendererProps = TreeRendererProps & Pick<TreeErrorRendererProps, "onFilterClick"> & Omit<TreeNodeRendererProps, "node" | "aria-level" | "aria-posinset" | "aria-setsize" | "reloadTree" | "selected" | "error"> & TreeRendererOwnProps & ComponentPropsWithoutRef<typeof LocalizationContextProvider>;
|
|
31
|
+
/**
|
|
32
|
+
* A component that renders a tree using the `Tree` component from `@itwin/itwinui-react`. The tree nodes
|
|
33
|
+
* are rendered using `TreeNodeRenderer` component from this package.
|
|
34
|
+
*
|
|
35
|
+
* @see https://itwinui.bentley.com/docs/tree
|
|
36
|
+
* @alpha
|
|
37
|
+
*/
|
|
38
|
+
export declare function StrataKitTreeRenderer({ rootNodes, selectNodes, selectionMode, expandNode, localizedStrings, getHierarchyLevelDetails, onFilterClick, reloadTree, isNodeSelected, errorRenderer, onNodeClick: onNodeClickOverride, onNodeKeyDown: onNodeKeyDownOverride, getEditingProps, ...treeProps }: StrataKitTreeRendererProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=TreeRenderer.d.ts.map
|
|
@@ -0,0 +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,EAA2C,MAAM,OAAO,CAAC;AACzI,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,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;CACH;AAED,aAAa;AACb,KAAK,0BAA0B,GAAG,iBAAiB,GACjD,IAAI,CAAC,sBAAsB,EAAE,eAAe,CAAC,GAC7C,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC,GAC3H,oBAAoB,GACpB,wBAAwB,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EAAE,mBAAmB,EAChC,aAAa,EAAE,qBAAqB,EACpC,eAAe,EACf,GAAG,SAAS,EACb,EAAE,0BAA0B,2CAsF5B"}
|