diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/AncestryBar.vue | 18 | ||||
| -rw-r--r-- | src/components/HelpModal.vue | 10 | ||||
| -rw-r--r-- | src/components/SCollapsible.vue | 28 | ||||
| -rw-r--r-- | src/components/SettingsModal.vue | 10 | ||||
| -rw-r--r-- | src/components/Tile.vue | 100 | ||||
| -rw-r--r-- | src/components/TileInfoModal.vue | 2 | ||||
| -rw-r--r-- | src/components/TutorialPane.vue | 36 |
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; |
