Skip to content

Instantly share code, notes, and snippets.

@GantMan
Last active March 21, 2018 17:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GantMan/36de16e2134129bea19c2e7a331f88da to your computer and use it in GitHub Desktop.
Save GantMan/36de16e2134129bea19c2e7a331f88da to your computer and use it in GitHub Desktop.
.add('Default', () => (
<View style={{padding: 10}}>
<MultiButton onChange={(status => window.alert(JSON.stringify(status)))} />
</View>
))
.add('Different Options', () => (
<View style={{padding: 10}}>
<MultiButton options={['Fall', 'Winter', 'Spring', 'Summer']} />
</View>
))
.add('Given State', () => (
<View style={{padding: 10}}>
<MultiButton startState={[
{value: 'Sunday', active: true},
{value: 'Monday', active: false},
{value: 'Tuesday', active: false},
{value: 'Wednesday', active: true},
{value: 'Thursday', active: false},
{value: 'Friday', active: false},
{value: 'Saturday', active: true}
]} />
</View>
))
import React from 'react'
import PropTypes from 'prop-types'
import { TouchableWithoutFeedback, Text, View } from 'react-native'
import { Colors, Metrics } from '../Themes'
const defaultOptions = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
]
const styles = StyleSheet.create({
button: {
width: '50%',
borderColor: Colors.primary,
borderWidth: 1,
// Trick to stop double border-lines
marginBottom: -1,
marginLeft: -1
},
buttonText: {
margin: 18,
textAlign: 'center',
color: Colors.primary,
fontSize: Fonts.size.small
}
})
export default class MultiButtonColumn extends React.Component {
constructor (props) {
super(props)
// We've been given state
if (this.props.startState) {
this.state = {
options: this.props.startState.map(i => i.value),
items: this.props.startState
}
// We make state from options
} else {
this.state = {
// create index bound version of options state
options: this.props.options,
items: this.props.options.map((v, i) => ({value: v, active: false}))
}
}
}
static propTypes = {
options: PropTypes.array,
startState: PropTypes.array,
onChange: PropTypes.func,
styles: PropTypes.object
}
onToggle = (index) => {
this.setState((state, props) => {
let items = state.items
items[index].active = !items[index].active
return { items }
}, this.props.onChange && this.props.onChange.bind(this, this.state.items))
}
renderOption = (text, active, index, renderLength) => {
const evenAmount = renderLength % 2 === 0
let containerAdjustments = {}
let textAdjustments = {}
// Top left cell
if (index === 0 && evenAmount) {
containerAdjustments = { borderTopLeftRadius: Metrics.sectionRadius }
// Top alone cell
} else if (index === 0) {
containerAdjustments = {
width: '99.7%',
borderTopLeftRadius: Metrics.sectionRadius,
borderTopRightRadius: Metrics.sectionRadius
}
// Top right cell
} else if (index === 1 && evenAmount) {
containerAdjustments = { borderTopRightRadius: Metrics.sectionRadius }
// Bottom left cell
} else if (index === renderLength - 2) {
containerAdjustments = { borderBottomLeftRadius: Metrics.sectionRadius }
// Bottom right cell
} else if (index === renderLength - 1) {
containerAdjustments = { borderBottomRightRadius: Metrics.sectionRadius }
}
// check if active
if (this.state.items[index] && this.state.items[index].active) {
containerAdjustments = {
...containerAdjustments,
backgroundColor: Colors.primary
}
textAdjustments = { color: Colors.snow }
}
return (
<TouchableWithoutFeedback key={text} onPress={this.onToggle.bind(this, index)}>
<View style={[styles.button, containerAdjustments, this.props.styles]} >
<Text style={[styles.buttonText, textAdjustments]}>{text}</Text>
</View>
</TouchableWithoutFeedback>
)
}
value = () => this.state.items
renderOptions = () => {
return this.state.options.map((option, index) => {
return this.renderOption(option, false, index, this.state.options.length)
})
}
render () {
return (
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
{this.renderOptions()}
</View>
)
}
}
MultiButtonColumn.defaultProps = {
options: defaultOptions
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment