Instantly share code, notes, and snippets.
Created
March 18, 2019 20:03
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save iErik/ac726b5f7d904f1f3045099d852d3e03 to your computer and use it in GitHub Desktop.
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
| <template> | |
| <c-input-container v-bind="$attrs" class="c-radio-button"> | |
| <p v-if="description" class="text">{{ description }}</p> | |
| <div class="inner" :style="rows"> | |
| <div | |
| class="option" | |
| v-for="(option, index) in options" | |
| :key="index" | |
| @click="emitInput" | |
| > | |
| <div class="borderline"> | |
| <div :class="isSelected(option)"/> | |
| </div> | |
| <p class="label">{{ getLabel(option) }}</p> | |
| </div> | |
| </div> | |
| </c-input-container> | |
| </template> | |
| <script> | |
| import CInputContainer from '../CInputContainer' | |
| /** | |
| * A radio button component. When an option is selected, it emits an 'input' | |
| * event with the chosen option. | |
| */ | |
| export default { | |
| name: 'CRadioButton', | |
| components: { CInputContainer }, | |
| props: { | |
| /** | |
| * Array of strings or objects | |
| */ | |
| options: { | |
| type: Array, | |
| default: () => ([]) | |
| }, | |
| /** | |
| * If `options` is an array of objects, CRadioButon will use this prop | |
| * to compare the currently selected item. | |
| */ | |
| trackBy: { | |
| type: String, | |
| default: '' | |
| }, | |
| /** | |
| * If `options` is an array of objects, CRadioButton will use this prop | |
| * to get the label of the option/value to be displayed for the user. | |
| */ | |
| displayBy: { | |
| type: String, | |
| default: '' | |
| }, | |
| /** | |
| * Number of columns | |
| */ | |
| columns: { | |
| type: Number, | |
| default: 1 | |
| }, | |
| /** | |
| * Selected option's value | |
| */ | |
| value: { | |
| type: [Object, String, Boolean], | |
| default: '' | |
| }, | |
| /** | |
| * Radio button description | |
| */ | |
| description: { | |
| type: String, | |
| default: '' | |
| } | |
| }, | |
| computed: { | |
| rows() { | |
| return 'grid-template-rows: repeat(' + Math.ceil(this.options.length/this.columns) + ', 1fr);' | |
| }, | |
| }, | |
| methods: { | |
| isSelected(option) { | |
| if (this.trackBy && option instanceof Object) { | |
| return this.value instanceof Object | |
| ? this.value[this.trackBy] === option[this.trackBy] ? 'selected' : 'unselected' | |
| : this.value === option[this.trackBy] ? 'selected' : 'unselected' | |
| } | |
| return this.value === option | |
| ? 'selected' | |
| : 'unselected' | |
| }, | |
| emitInput (option) { | |
| const value = this.trackBy && option instanceof Object && !(this.value instanceof Object) | |
| ? option[this.trackBy] | |
| : option | |
| this.$emit('input', value) | |
| }, | |
| getLabel(option) { | |
| if (this.displayBy && option instanceof Object) { | |
| return option[this.displayBy] | |
| } | |
| return option | |
| } | |
| } | |
| } | |
| </script> | |
| <style lang="scss"> | |
| .c-radio-button { | |
| & > .text { margin-bottom: 20px; } | |
| & > .inner { | |
| display: grid; | |
| grid-auto-flow: column; | |
| grid-auto-columns: 1fr; | |
| grid-column-gap: 30px; | |
| grid-row-gap: 15px; | |
| justify-content: space-around; | |
| & > .option { | |
| display: flex; | |
| flex-flow: row; | |
| align-items: center; | |
| & > .borderline { | |
| display: flex; | |
| flex-flow: row; | |
| align-items: center; | |
| justify-content: center; | |
| min-width: 25px; | |
| max-width: 25px; | |
| min-height: 25px; | |
| max-height: 25px; | |
| border: 1px solid $base-border-color; | |
| border-radius: 50%; | |
| background-color: white; | |
| & > .selected { | |
| width: 15px; | |
| height: 15px; | |
| border-radius: 50%; | |
| background-color: map-get($disabled-color-map, dark); | |
| transition: width .4s, height .4s; | |
| transition-timing-function: cubic-bezier(.45,1.8,.5,.75); | |
| } | |
| & > .unselected { | |
| width: 0; | |
| height: 0; | |
| } | |
| } | |
| & > .label { | |
| vertical-align: middle; | |
| margin-left: 10px; | |
| font-size: 14px; | |
| color: map-get($disabled-color-map, dark); | |
| } | |
| } | |
| } | |
| & > .jumbo-validation { display: none; } | |
| } | |
| </style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment