Skip to content

Commit

Permalink
Adding some additional options.
Browse files Browse the repository at this point in the history
  • Loading branch information
daveyholler committed Oct 17, 2019
1 parent ed1a474 commit b20779f
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 58 deletions.
96 changes: 56 additions & 40 deletions src-docs/src/views/recursive_tree/condensed.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,95 @@
import React from 'react';

import {
EuiIcon,
EuiRecursiveTree,
EuiToken,
} from '../../../../src/components';
import { EuiRecursiveTree, EuiToken } from '../../../../src/components';

export class RecursiveTreeCondensed extends React.Component {
showAlert = () => {
alert('You squashed a bug!');
};

// label: 'Item One',
// id: 'item_one',
// icon: <EuiIcon type="folderClosed" size="s" />,
// iconWhenExpanded: <EuiIcon type="folderOpen" size="s" />,
// isExpanded: true,

render() {
const items = [
{
label: 'Item One',
id: 'item_one',
icon: <EuiIcon type="folderClosed" size="s" />,
iconWhenExpanded: <EuiIcon type="folderOpen" size="s" />,
isExpanded: true,
label: 'transporter',
id: 'transporter',
icon: <EuiToken size="xs" iconType="tokenObject" />,
children: [
{
label: 'Item A',
id: 'item_a',
icon: <EuiIcon type="document" size="s" />,
label: 'service',
id: 'service',
icon: <EuiToken size="xs" iconType="tokenString" />,
},
{
label: 'Item B',
id: 'item_b',
icon: <EuiIcon type="arrowRight" size="s" />,
iconWhenExpanded: <EuiIcon type="arrowDown" size="s" />,
label: 'auth',
id: 'auth',
icon: <EuiToken size="xs" iconType="tokenObject" />,
children: [
{
label: 'A Cloud',
id: 'item_cloud',
icon: <EuiToken iconType="tokenConstant" size="xs" />,
label: 'user',
id: 'user',
icon: <EuiToken size="xs" iconType="tokenVariable" />,
},
{
label: "I'm a Bug",
id: 'item_bug',
icon: <EuiToken iconType="tokenEnum" size="xs" />,
callback: this.showAlert,
label: 'pass',
id: 'pass',
icon: <EuiToken size="xs" iconType="tokenVariable" />,
},
],
},
],
},
{
label: 'getContact',
id: 'getContact',
icon: <EuiToken size="xs" iconType="tokenFunction" />,
children: [
{
label: 'Item C',
id: 'item_c',
icon: <EuiIcon type="arrowRight" size="s" />,
iconWhenExpanded: <EuiIcon type="arrowDown" size="s" />,
label: 'render',
id: 'render',
icon: <EuiToken size="xs" iconType="tokenFunction" />,
children: [
{
label: 'Another Cloud',
id: 'item_cloud2',
icon: <EuiToken iconType="tokenConstant" size="xs" />,
},
{
label: 'Another Bug',
id: 'item_bug2',
icon: <EuiToken iconType="tokenEnum" size="xs" />,
callback: this.showAlert,
label: 'title',
id: 'title',
icon: <EuiToken size="xs" iconType="tokenString" />,
},
],
},
],
},
{
label: 'Item Two',
id: 'item_two',
label: 'postContact',
id: 'postContact',
icon: <EuiToken size="xs" iconType="tokenFunction" />,
children: [
{
label: 'errors',
id: 'errors',
icon: <EuiToken size="xs" iconType="tokenConstant" />,
},
{
label: 'mailOptions',
id: 'mailOptions',
icon: <EuiToken size="xs" iconType="tokenObject" />,
},
],
},
{
label: 'smokeMonster',
id: 'smokeMonster',
icon: <EuiToken size="xs" iconType="tokenMethod" />,
},
];

return (
<div style={{ width: '20rem' }}>
<EuiRecursiveTree items={items} isCondensed />
<EuiRecursiveTree items={items} isCondensed showExpansionArrows />
</div>
);
}
Expand Down
45 changes: 35 additions & 10 deletions src-docs/src/views/recursive_tree/recursive_tree_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export const RecursiveTreeExample = {
title: 'Recursive Tree',
sections: [
{
title: 'Recursive Tree',
source: [
{
type: GuideSectionTypes.JS,
Expand All @@ -31,17 +30,30 @@ export const RecursiveTreeExample = {
},
],
text: (
<p>
<EuiCode>EuiRecursiveTree</EuiCode> allows you to render nested
objects, such as a directory structure or JSON object.
</p>
<div>
<p>
<EuiCode>EuiRecursiveTree</EuiCode> allows you to render recursive
objects, such as a file directory. The <EuiCode>chilldren</EuiCode>{' '}
prop takes an array of <EuiCode>nodes</EuiCode>.
</p>
<p>
Keyboard navigation allows users to navigate and interact with the
tree using the arrow keys, spacebar, and return.
</p>
<p>
The <EuiCode>icon</EuiCode> prop accepts <EuiCode>EuiIcon</EuiCode>{' '}
and <EuiCode>EuiToken</EuiCode> as react nodes. You can also
specifiy a different icon for the open state with the{' '}
<EuiCode>iconWhenExpanded</EuiCode> prop.
</p>
</div>
),
components: { EuiRecursiveTree },
demo: <RecursiveTree />,
props: { EuiRecursiveTree, EuiRecursiveTreeNode },
},
{
title: 'Condensed Tree',
title: 'Condensed version',
source: [
{
type: GuideSectionTypes.JS,
Expand All @@ -53,10 +65,23 @@ export const RecursiveTreeExample = {
},
],
text: (
<p>
<EuiCode>EuiRecursiveTree</EuiCode> allows you to render nested
objects, such as a directory structure or JSON object.
</p>
<div>
<p>
<EuiCode>EuiRecursiveTree</EuiCode> supports a condensed mode with
the <EuiCode>isCondensed</EuiCode> prop. When using the condensed
version it&apos;s highly recommended to use the small size of{' '}
<EuiCode>EuiIcon</EuiCode> and the extra small size of{' '}
<EuiCode>EuiToken</EuiCode>. This will help prevent awkard alignment
issues when used alongside the{' '}
<EuiCode>showExpansionArrows</EuiCode> prop.
</p>
<p>
The <EuiCode>showExpansionArrows</EuiCode> prop provides an
additional visual indicator. Ideal for when a tree&apos;s items use
icons that don&apos;t immediately let a user know that there are
nested nodes that may not be visible.
</p>
</div>
),
components: { EuiRecursiveTree },
demo: <RecursiveTreeCondensed />,
Expand Down
31 changes: 31 additions & 0 deletions src/components/recursive_tree/_recursive_tree.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
.euiRecursiveTree__iconPlaceholder {
width: $euiSizeXL;
}

}

.euiRecursiveTree__iconWrapper {
Expand Down Expand Up @@ -81,3 +82,33 @@
overflow: auto;
}
}

.euiRecursiveTree--withArrows {
.euiRecursiveTree__expansionArrow {
margin-right: $euiSizeXS;
}

&.euiRecursiveTree {
.euiRecursiveTree__nodeInner--withArrows {
.euiRecursiveTree__iconWrapper {
margin-left: 0;
}
}

.euiRecursiveTree__iconWrapper {
margin-left: $euiSize + $euiSizeXS;
}
}

&.euiRecursiveTree--condensed {
.euiRecursiveTree__nodeInner--withArrows {
.euiRecursiveTree__iconWrapper {
margin-left: 0;
}
}

.euiRecursiveTree__iconWrapper {
margin-left: $euiSize;
}
}
}
47 changes: 39 additions & 8 deletions src/components/recursive_tree/recursive_tree.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component, HTMLAttributes, createContext } from 'react';
import classNames from 'classnames';
import { CommonProps } from '../common';
import { EuiIcon } from '../icon';
import { EuiText } from '../text';
import { keyCodes, htmlIdGenerator } from '../../services';

Expand Down Expand Up @@ -32,8 +33,8 @@ export interface Node {
*/
isExpanded?: boolean;
/** Function to call when the item is clicked.
The open state of the item will always be toggled.
*/
The open state of the item will always be toggled.
*/
callback?(): string;
}

Expand All @@ -51,6 +52,13 @@ export type EuiRecursiveTreeProps = HTMLAttributes<HTMLUListElement> &
/** Optionally use a variation with smaller text and icon sizes
*/
isCondensed?: boolean;
/** Set all items to open on initial load
*/
forceAllOpen?: boolean;
/** Display expansion arrows next to all itmes
* that contain children
*/
showExpansionArrows?: boolean;
};

export class EuiRecursiveTree extends Component<
Expand Down Expand Up @@ -87,17 +95,17 @@ export class EuiRecursiveTree extends Component<
});
} else {
// if the node isn't part of openItems[] then add it
this.setState({
openItems: [...this.state.openItems, node.id],
this.setState(prevState => ({
openItems: [...prevState.openItems, node.id],
activeItem: node.id,
});
}));
}
};

