Skip to content

Instantly share code, notes, and snippets.

@danielpost
Created June 28, 2017 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielpost/1a5eef80a3745a2842f44abbcf2ef69e to your computer and use it in GitHub Desktop.
Save danielpost/1a5eef80a3745a2842f44abbcf2ef69e to your computer and use it in GitHub Desktop.
Vue Functional Component
<script>
import { propsToClasses } from './../utils'
export default {
functional: true,
props: {
destructive: Boolean,
external: Boolean,
fullwidth: Boolean,
plain: Boolean,
primary: Boolean,
size: String,
url: String
},
render (h, { data, props, children }) {
// Set base class.
const baseClass = 'c-button'
// Get classes.
let classes = propsToClasses(baseClass, props)
// Set HTML element.
const element = props.url ? 'a' : 'button'
// Set empty attributes.
data.attrs = {}
// Add href if needed.
data.attrs.href = props.url ? props.url : false
// Add `size` class if needed.
classes +=
props.size && (props.size === 'large' || props.size === 'small')
? ` ${baseClass}--${props.size}`
: ''
// Set classes
data.class = classes
// Add click handler.
data.on = {
click: function (event) {
if (event.target !== event.currentTarget) return
event.target.blur()
}
}
// Render element.
return h(element, {
...data
}, children)
}
}
</script>
// Used to change camelCase props to kebab-case classes
import decamelize from 'decamelize'
export function propsToClasses (base, props) {
return Object.keys(props).reduce((classes, key) => {
if (props[key] && typeof props[key] === 'boolean') {
classes += ` ${base}--${decamelize(key, '-')}`
}
return classes
}, base)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment