Skip to content

Commit 7af4faa

Browse files
authored
feat(): forwarding refs in components
1 parent 3300037 commit 7af4faa

File tree

24 files changed

+218
-232
lines changed

24 files changed

+218
-232
lines changed

src/components/Anchor/Anchor.js

+11-14
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,29 @@ import React from 'react';
22
import propTypes from 'prop-types';
33

44
import styled from 'styled-components';
5-
import { fontSizes } from '../common/system';
65

76
const StyledAnchor = styled.a`
87
color: ${({ theme }) => theme.anchor};
9-
font-size: ${({ size }) => (size ? fontSizes[size] : 'inherit')};
8+
font-size: inherit;
109
text-decoration: underline;
1110
&:visited {
1211
color: ${({ theme }) => theme.anchorVisited};
1312
}
1413
`;
1514

16-
const Anchor = ({ className, style, href, children, ...otherProps }) => (
17-
<StyledAnchor href={href} className={className} style={style} {...otherProps}>
18-
{children}
19-
</StyledAnchor>
20-
);
15+
const Anchor = React.forwardRef(function Anchor(props, ref) {
16+
const { children, ...otherProps } = props;
2117

22-
Anchor.defaultProps = {
23-
className: '',
24-
style: {}
25-
};
18+
return (
19+
<StyledAnchor ref={ref} {...otherProps}>
20+
{children}
21+
</StyledAnchor>
22+
);
23+
});
24+
25+
Anchor.defaultProps = {};
2626

2727
Anchor.propTypes = {
28-
className: propTypes.string,
29-
href: propTypes.string.isRequired,
30-
style: propTypes.shape([propTypes.string, propTypes.number]),
3128
children: propTypes.node.isRequired
3229
};
3330

