aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/AncestryBar.vue18
-rw-r--r--src/components/HelpModal.vue10
-rw-r--r--src/components/SCollapsible.vue28
-rw-r--r--src/components/SettingsModal.vue10
-rw-r--r--src/components/Tile.vue100
-rw-r--r--src/components/TileInfoModal.vue2
-rw-r--r--src/components/TutorialPane.vue36
7 files changed, 110 insertions, 94 deletions
diff --git a/src/components/AncestryBar.vue b/src/components/AncestryBar.vue
index e7ba8a5..fcf9933 100644
--- a/src/components/AncestryBar.vue
+++ b/src/components/AncestryBar.vue
@@ -51,15 +51,6 @@ export default defineComponent({
};
},
},
- watch: {
- // Used to scroll to end of bar upon node/screen changes
- nodes(){
- this.$nextTick(() => this.scrollToEnd());
- },
- vert(){
- this.$nextTick(() => this.scrollToEnd());
- },
- },
methods: {
// Click events
onTileClick(node: LayoutNode){
@@ -83,6 +74,15 @@ export default defineComponent({
}
},
},
+ watch: {
+ // Used to scroll to end of bar upon node/screen changes
+ nodes(){
+ this.$nextTick(() => this.scrollToEnd());
+ },
+ vert(){
+ this.$nextTick(() => this.scrollToEnd());
+ },
+ },
mounted(){
this.scrollToEnd();
},
diff --git a/src/components/HelpModal.vue b/src/components/HelpModal.vue
index 9f7ff0b..3e30c9f 100644
--- a/src/components/HelpModal.vue
+++ b/src/components/HelpModal.vue
@@ -9,7 +9,7 @@
<s-collapsible :class="scClasses">
<template #summary="slotProps">
<div :class="scSummaryClasses">
- <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/>
+ <down-icon :class="slotProps.open ? downIconExpandedClasses : downIconClasses"/>
What is the Tree of Life?
</div>
</template>
@@ -46,7 +46,7 @@
<s-collapsible :class="scClasses">
<template #summary="slotProps">
<div :class="scSummaryClasses">
- <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/>
+ <down-icon :class="slotProps.open ? downIconExpandedClasses : downIconClasses"/>
Visualising the Tree
</div>
</template>
@@ -110,7 +110,7 @@
<s-collapsible :class="scClasses">
<template #summary="slotProps">
<div :class="scSummaryClasses">
- <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/>
+ <down-icon :class="slotProps.open ? downIconExpandedClasses : downIconClasses"/>
Using Tilo
</div>
</template>
@@ -228,7 +228,7 @@
<s-collapsible :class="scClasses">
<template #summary="slotProps">
<div :class="scSummaryClasses">
- <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/>
+ <down-icon :class="slotProps.open ? downIconExpandedClasses : downIconClasses"/>
Data Sources
</div>
</template>
@@ -336,7 +336,7 @@
<s-collapsible :class="scClasses">
<template #summary="slotProps">
<div :class="scSummaryClasses">
- <down-icon :class="slotProps.collapsed ? downIconClasses : downIconExpandedClasses"/>
+ <down-icon :class="slotProps.open ? downIconExpandedClasses : downIconClasses"/>
Project Information
</div>
</template>
diff --git a/src/components/SCollapsible.vue b/src/components/SCollapsible.vue
index 4570ee0..5b49c8c 100644
--- a/src/components/SCollapsible.vue
+++ b/src/components/SCollapsible.vue
@@ -1,10 +1,10 @@
<template>
<div :style="styles">
- <div class="hover:cursor-pointer" @click="collapsed = !collapsed">
- <slot name="summary" :collapsed="collapsed">(Summary)</slot>
+ <div class="hover:cursor-pointer" @click="onClick">
+ <slot name="summary" :open="open">(Summary)</slot>
</div>
<transition @enter="onEnter" @after-enter="onAfterEnter" @leave="onLeave" @before-leave="onBeforeLeave">
- <div v-show="!collapsed" :style="contentStyles" class="max-h-0" ref="content">
+ <div v-show="open" :style="contentStyles" class="max-h-0" ref="content">
<slot name="content">(Content)</slot>
</div>
</transition>
@@ -15,21 +15,24 @@
import {defineComponent, PropType} from 'vue';
export default defineComponent({
+ props: {
+ modelValue: {type: Boolean, default: false}, // For using v-model on the component
+ },
data(){
return {
- collapsed: true,
+ open: false,
};
},
computed: {
styles(): Record<string,string> {
return {
- overflow: this.collapsed ? 'hidden' : 'visible',
+ overflow: this.open ? 'visible' : 'hidden',
};
},
contentStyles(): Record<string,string> {
return {
overflow: 'hidden',
- opacity: this.collapsed ? '0' : '1',
+ opacity: this.open ? '1' : '0',
transitionProperty: 'max-height, opacity',
transitionDuration: '300ms',
transitionTimingFunction: 'ease-in-out',
@@ -37,6 +40,13 @@ export default defineComponent({
},
},
methods: {
+ onClick(evt: Event){
+ this.open = !this.open;
+ this.$emit('update:modelValue', this.open);
+ if (this.open){
+ this.$emit('open');
+ }
+ },
onEnter(el: HTMLDivElement){
el.style.maxHeight = el.scrollHeight + 'px';
},
@@ -52,5 +62,11 @@ export default defineComponent({
el.style.maxHeight = '0';
},
},
+ watch: {
+ modelValue(newVal, oldVal){
+ this.open = newVal;
+ },
+ },
+ emits: ['update:modelValue', 'open', ],
});
</script>
diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue
index 75db34b..28db9ab 100644
--- a/src/components/SettingsModal.vue
+++ b/src/components/SettingsModal.vue
@@ -150,11 +150,6 @@ export default defineComponent({
return "w-fit hover:cursor-pointer hover:text-lime-600";
},
},
- watch: {
- sweepLeaves(newVal: boolean, oldVal: boolean){
- this.lytOpts.layoutType = newVal ? 'sweep' : 'rect';
- },
- },
methods: {
onClose(evt: Event){
if (evt.target == this.$el || (this.$refs.closeIcon as typeof CloseIcon).$el.contains(evt.target)){
@@ -231,6 +226,11 @@ export default defineComponent({
this.saved = false;
},
},
+ watch: {
+ sweepLeaves(newVal: boolean, oldVal: boolean){
+ this.lytOpts.layoutType = newVal ? 'sweep' : 'rect';
+ },
+ },
components: {SButton, CloseIcon, },
emits: ['close', 'setting-chg', 'reset', ],
});
diff --git a/src/components/Tile.vue b/src/components/Tile.vue
index 2be6f40..c2f2b9c 100644
--- a/src/components/Tile.vue
+++ b/src/components/Tile.vue
@@ -380,56 +380,6 @@ export default defineComponent({
return this.layoutNode.failFlag;
},
},
- watch: {
- // For setting transition state (allows external triggering, like via search and auto-mode)
- pos: {
- handler(newVal: [number, number], oldVal: [number, number]){
- let valChanged = newVal[0] != oldVal[0] || newVal[1] != oldVal[1];
- if (valChanged && this.uiOpts.transitionDuration > 100 && !this.inTransition){
- this.inTransition = true;
- setTimeout(this.onTransitionEnd, this.uiOpts.transitionDuration);
- }
- },
- deep: true,
- },
- dims: {
- handler(newVal: [number, number], oldVal: [number, number]){
- let valChanged = newVal[0] != oldVal[0] || newVal[1] != oldVal[1];
- if (valChanged && this.uiOpts.transitionDuration > 100 && !this.inTransition){
- this.inTransition = true;
- setTimeout(this.onTransitionEnd, this.uiOpts.transitionDuration);
- }
- },
- deep: true,
- },
- // For externally triggering fail animations (used by search and auto-mode)
- failFlag(){
- this.triggerAnimation(this.isLeaf ? 'animate-expand-shrink' : 'animate-shrink-expand');
- },
- // Scroll to focused child if overflownRoot
- hasFocusedChild(newVal: boolean, oldVal: boolean){
- if (newVal && this.isOverflownRoot){
- let focusedChild = this.layoutNode.children.find(n => n.hasFocus)!
- let bottomY = focusedChild.pos[1] + focusedChild.dims[1] + this.lytOpts.tileSpacing;
- let scrollTop = Math.max(0, bottomY - (this.overflownDim / 2)); // No need to manually cap at max
- this.$el.scrollTop = scrollTop;
- }
- },
- // Allow overflow temporarily after being unhidden
- hidden(newVal: boolean, oldVal: boolean){
- if (oldVal && !newVal){
- this.justUnhidden = true;
- setTimeout(() => {this.justUnhidden = false;}, this.uiOpts.transitionDuration + 100);
- }
- },
- // Used to 'flash' the tile when focused
- hasFocus(newVal: boolean, oldVal: boolean){
- if (newVal != oldVal && newVal){
- this.inFlash = true;
- setTimeout(() => {this.inFlash = false;}, this.uiOpts.transitionDuration);
- }
- },
- },
methods: {
// Click handling
onMouseDown(): void {
@@ -550,6 +500,56 @@ export default defineComponent({
this.$el.classList.add(animation);
},
},
+ watch: {
+ // For setting transition state (allows external triggering, like via search and auto-mode)
+ pos: {
+ handler(newVal: [number, number], oldVal: [number, number]){
+ let valChanged = newVal[0] != oldVal[0] || newVal[1] != oldVal[1];
+ if (valChanged && this.uiOpts.transitionDuration > 100 && !this.inTransition){
+ this.inTransition = true;
+ setTimeout(this.onTransitionEnd, this.uiOpts.transitionDuration);
+ }
+ },
+ deep: true,
+ },
+ dims: {
+ handler(newVal: [number, number], oldVal: [number, number]){
+ let valChanged = newVal[0] != oldVal[0] || newVal[1] != oldVal[1];
+ if (valChanged && this.uiOpts.transitionDuration > 100 && !this.inTransition){
+ this.inTransition = true;
+ setTimeout(this.onTransitionEnd, this.uiOpts.transitionDuration);
+ }
+ },
+ deep: true,
+ },
+ // For externally triggering fail animations (used by search and auto-mode)
+ failFlag(){
+ this.triggerAnimation(this.isLeaf ? 'animate-expand-shrink' : 'animate-shrink-expand');
+ },
+ // Scroll to focused child if overflownRoot
+ hasFocusedChild(newVal: boolean, oldVal: boolean){
+ if (newVal && this.isOverflownRoot){
+ let focusedChild = this.layoutNode.children.find(n => n.hasFocus)!
+ let bottomY = focusedChild.pos[1] + focusedChild.dims[1] + this.lytOpts.tileSpacing;
+ let scrollTop = Math.max(0, bottomY - (this.overflownDim / 2)); // No need to manually cap at max
+ this.$el.scrollTop = scrollTop;
+ }
+ },
+ // Allow overflow temporarily after being unhidden
+ hidden(newVal: boolean, oldVal: boolean){
+ if (oldVal && !newVal){
+ this.justUnhidden = true;
+ setTimeout(() => {this.justUnhidden = false;}, this.uiOpts.transitionDuration + 100);
+ }
+ },
+ // Used to 'flash' the tile when focused
+ hasFocus(newVal: boolean, oldVal: boolean){
+ if (newVal != oldVal && newVal){
+ this.inFlash = true;
+ setTimeout(() => {this.inFlash = false;}, this.uiOpts.transitionDuration);
+ }
+ },
+ },
name: 'tile', // Note: Need this to use self in template
components: {InfoIcon, },
emits: ['leaf-click', 'nonleaf-click', 'leaf-click-held', 'nonleaf-click-held', 'info-click', ],
diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue
index 02712cd..e5ea77b 100644
--- a/src/components/TileInfoModal.vue
+++ b/src/components/TileInfoModal.vue
@@ -47,7 +47,7 @@
<template v-slot:summary="slotProps">
<div class="py-1 hover:underline">
<down-icon class="inline-block w-4 h-4 mr-1 transition-transform duration-300"
- :class="{'-rotate-90': !slotProps.collapsed}"/>Source Information
+ :class="{'-rotate-90': slotProps.open}"/>Source Information
</div>
</template>
<template v-slot:content>
diff --git a/src/components/TutorialPane.vue b/src/components/TutorialPane.vue
index 9a27dd1..90d0aca 100644
--- a/src/components/TutorialPane.vue
+++ b/src/components/TutorialPane.vue
@@ -118,6 +118,24 @@ export default defineComponent({
return this.uiOpts.touchDevice;
},
},
+ methods: {
+ onStartTutorial(){
+ this.stage = 1;
+ },
+ onSkipTutorial(){
+ this.$emit('skip');
+ this.$emit('close');
+ },
+ onPrevClick(){
+ this.stage = Math.max(1, this.stage - 1);
+ },
+ onNextClick(){
+ this.stage = Math.min(this.stage + 1, this.lastStage);
+ },
+ onClose(){
+ this.$emit('close');
+ },
+ },
watch: {
stage(newVal, oldVal){
// If starting tutorial, disable 'all' actions
@@ -147,24 +165,6 @@ export default defineComponent({
}
},
},
- methods: {
- onStartTutorial(){
- this.stage = 1;
- },
- onSkipTutorial(){
- this.$emit('skip');
- this.$emit('close');
- },
- onPrevClick(){
- this.stage = Math.max(1, this.stage - 1);
- },
- onNextClick(){
- this.stage = Math.min(this.stage + 1, this.lastStage);
- },
- onClose(){
- this.$emit('close');
- },
- },
created(){
if (this.skipWelcome){
this.stage += 1;