Add Skeleton for GridItem and Image + Refactor components architecture with more modularity + Delete Fruit feature
This commit is contained in:
125
src/components/Form/ImageUnsplash/ImageUnsplash.vue
Normal file
125
src/components/Form/ImageUnsplash/ImageUnsplash.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div 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" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import ImageSkeleton from "./ImageSkeleton";
|
||||
|
||||
export default {
|
||||
name: "ImageUnsplash",
|
||||
components: {
|
||||
ImageSkeleton
|
||||
},
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: "Image (from Unsplash)"
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "Type anything !"
|
||||
}
|
||||
},
|
||||
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 {
|
||||
label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.preview,
|
||||
.skeleton {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.preview {
|
||||
width: 100%;
|
||||
object-fit: scale-down;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #d63031;
|
||||
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.3rem;
|
||||
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>
|
||||
Reference in New Issue
Block a user