Skip to content

Commit 88b8275

Browse files
authored
[DO-22] Resizing images in website (#59)
* Fullscreen view component draft * Use fullscreen view on image * Implement close button * Add fullscreen mode for mermaid * Hide fullscreen image on overlay click * Lintfix * Final lintfix
1 parent f83fe61 commit 88b8275

File tree

5 files changed

+209
-43
lines changed

5 files changed

+209
-43
lines changed

components/content/Mermaid.vue

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,53 +15,24 @@
1515
-->
1616

1717
<script setup lang="ts">
18-
const { $mermaid } = useNuxtApp()
18+
import FullscreenView from '../ep/FullscreenView.vue'
19+
import MermaidDiagram from '../ep/MermaidDiagram.vue'
1920
2021
const props = defineProps<{
2122
code: string
2223
}>()
23-
24-
const decodedCode = computed(() => {
25-
return atob(props.code)
26-
})
27-
28-
const root = ref<HTMLElement | null>(null)
29-
const codeBlock = ref<HTMLElement | null>(null)
30-
const isDiagramLoading = ref(true)
31-
32-
async function renderMermaidDiagram() {
33-
isDiagramLoading.value = true
34-
if (codeBlock.value && $mermaid) {
35-
try {
36-
await $mermaid.run({
37-
nodes: [codeBlock.value],
38-
suppressErrors: true
39-
})
40-
} catch (e) {}
41-
42-
isDiagramLoading.value = false
43-
}
44-
}
45-
46-
onMounted(() => {
47-
renderMermaidDiagram()
48-
})
4924
</script>
5025

5126
<template>
52-
<figure ref="root" class="relative">
53-
<pre
54-
ref="codeBlock"
55-
style="background: none"
56-
:class="{
57-
'opacity-0': isDiagramLoading
58-
}"
59-
v-text="decodedCode"
60-
></pre>
61-
<div>
62-
<div v-if="isDiagramLoading" class="absolute inset-0 font-serif">
63-
Mermaid diagram is loading...
64-
</div>
65-
</div>
66-
</figure>
27+
<FullscreenView>
28+
<template #default="{ onClick, isFullscreen }">
29+
<MermaidDiagram
30+
:class="{
31+
'cursor-zoom-in hover:shadow transition-shadow': !isFullscreen
32+
}"
33+
:code="props.code"
34+
@click="onClick"
35+
/>
36+
</template>
37+
</FullscreenView>
6738
</template>

components/content/ProseImg.vue

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!--
2+
~ Copyright 2023 Exactpro (Exactpro Systems Limited)
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<template>
18+
<FullscreenView>
19+
<template #default="{ onClick, isFullscreen }">
20+
<img
21+
:class="{
22+
'cursor-zoom-in hover:shadow transition-shadow': !isFullscreen
23+
}"
24+
:src="refinedSrc"
25+
:alt="alt"
26+
:width="width"
27+
:height="height"
28+
@click="onClick"
29+
/>
30+
</template>
31+
</FullscreenView>
32+
</template>
33+
34+
<script setup lang="ts">
35+
import { withBase } from 'ufo'
36+
import FullscreenView from '../ep/FullscreenView.vue'
37+
import { useRuntimeConfig, computed } from '#imports'
38+
39+
const props = defineProps({
40+
src: {
41+
type: String,
42+
default: ''
43+
},
44+
alt: {
45+
type: String,
46+
default: ''
47+
},
48+
width: {
49+
type: [String, Number],
50+
default: undefined
51+
},
52+
height: {
53+
type: [String, Number],
54+
default: undefined
55+
}
56+
})
57+
58+
const refinedSrc = computed(() => {
59+
if (props.src?.startsWith('/') && !props.src.startsWith('//')) {
60+
return withBase(props.src, useRuntimeConfig().app.baseURL)
61+
}
62+
return props.src
63+
})
64+
</script>

components/ep/FullscreenView.vue

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<!--
2+
~ Copyright 2023 Exactpro (Exactpro Systems Limited)
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<script setup lang="ts">
18+
defineSlots<{
19+
default: {
20+
onClick: () => void
21+
isFullscreen: boolean
22+
}
23+
}>()
24+
25+
const isFullscreen = ref(false)
26+
27+
function toggleFullscreen() {
28+
isFullscreen.value = !isFullscreen.value
29+
}
30+
</script>
31+
32+
<template>
33+
<slot :on-click="toggleFullscreen" :is-fullscreen="isFullscreen" />
34+
<Teleport to="body">
35+
<div
36+
v-if="isFullscreen"
37+
class="fixed inset-0 z-50 flex items-center justify-center"
38+
>
39+
<div
40+
class="absolute inset-0 bg-black opacity-50"
41+
@click="toggleFullscreen"
42+
/>
43+
<Icon
44+
class="fullscreen-view__button--close"
45+
name="heroicons:x-mark"
46+
size="3rem"
47+
@click="toggleFullscreen"
48+
/>
49+
<div class="relative z-10">
50+
<slot :on-click="() => {}" :is-fullscreen="isFullscreen" />
51+
</div>
52+
</div>
53+
</Teleport>
54+
</template>
55+
56+
<style>
57+
.fullscreen-view__button--close {
58+
@apply absolute top-0 right-0 m-4
59+
text-neutral-400 hover:text-neutral-500 transition-colors
60+
cursor-pointer z-20 drop-shadow-lg;
61+
}
62+
</style>

components/ep/MermaidDiagram.vue

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<!--
2+
~ Copyright 2023 Exactpro (Exactpro Systems Limited)
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<script setup lang="ts">
18+
const { $mermaid } = useNuxtApp()
19+
20+
const props = defineProps<{
21+
code: string
22+
}>()
23+
24+
const decodedCode = computed(() => {
25+
return atob(props.code)
26+
})
27+
28+
const root = ref<HTMLElement | null>(null)
29+
const codeBlock = ref<HTMLElement | null>(null)
30+
const isDiagramLoading = ref(true)
31+
32+
async function renderMermaidDiagram() {
33+
isDiagramLoading.value = true
34+
if (codeBlock.value && $mermaid) {
35+
try {
36+
await $mermaid.run({
37+
nodes: [codeBlock.value],
38+
suppressErrors: true
39+
})
40+
} catch (e) {}
41+
42+
isDiagramLoading.value = false
43+
}
44+
}
45+
46+
onMounted(() => {
47+
renderMermaidDiagram()
48+
})
49+
</script>
50+
51+
<template>
52+
<figure ref="root" class="relative">
53+
<pre
54+
ref="codeBlock"
55+
style="background: none"
56+
:class="{
57+
'opacity-0': isDiagramLoading
58+
}"
59+
v-text="decodedCode"
60+
></pre>
61+
<div>
62+
<div v-if="isDiagramLoading" class="absolute inset-0 font-serif">
63+
Mermaid diagram is loading...
64+
</div>
65+
</div>
66+
</figure>
67+
</template>
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
# It is draft content
22

3-
lorem ipsum
3+
lorem ipsum
4+
5+
![image](https://img.freepik.com/premium-vector/job-exam-test-vector-illustration_138676-243.jpg)

0 commit comments

Comments
 (0)