Skip to content

Commit b8bc4b1

Browse files
guillaumevincenttlabaj
authored andcommitted
refactor: Use the same mechanism for autogenerated component id (#830)
To make the code more consistent, I added a method getUniqueId that is used by all components that need a unique id. I put this id recovery in the defaultProps object. Add also some tests for util file.
1 parent c7072c8 commit b8bc4b1

File tree

6 files changed

+63
-47
lines changed

6 files changed

+63
-47
lines changed

packages/patternfly-4/react-core/src/components/Nav/NavExpandable.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
66
import NavToggle from './NavToggle';
77
import { AngleRightIcon } from '@patternfly/react-icons';
88
import { NavContext } from './Nav';
9+
import { getUniqueId } from '../../internal/util';
910

1011
const propTypes = {
1112
/** Title shown for the expandable list */
@@ -37,19 +38,20 @@ const defaultProps = {
3738
};
3839

3940
class NavExpandable extends React.Component {
40-
constructor(props) {
41-
super(props);
42-
43-
this.uniqueId =
44-
props.id ||
45-
new Date().getTime() +
46-
Math.random()
47-
.toString(36)
48-
.slice(2);
49-
}
41+
id = this.props.id || getUniqueId();
5042

5143
render() {
52-
const { title, srText, isExpanded: defaultExpanded, children, className, groupId, isActive, ...props } = this.props;
44+
const {
45+
id,
46+
title,
47+
srText,
48+
isExpanded: defaultExpanded,
49+
children,
50+
className,
51+
groupId,
52+
isActive,
53+
...props
54+
} = this.props;
5355

5456
return (
5557
<NavContext.Consumer>
@@ -68,7 +70,7 @@ class NavExpandable extends React.Component {
6870
>
6971
<a
7072
className={css(styles.navLink)}
71-
id={srText ? null : this.uniqueId}
73+
id={srText ? null : this.id}
7274
href="#"
7375
onClick={e => e.preventDefault()}
7476
onMouseDown={e => e.preventDefault()}
@@ -81,11 +83,11 @@ class NavExpandable extends React.Component {
8183
</a>
8284
<section
8385
className={css(styles.navSubnav)}
84-
aria-labelledby={this.uniqueId}
86+
aria-labelledby={this.id}
8587
hidden={isExpanded ? null : true}
8688
>
8789
{srText && (
88-
<h2 className={css(a11yStyles.srOnly)} id={this.uniqueId}>
90+
<h2 className={css(a11yStyles.srOnly)} id={this.id}>
8991
{srText}
9092
</h2>
9193
)}

packages/patternfly-4/react-core/src/components/Nav/NavGroup.js

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import styles from '@patternfly/patternfly-next/components/Nav/nav.css';
33
import { css } from '@patternfly/react-styles';
44
import PropTypes from 'prop-types';
5+
import { getUniqueId } from '../../internal/util';
56

67
const propTypes = {
78
/** Title shown for the group */
@@ -21,23 +22,14 @@ const defaultProps = {
2122
};
2223

2324
class NavGroup extends React.Component {
24-
constructor(props) {
25-
super(props);
26-
27-
this.uniqueId =
28-
props.id ||
29-
new Date().getTime() +
30-
Math.random()
31-
.toString(36)
32-
.slice(2);
33-
}
25+
id = this.props.id || getUniqueId();
3426

3527
render() {
36-
const { title, children, className, ...props } = this.props;
28+
const { id, title, children, className, ...props } = this.props;
3729

3830
return (
39-
<section className={css(styles.navSection, className)} aria-labelledby={this.uniqueId} {...props}>
40-
<h2 className={css(styles.navSectionTitle)} id={this.uniqueId}>
31+
<section className={css(styles.navSection, className)} aria-labelledby={this.id} {...props}>
32+
<h2 className={css(styles.navSectionTitle)} id={this.id}>
4133
{title}
4234
</h2>
4335
<ul className={css(styles.navSimpleList)}>{children}</ul>

packages/patternfly-4/react-core/src/components/Nav/__snapshots__/Nav.test.js.snap

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,6 @@ exports[`Expandable Nav List - Trigger toggle 1`] = `
378378
>
379379
<li
380380
className="pf-c-nav__item expandable-group"
381-
id="grp-1"
382381
onClick={[Function]}
383382
>
384383
<a
@@ -613,7 +612,6 @@ exports[`Expandable Nav List 1`] = `
613612
>
614613
<li
615614
className="pf-c-nav__item"
616-
id="grp-1"
617615
onClick={[Function]}
618616
>
619617
<a
@@ -856,7 +854,6 @@ exports[`Expandable Nav List with aria label 1`] = `
856854
>
857855
<li
858856
className="pf-c-nav__item"
859-
id="grp-1"
860857
onClick={[Function]}
861858
>
862859
<a
@@ -1251,7 +1248,6 @@ exports[`Nav Grouped List 1`] = `
12511248
<section
12521249
aria-labelledby="grp-1"
12531250
className="pf-c-nav__section"
1254-
id="grp-1"
12551251
>
12561252
<h2
12571253
className="pf-c-nav__section-title"
@@ -1366,7 +1362,6 @@ exports[`Nav Grouped List 1`] = `
13661362
<section
13671363
aria-labelledby="grp-2"
13681364
className="pf-c-nav__section"
1369-
id="grp-2"
13701365
>
13711366
<h2
13721367
className="pf-c-nav__section-title"

packages/patternfly-4/react-core/src/components/Progress/Progress.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import styles from '@patternfly/patternfly-next/components/Progress/progress.css
33
import { css, getModifier } from '@patternfly/react-styles';
44
import PropTypes from 'prop-types';
55
import ProgressContainer, { ProgressMeasureLocation, ProgressVariant } from './ProgressContainer';
6+
import { getUniqueId } from '../../internal/util';
67

78
export const ProgressSize = {
89
sm: 'sm',
@@ -49,23 +50,26 @@ const defaultProps = {
4950
};
5051

5152
class Progress extends Component {
52-
constructor(props) {
53-
super(props);
54-
this.state = {
55-
uniqueId:
56-
props.id ||
57-
`progress-${new Date().getTime()}${Math.random()
58-
.toString(36)
59-
.slice(2)}`
60-
};
61-
}
53+
id = this.props.id || getUniqueId();
6254

6355
render() {
64-
const { className, size, id, value, title, label, variant, measureLocation, min, max, valueText, ...props } = this.props;
65-
const { uniqueId } = this.state;
56+
const {
57+
id,
58+
className,
59+
size,
60+
value,
61+
title,
62+
label,
63+
variant,
64+
measureLocation,
65+
min,
66+
max,
67+
valueText,
68+
...props
69+
} = this.props;
6670
const additionalProps = {
6771
...props,
68-
...(valueText ? { 'aria-valuetext': valueText } : { 'aria-describedby': `${id}-description` })
72+
...(valueText ? { 'aria-valuetext': valueText } : { 'aria-describedby': `${this.id}-description` })
6973
};
7074
let limitedValue;
7175
limitedValue = value < min ? min : value;
@@ -80,14 +84,14 @@ class Progress extends Component {
8084
getModifier(styles, measureLocation === ProgressMeasureLocation.inside ? ProgressSize.lg : size, ''),
8185
className
8286
)}
83-
id={uniqueId}
87+
id={this.id}
8488
role="progressbar"
8589
aria-valuemin={min}
8690
aria-valuenow={limitedValue}
8791
aria-valuemax={max}
8892
>
8993
<ProgressContainer
90-
parentId={uniqueId}
94+
parentId={this.id}
9195
value={limitedValue}
9296
title={title}
9397
label={label}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
11
export function capitalize(input) {
22
return input[0].toUpperCase() + input.substring(1);
33
}
4+
5+
export function getUniqueId(prefix = 'pf') {
6+
const uid =
7+
new Date().getTime() +
8+
Math.random()
9+
.toString(36)
10+
.slice(2);
11+
return `${prefix}-${uid}`;
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { capitalize, getUniqueId } from './util';
2+
3+
test('capitalize', () => {
4+
expect(capitalize('foo')).toBe('Foo');
5+
});
6+
7+
test('getUniqueId', () => {
8+
expect(getUniqueId()).not.toBe(getUniqueId());
9+
});
10+
11+
test('getUniqueId prefixed', () => {
12+
expect(getUniqueId().substring(0, 3)).toBe('pf-');
13+
expect(getUniqueId('pf-switch').substring(0, 10)).toBe('pf-switch-');
14+
});

0 commit comments

Comments
 (0)