Skip to content

Commit d462aaf

Browse files
authored
feat(NavigationTree): add additionalNodeElements to NavigationTree (#55)
1 parent 4d06d91 commit d462aaf

File tree

6 files changed

+53
-1
lines changed

6 files changed

+53
-1
lines changed

src/components/NavigationTree/NavigationTree.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function NavigationTree({
3434
rootState: partialRootState,
3535
fetchPath,
3636
getActions,
37+
renderAdditionalNodeElements,
3738
activePath,
3839
onActivePathUpdate,
3940
cache = true,
@@ -55,6 +56,7 @@ export function NavigationTree({
5556
dispatch={dispatch}
5657
onActivate={onActivePathUpdate}
5758
getActions={getActions}
59+
renderAdditionalNodeElements={renderAdditionalNodeElements}
5860
cache={cache}
5961
level={node.level}
6062
/>

src/components/NavigationTree/NavigationTreeNode.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export interface NavigationTreeNodeProps {
2424
children?: React.ReactNode;
2525
onActivate?: (path: string) => void;
2626
getActions?: NavigationTreeProps['getActions'];
27+
renderAdditionalNodeElements?: NavigationTreeProps['renderAdditionalNodeElements'];
2728
cache?: boolean;
2829
}
2930

@@ -62,6 +63,7 @@ export function NavigationTreeNode({
6263
children,
6364
onActivate,
6465
getActions,
66+
renderAdditionalNodeElements,
6567
cache,
6668
}: NavigationTreeNodeProps) {
6769
const nodeState = state[path];
@@ -112,6 +114,10 @@ export function NavigationTreeNode({
112114
dispatch({type: NavigationTreeActionType.ToggleCollapsed, payload: {path}});
113115
}, []);
114116

117+
const additionalNodeElements = React.useMemo(() => {
118+
return renderAdditionalNodeElements?.(nodeState.path, nodeState.type);
119+
}, [renderAdditionalNodeElements, nodeState]);
120+
115121
const actions = React.useMemo(() => {
116122
return getActions?.(nodeState.path, nodeState.type);
117123
}, [getActions, nodeState]);
@@ -123,6 +129,7 @@ export function NavigationTreeNode({
123129
collapsed={nodeState.collapsed}
124130
active={nodeState.path === activePath}
125131
actions={actions}
132+
additionalNodeElements={additionalNodeElements}
126133
hasArrow={nodeState.expandable}
127134
onClick={handleClick}
128135
onArrowClick={handleArrowClick}

src/components/NavigationTree/__stories__/NavigationTree.stories.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import {Meta, Story} from '@storybook/react';
3+
import {Button} from '@gravity-ui/uikit';
34
import {NavigationTreeDataItem, NavigationTreeNodeType} from '../types';
45
import {NavigationTree, NavigationTreeProps} from '../NavigationTree';
56

@@ -21,6 +22,7 @@ export const Default: Story<NavigationTreeProps> = () => {
2122
}}
2223
fetchPath={fetchPath}
2324
getActions={getActions}
25+
renderAdditionalNodeElements={renderAdditionalNodeElements}
2426
activePath={activePath}
2527
onActivePathUpdate={setActivePath}
2628
/>
@@ -217,3 +219,33 @@ function getActions(path: string, type: NavigationTreeNodeType) {
217219

218220
return [];
219221
}
222+
223+
function renderAdditionalNodeElements(path: string, type: NavigationTreeNodeType) {
224+
if (type === 'directory') {
225+
return (
226+
<Button
227+
onClick={() => {
228+
alert(`Directory path is "${path}"`);
229+
}}
230+
size="s"
231+
>
232+
Show Directory
233+
</Button>
234+
);
235+
}
236+
237+
if (type === 'table') {
238+
return (
239+
<Button
240+
onClick={() => {
241+
alert(`Table path is "${path}"`);
242+
}}
243+
size="s"
244+
>
245+
Show Table
246+
</Button>
247+
);
248+
}
249+
250+
return undefined;
251+
}

src/components/NavigationTree/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ export interface NavigationTreeProps<D = any> {
5151
rootState: NavigationTreeNodePartialState;
5252
fetchPath: (path: string) => Promise<NavigationTreeDataItem[]>;
5353
getActions?: (path: string, type: NavigationTreeNodeType) => DropdownMenuItemMixed<D>[];
54+
renderAdditionalNodeElements?: (
55+
path: string,
56+
type: NavigationTreeNodeType,
57+
) => JSX.Element | undefined;
5458
activePath?: string;
5559
onActivePathUpdate?: (activePath: string) => void;
5660
cache?: boolean;

src/components/TreeView/TreeView.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ $step-offset: 24px;
3030
background-color: var(--yc-color-base-simple-hover);
3131

3232
#{$root}__actions {
33-
display: block;
33+
display: flex;
3434
}
3535
}
3636

@@ -75,6 +75,10 @@ $step-offset: 24px;
7575
&__actions {
7676
display: none;
7777
margin-left: 6px;
78+
79+
align-items: center;
80+
81+
overflow: hidden;
7882
}
7983

8084
.tree-view_arrow {

src/components/TreeView/TreeView.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface TreeViewProps {
1616
onArrowClick?: () => void;
1717
hasArrow?: boolean;
1818
actions?: DropdownMenuItemMixed<any>[];
19+
additionalNodeElements?: JSX.Element;
1920
level?: number;
2021
}
2122

@@ -34,6 +35,7 @@ export function TreeView({
3435
onArrowClick,
3536
hasArrow = false,
3637
actions,
38+
additionalNodeElements,
3739
level,
3840
}: TreeViewProps) {
3941
const rootRef = React.useRef<HTMLDivElement>(null);
@@ -46,6 +48,7 @@ export function TreeView({
4648
</div>
4749
{actions && actions.length > 0 && (
4850
<div className={b('actions')}>
51+
{additionalNodeElements}
4952
<DropdownMenu
5053
defaultSwitcherProps={{
5154
view: 'flat-secondary',

0 commit comments

Comments
 (0)