Skip to content

Commit a02495e

Browse files
jschulertlabaj
authored andcommitted
feat(text component): adds the text component to PF4 (patternfly#733)
* feat(text component): adds the text component to PF4 affects: @patternfly/react-core, @patternfly/react-styles * mount in tests * parse css outside render & rename prop to component * break examples out * update snapshot
1 parent 4b279e9 commit a02495e

File tree

22 files changed

+1045
-22
lines changed

22 files changed

+1045
-22
lines changed

packages/patternfly-4/react-core/src/components/AboutModal/examples/SimpleAboutModal.js

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import React from 'react';
2-
import { AboutModal, Button } from '@patternfly/react-core';
3-
import { css } from '@patternfly/react-styles';
4-
import styles from '@patternfly/patternfly-next/components/Content/content.css';
2+
import { AboutModal, Button, TextContent, TextList, TextListItem } from '@patternfly/react-core';
53
import brandImg from './pf_mini_logo_white.svg';
64
import logoImg from './pf_logo.svg';
75
import heroImg from './pfbg_992.jpg';
@@ -38,24 +36,24 @@ class SimpleAboutModal extends React.Component {
3836
logoImageAlt="AboutModal Logo"
3937
heroImageSrc={heroImg}
4038
>
41-
<div className={css(styles.content)}>
42-
<dl>
43-
<dt>CFME Version</dt>
44-
<dd>5.5.3.4.20102789036450</dd>
45-
<dt>Cloudforms Version</dt>
46-
<dd>4.1</dd>
47-
<dt>Server Name</dt>
48-
<dd>40DemoMaster</dd>
49-
<dt>User Name</dt>
50-
<dd>Administrator</dd>
51-
<dt>User Role</dt>
52-
<dd>EvmRole-super_administrator</dd>
53-
<dt>Browser Version</dt>
54-
<dd>601.2</dd>
55-
<dt>Browser OS</dt>
56-
<dd>Mac</dd>
57-
</dl>
58-
</div>
39+
<TextContent>
40+
<TextList component="dl">
41+
<TextListItem component="dt">CFME Version</TextListItem>
42+
<TextListItem component="dd">5.5.3.4.20102789036450</TextListItem>
43+
<TextListItem component="dt">Cloudforms Version</TextListItem>
44+
<TextListItem component="dd">4.1</TextListItem>
45+
<TextListItem component="dt">Server Name</TextListItem>
46+
<TextListItem component="dd">40DemoMaster</TextListItem>
47+
<TextListItem component="dt">User Name</TextListItem>
48+
<TextListItem component="dd">Administrator</TextListItem>
49+
<TextListItem component="dt">User Role</TextListItem>
50+
<TextListItem component="dd">EvmRole-super_administrator</TextListItem>
51+
<TextListItem component="dt">Browser Version</TextListItem>
52+
<TextListItem component="dd">601.2</TextListItem>
53+
<TextListItem component="dt">Browser OS</TextListItem>
54+
<TextListItem component="dd">Mac</TextListItem>
55+
</TextList>
56+
</TextContent>
5957
</AboutModal>
6058
</React.Fragment>
6159
);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { SFC, HTMLProps, ReactNode } from 'react';
2+
import { OneOf } from '../../typeUtils';
3+
4+
export const TextVariants: {
5+
h1: 'h1';
6+
h2: 'h2';
7+
h3: 'h3';
8+
h4: 'h4';
9+
h5: 'h5';
10+
h6: 'h6';
11+
p: 'p';
12+
a: 'a';
13+
small: 'small';
14+
blockquote: 'blockquote';
15+
pre: 'pre';
16+
};
17+
18+
export interface TextProps extends HTMLProps<HTMLDivElement> {
19+
component?: OneOf<typeof TextVariants, keyof typeof TextVariants>;
20+
children?: ReactNode;
21+
className?: string;
22+
}
23+
24+
declare const Text: SFC<TextProps>;
25+
26+
export default Text;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
TextContent,
3+
Text,
4+
TextVariants,
5+
TextList,
6+
TextListVariants,
7+
TextListItem,
8+
TextListItemVariants
9+
} from '@patternfly/react-core';
10+
import BodyText from './examples/BodyText';
11+
import DataList from './examples/DataList';
12+
import Headings from './examples/Headings';
13+
import OrderedList from './examples/OrderedList';
14+
import UnorderedList from './examples/UnorderedList';
15+
16+
export default {
17+
title: 'Text',
18+
components: {
19+
TextContent,
20+
Text,
21+
TextList,
22+
TextListItem
23+
},
24+
enumValues: {
25+
'Object.values(TextVariants)': Object.values(TextVariants),
26+
'Object.values(TextListVariants)': Object.values(TextListVariants),
27+
'Object.values(TextListItemVariants)': Object.values(TextListItemVariants)
28+
},
29+
examples: [Headings, BodyText, UnorderedList, OrderedList, DataList]
30+
};
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { css } from '@patternfly/react-styles';
4+
5+
export const TextVariants = {
6+
h1: 'h1',
7+
h2: 'h2',
8+
h3: 'h3',
9+
h4: 'h4',
10+
h5: 'h5',
11+
h6: 'h6',
12+
p: 'p',
13+
a: 'a',
14+
small: 'small',
15+
blockquote: 'blockquote',
16+
pre: 'pre'
17+
};
18+
19+
const propTypes = {
20+
/** The text component */
21+
component: PropTypes.oneOf(Object.values(TextVariants)),
22+
/** Content rendered within the Text */
23+
children: PropTypes.node,
24+
/** Additional classes added to the Text */
25+
className: PropTypes.string
26+
};
27+
28+
const defaultProps = {
29+
component: 'p',
30+
children: null,
31+
className: ''
32+
};
33+
34+
const Text = ({ component, children, className, ...props }) => {
35+
const Component = TextVariants[component] || 'p';
36+
37+
return (
38+
<Component {...props} data-pf-content className={css(className)}>
39+
{children}
40+
</Component>
41+
);
42+
};
43+
44+
Text.propTypes = propTypes;
45+
Text.defaultProps = defaultProps;
46+
47+
export default Text;
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
import TextContent from './TextContent';
4+
import Text, { TextVariants } from './Text';
5+
import TextList, { TextListVariants } from './TextList';
6+
import TextListItem, { TextListItemVariants } from './TextListItem';
7+
8+
test('Text example should match snapshot', () => {
9+
const view = mount(
10+
<TextContent>
11+
<Text component={TextVariants.h1}>Hello World</Text>
12+
<Text component={TextVariants.p}>
13+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla accumsan, metus ultrices eleifend gravida, nulla
14+
nunc varius lectus, nec rutrum justo nibh eu lectus. Ut vulputate semper dui. Fusce erat odio, sollicitudin vel
15+
erat vel, interdum mattis neque. Sub works as well!
16+
</Text>
17+
<Text component={TextVariants.h2}>Second level</Text>
18+
<Text component={TextVariants.p}>
19+
Curabitur accumsan turpis pharetra <strong>augue tincidunt</strong> blandit. Quisque condimentum maximus mi, sit
20+
amet commodo arcu rutrum id. Proin pretium urna vel cursus venenatis. Suspendisse potenti. Etiam mattis sem
21+
rhoncus lacus dapibus facilisis. Donec at dignissim dui. Ut et neque nisl.
22+
</Text>
23+
<TextList>
24+
<TextListItem>In fermentum leo eu lectus mollis, quis dictum mi aliquet.</TextListItem>
25+
<TextListItem>Morbi eu nulla lobortis, lobortis est in, fringilla felis.</TextListItem>
26+
<TextListItem>
27+
Aliquam nec felis in sapien venenatis viverra fermentum nec lectus.
28+
<TextList>
29+
<TextListItem>In fermentum leo eu lectus mollis, quis dictum mi aliquet.</TextListItem>
30+
<TextListItem>Morbi eu nulla lobortis, lobortis est in, fringilla felis.</TextListItem>
31+
</TextList>
32+
</TextListItem>
33+
<TextListItem>Ut non enim metus.</TextListItem>
34+
</TextList>
35+
<Text component={TextVariants.h3}>Third level</Text>
36+
<Text component={TextVariants.p}>
37+
Quisque ante lacus, malesuada ac auctor vitae, congue{' '}
38+
<Text component={TextVariants.a} href="#">
39+
non ante
40+
</Text>
41+
. Phasellus lacus ex, semper ac tortor nec, fringilla condimentum orci. Fusce eu rutrum tellus.
42+
</Text>
43+
<TextList component={TextListVariants.ol}>
44+
<TextListItem>Donec blandit a lorem id convallis.</TextListItem>
45+
<TextListItem>Cras gravida arcu at diam gravida gravida.</TextListItem>
46+
<TextListItem>Integer in volutpat libero.</TextListItem>
47+
<TextListItem>Donec a diam tellus.</TextListItem>
48+
<TextListItem>Aenean nec tortor orci.</TextListItem>
49+
<TextListItem>Quisque aliquam cursus urna, non bibendum massa viverra eget.</TextListItem>
50+
<TextListItem>Vivamus maximus ultricies pulvinar.</TextListItem>
51+
</TextList>
52+
<Text component={TextVariants.blockquote}>
53+
Ut venenatis, nisl scelerisque sollicitudin fermentum, quam libero hendrerit ipsum, ut blandit est tellus sit
54+
amet turpis.
55+
</Text>
56+
<Text component={TextVariants.p}>
57+
Quisque at semper enim, eu hendrerit odio. Etiam auctor nisl et <em>justo sodales</em> elementum. Maecenas
58+
ultrices lacus quis neque consectetur, et lobortis nisi molestie.
59+
</Text>
60+
<Text component={TextVariants.p}>
61+
Sed sagittis enim ac tortor maximus rutrum. Nulla facilisi. Donec mattis vulputate risus in luctus. Maecenas
62+
vestibulum interdum commodo.
63+
</Text>
64+
<TextList component={TextListVariants.dl}>
65+
<TextListItem component={TextListItemVariants.dt}>Web</TextListItem>
66+
<TextListItem component={TextListItemVariants.dd}>
67+
The part of the Internet that contains websites and web pages
68+
</TextListItem>
69+
<TextListItem component={TextListItemVariants.dt}>HTML</TextListItem>
70+
<TextListItem component={TextListItemVariants.dd}>A markup language for creating web pages</TextListItem>
71+
<TextListItem component={TextListItemVariants.dt}>CSS</TextListItem>
72+
<TextListItem component={TextListItemVariants.dd}>A technology to make HTML look better</TextListItem>
73+
</TextList>
74+
<Text component={TextVariants.p}>
75+
Suspendisse egestas sapien non felis placerat elementum. Morbi tortor nisl, suscipit sed mi sit amet, mollis
76+
malesuada nulla. Nulla facilisi. Nullam ac erat ante.
77+
</Text>
78+
<Text component={TextVariants.h4}>Fourth level</Text>
79+
<Text component={TextVariants.p}>
80+
Nulla efficitur eleifend nisi, sit amet bibendum sapien fringilla ac. Mauris euismod metus a tellus laoreet, at
81+
elementum ex efficitur.
82+
</Text>
83+
<Text component={TextVariants.p}>
84+
Maecenas eleifend sollicitudin dui, faucibus sollicitudin augue cursus non. Ut finibus eleifend arcu ut
85+
vehicula. Mauris eu est maximus est porta condimentum in eu justo. Nulla id iaculis sapien.
86+
</Text>
87+
<Text component={TextVariants.small}>Sometimes you need small text to display things like date created</Text>
88+
<Text component={TextVariants.p}>
89+
Phasellus porttitor enim id metus volutpat ultricies. Ut nisi nunc, blandit sed dapibus at, vestibulum in felis.
90+
Etiam iaculis lorem ac nibh bibendum rhoncus. Nam interdum efficitur ligula sit amet ullamcorper. Etiam
91+
tristique, leo vitae porta faucibus, mi lacus laoreet metus, at cursus leo est vel tellus. Sed ac posuere est.
92+
Nunc ultricies nunc neque, vitae ultricies ex sodales quis. Aliquam eu nibh in libero accumsan pulvinar. Nullam
93+
nec nisl placerat, pretium metus vel, euismod ipsum. Proin tempor cursus nisl vel condimentum. Nam pharetra
94+
varius metus non pellentesque.
95+
</Text>
96+
<Text component={TextVariants.h5}>Fifth level</Text>
97+
<Text component={TextVariants.p}>
98+
Aliquam sagittis rhoncus vulputate. Cras non luctus sem, sed tincidunt ligula. Vestibulum at nunc elit. Praesent
99+
aliquet ligula mi, in luctus elit volutpat porta. Phasellus molestie diam vel nisi sodales, a eleifend augue
100+
laoreet. Sed nec eleifend justo. Nam et sollicitudin odio.
101+
</Text>
102+
<Text component={TextVariants.h6}>Sixth level</Text>
103+
<Text component={TextVariants.p}>
104+
Cras in nibh lacinia, venenatis nisi et, auctor urna. Donec pulvinar lacus sed diam dignissim, ut eleifend eros
105+
accumsan. Phasellus non tortor eros. Ut sed rutrum lacus. Etiam purus nunc, scelerisque quis enim vitae,
106+
malesuada ultrices turpis. Nunc vitae maximus purus, nec consectetur dui. Suspendisse euismod, elit vel rutrum
107+
commodo, ipsum tortor maximus dui, sed varius sapien odio vitae est. Etiam at cursus metus.
108+
</Text>
109+
</TextContent>
110+
);
111+
expect(view).toMatchSnapshot();
112+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { SFC, HTMLProps, ReactNode } from 'react';
2+
3+
export interface TextContentProps extends HTMLProps<HTMLDivElement> {
4+
children?: ReactNode;
5+
className?: string;
6+
}
7+
8+
declare const TextContent: SFC<TextContentProps>;
9+
10+
export default TextContent;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react';
2+
import styles from '@patternfly/patternfly-next/components/Content/content.css';
3+
import { StyleSheet, css } from '@patternfly/react-styles';
4+
import PropTypes from 'prop-types';
5+
6+
const propTypes = {
7+
/** Content rendered within the TextContent */
8+
children: PropTypes.node,
9+
/** Additional classes added to the TextContent */
10+
className: PropTypes.string
11+
};
12+
13+
const defaultProps = {
14+
children: null,
15+
className: ''
16+
};
17+
18+
// Get the stylesheet and make it more specific by appending [data-pf-content] attribute to selectors
19+
// This way even if other components are nested within the TextContent, their text styling will not be affected
20+
const moreSpecificStyles = styles.raw.replace(/(.pf-c-content\s[a-zA-Z0-9]+)/g, '$1[data-pf-content]');
21+
const updatedStyles = StyleSheet.parse(moreSpecificStyles);
22+
23+
const TextContent = ({ children, className, ...props }) => (
24+
<div {...props} className={css(updatedStyles.content, className)}>
25+
{children}
26+
</div>
27+
);
28+
29+
TextContent.propTypes = propTypes;
30+
TextContent.defaultProps = defaultProps;
31+
32+
export default TextContent;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { SFC, HTMLProps, ReactNode } from 'react';
2+
import { OneOf } from '../../typeUtils';
3+
4+
export const TextListVariants: {
5+
ul: 'ul';
6+
ol: 'ol';
7+
dl: 'dl';
8+
};
9+
10+
export interface TextListProps extends HTMLProps<HTMLDivElement> {
11+
component?: OneOf<typeof TextListVariants, keyof typeof TextListVariants>;
12+
children?: ReactNode;
13+
className?: string;
14+
}
15+
16+
declare const TextList: SFC<TextListProps>;
17+
18+
export default TextList;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { css } from '@patternfly/react-styles';
4+
5+
export const TextListVariants = {
6+
ul: 'ul',
7+
ol: 'ol',
8+
dl: 'dl'
9+
};
10+
11+
const propTypes = {
12+
/** The text list component */
13+
component: PropTypes.oneOf(Object.values(TextListVariants)),
14+
/** Content rendered within the TextList */
15+
children: PropTypes.node,
16+
/** Additional classes added to the TextList */
17+
className: PropTypes.string
18+
};
19+
20+
const defaultProps = {
21+
component: 'ul',
22+
children: null,
23+
className: ''
24+
};
25+
26+
const TextList = ({ component, children, className, ...props }) => {
27+
const Component = TextListVariants[component] || 'ul';
28+
29+
return (
30+
<Component {...props} data-pf-content className={css(className)}>
31+
{children}
32+
</Component>
33+
);
34+
};
35+
36+
TextList.propTypes = propTypes;
37+
TextList.defaultProps = defaultProps;
38+
39+
export default TextList;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { SFC, HTMLProps, ReactNode } from 'react';
2+
import { OneOf } from '../../typeUtils';
3+
4+
export const TextListItemVariants: {
5+
li: 'li';
6+
dt: 'dt';
7+
dd: 'dd';
8+
};
9+
10+
export interface TextListItemProps extends HTMLProps<HTMLDivElement> {
11+
component?: OneOf<typeof TextListItemVariants, keyof typeof TextListItemVariants>;
12+
children?: ReactNode;
13+
className?: string;
14+
}
15+
16+
declare const TextListItem: SFC<TextListItemProps>;
17+
18+
export default TextListItem;

0 commit comments

Comments
 (0)