dashboard: use webpack for builds; use tailwindcss instead of bulma; all sorts of tweaks
This commit is contained in:
parent
028786d348
commit
577500af92
42 changed files with 4813 additions and 3174 deletions
119
dashboard/src/components/Expandable.vue
Normal file
119
dashboard/src/components/Expandable.vue
Normal file
|
@ -0,0 +1,119 @@
|
|||
<template>
|
||||
<div class="expandable mb-4 bg-gray-800 border border-gray-600 rounded overflow-hidden" ref="root" v-bind:class="{'shadow-xl': isOpen}">
|
||||
<div role="button" class="title p-2" v-on:click="toggle">
|
||||
<chevron-down class="icon" v-bind:class="{'icon-open': isOpen}" />
|
||||
<span class="title-text"><slot name="title"></slot></span>
|
||||
</div>
|
||||
<div class="content border-t border-gray-700" ref="content">
|
||||
<div class="p-4 pb-0">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:root {
|
||||
--animation-time: 400ms;
|
||||
--target-height: auto;
|
||||
}
|
||||
|
||||
.expandable {
|
||||
transition: box-shadow var(--animation-time);
|
||||
}
|
||||
|
||||
.title {
|
||||
&:hover {
|
||||
& .title-text {
|
||||
@apply underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
transition: transform var(--animation-time);
|
||||
transform-origin: 50% 60%;
|
||||
}
|
||||
|
||||
.icon-open {
|
||||
transform: rotate(179deg);
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@keyframes open {
|
||||
0% { height: 0; }
|
||||
100% { height: var(--target-height); }
|
||||
}
|
||||
|
||||
@keyframes close {
|
||||
100% { height: 0; }
|
||||
0% { height: var(--target-height); }
|
||||
}
|
||||
|
||||
.opening {
|
||||
animation: open var(--animation-time) ease-in-out;
|
||||
}
|
||||
|
||||
.closing {
|
||||
animation: close var(--animation-time) ease-in-out;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="ts">
|
||||
import ChevronDown from 'vue-material-design-icons/ChevronDown.vue';
|
||||
|
||||
const ANIMATION_TIME = 400;
|
||||
|
||||
export default {
|
||||
components: { ChevronDown },
|
||||
mounted() {
|
||||
this.$refs.root.style.setProperty('--animation-time', `${ANIMATION_TIME}ms`);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isOpen: false,
|
||||
animating: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
if (this.isOpen) this.close();
|
||||
else this.open();
|
||||
},
|
||||
open() {
|
||||
if (this.animating) return;
|
||||
this.animating = true;
|
||||
this.isOpen = true;
|
||||
|
||||
this.$refs.content.style.display = 'block';
|
||||
const targetHeight = this.$refs.content.clientHeight;
|
||||
this.$refs.content.style.setProperty('--target-height', `${targetHeight}px`);
|
||||
this.$refs.content.classList.add('opening');
|
||||
|
||||
setTimeout(() => {
|
||||
this.$refs.content.classList.remove('opening');
|
||||
this.animating = false;
|
||||
}, ANIMATION_TIME);
|
||||
},
|
||||
close() {
|
||||
if (this.animating) return;
|
||||
this.animating = true;
|
||||
this.isOpen = false;
|
||||
|
||||
const targetHeight = this.$refs.content.clientHeight;
|
||||
this.$refs.content.style.setProperty('--target-height', `${targetHeight}px`);
|
||||
this.$refs.content.classList.add('closing');
|
||||
|
||||
setTimeout(() => {
|
||||
this.$refs.content.classList.remove('closing');
|
||||
this.$refs.content.style.display = 'none';
|
||||
this.animating = false;
|
||||
}, ANIMATION_TIME);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue