all files / src/radio/ index.vue

100% Statements 7/7
100% Branches 2/2
100% Functions 4/4
100% Lines 7/7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143                                                                                                                                                                                                                                                                               
<template>
  <div class="am-radio-wrapper" :class="classes" @click="onClick">
    <div class="am-radio">
      <input type="radio" v-bind="attrs">
    </div>
    <label class="am-radio-label">
      <slot></slot>
    </label>
  </div>
</template>
<script>
  export default {
    name: "amRadio",
    model: {
      prop: "model",
      event: "change"
    },
    props: {
      value: {
        type: [String, Number, Boolean]
      },
      model: {
        type: [String, Number, Boolean]
      },
      name: {
        type: String
      },
      disabled: {
        type: Boolean,
        default: false
      }
    },
    computed: {
      attrs() {
        const attrs = {
          name: this.name,
          disabled: this.disabled
        };
        return attrs;
      },
      isSelected() {
        return this.model === this.value;
      },
      classes() {
        return {
          "am-radio-disabled": this.disabled,
          "am-radio-checked": this.isSelected
        };
      }
    },
    methods: {
      onClick() {
        if (this.disabled) {
          return false;
        }
        this.$emit("change", this.value);
      }
    }
  };
</script>
<style lang="scss" scoped>
  @import "var";
  .am-radio {
    width: 14px;
    height: 14px;
    background-color: #fff;
    border-radius: 50%;
    transition: border-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46),
    background-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46);
    border: 1px solid $border-color;
    box-sizing: border-box;
    position: relative;
    z-index: 1;
    &:after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      width: 4px;
      height: 4px;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      background: transparent;
      transition: background 0.15s ease-in 0.05s;
    }
    &-wrapper {
      display: inline-flex;
      justify-content: center;
      align-items: center;
      vertical-align: middle;
      &.am-radio-checked {
        .am-radio {
          background-color: $blue;
          border-color: $blue;
        }
        &:not(.am-radio-disabled) {
          .am-radio {
            &:after {
              background: #fff;
            }
          }
        }
      }
      &.am-radio-disabled {
        cursor: not-allowed;
        .am-radio {
          border-color: rgba($border-color, 0.6);
          background: $border-active-bg;
        }
        &.am-radio-checked {
          .am-radio {
            &:after {
              background: $light-color;
            }
          }
        }
      }
    }
    input[type="radio"] {
      position: absolute;
      width: 100%;
      height: 100%;
      opacity: 0;
      border: 0;
      margin: 0;
      padding: 0;
      cursor: pointer;
      &:disabled {
        cursor: not-allowed;
      }
    }
    &-wrapper:not(.am-radio-disabled) {
      .am-radio-label {
        cursor: pointer;
      }
    }
    &-label {
      padding: 0 0.5em;
      cursor: not-allowed;
    }
  }
</style>