All files / components/Form/ImageUnsplash ImageUnsplash.vue

10% Statements 1/10
0% Branches 0/2
0% Functions 0/5
10% Lines 1/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                                                              1x                                                                                                                                                                                                          
<template>
  <div :class="containerClass" class="image-unsplash">
    <label for="search-unsplash">{{ label }}</label>
    <!-- Loading placeholder -->
    <ImageSkeleton v-if="loading" />
 
    <!-- Image preview -->
    <img
      class="preview"
      v-if="!loading && !error && preview"
      :src="preview.urls.regular"
      :alt="preview.alt_description"
    />
 
    <!-- API error messages -->
    <p class="error" v-if="error">{{ error }}</p>
 
    <!-- Search input -->
    <div class="search-box">
      <input
        id="search-unsplash"
        type="search"
        :placeholder="placeholder"
        @change="handleSearch"
        :required="required"
      />
    </div>
  </div>
</template>
 
<script>
import { mapState } from "vuex";
 
export default {
  name: "ImageUnsplash",
  components: {
    ImageSkeleton: () => import("./ImageSkeleton")
  },
  props: {
    containerClass: {
      type: String,
      default: null
    },
    label: {
      type: String,
      default: "Image (from Unsplash)"
    },
    placeholder: {
      type: String,
      default: "Type anything !"
    },
    required: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      error: null,
      preview: null
    };
  },
  computed: {
    ...mapState(["loading"])
  },
  methods: {
    async handleSearch(e) {
      this.error = null;
      if (e.target.value != "") {
        await this.$store
          .dispatch("getImageFromUnsplash", e.target.value)
          .then(res => {
            this.preview = res;
            this.$emit("getValue", res.urls.regular);
          })
          .catch(err => (this.error = err.message));
      } else this.preview = null;
    }
  }
};
</script>
 
<style scoped lang="less">
.image-unsplash {
  .preview,
  .skeleton {
    margin-bottom: 1rem;
  }
 
  .preview {
    width: 100%;
    object-fit: scale-down;
    height: 180px;
  }
 
  .error {
    color: @text-error;
    text-align: center;
  }
 
  .search-box {
    position: relative;
    z-index: 0;
 
    &:focus-within::after {
      opacity: 1;
    }
 
    &::after {
      content: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 350.439 350.439' style='enable-background:new 0 0 350.439 350.439;' xml:space='preserve'%3E%3Cg%3E%3Cpath d='M312.856,36.464H202.507c-4.87,0-8.83,3.961-8.83,8.832v138.422H52.371c-4.87,0-8.832,3.973-8.832,8.843v108.023 c0,4.87,3.961,8.831,8.832,8.831l260.474-0.071c4.873,0,8.838-3.962,8.838-8.843l0.011-255.211 C321.701,40.425,317.737,36.464,312.856,36.464z M175.216,253.617c0,5.724-4.635,10.353-10.356,10.353h-57.814 c-0.392,0-0.775-0.022-1.155-0.065v0.887l8.294,21.002c0.281,0.7,0.057,1.51-0.551,1.965c-0.301,0.229-0.658,0.344-1.013,0.344 c-0.364,0-0.722-0.12-1.025-0.355l-41.251-31.715c-0.416-0.318-0.657-0.816-0.657-1.33c0-0.531,0.241-1.023,0.657-1.345 l41.251-31.712c0.6-0.463,1.433-0.463,2.038-0.011c0.603,0.459,0.827,1.258,0.551,1.958l-7.776,19.694 c0.21-0.011,0.418-0.033,0.637-0.033h47.462v-34.715c0-5.724,4.637-10.353,10.352-10.353c5.721,0,10.356,4.629,10.356,10.353 V253.617z M332.215,7.41H174.623c-10.062,0-18.221,8.159-18.221,18.225v126.679H18.223C8.159,152.314,0,160.479,0,170.541v154.267 c0,10.063,8.159,18.222,18.223,18.222h157.588c0.346,0,0.667-0.087,1.008-0.099h155.375c10.065,0,18.228-8.164,18.228-18.232 V180.074c0-0.066,0.018-0.121,0.018-0.176V25.635C350.439,15.569,342.273,7.41,332.215,7.41z M329.535,300.512 c0,9.205-7.483,16.69-16.69,16.69H204.052c-0.078,0.043-0.383,0.076-0.705,0.076H52.371c-9.202,0-16.688-7.485-16.688-16.689 V192.571c0-9.209,7.485-16.689,16.688-16.689h133.453V45.295c0-9.201,7.485-16.687,16.684-16.687h110.349 c9.204,0,16.689,7.486,16.689,16.687L329.535,300.512z'/%3E%3C/g%3E%3C/svg%3E");
      position: absolute;
      z-index: 1;
      top: 50%;
      right: 0.5rem;
      width: 24px;
      height: 24px;
      transform: translateY(-50%);
      opacity: 0.4;
    }
 
    [type="search"] {
      padding-right: 2.35rem;
      border: none;
      background-color: lighten(#cecece, 15%);
    }
  }
 
  [type="file"] {
    border: none;
  }
}
</style>