Skip to content

Commit

Permalink
feat(): forwarding refs in components
Browse files Browse the repository at this point in the history
  • Loading branch information
arturbien committed Mar 17, 2020
1 parent 3300037 commit 7af4faa
Show file tree
Hide file tree
Showing 24 changed files with 218 additions and 232 deletions.
25 changes: 11 additions & 14 deletions src/components/Anchor/Anchor.js
Expand Up @@ -2,32 +2,29 @@ import React from 'react';
import propTypes from 'prop-types';

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

const StyledAnchor = styled.a`
color: ${({ theme }) => theme.anchor};
font-size: ${({ size }) => (size ? fontSizes[size] : 'inherit')};
font-size: inherit;
text-decoration: underline;
&:visited {
color: ${({ theme }) => theme.anchorVisited};
}
`;

const Anchor = ({ className, style, href, children, ...otherProps }) => (
<StyledAnchor href={href} className={className} style={style} {...otherProps}>
{children}
</StyledAnchor>
);
const Anchor = React.forwardRef(function Anchor(props, ref) {
const { children, ...otherProps } = props;

Anchor.defaultProps = {
className: '',
style: {}
};
return (
<StyledAnchor ref={ref} {...otherProps}>
{children}
</StyledAnchor>
);
});

Anchor.defaultProps = {};

Anchor.propTypes = {
className: propTypes.string,
href: propTypes.string.isRequired,
style: propTypes.shape([propTypes.string, propTypes.number]),
children: propTypes.node.isRequired
};

Expand Down
1 change: 1 addition & 0 deletions src/components/Anchor/Anchor.stories.js
Expand Up @@ -22,6 +22,7 @@ storiesOf('Anchor', module)
.add('within text', () => (
<h1>
Everybody needs
{/* eslint-disable-next-line prettier/prettier */}{' '}
<Anchor href='https://expensive.toys' target='_blank'>
Expensive Toys
</Anchor>
Expand Down
37 changes: 11 additions & 26 deletions src/components/AppBar/AppBar.js
Expand Up @@ -16,37 +16,22 @@ const StyledAppBar = styled.header`
width: 100%;
`;

const AppBar = ({
fixed,
children,
className,
style,
shadow,
...otherProps
}) => (
<StyledAppBar
fixed={fixed}
style={style}
className={className}
shadow={shadow}
{...otherProps}
>
{children}
</StyledAppBar>
);
const AppBar = React.forwardRef(function AppBar(props, ref) {
const { children, ...otherProps } = props;
return (
<StyledAppBar ref={ref} {...otherProps}>
{children}
</StyledAppBar>
);
});

AppBar.defaultProps = {
shadow: true,
fixed: true,
style: {},
className: ''
children: null,
fixed: true
};

AppBar.propTypes = {
style: propTypes.shape([propTypes.string, propTypes.number]),
shadow: propTypes.bool,
className: propTypes.string,
children: propTypes.node.isRequired,
children: propTypes.node,
fixed: propTypes.bool
};

Expand Down
13 changes: 8 additions & 5 deletions src/components/Avatar/Avatar.js
Expand Up @@ -38,11 +38,14 @@ const SlyledAvatarIMG = styled.img`
height: 100%;
`;

const Avatar = ({ children, noBorder, square, src, alt, ...otherProps }) => (
<StyledAvatar noBorder={noBorder} square={square} {...otherProps}>
{src ? <SlyledAvatarIMG src={src} alt={alt} /> : children}
</StyledAvatar>
);
const Avatar = React.forwardRef(function Avatar(props, ref) {
const { children, noBorder, square, src, alt, ...otherProps } = props;
return (
<StyledAvatar noBorder={noBorder} square={square} ref={ref} {...otherProps}>
{src ? <SlyledAvatarIMG src={src} alt={alt} /> : children}
</StyledAvatar>
);
});

Avatar.defaultProps = {
square: false,
Expand Down
16 changes: 8 additions & 8 deletions src/components/Bar/Bar.js
Expand Up @@ -14,19 +14,19 @@ const StyledBar = styled.div`
border-right: 2px solid ${({ theme }) => theme.borderDark};
background: ${({ theme }) => theme.material};
`;
// TODO: add horizontal variant
// TODO: allow user to specify number of bars (like 3 horizontal bars for drag handle)
const Bar = React.forwardRef(function Bar(props, ref) {
const { size, ...otherProps } = props;

const Bar = ({ size, className, style, ...otherProps }) => (
<StyledBar size={size} className={className} style={style} {...otherProps} />
);
return <StyledBar size={size} ref={ref} {...otherProps} />;
});

Bar.defaultProps = {
size: 'md',
className: '',
style: {}
size: 'md'
};
Bar.propTypes = {
className: propTypes.string,
style: propTypes.shape([propTypes.string, propTypes.number]),
size: propTypes.oneOf(['sm', 'md', 'lg'])
};

export default Bar;
62 changes: 20 additions & 42 deletions src/components/Button/Button.js
Expand Up @@ -99,70 +99,48 @@ export const StyledButton = styled.button`
${commonButtonStyles}
`;

const Button = ({
type,
onClick,
style,
disabled,
fullWidth,
size,
square,
active,
primary,
variant,
className,
children,
...otherProps
}) => (
<StyledButton
type={type}
variant={variant}
primary={primary}
onClick={disabled ? undefined : onClick}
style={style}
disabled={disabled}
isDisabled={disabled}
fullWidth={fullWidth}
size={size}
square={square}
active={active}
className={className}
// onTouchStart below to enable button :active style on iOS
onTouchStart={() => ''}
{...otherProps}
>
{children}
</StyledButton>
);
const Button = React.forwardRef(function Button(props, ref) {
const { onClick, disabled, children, ...otherProps } = props;

return (
<StyledButton
onClick={disabled ? undefined : onClick}
disabled={disabled}
isDisabled={disabled}
// onTouchStart below to enable button :active style on iOS
onTouchStart={() => ''}
ref={ref}
{...otherProps}
>
{children}
</StyledButton>
);
});

Button.defaultProps = {
type: 'button',
onClick: null,
style: {},
disabled: false,
fullWidth: false,
size: 'md',
square: false,
active: false,
primary: false,
variant: 'default',
className: ''
variant: 'default'
};

Button.propTypes = {
type: propTypes.string,
onClick: propTypes.func,
style: propTypes.shape([propTypes.string, propTypes.number]),
disabled: propTypes.bool,
fullWidth: propTypes.bool,
size: propTypes.oneOf(['sm', 'md', 'lg']),
square: propTypes.bool,
active: propTypes.bool,
primary: propTypes.bool,

variant: propTypes.oneOf(['default', 'menu', 'flat']),
className: propTypes.string,
children: propTypes.node.isRequired
// eslint-disable-next-line react/require-default-props
children: propTypes.node
};

export default Button;
27 changes: 10 additions & 17 deletions src/components/Cutout/Cutout.js
Expand Up @@ -35,31 +35,24 @@ const StyledCutout = styled.div`
${props => props.shadow && `box-shadow:${insetShadow};`}
}
`;
// add padding prop ?

const Cutout = ({ className, style, children, shadow, ...otherProps }) => (
<StyledCutout
shadow={shadow}
className={className}
style={style}
{...otherProps}
>
{children}
</StyledCutout>
);
const Cutout = React.forwardRef(function Cutout(props, ref) {
const { children, ...otherProps } = props;
return (
<StyledCutout ref={ref} {...otherProps}>
{children}
</StyledCutout>
);
});

Cutout.defaultProps = {
shadow: true,
className: '',
children: null,
style: {}
shadow: true
};

Cutout.propTypes = {
className: propTypes.string,
shadow: propTypes.bool,
children: propTypes.node,
style: propTypes.shape([propTypes.string, propTypes.number])
shadow: propTypes.bool
};

export default Cutout;
10 changes: 5 additions & 5 deletions src/components/Divider/Divider.js
Expand Up @@ -19,18 +19,18 @@ const StyledDivider = styled.hr`
`}
`;

const Divider = ({ vertical, size, ...otherProps }) => (
<StyledDivider vertical={vertical} size={size} {...otherProps} />
);
const Divider = React.forwardRef(function Divider(props, ref) {
return <StyledDivider ref={ref} {...props} />;
});

Divider.defaultProps = {
size: '100%',
vertical: false
};

Divider.propTypes = {
vertical: propTypes.bool,
size: propTypes.string
size: propTypes.string,
vertical: propTypes.bool
};

export default Divider;
26 changes: 15 additions & 11 deletions src/components/Fieldset/Fieldset.js
Expand Up @@ -35,17 +35,21 @@ const StyledLegend = styled.legend`
variant === 'flat' ? theme.canvas : theme.material};
`;

const Fieldset = ({ label, disabled, variant, children, ...otherProps }) => (
<StyledFieldset
aria-disabled={disabled}
isDisabled={disabled}
variant={variant}
{...otherProps}
>
{label && <StyledLegend variant={variant}>{label}</StyledLegend>}
{children}
</StyledFieldset>
);
const Fieldset = React.forwardRef(function Fieldset(props, ref) {
const { label, disabled, variant, children, ...otherProps } = props;
return (
<StyledFieldset
aria-disabled={disabled}
isDisabled={disabled}
variant={variant}
ref={ref}
{...otherProps}
>
{label && <StyledLegend variant={variant}>{label}</StyledLegend>}
{children}
</StyledFieldset>
);
});

Fieldset.defaultProps = {
disabled: false,
Expand Down
37 changes: 19 additions & 18 deletions src/components/Hourglass/Hourglass.js
@@ -1,8 +1,6 @@
import React from 'react';
import propTypes from 'prop-types';

import styled from 'styled-components';

import base64hourglass from './base64hourglass';

const StyledContainer = styled.span`
Expand All @@ -16,29 +14,32 @@ const StyledHourglass = styled.span`
width: 100%;
height: 100%;
`;
const Hourglass = ({ size, className, style, ...otherProps }) => (
<StyledContainer
className={className}
style={{
...style,
width: size || '30px',
height: size || '30px'
}}
{...otherProps}
>
<StyledHourglass />
</StyledContainer>
);

const Hourglass = React.forwardRef(function HourGlass(props, ref) {
const { size, style, ...otherProps } = props;
return (
<StyledContainer
style={{
...style,
width: size || '30px',
height: size || '30px'
}}
ref={ref}
{...otherProps}
>
<StyledHourglass />
</StyledContainer>
);
});

Hourglass.defaultProps = {
size: '30px',
className: '',
style: {}
};

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

0 comments on commit 7af4faa

Please sign in to comment.