Skip to content

Commit 9e92213

Browse files
committed
stable first commit
1 parent f215d10 commit 9e92213

File tree

9 files changed

+296
-70
lines changed

9 files changed

+296
-70
lines changed

Diff for: LICENSE.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Bora Kucukkara
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: README.md

+45
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
11
# vue-user-card
22

3+
Simple user card component
4+
5+
![vue-user-avatar.png](src%2Fassets%2Fvue-user-avatar.png)
6+
7+
![vue-user-card.gif](src%2Fassets%2Fvue-user-card.gif)
8+
9+
Easily implement into your projects, just copy "user-card.vue" into your project.
10+
11+
External props passed to the component:
12+
13+
```json
14+
data() {
15+
return{
16+
user: {
17+
name:"Bora Kucukkara",
18+
country: "Turkey",
19+
title: "UI Designer / Front-end Developer",
20+
tags: ["UI/UX", "HTML", "CSS", "javaScript", "VueJS", "SASS", "JSON", "GIT"],
21+
avatar: "https://i.pravatar.cc/"
22+
}
23+
}
24+
}
25+
26+
<template >
27+
<user-card :user-data="user" />
28+
</template>
29+
30+
props: {
31+
userData: {
32+
type: Object,
33+
}
34+
},
35+
36+
UI Config CSS:
37+
/* CARD SETTINGS */
38+
--avatar-size: 7rem;
39+
--user-card-size: 20rem;
40+
--user-card-height: 30rem;
41+
--card-bg: #2d2d2d;
42+
--card-font-color:#cae5e5;
43+
--card-accent-color: coral;
44+
--card-radius: 1.5rem;
45+
46+
```
47+
348
## Project setup
449
```
550
npm install

Diff for: src/App.vue

+30-12
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,44 @@
1-
<template>
2-
<img alt="Vue logo" src="./assets/logo.png">
3-
<HelloWorld msg="Welcome to Your Vue.js App"/>
1+
<template >
2+
<user-card :user-data="user" />
43
</template>
54

65
<script>
7-
import HelloWorld from './components/HelloWorld.vue'
6+
import userCard from './components/user-card.vue'
87
98
export default {
109
name: 'App',
1110
components: {
12-
HelloWorld
11+
userCard
12+
},
13+
data() {
14+
return{
15+
user: {
16+
name:"Bora Kucukkara",
17+
country: "Turkey",
18+
title: "UI Designer / Front-end Developer",
19+
tags: ["UI/UX", "HTML", "CSS", "javaScript", "VueJS", "SASS", "JSON", "GIT"],
20+
avatar: "https://i.pravatar.cc/"
21+
}
22+
}
1323
}
1424
}
1525
</script>
1626

1727
<style>
18-
#app {
19-
font-family: Avenir, Helvetica, Arial, sans-serif;
20-
-webkit-font-smoothing: antialiased;
21-
-moz-osx-font-smoothing: grayscale;
22-
text-align: center;
23-
color: #2c3e50;
24-
margin-top: 60px;
28+
/* RESET */
29+
*,
30+
*::before,
31+
*::after {
32+
box-sizing: border-box;
33+
}
34+
35+
body {
36+
margin:0;
37+
font-family: system-ui;
38+
display:flex;
39+
align-items: center;
40+
justify-content: center;
41+
width: 100vw;
42+
height: 100vh;
2543
}
2644
</style>

Diff for: src/assets/avatar.jpg

111 KB
Loading

Diff for: src/assets/logo.png

-6.69 KB
Binary file not shown.

Diff for: src/assets/vue-user-avatar.png

300 KB
Loading

Diff for: src/assets/vue-user-card.gif

1.28 MB
Loading

Diff for: src/components/HelloWorld.vue

-58
This file was deleted.

Diff for: src/components/user-card.vue

+200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<template>
2+
<div class="user-card" :class="{'toggle-index': toggle}"
3+
tabindex="1" @focus="togglePop(true)" @focusout="togglePop(false)">
4+
<div class="user-card_avatar" @mouseover="togglePop(true)">
5+
<img :src="userData.avatar" :class="{'user-card_avatar_border': toggle}" alt="user-avatar" />
6+
</div>
7+
<div class="user-card_popup" :class="{'toggle-show': toggle, 'toggle-hide': !toggle, 'toggle-reset': firstLoad}">
8+
<div class="user-card_avatar_bokeh">
9+
<img :src="userData.avatar" alt="user-avatar" />
10+
</div>
11+
<div class="user-card_content" @mouseleave="togglePop(false)" >
12+
<p class="user-card_badge">PRO</p>
13+
<h1>{{userData.name}}</h1>
14+
<span>{{userData.country}}</span>
15+
<span>{{userData.title}}</span>
16+
<div class="user-card_tags" >
17+
<span v-for="(tag,index) in userData.tags" :key="index">{{tag}}</span>
18+
</div>
19+
<button class="user-card_cta">Follow</button>
20+
</div>
21+
</div>
22+
</div>
23+
</template>
24+
25+
<script>
26+
export default {
27+
data() {
28+
return {
29+
toggle: false,
30+
firstLoad: true
31+
}
32+
},
33+
props: {
34+
userData: {
35+
type: Object,
36+
}
37+
},
38+
methods: {
39+
togglePop(event) {
40+
this.firstLoad = false
41+
this.toggle = event;
42+
}
43+
}
44+
}
45+
</script>
46+
47+
<style scoped>
48+
.user-card {
49+
/* CARD SETTINGS */
50+
--avatar-size: 7rem;
51+
--user-card-size: 20rem;
52+
--user-card-height: 30rem;
53+
--card-bg: #2d2d2d;
54+
--card-font-color:#cae5e5;
55+
--card-accent-color: coral;
56+
--card-radius: 1.5rem;
57+
58+
position:relative;
59+
width: var(--avatar-size);
60+
height: var(--avatar-size);
61+
display: inline-block;
62+
}
63+
.user-card_popup {
64+
position: absolute;
65+
overflow: hidden;
66+
color: var(--card-font-color);
67+
width:var(--user-card-size);
68+
height: var(--user-card-height);
69+
top:calc(var(--avatar-size) / -2 + -2rem);
70+
left:calc((var(--avatar-size) - var(--user-card-size)) / 2);
71+
background: var(--card-bg);
72+
z-index: 0;
73+
border-radius: var(--card-radius);
74+
box-shadow: rgb(55, 56, 56) 0 1rem 2rem -.5rem;
75+
}
76+
.user-card_avatar {
77+
width: inherit;
78+
height: inherit;
79+
}
80+
.user-card_avatar img {
81+
position: absolute;
82+
width: inherit;
83+
height: inherit;
84+
object-fit: cover;
85+
border-radius: 50%;
86+
z-index: 3;
87+
transition: all .2s;
88+
}
89+
.user-card_avatar_border {
90+
box-shadow: 0 0 0 .3rem var(--card-bg);
91+
}
92+
.user-card_avatar_bokeh {
93+
width: var(--user-card-size);
94+
height: calc(var(--avatar-size) + 2rem);
95+
overflow: hidden;
96+
position: relative;
97+
display: flex;
98+
align-items: center;
99+
justify-content: center;
100+
}
101+
.user-card_avatar_bokeh:after {
102+
content:"";
103+
backdrop-filter: blur(.3rem);
104+
background: #00000022;
105+
-webkit-backdrop-filter: blur(.3rem);
106+
position: absolute;
107+
z-index: 4;
108+
inset: 0;
109+
}
110+
.user-card_avatar_bokeh img {
111+
position: absolute;
112+
width: calc(var(--user-card-size) * 1.2); /* bokeh image zoom */
113+
}
114+
.user-card_badge {
115+
position: absolute;
116+
top: 0;
117+
right: 0;
118+
margin:1rem;
119+
background: var(--card-accent-color);
120+
padding: .3rem;
121+
border-radius: .4rem;
122+
font-size: .8rem;
123+
color:#fff;
124+
z-index: 4;
125+
}
126+
/* CARD CONTENT */
127+
.user-card_content {
128+
padding: calc(var(--avatar-size) * 1.8 ) 1rem 0rem 1rem;
129+
display: flex;
130+
flex-direction: column;
131+
align-items: center;
132+
justify-content: space-between;
133+
position: absolute;
134+
inset: 0;
135+
z-index: 4;
136+
}
137+
.user-card_content h1 {font-size: 1.5rem; font-weight: normal}
138+
.user-card_tags {
139+
display: flex;
140+
flex-wrap: wrap;
141+
align-items: center;
142+
justify-content: center;
143+
gap:.5rem;
144+
margin: 1rem 0;
145+
}
146+
.user-card_tags span {
147+
color:#777;
148+
padding: .2rem .3rem;
149+
border: 1px solid #777;
150+
border-radius: .3rem;
151+
font-size: .8rem;
152+
}
153+
.user-card_cta {
154+
width: calc(var(--user-card-size) - 2rem);
155+
margin: 1rem;
156+
padding: .5rem 1rem;
157+
background: var(--card-accent-color);
158+
font-size: 1rem;
159+
color:#fff;
160+
border-radius: 1rem;
161+
border:none;
162+
}
163+
/* TOGGLE */
164+
.toggle-show {
165+
opacity: 0;
166+
animation: fade-in .5s ease forwards;
167+
}
168+
.toggle-hide {
169+
opacity: 0;
170+
animation: fade-out .5s ease forwards;
171+
}
172+
.toggle-index {
173+
z-index: 99;
174+
}
175+
.toggle-reset {
176+
display: none;
177+
}
178+
@keyframes fade-in {
179+
0% {
180+
opacity: 1;
181+
clip-path: circle(8% at 50% 27%);
182+
}
183+
1%{display: block}
184+
100% {
185+
opacity:1;
186+
clip-path: circle(100% at 50% 50%);
187+
}
188+
}
189+
@keyframes fade-out {
190+
0% {
191+
opacity:1;
192+
clip-path: circle(100% at 50% 50%);
193+
}
194+
99% {
195+
opacity:1;
196+
clip-path: circle(8% at 50% 27%);
197+
}
198+
100% {display: none}
199+
}
200+
</style>

0 commit comments

Comments
 (0)