Skip to content

Instantly share code, notes, and snippets.

@alisamie97
Created October 26, 2021 05:57
Show Gist options
  • Save alisamie97/12232d9930070bdf6d5517b3cea9a7ed to your computer and use it in GitHub Desktop.
Save alisamie97/12232d9930070bdf6d5517b3cea9a7ed to your computer and use it in GitHub Desktop.
React random name picker component
<div id="random-picker"></div>
class RandomPicker extends React.PureComponent {
constructor() {
super();
this.state = {
isRunning: false,
currentChoice: ''
};
this.interval = null;
this.intervalDuration = 25;
this.duration = 1000;
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.reset = this.reset.bind(this);
this.pickChoice = this.pickChoice.bind(this);
this.setChoice = this.setChoice.bind(this);
}
start() {
clearInterval(this.interval);
this.interval = setInterval(this.setChoice, this.intervalDuration);
this.setState({ isRunning: true });
setTimeout(() => {
if (this.state.isRunning) {
this.stop()
}
}, this.duration);
}
stop() {
clearInterval(this.interval);
this.setState({ isRunning: false });
}
reset() {
clearInterval(this.interval);
this.setState({ isRunning: false, currentChoice: '' });
}
pickChoice() {
const { items } = this.props;
const choice = items[Math.floor(Math.random() * items.length)];
return choice;
}
setChoice() {
this.setState({ currentChoice: this.pickChoice() })
}
render() {
const { isRunning, currentChoice } = this.state;
return (
<div className="RandomPicker">
<RandomPickerChoice choice={currentChoice} />
<RandomPickerControls
isRunning={isRunning}
hasChoice={currentChoice.trim().length > 0}
start={this.start}
stop={this.stop}
reset={this.reset}
/>
</div>
);
}
}
RandomPicker.propTypes = {
items: PropTypes.array,
duration: PropTypes.number
};
class RandomPickerChoice extends React.PureComponent {
render() {
const { choice } = this.props;
const content = choice.trim().length > 0 ? choice : '?';
return (
<div className="RandomPicker__choice">
<span className="RandomPicker__choiceItem">{content}</span>
</div>
);
}
}
RandomPickerChoice.propTypes = {
choice: PropTypes.string
};
class RandomPickerControls extends React.PureComponent {
render() {
const {
isRunning,
hasChoice,
start,
stop,
reset
} = this.props;
return (
<div className="RandomPicker__controls">
<button
class={`RandomPicker__button ${isRunning && 'RandomPicker__button--stop'}`}
onClick={isRunning ? stop : start}
>
{isRunning ? 'stop' : 'start'}
</button>
<button
disabled={isRunning || !hasChoice}
class="RandomPicker__button RandomPicker__button--reset"
onClick={reset}
>
reset
</button>
</div>
);
}
}
RandomPickerControls.propTypes = {
isRunning: PropTypes.bool,
hasChoice: PropTypes.bool,
start: PropTypes.func,
stop: PropTypes.func,
reset: PropTypes.func,
};
const namesList = [
'Marcelo',  
'Lizzette',  
'Pauline',  
'Fumiko',  
'Tomasa',  
'Bertha',  
'Antoinette',  
'Tianna',  
'Ammie',  
'Victorina',  
'Marlon',  
'Jules',  
'Arletha',  
'Ellyn',  
'Karol',  
'Corrin', 
'Josephine',
];
ReactDOM.render(
<RandomPicker items={namesList} />,
document.getElementById('random-picker')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script>
html {
--color-background: #ffffff;
--color-text: #000000;
--color-text-light: lightgray;
--color-button-start: #0557ff;
--color-button-stop: #ff0000;
--color-button-text: #ffffff;
}
@media (prefers-color-scheme: dark) {
html {
--color-background: #000213;
--color-text: #a5a8d2;
--color-text-light: #444766;
--color-button-start: #0557ff;
--color-button-stop: #ff0000;
--color-button-text: #d8d8d8;
}
}
body {
margin: 0;
padding: 0;
min-height: 100vh;
background: var(--color-background);
display: flex;
align-items: center;
justify-content: center;
}
.RandomPicker {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 16px;
font-family: 'Helvetica', sans-serif;
}
.RandomPicker__choice {
display: flex;
align-content: center;
margin: 0;
margin-bottom: 1em;
color: var(--color-text);
font-size: 60px;
font-weight: bold;
line-height: 1;
text-align: center;
white-space: nowrap;
}
.RandomPicker__button {
display: block;
padding: .8em 1.6em;
min-width: 160px;
color: var(--color-button-text);
font-size: 20px;
font-weight: bold;
text-align: center;
text-transform: uppercase;
letter-spacing: 2px;
border: 0;
border-radius: 4em;
background-color: var(--color-button-start);
user-select: none;
cursor: pointer;
transition:
background-color 250ms ease-in-out,
color 150ms ease-in-out;
&--stop {
background-color: var(--color-button-stop);
}
&--reset {
color: var(--color-text);
font-size: 14px;
text-transform: lowercase;
background-color: inherit;
&[disabled] {
color: var(--color-text-light);
text-decoration: line-through;
cursor: not-allowed;
}
}
}
.RandomPicker__controls {
display: flex;
flex-direction: column;
align-items: center;
> *:not(:last-child) {
margin-bottom: 16px;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment