Pick a random item from an array of strings.
Created
October 26, 2021 05:57
-
-
Save alisamie97/56e9acfe3be1248691a5cba5f3ba1f26 to your computer and use it in GitHub Desktop.
React random name picker component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="random-picker"></div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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') | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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