Skip to content

Commit cbc761c

Browse files
Gilad Leknerglekner
Gilad Lekner
authored andcommitted
feat(ApplicationLauncher): application Launcher Component
affects: patternfly-react fix #184 ISSUES CLOSED: #184
1 parent 7d0c2e3 commit cbc761c

17 files changed

+1133
-1
lines changed

packages/core/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"react-bootstrap": "^0.32.1",
3333
"react-bootstrap-switch": "^15.5.3",
3434
"react-c3js": "^0.1.20",
35+
"react-click-outside": "^3.0.1",
3536
"react-fontawesome": "^1.6.1",
3637
"reactabular-table": "^8.13.0",
3738
"recompose": "^0.26.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import classNames from 'classnames';
4+
import ApplicationLauncherToggle from './ApplicationLauncherToggle';
5+
import { Dropdown } from '../Dropdown';
6+
import { noop } from '../../common/helpers';
7+
8+
const ApplicationLauncher = ({
9+
open,
10+
grid,
11+
tooltip,
12+
tooltipPlacement,
13+
children,
14+
toggleLauncher,
15+
className,
16+
...propTypes
17+
}) => {
18+
const classes = classNames(
19+
'applauncher-pf dropdown',
20+
{
21+
'applauncher-pf-block-list': grid
22+
},
23+
{ open }
24+
);
25+
return (
26+
<li className={classes}>
27+
<ApplicationLauncherToggle
28+
tooltip={tooltip}
29+
tooltipPlacement={tooltipPlacement}
30+
onClick={() => toggleLauncher()}
31+
open={open}
32+
/>
33+
<Dropdown.Menu className="dropdown-menu-right">{children}</Dropdown.Menu>
34+
</li>
35+
);
36+
};
37+
38+
ApplicationLauncher.propTypes = {
39+
/** Additional element css classes */
40+
className: PropTypes.string,
41+
/** Children Node */
42+
children: PropTypes.node.isRequired,
43+
/** Toggle Tooltip */
44+
tooltip: PropTypes.string,
45+
/** tooltipPlacement */
46+
tooltipPlacement: PropTypes.string,
47+
/** Application Launcher Type (Default List) */
48+
grid: PropTypes.bool,
49+
/** open bool */
50+
open: PropTypes.bool,
51+
/** Toggle launcher func */
52+
toggleLauncher: PropTypes.func
53+
};
54+
ApplicationLauncher.defaultProps = {
55+
className: '',
56+
tooltip: '',
57+
tooltipPlacement: 'left',
58+
toggleLauncher: noop,
59+
grid: false,
60+
open: false
61+
};
62+
63+
export default ApplicationLauncher;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { storiesOf } from '@storybook/react';
2+
import { withKnobs } from '@storybook/addon-knobs';
3+
import {
4+
storybookPackageName,
5+
STORYBOOK_CATEGORY
6+
} from 'storybook/constants/siteConstants';
7+
import {
8+
NavApplicationLauncherStory,
9+
WrapperNavApplicationLauncherStory
10+
} from './Stories/index';
11+
import { name } from '../../../package.json';
12+
13+
const stories = storiesOf(
14+
`${storybookPackageName(name)}/${
15+
STORYBOOK_CATEGORY.APPLICATION_FRAMEWORK
16+
}/Launcher`,
17+
module
18+
);
19+
stories.addDecorator(withKnobs);
20+
21+
NavApplicationLauncherStory(stories);
22+
WrapperNavApplicationLauncherStory(stories);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
import {
4+
ApplicationLauncher,
5+
ApplicationLauncherItem,
6+
ApplicationLauncherToggle
7+
} from './index';
8+
9+
const handleClick = e => {
10+
e.preventDefault();
11+
};
12+
13+
test('ApplicationLauncher is working properly', () => {
14+
const component = mount(
15+
<ApplicationLauncher type="grid" tooltipPlacement="left">
16+
<ApplicationLauncherItem
17+
icon="pficon pficon-storage-domain"
18+
title="Recteque"
19+
tooltip="Tooltip!"
20+
onClick={handleClick}
21+
/>
22+
</ApplicationLauncher>
23+
);
24+
25+
expect(component.render()).toMatchSnapshot();
26+
});
27+
28+
test('ApplicationLauncherItem is working properly', () => {
29+
const component = mount(
30+
<ApplicationLauncherItem
31+
icon="pficon pficon-storage-domain"
32+
title="Recteque"
33+
tooltip="Tooltip!"
34+
onClick={handleClick}
35+
/>
36+
);
37+
38+
expect(component.render()).toMatchSnapshot();
39+
});
40+
41+
test('ApplicationLauncherToggle is working properly', () => {
42+
const component = mount(
43+
<ApplicationLauncherToggle tooltipPlacement="left" onClick={handleClick} />
44+
);
45+
46+
expect(component.render()).toMatchSnapshot();
47+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import classNames from 'classnames';
2+
import React from 'react';
3+
import PropTypes from 'prop-types';
4+
import { Tooltip } from '../Tooltip';
5+
import { OverlayTrigger } from '../OverlayTrigger';
6+
import { Icon } from '../Icon';
7+
8+
const ApplicationLauncherItem = ({
9+
onClick,
10+
tooltip,
11+
tooltipPlacement,
12+
title,
13+
icon,
14+
noIcons,
15+
className,
16+
...props
17+
}) => {
18+
const classes = classNames('applauncher-pf-item', className);
19+
20+
if (tooltip !== null) {
21+
return (
22+
<OverlayTrigger
23+
overlay={<Tooltip>{tooltip}</Tooltip>}
24+
placement={tooltipPlacement}
25+
trigger={['hover', 'focus']}
26+
rootClose={false}
27+
>
28+
<li className={classes} role="presentation">
29+
<a
30+
className="applauncher-pf-link"
31+
href="#"
32+
onClick={e => onClick(e)}
33+
role="menuitem"
34+
>
35+
{!noIcons && (
36+
<Icon
37+
type="pf"
38+
name={icon}
39+
className="applauncher-pf-link-icon"
40+
/>
41+
)}
42+
<span className="applauncher-pf-link-title">{title}</span>
43+
</a>
44+
</li>
45+
</OverlayTrigger>
46+
);
47+
}
48+
return (
49+
<li className={classes} role="presentation">
50+
<a
51+
className="applauncher-pf-link"
52+
href="#"
53+
onClick={e => onClick(e)}
54+
role="menuitem"
55+
>
56+
{!noIcons && (
57+
<Icon type="pf" name={icon} className="applauncher-pf-link-icon" />
58+
)}
59+
<span className="applauncher-pf-link-title">{title}</span>
60+
</a>
61+
</li>
62+
);
63+
};
64+
ApplicationLauncherItem.propTypes = {
65+
/** Additional element css classes */
66+
className: PropTypes.string,
67+
/** onClick func */
68+
onClick: PropTypes.func,
69+
/** Title String */
70+
title: PropTypes.string.isRequired,
71+
/** Icon Type */
72+
icon: PropTypes.string.isRequired,
73+
/** App Tooltip */
74+
tooltip: PropTypes.string,
75+
/** Tooltip Placement */
76+
tooltipPlacement: PropTypes.string,
77+
/** No Icons Bool */
78+
noIcons: PropTypes.bool
79+
};
80+
ApplicationLauncherItem.defaultProps = {
81+
className: '',
82+
onClick: null,
83+
noIcons: false,
84+
tooltipPlacement: 'left',
85+
tooltip: null
86+
};
87+
export default ApplicationLauncherItem;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { OverlayTrigger } from '../OverlayTrigger';
4+
import { Tooltip } from '../Tooltip';
5+
import { Icon } from '../Icon';
6+
import { Button } from '../Button';
7+
8+
const ApplicationLauncherToggle = ({
9+
open,
10+
tooltip,
11+
onClick,
12+
tooltipPlacement
13+
}) => {
14+
if (tooltip)
15+
return (
16+
<OverlayTrigger
17+
placement={tooltipPlacement}
18+
id="applauncher-pf-block-list"
19+
overlay={<Tooltip>{tooltip}</Tooltip>}
20+
>
21+
<Button
22+
onClick={onClick}
23+
bsStyle="link"
24+
className="nav-item-iconic dropdown-toggle"
25+
aria-describedby="tooltip"
26+
aria-expanded={open}
27+
>
28+
<Icon name="applauncher-pf-icon" type="pf" />
29+
</Button>
30+
</OverlayTrigger>
31+
);
32+
return (
33+
<Button
34+
onClick={onClick}
35+
bsStyle="link"
36+
className="nav-item-iconic dropdown-toggle"
37+
aria-expanded={open}
38+
>
39+
<Icon
40+
className="fa fa-th applauncher-pf-icon"
41+
aria-describedby="tooltip"
42+
name=""
43+
/>
44+
<span className="dropdown-title">
45+
<span className="applauncher-pf-title">
46+
Application Launcher
47+
<span className="caret" aria-hidden="true" />
48+
</span>
49+
</span>
50+
</Button>
51+
);
52+
};
53+
ApplicationLauncherToggle.propTypes = {
54+
/** onClick func */
55+
onClick: PropTypes.func,
56+
/** tooltipPlacement */
57+
tooltipPlacement: PropTypes.string,
58+
/** Toggle Tooltip */
59+
tooltip: PropTypes.string,
60+
/** is Open bool */
61+
open: PropTypes.bool.isRequired
62+
};
63+
ApplicationLauncherToggle.defaultProps = {
64+
onClick: null,
65+
tooltipPlacement: 'bottom',
66+
tooltip: ''
67+
};
68+
69+
export default ApplicationLauncherToggle;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React from 'react';
2+
import { action } from '@storybook/addon-actions';
3+
import { boolean, select } from '@storybook/addon-knobs';
4+
import { inlineTemplate } from 'storybook/decorators/storyTemplates';
5+
import { DOCUMENTATION_URL } from 'storybook/constants/siteConstants';
6+
import ApplicationLauncher from '../ApplicationLauncher';
7+
import ApplicationLauncherItem from '../ApplicationLauncherItem';
8+
9+
const handleClick = e => {
10+
e.preventDefault();
11+
action('app clicked!')();
12+
};
13+
14+
const NavApplicationLauncherStory = stories => {
15+
stories.addWithInfo('Launcher', '', () => {
16+
const type = select(
17+
'Launcher Type',
18+
{ true: 'Grid', false: 'List' },
19+
'true'
20+
);
21+
const iconBool = boolean('Icons', true);
22+
23+
const story = (
24+
<nav className="navbar navbar-pf-vertical">
25+
<nav className="collapse navbar-collapse">
26+
<ul className="nav navbar-nav navbar-right navbar-iconic">
27+
<ApplicationLauncher
28+
grid={type === 'true'}
29+
tooltipPlacement="left"
30+
open
31+
>
32+
<ApplicationLauncherItem
33+
key="app1"
34+
icon="storage-domain"
35+
title="Recteque"
36+
tooltip="Tooltip!"
37+
tooltipPlacement="left"
38+
onClick={handleClick}
39+
noIcons={!iconBool}
40+
/>
41+
<ApplicationLauncherItem
42+
key="app2"
43+
icon="virtual-machine"
44+
title="No Tooltip"
45+
onClick={handleClick}
46+
noIcons={!iconBool}
47+
/>
48+
<ApplicationLauncherItem
49+
key="app3"
50+
icon="domain"
51+
title="Lorem"
52+
tooltip="Tooltip!"
53+
tooltipPlacement="left"
54+
onClick={handleClick}
55+
noIcons={!iconBool}
56+
/>
57+
<ApplicationLauncherItem
58+
key="app4"
59+
icon="home"
60+
title="Home"
61+
tooltip="Tooltip!"
62+
tooltipPlacement="left"
63+
onClick={handleClick}
64+
noIcons={!iconBool}
65+
/>
66+
</ApplicationLauncher>
67+
</ul>
68+
</nav>
69+
</nav>
70+
);
71+
return inlineTemplate({
72+
title: 'ApplicationLauncher',
73+
documentationLink: `${
74+
DOCUMENTATION_URL.PATTERNFLY_ORG_APPLICATION_FRAMEWORK
75+
}launcher/`,
76+
story
77+
});
78+
});
79+
};
80+
81+
export default NavApplicationLauncherStory;

0 commit comments

Comments
 (0)