diff options
| author | Terry Truong <terry06890@gmail.com> | 2022-03-24 14:57:45 +1100 |
|---|---|---|
| committer | Terry Truong <terry06890@gmail.com> | 2022-03-24 14:57:45 +1100 |
| commit | d19e4e971f737b491742e8b77e411ae5fbc73bb4 (patch) | |
| tree | 39d64ab1a7cf6f96aa8b1adc15bafbc30004e070 /src/components | |
| parent | b18bc3ff50671e7109bde3d1eabb8276d313863e (diff) | |
Add TileInfoModal and associated events
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/ParentBar.vue | 7 | ||||
| -rw-r--r-- | src/components/Tile.vue | 11 | ||||
| -rw-r--r-- | src/components/TileImg.vue | 3 | ||||
| -rw-r--r-- | src/components/TileInfoModal.vue | 46 | ||||
| -rw-r--r-- | src/components/TileTree.vue | 19 |
5 files changed, 78 insertions, 8 deletions
diff --git a/src/components/ParentBar.vue b/src/components/ParentBar.vue index 26061b7..0f73008 100644 --- a/src/components/ParentBar.vue +++ b/src/components/ParentBar.vue @@ -54,16 +54,21 @@ export default defineComponent({ onClick(node: LayoutNode){ this.$emit('sepd-parent-clicked', node); }, + onInnerInfoIconClicked(data: LayoutNode){ + this.$emit('info-icon-clicked', data); + } }, components: { TileImg, }, + emits: ['sepd-parent-clicked', 'info-icon-clicked'], }); </script> <template> <div :style="styles"> <tile-img v-for="node in nodes" :key="node.tolNode.name" - :layoutNode="node" :tileSz="tileSz" :options="options" @click="onClick(node)"/> + :layoutNode="node" :tileSz="tileSz" :options="options" + @click="onClick(node)" @info-icon-clicked="onInnerInfoIconClicked"/> </div> </template> diff --git a/src/components/Tile.vue b/src/components/Tile.vue index 579e880..7722101 100644 --- a/src/components/Tile.vue +++ b/src/components/Tile.vue @@ -181,19 +181,23 @@ export default defineComponent({ onNonLeafMouseLeave(evt: Event){ this.nonLeafHighlight = false; }, + // For child event propagation + onInnerInfoIconClicked(data: LayoutNode){ + this.$emit('info-icon-clicked', data); + } }, name: 'tile', // Need this to use self in template components: { TileImg, }, - emits: ['leaf-clicked', 'header-clicked', 'leaf-dbl-clicked', 'header-dbl-clicked'], + emits: ['leaf-clicked', 'header-clicked', 'leaf-dbl-clicked', 'header-dbl-clicked', 'info-icon-clicked'], }); </script> <template> <div :style="tileStyles"> <tile-img v-if="isLeaf" :layoutNode="layoutNode" :tileSz="layoutNode.dims[0]" :options="options" - @click="onLeafClick"/> + @click="onLeafClick" @info-icon-clicked="onInnerInfoIconClicked"/> <div v-else :style="nonLeafStyles" ref="nonLeaf"> <h1 v-if="showHeader" :style="nonLeafHeaderStyles" class="hover:cursor-pointer" @click="onHeaderClick($event)" @mouseenter="onNonLeafMouseEnter" @mouseleave="onNonLeafMouseLeave"> @@ -210,7 +214,8 @@ export default defineComponent({ <tile v-for="child in layoutNode.children" :key="child.tolNode.name" :layoutNode="child" :headerSz="headerSz" :tileSpacing="tileSpacing" :options="options" @leaf-clicked="onInnerLeafClicked" @header-clicked="onInnerHeaderClicked" - @leaf-dbl-clicked="onInnerLeafDblClicked" @header-dbl-clicked="onInnerHeaderDblClicked"/> + @leaf-dbl-clicked="onInnerLeafDblClicked" @header-dbl-clicked="onInnerHeaderDblClicked" + @info-icon-clicked="onInnerInfoIconClicked"/> </div> </div> </template> diff --git a/src/components/TileImg.vue b/src/components/TileImg.vue index 5a3a2f8..2445f98 100644 --- a/src/components/TileImg.vue +++ b/src/components/TileImg.vue @@ -86,9 +86,10 @@ export default defineComponent({ this.infoMouseOver = false; }, onInfoClick(evt: Event){ - console.log('Clicked on info icon: ' + this.layoutNode.tolNode.name); + this.$emit('info-icon-clicked', this.layoutNode); }, }, + emits: ['info-icon-clicked'], }); </script> diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue new file mode 100644 index 0000000..6e0e99c --- /dev/null +++ b/src/components/TileInfoModal.vue @@ -0,0 +1,46 @@ +<script lang="ts"> +import {defineComponent, PropType} from 'vue'; +import {TolNode} from '../lib'; + +export default defineComponent({ + props: { + tolNode: {type: Object as PropType<TolNode | null>}, + }, + computed: { + hidden(){ + return this.tolNode == null; + }, + styles(): Record<string,string> { + return { + display: this.hidden ? 'none' : 'block', + opacity: this.hidden ? '0' : '1', + transition: 'opacity 0.3s', + }; + }, + }, + methods: { + closeIconClicked(){ + this.$emit('info-modal-close'); + }, + }, + emits: ['info-modal-close'] +}); +</script> + +<template> +<div :style="styles" class="fixed left-0 top-0 w-full h-full bg-black/40" @click="closeIconClicked"> + <div class="absolute left-1/2 -translate-x-1/2 min-w-3/5 top-1/3 p-2 bg-white rounded-md"> + <div class="absolute top-1 right-1 text-lg font-bold hover:cursor-pointer" + @click="closeIconClicked">×</div> + <img class="float-left mr-2 mb-2" width="200" height="200" alt="an image"/> + <h1>{{hidden ? 'If you can see this, something\'s wrong' : tolNode!.name}}</h1> + <div> + Lorem ipsum dolor sit amet, consectetur adipiscing + elit, sed do eiusmod tempor incididunt ut labore + et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. + </div> + </div> +</div> +</template> diff --git a/src/components/TileTree.vue b/src/components/TileTree.vue index d42dd24..0b1cc58 100644 --- a/src/components/TileTree.vue +++ b/src/components/TileTree.vue @@ -2,6 +2,7 @@ import {defineComponent, PropType} from 'vue'; import Tile from './Tile.vue'; import ParentBar from './ParentBar.vue'; +import TileInfoModal from './TileInfoModal.vue'; import {TolNode, LayoutNode, initLayoutTree, tryLayout} from '../lib'; import type {LayoutOptions} from '../lib'; // Import paths lack a .ts or .js extension because .ts makes vue-tsc complain, and .js makes vite complain @@ -67,6 +68,7 @@ export default defineComponent({ return { layoutTree: layoutTree, activeRoot: layoutTree, + infoModalNode: null as TolNode | null, // Hides/unhides info modal, and provides the node to display // Options layoutOptions: {...defaultLayoutOptions}, componentOptions: {...defaultComponentOptions}, @@ -148,7 +150,7 @@ export default defineComponent({ setTimeout(() => {this.resizeThrottled = false;}, this.resizeDelay); } }, - // For click events + // For tile expand/collapse events onInnerLeafClicked({layoutNode, domNode}: {layoutNode: LayoutNode, domNode: HTMLElement}){ let success = tryLayout(this.activeRoot, this.tileAreaPos, this.tileAreaDims, this.layoutOptions, false, {type: 'expand', node: layoutNode}); @@ -169,6 +171,7 @@ export default defineComponent({ domNode.classList.add('animate-shrink-expand'); } }, + // For expand-to-view events onInnerLeafDblClicked(layoutNode: LayoutNode){ if (layoutNode == this.activeRoot){ console.log('Ignored expand-to-view on root node'); @@ -193,6 +196,13 @@ export default defineComponent({ this.activeRoot = layoutNode; tryLayout(layoutNode, this.tileAreaPos, this.tileAreaDims, this.layoutOptions, true); }, + // For info modal events + onInnerInfoIconClicked(node: LayoutNode){ + this.infoModalNode = node.tolNode; + }, + onInfoModalClose(){ + this.infoModalNode = null; + }, // For preventing double-clicks from highlighting text onMouseDown(evt: UIEvent){ if (evt.detail == 2){ @@ -210,6 +220,7 @@ export default defineComponent({ components: { Tile, ParentBar, + TileInfoModal, }, }); </script> @@ -219,10 +230,12 @@ export default defineComponent({ <tile :layoutNode="layoutTree" :headerSz="layoutOptions.headerSz" :tileSpacing="layoutOptions.tileSpacing" :options="componentOptions" @leaf-clicked="onInnerLeafClicked" @header-clicked="onInnerHeaderClicked" - @leaf-dbl-clicked="onInnerLeafDblClicked" @header-dbl-clicked="onInnerHeaderDblClicked"/> + @leaf-dbl-clicked="onInnerLeafDblClicked" @header-dbl-clicked="onInnerHeaderDblClicked" + @info-icon-clicked="onInnerInfoIconClicked"/> <parent-bar v-if="sepdParents != null" :pos="[0,0]" :dims="parentBarDims" :nodes="sepdParents" :options="componentOptions" - @sepd-parent-clicked="onSepdParentClicked"/> + @sepd-parent-clicked="onSepdParentClicked" @info-icon-clicked="onInnerInfoIconClicked"/> + <tile-info-modal :tolNode="infoModalNode" @info-modal-close="onInfoModalClose"/> </div> </template> |
