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