@hina-ui/vue 1.7.4 → 1.7.5
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/dist/index.js +32 -8
- package/dist/index.js.map +1 -1
- package/dist/types/vue/src/components/anchor/Anchor.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/anchor/composables/useAnchorFollow.d.ts +1 -1
- package/dist/types/vue/src/components/anchor/composables/useAnchorFollow.d.ts.map +1 -1
- package/dist/types/vue/src/components/lightbox/composables/useLightboxHint.d.ts.map +1 -1
- package/dist/types/vue/src/components/prev-next/PrevNextLink.vue.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/anchor/Anchor.vue +13 -9
- package/src/components/anchor/composables/useAnchorFollow.ts +18 -3
- package/src/components/lightbox/composables/useLightboxHint.ts +6 -1
- package/src/components/prev-next/PrevNext.vue +1 -1
- package/src/components/prev-next/PrevNextLink.vue +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Anchor.vue.d.ts","sourceRoot":"","sources":["../../../../../../src/components/anchor/Anchor.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Anchor.vue.d.ts","sourceRoot":"","sources":["../../../../../../src/components/anchor/Anchor.vue"],"names":[],"mappings":"AA+FE,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEzD,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,QAAA,MAAM,YAAY,GAAK,CAAC,SAAS,UAAU,GAAG,UAAU,EACzD,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,gBAAgB,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EAClE;WA2KO,OAAO,KAAK,EAAE,WAAW,GAAG,mBAAmB,CAAC;eAvK3C,CAAC,EAAE;gBACF,MAAM;qBACD,OAAO;gBACZ,MAAM;;;KAoKuE,CAAC,GAAG,CAAC,OAAO,UAAU,SAAS;QAAE,oBAAoB,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC5J,CAAC,OAAO,EAAE,OAAO,KAAK,EAAE,gBAAgB;;MAAsB,KAAK,IAAI;WACxE,GAAG;;yBA3JU;YAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;YAAC,MAAM,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO;;;EA+JvE,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAA;CAAI,CAAC;wBACpE,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,CAAC,GAAG,EAAE,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type Ref } from 'vue';
|
|
2
|
-
export declare function useAnchorFollow(root: Readonly<Ref<HTMLElement | null>>, current: Readonly<Ref<string | undefined>>, enabled: () => boolean): void;
|
|
2
|
+
export declare function useAnchorFollow(root: Readonly<Ref<HTMLElement | null>>, current: Readonly<Ref<string | undefined>>, lastCovered: Readonly<Ref<string | undefined>>, enabled: () => boolean): void;
|
|
3
3
|
//# sourceMappingURL=useAnchorFollow.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnchorFollow.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/anchor/composables/useAnchorFollow.ts"],"names":[],"mappings":"AACA,OAAO,EAAiD,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAG7E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,EACvC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,EAC1C,OAAO,EAAE,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"useAnchorFollow.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/anchor/composables/useAnchorFollow.ts"],"names":[],"mappings":"AACA,OAAO,EAAiD,KAAK,GAAG,EAAE,MAAM,KAAK,CAAA;AAG7E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,EACvC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,EAC1C,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,EAC9C,OAAO,EAAE,MAAM,OAAO,QA0GvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLightboxHint.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/lightbox/composables/useLightboxHint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,MAAM,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;IAC5C,MAAM,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;IAC5C,MAAM,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;IAC5C,OAAO,EAAE,MAAM,YAAY,GAAG,SAAS,CAAA;CACxC;;;
|
|
1
|
+
{"version":3,"file":"useLightboxHint.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/lightbox/composables/useLightboxHint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,MAAM,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;IAC5C,MAAM,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;IAC5C,MAAM,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;IAC5C,OAAO,EAAE,MAAM,YAAY,GAAG,SAAS,CAAA;CACxC;;;EA8BA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrevNextLink.vue.d.ts","sourceRoot":"","sources":["../../../../../../src/components/prev-next/PrevNextLink.vue"],"names":[],"mappings":"AA+CE,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAKxD,OAAO,EAAiC,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAI3F,KAAK,WAAW,GAAG,cAAc,GAAG;IAC9B,SAAS,EAAE,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAA;IACrD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;
|
|
1
|
+
{"version":3,"file":"PrevNextLink.vue.d.ts","sourceRoot":"","sources":["../../../../../../src/components/prev-next/PrevNextLink.vue"],"names":[],"mappings":"AA+CE,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAKxD,OAAO,EAAiC,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAI3F,KAAK,WAAW,GAAG,cAAc,GAAG;IAC9B,SAAS,EAAE,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAA;IACrD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;AA2GR,QAAA,IAAI,QAAQ,IAAY,CAAE;AAC1B,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAKhD,QAAA,MAAM,UAAU;;6EAGd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts" generic="T extends AnchorItem = AnchorItem">
|
|
2
|
-
import { useTemplateRef, watch } from 'vue'
|
|
2
|
+
import { computed, useTemplateRef, watch } from 'vue'
|
|
3
3
|
import { cn } from '../../lib/cn'
|
|
4
4
|
import { useUiLocale } from '../../locale'
|
|
5
5
|
import Highlight from '../highlight/Highlight.vue'
|
|
@@ -11,12 +11,15 @@
|
|
|
11
11
|
|
|
12
12
|
defineOptions({ name: 'HnAnchor' })
|
|
13
13
|
|
|
14
|
-
const props =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
const props = withDefaults(
|
|
15
|
+
defineProps<{
|
|
16
|
+
items: T[]
|
|
17
|
+
label?: string
|
|
18
|
+
autoScroll?: boolean
|
|
19
|
+
class?: string
|
|
20
|
+
}>(),
|
|
21
|
+
{ autoScroll: true },
|
|
22
|
+
)
|
|
20
23
|
|
|
21
24
|
const emit = defineEmits<{ change: [current: string | undefined] }>()
|
|
22
25
|
|
|
@@ -26,9 +29,10 @@
|
|
|
26
29
|
|
|
27
30
|
const t = useUiLocale()
|
|
28
31
|
|
|
29
|
-
const { entries, visible, current, span, jump } = useAnchor(() => props.items)
|
|
32
|
+
const { entries, visible, covered, current, span, jump } = useAnchor(() => props.items)
|
|
33
|
+
const lastCovered = computed(() => covered.value.at(-1)?.id)
|
|
30
34
|
const root = useTemplateRef<HTMLElement>('root')
|
|
31
|
-
useAnchorFollow(root, current, () => props.autoScroll
|
|
35
|
+
useAnchorFollow(root, current, lastCovered, () => props.autoScroll)
|
|
32
36
|
watch(current, id => emit('change', id), { flush: 'post' })
|
|
33
37
|
defineExpose({ current })
|
|
34
38
|
</script>
|
|
@@ -5,12 +5,14 @@ import { prefersReducedMotion } from '../../../motion'
|
|
|
5
5
|
export function useAnchorFollow(
|
|
6
6
|
root: Readonly<Ref<HTMLElement | null>>,
|
|
7
7
|
current: Readonly<Ref<string | undefined>>,
|
|
8
|
+
lastCovered: Readonly<Ref<string | undefined>>,
|
|
8
9
|
enabled: () => boolean,
|
|
9
10
|
) {
|
|
10
11
|
const viewport = shallowRef<HTMLElement>()
|
|
11
12
|
let mounted = false
|
|
12
13
|
let frame = 0
|
|
13
14
|
let lastCurrent: string | undefined
|
|
15
|
+
let lastEnd: string | undefined
|
|
14
16
|
|
|
15
17
|
function findViewport(nav: HTMLElement, target: HTMLElement) {
|
|
16
18
|
const doc = nav.ownerDocument
|
|
@@ -36,14 +38,27 @@ export function useAnchorFollow(
|
|
|
36
38
|
if (!target || !link || !link.getClientRects().length) return
|
|
37
39
|
const port = findViewport(nav, target)
|
|
38
40
|
viewport.value = port
|
|
39
|
-
const
|
|
41
|
+
const endId = lastCovered.value ?? id
|
|
42
|
+
const changed = lastCurrent !== undefined && (lastCurrent !== id || lastEnd !== endId)
|
|
40
43
|
lastCurrent = id
|
|
44
|
+
lastEnd = endId
|
|
41
45
|
if (!port || port.clientHeight <= 0 || port.scrollHeight <= port.clientHeight) return
|
|
42
46
|
|
|
43
47
|
const box = port.getBoundingClientRect()
|
|
44
|
-
|
|
48
|
+
let row: Pick<DOMRect, 'top' | 'bottom' | 'height'> = link.getBoundingClientRect()
|
|
45
49
|
const scale = port.offsetHeight ? box.height / port.offsetHeight : 1
|
|
46
50
|
if (scale <= 0) return
|
|
51
|
+
if (endId !== id) {
|
|
52
|
+
const end = nav.querySelector<HTMLElement>(`a[href="#${CSS.escape(endId)}"]`)
|
|
53
|
+
if (end?.getClientRects().length) {
|
|
54
|
+
const bottom = end.getBoundingClientRect().bottom
|
|
55
|
+
const height = bottom - row.top
|
|
56
|
+
// Follow the full highlight only when it fits; oversized ranges keep
|
|
57
|
+
// following the first entry instead of alternating between both ends.
|
|
58
|
+
if (height >= row.height && height <= port.clientHeight * scale)
|
|
59
|
+
row = { top: row.top, bottom, height }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
47
62
|
const top = box.top + port.clientTop * scale
|
|
48
63
|
const bottom = top + port.clientHeight * scale
|
|
49
64
|
if (row.top >= top && row.bottom <= bottom) return
|
|
@@ -81,7 +96,7 @@ export function useAnchorFollow(
|
|
|
81
96
|
if (mounted && !frame) frame = requestAnimationFrame(follow)
|
|
82
97
|
}
|
|
83
98
|
|
|
84
|
-
watch([root, current, enabled], schedule, { flush: 'post' })
|
|
99
|
+
watch([root, current, lastCovered, enabled], schedule, { flush: 'post' })
|
|
85
100
|
useResizeObserver(
|
|
86
101
|
() =>
|
|
87
102
|
[root.value, root.value?.parentElement, viewport.value].filter(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useTransform } from 'motion-v'
|
|
1
|
+
import { useMotionValue, useTransform } from 'motion-v'
|
|
2
2
|
import type { useLightboxMotion } from './useLightboxMotion'
|
|
3
3
|
import type { useLightboxFrames } from './useLightboxFrames'
|
|
4
4
|
import type { useLightboxPaging } from './useLightboxPaging'
|
|
@@ -10,6 +10,11 @@ export function useLightboxHint(options: {
|
|
|
10
10
|
paging: ReturnType<typeof useLightboxPaging>
|
|
11
11
|
current: () => LightboxItem | undefined
|
|
12
12
|
}) {
|
|
13
|
+
// useTransform's subscription refresh queues frame callbacks even during SSR.
|
|
14
|
+
// Node never drains that queue, retaining the request through these closures.
|
|
15
|
+
// The hint is only rendered inside the client-mounted lightbox.
|
|
16
|
+
if (typeof window === 'undefined') return { x: useMotionValue(0), y: useMotionValue(0) }
|
|
17
|
+
|
|
13
18
|
const { motion, frames, paging } = options
|
|
14
19
|
|
|
15
20
|
function corner() {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<ArrowRight v-else class="size-4" aria-hidden="true" />
|
|
38
38
|
{{ props.label ?? (props.direction === 'prev' ? t.pagination.prev : t.pagination.next) }}
|
|
39
39
|
</span>
|
|
40
|
-
<span class="text-fg font-medium">
|
|
40
|
+
<span class="text-fg max-w-full font-medium">
|
|
41
41
|
<slot />
|
|
42
42
|
</span>
|
|
43
43
|
</Primitive>
|