feat: create the skill card component
This commit is contained in:
parent
52b45583c6
commit
890271086a
|
@ -0,0 +1,125 @@
|
||||||
|
<template>
|
||||||
|
<div class='skill-card' ref='root' :data-active='active ? "1" : "0"' @click='onClick()'>
|
||||||
|
<img class='icon' :src='icon()' />
|
||||||
|
<span class='name'>
|
||||||
|
<span v-html='name()'></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||||
|
import { tID, Skills } from '@/model/skills';
|
||||||
|
|
||||||
|
@Component({})
|
||||||
|
export default class SkillCard extends Vue {
|
||||||
|
// id of the skill to display
|
||||||
|
@Prop(Number) readonly id: tID|undefined;
|
||||||
|
|
||||||
|
// undefined -> automatic size
|
||||||
|
// value -> fixed size applied (valid css value with unit)
|
||||||
|
@Prop(String) readonly width: string|undefined;
|
||||||
|
|
||||||
|
// whether it has the active style
|
||||||
|
@Prop(Boolean) active: boolean|undefined;
|
||||||
|
|
||||||
|
protected mounted() {
|
||||||
|
if( this.width == undefined ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const el = this.$refs.root as HTMLElement;
|
||||||
|
el.style.width = this.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected icon(): string {
|
||||||
|
let icon: string|null = null;
|
||||||
|
if( this.id != undefined ){
|
||||||
|
icon = Skills[this.id].icon;
|
||||||
|
}
|
||||||
|
if( icon == null ){
|
||||||
|
return require('../assets/skills/unknown.svg');
|
||||||
|
}
|
||||||
|
return require(`../assets/${icon}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected name(): string {
|
||||||
|
if( this.id != undefined ){
|
||||||
|
return Skills[this.id].name!;
|
||||||
|
}
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
private onClick(e: MouseEvent) {
|
||||||
|
this.$emit('pick', !this.active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
$height: 2em;
|
||||||
|
$active-border: .2em;
|
||||||
|
|
||||||
|
.skill-card {
|
||||||
|
display: inline-flex;
|
||||||
|
position: relative;
|
||||||
|
width: auto;
|
||||||
|
height: $height;
|
||||||
|
|
||||||
|
font-size: 1.2rem;
|
||||||
|
|
||||||
|
background: #2a2e36;
|
||||||
|
border-radius: .3rem / .3rem;
|
||||||
|
transition: background .1s ease-in-out;
|
||||||
|
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
height: $height;
|
||||||
|
width: $height;
|
||||||
|
|
||||||
|
background: #323945;
|
||||||
|
border-radius: .3rem / .3rem;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
|
||||||
|
transition: background .1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
height: $height;
|
||||||
|
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 0 .6em;
|
||||||
|
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
border-left: $active-border solid transparent;
|
||||||
|
transition: border-color .1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-active="1"]{
|
||||||
|
background: #444952;
|
||||||
|
.icon {
|
||||||
|
background: #3c4150;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
border-color: #41b883;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue