@fy-/fws-vue 2.2.52 → 2.2.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ import {
9
9
  InformationCircleIcon,
10
10
  XMarkIcon,
11
11
  } from '@heroicons/vue/24/solid'
12
- import { computed, h, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
12
+ import { computed, h, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
13
13
  import { useEventBus } from '../../composables/event-bus'
14
14
  import DefaultPaging from './DefaultPaging.vue'
15
15
 
@@ -18,8 +18,9 @@ const eventBus = useEventBus()
18
18
  const sidePanel = ref<boolean>(true)
19
19
  const showControls = ref<boolean>(true)
20
20
  const isFullscreen = ref<boolean>(false)
21
- const infoPanel = ref<boolean>(false)
21
+ const infoPanel = ref<boolean>(true) // Show info panel by default
22
22
  const touchStartTime = ref<number>(0)
23
+ const infoHeight = ref<number>(0)
23
24
 
24
25
  const props = withDefaults(
25
26
  defineProps<{
@@ -107,7 +108,8 @@ function setModal(value: boolean) {
107
108
  }
108
109
  isGalleryOpen.value = value
109
110
  showControls.value = true
110
- infoPanel.value = false
111
+ // Keep info panel open by default
112
+ infoPanel.value = true
111
113
  }
112
114
 
113
115
  function openGalleryImage(index: number | undefined) {
@@ -184,6 +186,17 @@ function toggleControls() {
184
186
  function toggleInfoPanel() {
185
187
  infoPanel.value = !infoPanel.value
186
188
  resetControlsTimer()
189
+
190
+ // Update the info height after panel toggle
191
+ if (infoPanel.value) {
192
+ nextTick(() => {
193
+ updateInfoHeight()
194
+ })
195
+ }
196
+ else {
197
+ // Reset when hiding
198
+ document.documentElement.style.setProperty('--info-height', '0px')
199
+ }
187
200
  }
188
201
 
189
202
  function toggleFullscreen() {
@@ -312,14 +325,44 @@ function handleBackdropClick(event: MouseEvent) {
312
325
  }
313
326
 
314
327
  watch(currentImage, () => {
315
- // Reset info panel when image changes
316
- infoPanel.value = false
328
+ // Keep info panel open when image changes
329
+ infoPanel.value = true
330
+
331
+ // Update info height after image changes
332
+ nextTick(() => {
333
+ updateInfoHeight()
334
+ })
317
335
  })
318
336
 
337
+ // Update CSS variable with info panel height
338
+ function updateInfoHeight() {
339
+ nextTick(() => {
340
+ const infoElement = document.querySelector('.info-panel-slot') as HTMLElement
341
+ if (infoElement) {
342
+ const height = infoElement.offsetHeight
343
+ infoHeight.value = height
344
+ document.documentElement.style.setProperty('--info-height', `${height}px`)
345
+ }
346
+ })
347
+ }
348
+
319
349
  onMounted(() => {
320
350
  eventBus.on(`${props.id}GalleryImage`, openGalleryImage)
321
351
  eventBus.on(`${props.id}Gallery`, openGalleryImage)
322
352
  eventBus.on(`${props.id}GalleryClose`, closeGallery)
353
+
354
+ // Initialize info height once mounted
355
+ updateInfoHeight()
356
+
357
+ // Set up a resize observer to track info panel height changes
358
+ const resizeObserver = new ResizeObserver(() => {
359
+ updateInfoHeight()
360
+ })
361
+
362
+ const infoElement = document.querySelector('.info-panel-slot')
363
+ if (infoElement) {
364
+ resizeObserver.observe(infoElement)
365
+ }
323
366
  })
324
367
 
325
368
  onUnmounted(() => {
@@ -415,14 +458,20 @@ onUnmounted(() => {
415
458
  <component
416
459
  :is="videoComponent"
417
460
  :src="isVideo(images[modelValue])"
418
- class="shadow max-w-full h-auto object-contain max-h-[85vh]"
461
+ class="shadow max-w-full h-auto object-contain"
462
+ :style="{
463
+ maxHeight: infoPanel ? 'calc(85vh - var(--info-height, 0px))' : '85vh',
464
+ }"
419
465
  />
420
466
  </ClientOnly>
421
467
  </template>
422
468
  <template v-else>
423
469
  <img
424
470
  v-if="modelValueSrc && imageComponent === 'img'"
425
- class="shadow max-w-full h-auto object-contain max-h-[85vh]"
471
+ class="shadow max-w-full h-auto object-contain"
472
+ :style="{
473
+ maxHeight: infoPanel ? 'calc(85vh - var(--info-height, 0px))' : '85vh',
474
+ }"
426
475
  :src="modelValueSrc"
427
476
  :alt="`Gallery image ${modelValue + 1}`"
428
477
  >
@@ -432,7 +481,10 @@ onUnmounted(() => {
432
481
  :image="modelValueSrc.image"
433
482
  :variant="modelValueSrc.variant"
434
483
  :alt="modelValueSrc.alt"
435
- class="shadow max-w-full h-auto object-contain max-h-[85vh]"
484
+ class="shadow max-w-full h-auto object-contain"
485
+ :style="{
486
+ maxHeight: infoPanel ? 'calc(85vh - var(--info-height, 0px))' : '85vh',
487
+ }"
436
488
  />
437
489
  </template>
438
490
  </div>
@@ -440,7 +492,8 @@ onUnmounted(() => {
440
492
  <!-- Image Slot Content -->
441
493
  <div
442
494
  v-if="infoPanel"
443
- class="flex-0 px-4 py-3 backdrop-blur-md bg-fv-neutral-900/70 rounded-t-lg flex items-center justify-center max-w-full w-full !z-[45] transition-all"
495
+ class="info-panel-slot flex-0 px-4 py-3 backdrop-blur-md bg-fv-neutral-900/70 rounded-t-lg flex items-center justify-center max-w-full w-full !z-[45] transition-all"
496
+ @transitionend="updateInfoHeight"
444
497
  >
445
498
  <slot :value="images[modelValue]" />
446
499
  </div>
@@ -563,7 +616,8 @@ onUnmounted(() => {
563
616
  <div class="flex items-center space-x-2">
564
617
  <button
565
618
  class="btn p-1.5 rounded-full bg-fv-neutral-800/70 hover:bg-fv-neutral-700/90 transition-transform transform hover:scale-110"
566
- title="Toggle info"
619
+ :class="{ 'bg-fv-primary-500/70': infoPanel }"
620
+ :title="infoPanel ? 'Hide info' : 'Show info'"
567
621
  @click="toggleInfoPanel"
568
622
  >
569
623
  <InformationCircleIcon class="w-5 h-5" />
@@ -164,11 +164,6 @@ function setModal(value: boolean) {
164
164
  // Set this modal's z-index
165
165
  zIndex.value = newZIndex
166
166
 
167
- // Only manage body overflow for the first opened modal
168
- if (modalRegistry.modals.size === 1) {
169
- document.body.style.overflow = 'hidden' // Prevent scrolling when modal is open
170
- }
171
-
172
167
  document.addEventListener('keydown', handleKeyDown)
173
168
  }
174
169
  if (value === false) {
@@ -183,11 +178,6 @@ function setModal(value: boolean) {
183
178
  }
184
179
  }
185
180
 
186
- // Only restore body overflow if this is the last open modal
187
- if (modalRegistry.modals.size === 0) {
188
- document.body.style.overflow = '' // Restore scrolling
189
- }
190
-
191
181
  document.removeEventListener('keydown', handleKeyDown)
192
182
  if (previouslyFocusedElement) {
193
183
  previouslyFocusedElement.focus()
@@ -196,8 +186,6 @@ function setModal(value: boolean) {
196
186
  isOpen.value = value
197
187
  }
198
188
 
199
- // These functions have been moved to the global registry object
200
-
201
189
  // After modal is opened, set focus and collect focusable elements
202
190
  watch(isOpen, async (newVal) => {
203
191
  if (newVal) {
@@ -238,11 +226,6 @@ onUnmounted(() => {
238
226
  modalRegistry.modals.delete(uniqueId)
239
227
  }
240
228
  }
241
-
242
- // Only restore body overflow if this is the last open modal
243
- if (modalRegistry.modals.size === 0) {
244
- document.body.style.overflow = '' // Restore scrolling
245
- }
246
229
  }
247
230
  })
248
231
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fy-/fws-vue",
3
- "version": "2.2.52",
3
+ "version": "2.2.55",
4
4
  "author": "Florian 'Fy' Gasquez <m@fy.to>",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/fy-to/FWJS#readme",