// check if the node is included in openItems[]
isNodeOpen(node: Node) {
isNodeOpen = (node: Node) => {
return this.state.openItems.includes(node.id);
}
};

// Enable keyboard navigation
onKeyDown = (e: React.KeyboardEvent, node: Node) => {
Expand Down Expand Up @@ -165,12 +173,21 @@ export class EuiRecursiveTree extends Component<
};

render() {
const { children, className, items, isCondensed, ...rest } = this.props;
const {
children,
className,
items,
isCondensed,
forceAllOpen,
showExpansionArrows,
...rest
} = this.props;

// Computed classNames
const classes = classNames(
'euiRecursiveTree',
{ 'euiRecursiveTree--condensed': isCondensed },
{ 'euiRecursiveTree--withArrows': showExpansionArrows },
className
);

Expand Down Expand Up @@ -201,10 +218,22 @@ export class EuiRecursiveTree extends Component<
onClick={() => this.handleNodeClick(node)}
className={classNames(
'euiRecursiveTree__nodeInner',
showExpansionArrows && node.children
? 'euiRecursiveTree__nodeInner--withArrows'
: null,
this.state.activeItem === node.id
? 'euiRecursiveTree__node--active'
: null
)}>
{showExpansionArrows && node.children ? (
<EuiIcon
className="euiRecursiveTree__expansionArrow"
size={isCondensed ? 's' : 'm'}
type={
this.isNodeOpen(node) ? 'arrowDown' : 'arrowRight'
}
/>
) : null}
{node.icon && !node.useEmptyIcon ? (
<div className="euiRecursiveTree__iconWrapper">
{this.isNodeOpen(node) && node.iconWhenExpanded
Expand All @@ -227,6 +256,8 @@ export class EuiRecursiveTree extends Component<
<EuiRecursiveTree
items={node.children}
isCondensed={isCondensed}
showExpansionArrows={showExpansionArrows}
forceAllOpen={forceAllOpen}
/>
) : null}
</div>
Expand Down

0 comments on commit b20779f

Please sign in to comment.