From 567a21a8d0498f467f558d9ec1a6db8f1b52c0e6 Mon Sep 17 00:00:00 2001
From: Terry Truong <terry06890@gmail.com>
Date: Sun, 3 Jul 2022 20:37:46 +1000
Subject: Add SCollapsible component

Also update info-modal source-info styling
---
 src/components/TileInfoModal.vue | 113 +++++++++++++++++----------------------
 1 file changed, 50 insertions(+), 63 deletions(-)

(limited to 'src/components/TileInfoModal.vue')

diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue
index 6b7bd26..e1b31db 100644
--- a/src/components/TileInfoModal.vue
+++ b/src/components/TileInfoModal.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="fixed left-0 top-0 w-full h-full bg-black/40" @click="onClose">
 	<div class="absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2
-		max-w-[80%] min-w-[8cm] md:min-w-[15cm] max-h-[80%]"
+		max-w-[80%] min-w-[8cm] md:min-w-[14cm] max-h-[80%]"
 		:style="styles">
 		<div class="pb-1 md:pb-2">
 			<div class="flex">
@@ -32,53 +32,54 @@
 			</div>
 			<div v-else>
 				<div v-if="imgInfos[idx] != null" class="mt-1 mr-2 md:mb-2 md:mr-4 md:float-left">
-					<a :href="imgInfos[idx]!.url" target="_blank" class="block w-fit mx-auto">
+					<a :href="imgInfos[idx]!.url != '' ? imgInfos[idx]!.url : 'javascript:;'"
+						:target="imgInfos[idx]!.url != '' ? '_blank' : ''" class="block w-fit mx-auto">
 						<div :style="getImgStyles(nodes[idx])"/>
 					</a>
-					<div class="relative">
-						<details class="w-fit mx-auto text-sm hover:cursor-pointer"
-							@click="onDetailsClick($event, idx)" ref="srcInfoDetails">
-							<summary>Source information</summary>
-							<transition name="fade" @after-leave="onSrcInfoHideTransition(idx)">
-								<div v-if="srcInfoShow[idx]" class="absolute left-1/2 -translate-x-1/2 w-max max-w-full
-									md:left-0 md:translate-x-0 md:max-w-[14cm] pb-2"> <!-- Provides bottom-padding -->
-									<ul class="rounded shadow p-1 overflow-auto"
-										:style="{backgroundColor: uiOpts.bgColor, color: uiOpts.textColor}">
-										<li v-if="imgInfos[idx]!.url != ''">
-											<span :style="{color: uiOpts.altColor}">Source: </span>
-											<a :href="imgInfos[idx]!.url" target="_blank">Link</a>
-											<external-link-icon class="inline-block w-3 h-3 ml-1"/>
-										</li>
-										<li v-if="imgInfos[idx]!.artist != ''">
-											<span :style="{color: uiOpts.altColor}">Artist: </span>
-											{{imgInfos[idx]!.artist}}
-										</li>
-										<li v-if="imgInfos[idx]!.credit != ''">
-											<span :style="{color: uiOpts.altColor}">Credits: </span>
-											{{imgInfos[idx]!.credit}}
-										</li>
-										<li>
-											<span :style="{color: uiOpts.altColor}">License: </span>
-											<a :href="licenseToUrl(imgInfos[idx]!.license)" target="_blank">
-												{{imgInfos[idx]!.license}}
-											</a>
-											<external-link-icon class="inline-block w-3 h-3 ml-1"/>
-										</li>
-										<li v-if="imgInfos[idx]!.src != 'picked'">
-											<span :style="{color: uiOpts.altColor}">Obtained via: </span>
-											<a v-if="imgInfos[idx]!.src == 'eol'" href="https://eol.org/">EoL</a>
-											<a v-else href="https://www.wikipedia.org/">Wikipedia</a>
-											<external-link-icon class="inline-block w-3 h-3 ml-1"/>
-										</li>
-										<li>
-											<span :style="{color: uiOpts.altColor}">Changes: </span>
-											Cropped and resized
-										</li>
-									</ul>
-								</div>
-							</transition>
-						</details>
-					</div>
+					<s-collapsible class="text-sm text-center max-w-full md:max-w-[200px] mx-auto">
+						<template v-slot:summary="slotProps">
+							<div class="py-1">
+								<down-icon class="inline-block w-4 h-4 transition-transform duration-300"
+									:class="{'-rotate-90': !slotProps.collapsed}"/>
+								Source Information
+							</div>
+						</template>
+						<template v-slot:content>
+							<ul class="rounded shadow overflow-x-auto p-1"
+								:style="{backgroundColor: uiOpts.bgColor, color: uiOpts.textColor}">
+								<li v-if="imgInfos[idx]!.url != ''">
+									<span :style="{color: uiOpts.altColor}">Source: </span>
+									<a :href="imgInfos[idx]!.url" target="_blank">Link</a>
+									<external-link-icon class="inline-block w-3 h-3 ml-1"/>
+								</li>
+								<li v-if="imgInfos[idx]!.artist != ''" class="whitespace-nowrap">
+									<span :style="{color: uiOpts.altColor}">Artist: </span>
+									{{imgInfos[idx]!.artist}}
+								</li>
+								<li v-if="imgInfos[idx]!.credit != ''" class="whitespace-nowrap">
+									<span :style="{color: uiOpts.altColor}">Credits: </span>
+									{{imgInfos[idx]!.credit}}
+								</li>
+								<li>
+									<span :style="{color: uiOpts.altColor}">License: </span>
+									<a :href="licenseToUrl(imgInfos[idx]!.license)" target="_blank">
+										{{imgInfos[idx]!.license}}
+									</a>
+									<external-link-icon class="inline-block w-3 h-3 ml-1"/>
+								</li>
+								<li v-if="imgInfos[idx]!.src != 'picked'">
+									<span :style="{color: uiOpts.altColor}">Obtained via: </span>
+									<a v-if="imgInfos[idx]!.src == 'eol'" href="https://eol.org/">EoL</a>
+									<a v-else href="https://www.wikipedia.org/">Wikipedia</a>
+									<external-link-icon class="inline-block w-3 h-3 ml-1"/>
+								</li>
+								<li>
+									<span :style="{color: uiOpts.altColor}">Changes: </span>
+									Cropped and resized
+								</li>
+							</ul>
+						</template>
+					</s-collapsible>
 				</div>
 				<div v-if="descInfos[idx]! != null">
 					<div>{{descInfos[idx]!.text}}</div>
