Skip to content

Instantly share code, notes, and snippets.

@jaksm
Last active May 26, 2019 13:30
Show Gist options
  • Save jaksm/8a00f5931b671c74c346c876c41a56bf to your computer and use it in GitHub Desktop.
Save jaksm/8a00f5931b671c74c346c876c41a56bf to your computer and use it in GitHub Desktop.
Semantic and animated components.
import PropTypes from "prop-types";
import React, { useEffect } from "react";
import { animated, useSpring } from "react-spring";
import styled from "styled-components";
/*
* Works like this
* <Stat value={164} label={"Lines of code"} />
* */
const Container = styled.div`
padding: 1.5em;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`;
const Value = styled(animated.span)`
font-size: 5rem;
`;
const Label = styled.strong`
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 1px;
`;
export const Stat = props => {
let { label, value: max } = props;
const x = useSpring({ value: max, from: { value: 0 } });
useEffect(() => {
setInterval(() => (max += 1), 1500);
});
return (
<Container>
<Value>{x.value.interpolate(x => x.toFixed(0))}</Value>
<Label>{label}</Label>
</Container>
);
};
Stat.propTypes = {
label: PropTypes.string,
value: PropTypes.number.isRequired
};
import PropTypes from "prop-types";
import React from "react";
import styled from "styled-components";
import { animated, useSpring } from "react-spring";
/*
* Works like this
* <Title size={1}>Hello World!</Title>
* <Title size={2}>Hello World!</Title>
* <Title size={3}>Hello World!</Title>
* <Title size={4}>Hello World!</Title>
* <Title size={5}>Hello World!</Title>
* <Title size={6} animated={true}>
Hello World!
</Title>
* */
// Element collection factory
const MakeElements = size => styled(animated[`h${size}`])``;
// Element collection
let Elements = {}; // { h1, h2, h3 ... }
for (let size = 1; size <= 6; size++) {
Elements[`h${size}`] = MakeElements(size);
}
export const Title = props => {
const { children, size, animated } = props;
// Animation
const fadeIn = useSpring({
transform: "translateY(0)",
opacity: 1,
from: {
transform: "translateY(25%)",
opacity: 0
}
});
// Element selection
const Element = Elements[`h${Math.abs(size - 7)}`];
return <Element style={animated && fadeIn}>{children}</Element>;
};
Title.propTypes = {
animated: PropTypes.bool,
children: PropTypes.any,
size: PropTypes.number
};
Title.defaultProps = {
animated: undefined,
size: 1
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment