* {
box-sizing: border-box;
}
div, button, a {
border-radius: 3px;
}
.same-color {
background-color: var(--bg);
color: white;
text-decoration: none;
transition: all calc(var(--trans-time) * 2);
}
.faded {
background-color: white;
color: var(--color);
transition: all var(--trans-time);
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
#wrapper {
width: 35em;
#quote-box {
width: 100%;
height: 100%;
padding: 2em;
background-color: white;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: space-around;
}
}
#text-container {
align-self: center;
font-family: 'Akshar', sans-serif;
font-size: 2em;
}
#author-container {
$margins: 1em;
margin-top: $margins;
margin-bottom: $margins;
font-family: 'Open Sans', sans-serif;
font-size: 1.2em;
}
.padded-button {
padding: 0.5em;
height: 100%;
font-size: 1.2em;
}
#button-container {
width: 100%;
#tweet-quote {
float: left;
}
#new-quote {
float: right;
font-family: 'Akshar', sans-serif;
border: none;
}
}
View Compiled
var body = document.body;
body.classList.add("same-color");
document.documentElement.style.setProperty("--trans-time", "0.5s");
class QuoteBox extends React.Component {
constructor(props) {
super(props);
this.state = {
quote: "",
author: "",
tweetIntent: "https://twitter.com/intent/tweet"
};
this.handleNewQuote = this.handleNewQuote.bind(this);
}
handleNewQuote() {
const this_func = this;
const colorArray = ["#16A085", "#1974D2", "#27AE60", "#E74C3C", "#FFAA1D", "#FF007F"];
let newColor = colorArray[Math.floor(Math.random() * colorArray.length)];
document.documentElement.style.setProperty("--color", "white");
document.documentElement.style.setProperty("--bg", newColor);
async function getApi() {
return fetch("https://api.quotable.io/random?tags=famous-quotes")
.then(Response => Response.json())
.then(data => ({
quote: data.content,
author: data.author,
tweetIntent: `https://twitter.com/intent/tweet?text=${data.content}%0A-${data.author}`
}));
};
async function updateQuote() {
let responseData = await getApi();
setTimeout(() => {
this_func.setState(() => ({
quote: responseData.quote,
author: responseData.author,
tweetIntent: responseData.tweetIntent
}));
document.documentElement.style.setProperty("--color", newColor);
}, 500);
};
updateQuote();
}
componentDidMount() {
this.handleNewQuote();
}
render() {
return (
<div id="quote-box">
<QuoteText quote={this.state.quote}/>
<QuoteAuthor author={this.state.author}/>
<ButtonContainer handleNewQuote={this.handleNewQuote} tweet={this.state.tweetIntent}/>
</div>
);
}
};
class QuoteText extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div id="text-container">
<span id="text" className="same-color faded">{this.props.quote}</span>
</div>
);
}
};
class QuoteAuthor extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div id="author-container">
<span id="author" className="same-color faded">{"-" + this.props.author}</span>
</div>
);
}
};
class ButtonContainer extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div id="button-container">
<a href={this.props.tweet} id="tweet-quote" className="same-color padded-button" target="_blank">
<i className="fa-brands fa-twitter"></i>
</a>
<button id="new-quote" className="same-color padded-button" onClick={this.props.handleNewQuote}>New Quote</button>
</div>
);
}
};
// To render root element
const rootDiv = document.getElementById("wrapper")
const root = ReactDOM.createRoot(rootDiv);
document.body.onload = () => {
root.render(<QuoteBox />);
};
View Compiled