Reputation: 3899
I am attempting to make my own icon button using React, styled-components, and SVG. My icons are generally rectangular, however I want the buttons to be squares and to have the icons centered inside of them. This is where I am getting stuck. I tried tweaking the viewBox dimensions on the SVGs but (1) there is a lot of guesswork in this process, and (2) it screws up the position of the icons inside the buttons. Please can anyone offer some suggestions for how to achieve the square buttons with rectangular icons inside them?
Here is a CodePen with the below code: https://codepen.io/DanielPBank/pen/rPJgPW
const styled = styled.default; //normailly import from npm mmodules
const StyledButton = styled.button`
appearance: none;
opacity: 1;
cursor: pointer;
display: flex;
height: ${props => props.size};
width: ${props => props.size};
max-height: ${props => props.maxSize}
max-width: ${props => props.maxSize}
margin: 1rem;
font-size: 0.75rem;
font-weight: 500;
line-height: 0.88rem;
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
border-radius: 8px;
border: 3px solid ${props => props.active ? '#C23631' : '#222'};
background-color: ${props => props.active ? '#C09AA1' : '#fcfcfc'};
color: #222;
&:hover {
opacity: 0.70;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}
&:disabled {
opacity: 0.5;
pointer-events: none;
}
&:active {
border: 3px solid #ccc;
background-color: #444;
}
`;
const StyledIcon = styled.svg`
display: inline-block;
fill: ${props => props.color || "white"};
height ${props => props.size};
width: ${props => props.size};
user-select: none;
flex-shrink: 0;
`;
class Icon extends React.Component {
render() {
const { size, viewBox, color } = this.props;
return (
<StyledIcon
width={size || '1rem'}
height={size || '1rem'}
viewBox={viewBox}
color={color}
>
{this.props.children}
</StyledIcon>
);
}
}
class Undo extends React.Component {
render() {
return (
<Icon
{...this.props}
x="0px"
y="0px"
viewBox="50 50 950 950"
fill="#222"
>
<path
d="M588.5,913.8c44.4,0,88.9,0,133.3,0c18,0,36.1,0,54.1,0c11.6,0,23.1-1.9,34.6-3.5 c10.3-1.5,20.3-4.1,29.9-8.1c14.8-6,29.1-12,41.9-21.5c12.4-9.2,24.7-18.5,34.6-30.4c20-24.2,36.5-51.4,42.8-82.6 c3.1-15.2,4.8-30.8,4.8-46.3c0-20.5,0-40.9,0-61.4c0-47.9,0-95.8,0-143.7c0-50.2-19.5-99.2-55.2-134.8 c-35.2-35.2-83.9-55.1-133.6-55.2c-23.7,0-47.3,0-71,0c-50,0-100,0-150,0c-59.9,0-119.8,0-179.7,0c-52.3,0-104.6,0-156.9,0 c-28.3,0-56.7,0-85,0c-1.3,0-2.6,0-3.9,0c-18,0-36.8,7.8-49.5,20.5c-6.8,6.3-11.7,13.8-14.5,22.5c-4.4,8.3-6.4,17.3-6,27 c0.8,18.1,6.8,36.9,20.5,49.5c13.7,12.6,30.5,20.5,49.5,20.5c22,0,43.9,0,65.9,0c52.6,0,105.1,0,157.7,0c62.8,0,125.7,0,188.5,0 c53.8,0,107.6,0,161.4,0c24.5,0,48.9-0.1,73.4,0c5.2,0,10.4,0.3,15.6,1c-6.2-0.8-12.4-1.7-18.6-2.5c10.3,1.4,20.3,4.1,29.9,8.1 c-5.6-2.4-11.1-4.7-16.7-7.1c9.4,4,18.2,9.1,26.3,15.2c-4.7-3.6-9.4-7.3-14.2-10.9c8.4,6.5,15.8,13.9,22.3,22.3 c-3.6-4.7-7.3-9.4-10.9-14.2c6.1,8.1,11.2,16.9,15.2,26.3c-2.4-5.6-4.7-11.1-7.1-16.7c4,9.6,6.7,19.6,8.1,29.9 c-0.8-6.2-1.7-12.4-2.5-18.6c1.3,10.7,1,21.6,1,32.3c0,17.5,0,34.9,0,52.4c0,39.9,0,79.8,0,119.7c0,12.5,0.6,25.1-1,37.5 c0.8-6.2,1.7-12.4,2.5-18.6c-1.4,10.3-4.1,20.3-8.1,29.9c2.4-5.6,4.7-11.1,7.1-16.7c-4,9.4-9.1,18.2-15.2,26.3 c3.6-4.7,7.3-9.4,10.9-14.2c-6.5,8.4-13.9,15.8-22.3,22.3c4.7-3.6,9.4-7.3,14.2-10.9c-8.1,6.1-16.9,11.2-26.3,15.2 c5.6-2.4,11.1-4.7,16.7-7.1c-9.6,4-19.6,6.7-29.9,8.1c6.2-0.8,12.4-1.7,18.6-2.5c-9.6,1.2-19.2,1-28.8,1c-14.5,0-29,0-43.5,0 c-35.4,0-70.8,0-106.1,0c-8.3,0-16.6,0-24.9,0c-17.9,0-36.8,7.8-49.5,20.5c-6.8,6.3-11.7,13.8-14.5,22.5c-4.4,8.3-6.4,17.3-6,27 c0.8,18.1,6.8,36.9,20.5,49.5C552.7,905.8,569.6,913.8,588.5,913.8L588.5,913.8z"
/>
<path
d="M296.1,130.8c-24.3,24.3-48.7,48.7-73,73c-38.8,38.8-77.6,77.6-116.4,116.4c-8.9,8.9-17.9,17.9-26.8,26.8 c-26.7,26.7-26.8,72.2,0,99c24.3,24.4,48.7,48.7,73,73.1c38.8,38.9,77.6,77.7,116.4,116.6c8.9,8.9,17.9,17.9,26.8,26.8 c12.7,12.7,31.6,20.5,49.5,20.5c17.2,0,37.7-7.6,49.5-20.5c12.2-13.3,21.3-30.9,20.5-49.5c-0.8-18.6-7.1-36.1-20.5-49.5 c-24.3-24.4-48.7-48.7-73-73.1c-38.8-38.9-77.6-77.7-116.4-116.6c-8.9-8.9-17.9-17.9-26.8-26.8c0,33,0,66,0,99 c24.3-24.3,48.7-48.7,73-73c38.8-38.8,77.6-77.6,116.4-116.4c8.9-8.9,17.9-17.9,26.8-26.8c12.7-12.7,20.5-31.5,20.5-49.5 c0-17.2-7.6-37.7-20.5-49.5c-13.3-12.2-30.9-21.3-49.5-20.5C327,111.1,309.5,117.4,296.1,130.8L296.1,130.8z"
/>
</Icon>
);
}
}
class Button extends React.Component {
render() {
const { icon, size, maxSize, active, disabled } = this.props;
return (
<StyledButton
type="button"
ref={this.buttonRef}
size={size}
maxSize={maxSize}
active={active}
disabled={disabled}
>
{icon}
</StyledButton>
);
}
}
class Application extends React.Component {
render() {
return (
<div>
<Button
icon={<Undo color="black" size="100%"/>}
size="25%"
maxSize="5rem"
/>
</div>
)
}
}
ReactDOM.render(<Application />, document.getElementById('content'));
Upvotes: 1
Views: 3409
Reputation: 11577
Your icon is square alright. The button is rectangle because of button's default padding. In StyledButton
, add padding: 0;
and your button should be squared.
Upvotes: 3