Skip to content

Commit 92559e6

Browse files
jeff-phillips-18dtaylor113
authored andcommitted
feat(HintBlock): Add the HintBlock component (#922)
1 parent 56a4cc4 commit 92559e6

File tree

9 files changed

+361
-3
lines changed

9 files changed

+361
-3
lines changed

packages/patternfly-3/patternfly-react-extensions/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"breakjs": "^1.0.0",
4242
"classnames": "^2.2.5",
4343
"css-element-queries": "^1.0.1",
44-
"patternfly": "^3.52.1",
44+
"patternfly": "^3.58.0",
4545
"patternfly-react": "^2.23.3",
4646
"react-virtualized": "9.x"
4747
},

packages/patternfly-3/patternfly-react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"breakjs": "^1.0.0",
2929
"classnames": "^2.2.5",
3030
"css-element-queries": "^1.0.1",
31-
"patternfly": "^3.52.4",
31+
"patternfly": "^3.58.0",
3232
"react-bootstrap": "^0.32.1",
3333
"react-bootstrap-switch": "^15.5.3",
3434
"react-bootstrap-typeahead": "^3.1.3",
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import classNames from 'classnames';
2+
import React from 'react';
3+
import PropTypes from 'prop-types';
4+
import { noop } from '../../common/helpers';
5+
6+
const HintBlock = ({ className, onClose, title, body, buttonContent, onButtonClick, ...props }) => {
7+
const classes = classNames('hint-block-pf', className);
8+
9+
return (
10+
<div className={classes} {...props}>
11+
{onClose && (
12+
<button type="button" className="close" aria-hidden="true" aria-label="Close" onClick={onClose}>
13+
<span className="pficon pficon-close" />
14+
</button>
15+
)}
16+
<div className="hint-block-pf-title">{title}</div>
17+
<div className="hint-block-pf-body">{body}</div>
18+
{buttonContent && (
19+
<button className="btn btn-primary" type="button" onClick={onButtonClick}>
20+
{buttonContent}
21+
</button>
22+
)}
23+
</div>
24+
);
25+
};
26+
27+
HintBlock.propTypes = {
28+
/** Additional element css classes */
29+
className: PropTypes.string,
30+
/** Close callback, if not provided the block will not be closable */
31+
onClose: PropTypes.func,
32+
/** Title for the hint block */
33+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
34+
/** Body of the hint block */
35+
body: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
36+
/** Optional button contents for the hint block */
37+
buttonContent: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
38+
/** Callback for the button if buttonContent is provided */
39+
onButtonClick: PropTypes.func
40+
};
41+
42+
HintBlock.defaultProps = {
43+
className: '',
44+
onClose: null,
45+
buttonContent: null,
46+
onButtonClick: noop
47+
};
48+
49+
export default HintBlock;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React from 'react';
2+
import { storiesOf } from '@storybook/react';
3+
import { withInfo } from '@storybook/addon-info';
4+
import { action } from '@storybook/addon-actions';
5+
6+
import { storybookPackageName, STORYBOOK_CATEGORY } from 'storybook/constants/siteConstants';
7+
import { HintBlock } from './index';
8+
import { name } from '../../../package.json';
9+
import { defaultTemplate } from '../../../../../../storybook/decorators/storyTemplates';
10+
11+
const stories = storiesOf(`${storybookPackageName(name)}/${STORYBOOK_CATEGORY.COMMUNICATION}/HintBlock`, module);
12+
13+
const description = (
14+
<div>
15+
The <b>Hint Block</b> pattern is similar to an informational inline notification, but with additional emphasis (blue
16+
highlight). The intention is to use this for specific use cases involving new users, new features, or cases where
17+
extra guidance may assist in successfully completing a flow. The hint pattern involves a one-step reminder,
18+
explanation, or call to action. Potential Use Cases
19+
<ul>
20+
<li>
21+
To provide guidance to <b>new users</b> who do not know how to use the application
22+
</li>
23+
<li>
24+
To provide contextual help on using <b>new features</b>
25+
</li>
26+
<li>
27+
To provide hints on a flow/ the <b>next steps</b> a user should be thinking about.
28+
</li>
29+
</ul>
30+
</div>
31+
);
32+
33+
stories.addDecorator(
34+
defaultTemplate({
35+
title: 'HintBlock',
36+
description
37+
})
38+
);
39+
40+
stories.add(
41+
'HintBlock',
42+
withInfo()(() => (
43+
<HintBlock
44+
title="Some Title"
45+
onClose={action('Close')}
46+
body="Something introductory. Some body text explaining the feature. Some body text explaining the feature. Some body text explaining the feature. Some body text explaining the feature. Some body text explaining the feature. Some body text explaining the feature."
47+
buttonContent="Optional Action"
48+
onButtonClick={action('Button Click')}
49+
/>
50+
))
51+
);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
import { HintBlock } from '../../index';
4+
import { Icon } from '../Icon';
5+
6+
test('HintBlock displays correctly', () => {
7+
const onClose = jest.fn();
8+
const onButtonClick = jest.fn();
9+
const component = mount(
10+
<HintBlock
11+
id="test-id"
12+
className="test-class"
13+
title="Test Title Text"
14+
onClose={onClose}
15+
body="Test Body Text"
16+
buttonContent={
17+
<span>
18+
<Icon type="pf" name="help" /> Optional Action
19+
</span>
20+
}
21+
onButtonClick={onButtonClick}
22+
/>
23+
);
24+
25+
expect(component.render()).toMatchSnapshot();
26+
27+
component.find('.close').simulate('click');
28+
expect(onClose).toBeCalled();
29+
30+
component.find('.btn').simulate('click');
31+
expect(onClose).toBeCalled();
32+
});
33+
34+
test('HintBlock hides close button when no close callback', () => {
35+
const onButtonClick = jest.fn();
36+
const component = mount(
37+
<HintBlock
38+
title="Test Title Text"
39+
body="Test Body Text"
40+
buttonContent="Optional Action"
41+
onButtonClick={onButtonClick}
42+
/>
43+
);
44+
45+
expect(component.render()).toMatchSnapshot();
46+
});
47+
48+
test('HintBlock hides optional button when no button content', () => {
49+
const onClose = jest.fn();
50+
const component = mount(<HintBlock title="Test Title Text" onClose={onClose} body="Test Body Text" />);
51+
52+
expect(component.render()).toMatchSnapshot();
53+
});
54+
55+
test('HintBlock display complex content', () => {
56+
const component = mount(
57+
<HintBlock
58+
title={
59+
<div>
60+
My Custom <b>Title</b>
61+
</div>
62+
}
63+
body={
64+
<div>
65+
<p>
66+
This pattern does not yet exist in <a href="http://www.patternfly.org/pattern-library/">PatternFly</a>.
67+
</p>
68+
The <b>Hint Block</b> pattern is similar to an informational inline notification, but with additional emphasis
69+
(blue highlight). The intention is to use this for specific use cases involving new users, new features, or
70+
cases where extra guidance may assist in successfully completing a flow. The hint pattern involves a one-step
71+
reminder, explanation, or call to action. Potential Use Cases
72+
<ul>
73+
<li>
74+
To provide guidance to <b>new users</b> who do not know how to use the application
75+
</li>
76+
<li>
77+
To provide contextual help on using <b>new features</b>
78+
</li>
79+
<li>
80+
To provide hints on a flow/ the <b>next steps</b> a user should be thinking about.
81+
</li>
82+
</ul>
83+
</div>
84+
}
85+
buttonContent={
86+
<span>
87+
<Icon type="pf" name="help" /> Optional Action
88+
</span>
89+
}
90+
/>
91+
);
92+
93+
expect(component.render()).toMatchSnapshot();
94+
});
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`HintBlock display complex content 1`] = `
4+
<div
5+
class="hint-block-pf"
6+
>
7+
<div
8+
class="hint-block-pf-title"
9+
>
10+
<div>
11+
My Custom
12+
<b>
13+
Title
14+
</b>
15+
</div>
16+
</div>
17+
<div
18+
class="hint-block-pf-body"
19+
>
20+
<div>
21+
<p>
22+
This pattern does not yet exist in
23+
<a
24+
href="http://www.patternfly.org/pattern-library/"
25+
>
26+
PatternFly
27+
</a>
28+
.
29+
</p>
30+
The
31+
<b>
32+
Hint Block
33+
</b>
34+
pattern is similar to an informational inline notification, but with additional emphasis (blue highlight). The intention is to use this for specific use cases involving new users, new features, or cases where extra guidance may assist in successfully completing a flow. The hint pattern involves a one-step reminder, explanation, or call to action. Potential Use Cases
35+
<ul>
36+
<li>
37+
To provide guidance to
38+
<b>
39+
new users
40+
</b>
41+
who do not know how to use the application
42+
</li>
43+
<li>
44+
To provide contextual help on using
45+
<b>
46+
new features
47+
</b>
48+
</li>
49+
<li>
50+
To provide hints on a flow/ the
51+
<b>
52+
next steps
53+
</b>
54+
a user should be thinking about.
55+
</li>
56+
</ul>
57+
</div>
58+
</div>
59+
<button
60+
class="btn btn-primary"
61+
type="button"
62+
>
63+
<span>
64+
<span
65+
aria-hidden="true"
66+
class="pficon pficon-help"
67+
/>
68+
Optional Action
69+
</span>
70+
</button>
71+
</div>
72+
`;
73+
74+
exports[`HintBlock displays correctly 1`] = `
75+
<div
76+
class="hint-block-pf test-class"
77+
id="test-id"
78+
>
79+
<button
80+
aria-hidden="true"
81+
aria-label="Close"
82+
class="close"
83+
type="button"
84+
>
85+
<span
86+
class="pficon pficon-close"
87+
/>
88+
</button>
89+
<div
90+
class="hint-block-pf-title"
91+
>
92+
Test Title Text
93+
</div>
94+
<div
95+
class="hint-block-pf-body"
96+
>
97+
Test Body Text
98+
</div>
99+
<button
100+
class="btn btn-primary"
101+
type="button"
102+
>
103+
<span>
104+
<span
105+
aria-hidden="true"
106+
class="pficon pficon-help"
107+
/>
108+
Optional Action
109+
</span>
110+
</button>
111+
</div>
112+
`;
113+
114+
exports[`HintBlock hides close button when no close callback 1`] = `
115+
<div
116+
class="hint-block-pf"
117+
>
118+
<div
119+
class="hint-block-pf-title"
120+
>
121+
Test Title Text
122+
</div>
123+
<div
124+
class="hint-block-pf-body"
125+
>
126+
Test Body Text
127+
</div>
128+
<button
129+
class="btn btn-primary"
130+
type="button"
131+
>
132+
Optional Action
133+
</button>
134+
</div>
135+
`;
136+
137+
exports[`HintBlock hides optional button when no button content 1`] = `
138+
<div
139+
class="hint-block-pf"
140+
>
141+
<button
142+
aria-hidden="true"
143+
aria-label="Close"
144+
class="close"
145+
type="button"
146+
>
147+
<span
148+
class="pficon pficon-close"
149+
/>
150+
</button>
151+
<div
152+
class="hint-block-pf-title"
153+
>
154+
Test Title Text
155+
</div>
156+
<div
157+
class="hint-block-pf-body"
158+
>
159+
Test Body Text
160+
</div>
161+
</div>
162+
`;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as HintBlock } from './HintBlock';

packages/patternfly-3/patternfly-react/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export * from './components/FieldLevelHelp';
1515
export * from './components/Filter';
1616
export * from './components/Form';
1717
export * from './components/Grid';
18+
export * from './components/HintBlock';
1819
export * from './components/Icon';
1920
export * from './components/InfoTip';
2021
export * from './components/InlineEdit';

packages/patternfly-3/react-console/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"patternfly-react": "^2.23.3"
5050
},
5151
"peerDependencies": {
52-
"patternfly": "^3.52.1",
52+
"patternfly": "^3.58.0",
5353
"patternfly-react": "^2.22.5",
5454
"prop-types": "^15.6.1",
5555
"react": "^16.3.2",

0 commit comments

Comments
 (0)