src/components/Anchor/Anchor.stories.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ storiesOf('Anchor', module)
2222
.add('within text', () => (
2323
<h1>
2424
Everybody needs
25+
{/* eslint-disable-next-line prettier/prettier */}{' '}
2526
<Anchor href='https://expensive.toys' target='_blank'>
2627
Expensive Toys
2728
</Anchor>

src/components/AppBar/AppBar.js

+11-26
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,22 @@ const StyledAppBar = styled.header`
1616
width: 100%;
1717
`;
1818

19-
const AppBar = ({
20-
fixed,
21-
children,
22-
className,
23-
style,
24-
shadow,
25-
...otherProps
26-
}) => (
27-
<StyledAppBar
28-
fixed={fixed}
29-
style={style}
30-
className={className}
31-
shadow={shadow}
32-
{...otherProps}
33-
>
34-
{children}
35-
</StyledAppBar>
36-
);
19+
const AppBar = React.forwardRef(function AppBar(props, ref) {
20+
const { children, ...otherProps } = props;
21+
return (
22+
<StyledAppBar ref={ref} {...otherProps}>
23+
{children}
24+
</StyledAppBar>
25+
);
26+
});
3727

3828
AppBar.defaultProps = {
39-
shadow: true,
40-
fixed: true,
41-
style: {},
42-
className: ''
29+
children: null,
30+
fixed: true
4331
};
4432

4533
AppBar.propTypes = {
46-
style: propTypes.shape([propTypes.string, propTypes.number]),
47-
shadow: propTypes.bool,
48-
className: propTypes.string,
49-
children: propTypes.node.isRequired,
34+
children: propTypes.node,
5035
fixed: propTypes.bool
5136
};
5237

src/components/Avatar/Avatar.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@ const SlyledAvatarIMG = styled.img`
3838
height: 100%;
3939
`;
4040

41-
const Avatar = ({ children, noBorder, square, src, alt, ...otherProps }) => (
42-
<StyledAvatar noBorder={noBorder} square={square} {...otherProps}>
43-
{src ? <SlyledAvatarIMG src={src} alt={alt} /> : children}
44-
</StyledAvatar>
45-
);
41+
const Avatar = React.forwardRef(function Avatar(props, ref) {
42+
const { children, noBorder, square, src, alt, ...otherProps } = props;
43+
return (
44+
<StyledAvatar noBorder={noBorder} square={square} ref={ref} {...otherProps}>
45+
{src ? <SlyledAvatarIMG src={src} alt={alt} /> : children}
46+
</StyledAvatar>
47+
);
48+
});
4649

4750
Avatar.defaultProps = {
4851
square: false,

src/components/Bar/Bar.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ const StyledBar = styled.div`
1414
border-right: 2px solid ${({ theme }) => theme.borderDark};
1515
background: ${({ theme }) => theme.material};
1616
`;
17+
// TODO: add horizontal variant
18+
// TODO: allow user to specify number of bars (like 3 horizontal bars for drag handle)
19+
const Bar = React.forwardRef(function Bar(props, ref) {
20+
const { size, ...otherProps } = props;
1721

18-
const Bar = ({ size, className, style, ...otherProps }) => (
19-
<StyledBar size={size} className={className} style={style} {...otherProps} />
20-
);
22+
return <StyledBar size={size} ref={ref} {...otherProps} />;
23+
});
2124

2225
Bar.defaultProps = {
23-
size: 'md',
24-
className: '',
25-
style: {}
26+
size: 'md'
2627
};
2728
Bar.propTypes = {
28-
className: propTypes.string,
29-
style: propTypes.shape([propTypes.string, propTypes.number]),
3029
size: propTypes.oneOf(['sm', 'md', 'lg'])
3130
};
31+
3232
export default Bar;

src/components/Button/Button.js

+20-42
Original file line numberDiff line numberDiff line change
@@ -99,70 +99,48 @@ export const StyledButton = styled.button`
9999
${commonButtonStyles}
100100
`;
101101

102-
const Button = ({
103-
type,
104-
onClick,
105-
style,
106-
disabled,
107-
fullWidth,
108-
size,
109-
square,
110-
active,
111-
primary,
112-
variant,
113-
className,
114-
children,
115-
...otherProps
116-
}) => (
117-
<StyledButton
118-
type={type}
119-
variant={variant}
120-
primary={primary}
121-
onClick={disabled ? undefined : onClick}
122-
style={style}
123-
disabled={disabled}
124-
isDisabled={disabled}
125-
fullWidth={fullWidth}
126-
size={size}
127-
square={square}
128-
active={active}
129-
className={className}
130-
// onTouchStart below to enable button :active style on iOS
131-
onTouchStart={() => ''}
132-
{...otherProps}
133-
>
134-
{children}
135-
</StyledButton>
136-
);
102+
const Button = React.forwardRef(function Button(props, ref) {
103+
const { onClick, disabled, children, ...otherProps } = props;
104+
105+
return (
106+
<StyledButton
107+
onClick={disabled ? undefined : onClick}
108+
disabled={disabled}
109+
isDisabled={disabled}
110+
// onTouchStart below to enable button :active style on iOS
111+
onTouchStart={() => ''}
112+
ref={ref}
113+
{...otherProps}
114+
>
115+
{children}
116+
</StyledButton>
117+
);
118+
});
137119

138120
Button.defaultProps = {
139121
type: 'button',
140122
onClick: null,
141-
style: {},
142123
disabled: false,
143124
fullWidth: false,
144125
size: 'md',
145126
square: false,
146127
active: false,
147128
primary: false,
148-
variant: 'default',
149-
className: ''
129+
variant: 'default'
150130
};
151131

152132
Button.propTypes = {
153133
type: propTypes.string,
154134
onClick: propTypes.func,
155-
style: propTypes.shape([propTypes.string, propTypes.number]),
156135
disabled: propTypes.bool,
157136
fullWidth: propTypes.bool,
158137
size: propTypes.oneOf(['sm', 'md', 'lg']),
159138
square: propTypes.bool,
160139
active: propTypes.bool,
161140
primary: propTypes.bool,
162-
163141
variant: propTypes.oneOf(['default', 'menu', 'flat']),
164-
className: propTypes.string,
165-
children: propTypes.node.isRequired
142+
// eslint-disable-next-line react/require-default-props
143+
children: propTypes.node
166144
};
167145

168146
export default Button;

src/components/Cutout/Cutout.js

+10-17
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,24 @@ const StyledCutout = styled.div`
3535
${props => props.shadow && `box-shadow:${insetShadow};`}
3636
}
3737
`;
38-
// add padding prop ?
3938

40-
const Cutout = ({ className, style, children, shadow, ...otherProps }) => (
41-
<StyledCutout
42-
shadow={shadow}
43-
className={className}
44-
style={style}
45-
{...otherProps}
46-
>
47-
{children}
48-
</StyledCutout>
49-
);
39+
const Cutout = React.forwardRef(function Cutout(props, ref) {
40+
const { children, ...otherProps } = props;
41+
return (
42+
<StyledCutout ref={ref} {...otherProps}>
43+
{children}
44+
</StyledCutout>
45+
);
46+
});
5047

5148
Cutout.defaultProps = {
52-
shadow: true,
53-
className: '',
5449
children: null,
55-
style: {}
50+
shadow: true
5651
};
5752

5853
Cutout.propTypes = {
59-
className: propTypes.string,
60-
shadow: propTypes.bool,
6154
children: propTypes.node,
62-
style: propTypes.shape([propTypes.string, propTypes.number])
55+
shadow: propTypes.bool
6356
};
6457

6558
export default Cutout;

src/components/Divider/Divider.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ const StyledDivider = styled.hr`
1919
`}
2020
`;
2121

22-
const Divider = ({ vertical, size, ...otherProps }) => (
23-
<StyledDivider vertical={vertical} size={size} {...otherProps} />
24-
);
22+
const Divider = React.forwardRef(function Divider(props, ref) {
23+
return <StyledDivider ref={ref} {...props} />;
24+
});
2525

2626
Divider.defaultProps = {
2727
size: '100%',
2828
vertical: false
2929
};
3030

3131
Divider.propTypes = {
32-
vertical: propTypes.bool,
33-
size: propTypes.string
32+
size: propTypes.string,
33+
vertical: propTypes.bool
3434
};
3535

3636
export default Divider;

src/components/Fieldset/Fieldset.js

+15-11
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,21 @@ const StyledLegend = styled.legend`
3535
variant === 'flat' ? theme.canvas : theme.material};
3636
`;
3737

38-
const Fieldset = ({ label, disabled, variant, children, ...otherProps }) => (
39-
<StyledFieldset
40-
aria-disabled={disabled}
41-
isDisabled={disabled}
42-
variant={variant}
43-
{...otherProps}
44-
>
45-
{label && <StyledLegend variant={variant}>{label}</StyledLegend>}
46-
{children}
47-
</StyledFieldset>
48-
);
38+
const Fieldset = React.forwardRef(function Fieldset(props, ref) {
39+
const { label, disabled, variant, children, ...otherProps } = props;
40+
return (
41+
<StyledFieldset
42+
aria-disabled={disabled}
43+
isDisabled={disabled}
44+
variant={variant}
45+
ref={ref}
46+
{...otherProps}
47+
>
48+
{label && <StyledLegend variant={variant}>{label}</StyledLegend>}
49+
{children}
50+
</StyledFieldset>
51+
);
52+
});
4953

5054
Fieldset.defaultProps = {
5155
disabled: false,

src/components/Hourglass/Hourglass.js

+19-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import React from 'react';
22
import propTypes from 'prop-types';
3-
43
import styled from 'styled-components';
5-
64
import base64hourglass from './base64hourglass';
75

86
const StyledContainer = styled.span`
@@ -16,29 +14,32 @@ const StyledHourglass = styled.span`
1614
width: 100%;
1715
height: 100%;
1816
`;
19-
const Hourglass = ({ size, className, style, ...otherProps }) => (
20-
<StyledContainer
21-
className={className}
22-
style={{
23-
...style,
24-
width: size || '30px',
25-
height: size || '30px'
26-
}}
27-
{...otherProps}
28-
>
29-
<StyledHourglass />
30-
</StyledContainer>
31-
);
17+
18+
const Hourglass = React.forwardRef(function HourGlass(props, ref) {
19+
const { size, style, ...otherProps } = props;
20+
return (
21+
<StyledContainer
22+
style={{
23+
...style,
24+
width: size || '30px',
25+
height: size || '30px'
26+
}}
27+
ref={ref}
28+
{...otherProps}
29+
>
30+
<StyledHourglass />
31+
</StyledContainer>
32+
);
33+
});
3234

3335
Hourglass.defaultProps = {
3436
size: '30px',
35-
className: '',
3637
style: {}
3738
};
3839

3940
Hourglass.propTypes = {
4041
size: propTypes.oneOfType([propTypes.string, propTypes.number]),
41-
className: propTypes.string,
42-
style: propTypes.shape([propTypes.string, propTypes.number])
42+
// eslint-disable-next-line react/forbid-prop-types
43+
style: propTypes.object
4344
};
4445
export default Hourglass;

0 commit comments

Comments
 (0)