@@ -101,8 +102,10 @@
 
 <script lang="ts">
 import {defineComponent, PropType} from 'vue';
+import SCollapsible from './SCollapsible.vue';
 import CloseIcon from './icon/CloseIcon.vue';
 import ExternalLinkIcon from './icon/ExternalLinkIcon.vue';
+import DownIcon from './icon/DownIcon.vue';
 import {TolNode, TolMap} from '../tol';
 import {LayoutNode, LayoutOptions} from '../layout';
 import {getImagePath, DescInfo, ImgInfo, NodeInfo, InfoResponse, UiOptions} from '../lib';
@@ -117,11 +120,6 @@ export default defineComponent({
 		lytOpts: {type: Object as PropType<LayoutOptions>, required: true},
 		uiOpts: {type: Object as PropType<UiOptions>, required: true},
 	},
-	data(){
-		return {
-			srcInfoShow: [false, false], // For transitioning source-info panes when enclosing <details> are clicked
-		};
-	},
 	computed: {
 		tolNode(): TolNode {
 			return this.infoResponse.nodeInfo.tolNode;
@@ -221,19 +219,8 @@ export default defineComponent({
 				this.$emit('close');
 			}
 		},
-		onDetailsClick(evt: Event, idx: number){
-			this.srcInfoShow[idx] = !this.srcInfoShow[idx];
-			if (this.srcInfoShow[idx] == false){
-				evt.preventDefault(); // Delay <details> closure, to allow for transition
-			}
-		},
-		onSrcInfoHideTransition(idx: number){
-			// Close <details>, now that it's content has transitioned away
-			let details = this.$refs.srcInfoDetails[idx];
-			details.removeAttribute('open');
-		},
 	},
-	components: {CloseIcon, ExternalLinkIcon, },
+	components: {SCollapsible, CloseIcon, ExternalLinkIcon, DownIcon, },
 	emits: ['close', ],
 });
 </script>
-- 
cgit v1.2.3

