SelectButton.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <div class='select_button'>
  3. <div class='button' @click='toggleMenu' v-if='options.length'>
  4. {{options[selectedIndex].name}}
  5. <span class='button__icon fa fa-fw' :class='[hideMenu ? "fa-caret-down" : "fa-caret-up"]'></span>
  6. </div>
  7. <div class='button' v-else>
  8. No options
  9. </div>
  10. <div class='select_button__options' :class='{"select_button__options--hidden": hideMenu}'>
  11. <div
  12. v-for='(option, index) in options'
  13. @click='select(index, option.disabled)'
  14. class='select_button__option'
  15. :class='{"select_button__option--disabled": option.disabled}'
  16. >
  17. {{option.name}}
  18. </div>
  19. </div>
  20. </div>
  21. </template>
  22. <script>
  23. export default {
  24. name: 'SelectButton',
  25. props: ['options', 'value', 'name'],
  26. methods: {
  27. toggleMenu () {
  28. this.hideMenu = !this.hideMenu;
  29. },
  30. select (index, disabled) {
  31. if(disabled) return;
  32. this.selectedIndex = index;
  33. this.hideMenu = true;
  34. this.$emit('input', this.options[index].value);
  35. },
  36. getIndexFromValue () {
  37. var index = 0;
  38. var self = this;
  39. if(this.value !== null) {
  40. this.options.forEach((option, i) => {
  41. if(option.value === self.value) {
  42. index = i;
  43. }
  44. })
  45. }
  46. return index;
  47. }
  48. },
  49. data () {
  50. return {
  51. selectedIndex: this.getIndexFromValue(),
  52. hideMenu: true
  53. }
  54. },
  55. watch: {
  56. value () {
  57. this.selectedIndex = this.getIndexFromValue();
  58. }
  59. }
  60. }
  61. </script>
  62. <style lang='scss' scoped>
  63. @import '../assets/scss/variables.scss';
  64. .select_button {
  65. display: inline-block;
  66. @at-root #{&}__options {
  67. position: absolute;
  68. z-index: 1;
  69. overflow: hidden;
  70. background-color: #fff;
  71. width: 15rem;
  72. border: 0.125rem solid $color__gray--primary;
  73. margin-top: -0.125rem;
  74. max-height: 20rem;
  75. box-shadow: 0 0.12rem 0.125rem rgba(0,0,0,0.125);
  76. transition: max-height 0.4s ease-out;
  77. @at-root #{&}--hidden {
  78. max-height: 0;
  79. box-shadow: none;
  80. border-color: transparent;
  81. background-color: transparent;
  82. transition: max-height 0.2s ease-out, box-shadow 0.2s, border-color 0s ease-in 0.19s, background-color 0s ease-in 0.19s;
  83. }
  84. }
  85. @at-root #{&}__option {
  86. padding: 0.25rem 0.5rem;
  87. transition: background-color 0.2s;
  88. cursor: default;
  89. &:hover {
  90. background-color: $color__lightgray--primary;
  91. }
  92. &:active {
  93. background-color: $color__lightgray--darker;
  94. }
  95. @at-root #{&}--disabled {
  96. color: $color__gray--darkest;
  97. pointer-events: none;
  98. }
  99. }
  100. }
  101. </style>