@birdycom/omniaui-vue 0.11.2 → 0.12.0
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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@birdycom/omniaui-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "OmniaUI for Vue 3: one single-file component per OmniaUI component and block, rendering the exact markup of the CSS packages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
<script setup lang="ts">
|
|
3
3
|
/**
|
|
4
4
|
* Lightbox on a native <dialog> (same markup as snippets/lightbox.html). v-model:open controls it.
|
|
5
|
-
* images: { src?, alt, caption?, thumb? }[] (no src = placeholder art). Prev / next are anchor links
|
|
5
|
+
* images: { src?, alt, caption?, thumb? }[] (no src = placeholder art). Prev / next are anchor links; with JavaScript
|
|
6
|
+
* they scroll without putting #slide in the address, and closing removes a slide hash of this viewer.
|
|
6
7
|
* Slot: caption (scoped: { image, index }). Classes: .oc-lightbox(--single), __bar, __title, __close, __track,
|
|
7
8
|
* __slide, __media, __nav(--prev/--next), __caption, __counter; .oc-lightbox-thumbs / -thumb.
|
|
8
9
|
*/
|
|
@@ -16,7 +17,19 @@ const props = withDefaults(
|
|
|
16
17
|
)
|
|
17
18
|
const open = defineModel<boolean>('open', { default: false })
|
|
18
19
|
const el = ref<HTMLDialogElement | null>(null)
|
|
19
|
-
const { onClose } = useDialog(open, el)
|
|
20
|
+
const { onClose: dialogClose } = useDialog(open, el)
|
|
21
|
+
const onClose = () => {
|
|
22
|
+
const slide = location.hash && document.getElementById(decodeURIComponent(location.hash.slice(1)))
|
|
23
|
+
if (slide && el.value?.contains(slide)) history.replaceState(history.state, '', location.pathname + location.search)
|
|
24
|
+
dialogClose()
|
|
25
|
+
}
|
|
26
|
+
// Prev / next: scroll to the slide without changing the address (the href still works without JavaScript).
|
|
27
|
+
function go(event: MouseEvent, i: number) {
|
|
28
|
+
const slide = document.getElementById(slideId(i))
|
|
29
|
+
if (!slide) return
|
|
30
|
+
event.preventDefault()
|
|
31
|
+
slide.scrollIntoView?.({ behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' as ScrollBehavior : 'smooth', block: 'nearest', inline: 'center' })
|
|
32
|
+
}
|
|
20
33
|
const base = useUid('oc-lightbox')
|
|
21
34
|
const n = () => props.images.length
|
|
22
35
|
const slideId = (i: number) => `${base}-${((i % n()) + n()) % n() + 1}`
|
|
@@ -50,8 +63,8 @@ defineExpose({ show, close: () => (open.value = false) })
|
|
|
50
63
|
<span v-else class="oc-media-art" role="img" :aria-label="img.alt" />
|
|
51
64
|
</div>
|
|
52
65
|
<template v-if="images.length > 1">
|
|
53
|
-
<a class="oc-lightbox__nav oc-lightbox__nav--prev" :href="`#${slideId(i - 1)}`" aria-label="Previous photo">←</a>
|
|
54
|
-
<a class="oc-lightbox__nav oc-lightbox__nav--next" :href="`#${slideId(i + 1)}`" aria-label="Next photo">→</a>
|
|
66
|
+
<a class="oc-lightbox__nav oc-lightbox__nav--prev" :href="`#${slideId(i - 1)}`" aria-label="Previous photo" @click="go($event, i - 1)">←</a>
|
|
67
|
+
<a class="oc-lightbox__nav oc-lightbox__nav--next" :href="`#${slideId(i + 1)}`" aria-label="Next photo" @click="go($event, i + 1)">→</a>
|
|
55
68
|
</template>
|
|
56
69
|
<figcaption class="oc-lightbox__caption">
|
|
57
70
|
<span v-if="images.length > 1" class="oc-lightbox__counter">{{ i + 1 }} / {{ images.length }}</span>
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
/** CSS-only tooltip: wraps the default slot and shows `text` via data-tooltip.
|
|
3
|
-
|
|
2
|
+
/** CSS-only tooltip: wraps the default slot and shows `text` via data-tooltip. `multiline` keeps its line breaks;
|
|
3
|
+
* `heading` puts a title above `text` (.oc-tooltip__content); `side` is the preferred side (default top), with
|
|
4
|
+
* anchor positioning it flips when there is no room. */
|
|
5
|
+
defineProps<{ text: string; multiline?: boolean; heading?: string; side?: 'top' | 'bottom' | 'left' | 'right' }>()
|
|
4
6
|
</script>
|
|
5
7
|
|
|
6
8
|
<template>
|
|
7
|
-
<span
|
|
9
|
+
<span
|
|
10
|
+
:class="['oc-tooltip', { 'oc-tooltip--multiline': multiline && !heading, [`oc-tooltip--${side}`]: side && side !== 'top' }]"
|
|
11
|
+
:data-tooltip="heading ? undefined : text"
|
|
12
|
+
>
|
|
13
|
+
<slot />
|
|
14
|
+
<span v-if="heading" class="oc-tooltip__content" role="tooltip"><span class="oc-tooltip__title">{{ heading }}</span>{{ text }}</span>
|
|
15
|
+
</span>
|
|
8
16
|
</template>
|