@uniweb/kit 0.12.1 → 0.12.3
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": "@uniweb/kit",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.3",
|
|
4
4
|
"description": "Standard component library for Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"shiki": "^3.0.0",
|
|
45
45
|
"tailwind-merge": "^3.6.0",
|
|
46
46
|
"temml": "^0.13.2",
|
|
47
|
-
"@uniweb/core": "^0.
|
|
48
|
-
"@uniweb/semantic-parser": "^1.2.
|
|
47
|
+
"@uniweb/core": "^0.10.1",
|
|
48
|
+
"@uniweb/semantic-parser": "^1.2.3",
|
|
49
49
|
"@uniweb/scene": "^0.1.3"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
package/src/hooks/index.js
CHANGED
|
@@ -39,7 +39,7 @@ export {
|
|
|
39
39
|
export { useFormSubmit } from './useFormSubmit.js'
|
|
40
40
|
export { useFormValues, valueAt } from './useFormValues.js'
|
|
41
41
|
|
|
42
|
-
// Site tracking — one event stream
|
|
42
|
+
// Site tracking — one event stream.
|
|
43
43
|
// `block.track(name, data)` is the common case and needs no hook; these cover
|
|
44
44
|
// events with no block in hand, the consent gate, and opt-in scroll reporting.
|
|
45
45
|
export { useTracker } from './useTracker.js'
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
import { useEffect, useRef } from 'react'
|
|
26
26
|
import { getUniweb } from '@uniweb/core'
|
|
27
|
+
import { useRouting } from './useRouting.js'
|
|
27
28
|
|
|
28
29
|
const MILESTONES = [25, 50, 75, 100]
|
|
29
30
|
|
|
@@ -47,6 +48,21 @@ export function useScrollDepth(options = {}) {
|
|
|
47
48
|
const lastCheck = useRef(0)
|
|
48
49
|
const reported = useRef(new Set())
|
|
49
50
|
|
|
51
|
+
// ⛔ **Keyed on the path, or "once each per page" is not true.** The milestone
|
|
52
|
+
// set lives in a ref, so without this the effect runs once at mount and the
|
|
53
|
+
// set is never cleared again — a second page reports nothing at all. That bites
|
|
54
|
+
// exactly where this hook is most naturally called: once, in a layout
|
|
55
|
+
// component, which persists across SPA navigation (`PageRenderer` does not
|
|
56
|
+
// remount — the router declares a single catch-all route). Calling it in every
|
|
57
|
+
// section would have hidden the bug and multiplied the events instead.
|
|
58
|
+
//
|
|
59
|
+
// ⭐ `pathname` rather than a route object, deliberately: it is the same
|
|
60
|
+
// boundary `usePageView` emits on, so a `scroll_depth` always pairs with the
|
|
61
|
+
// `page_view` it belongs to. `useRouting` returns a default location when there
|
|
62
|
+
// is no Router, so this stays SSG-safe.
|
|
63
|
+
const { useLocation } = useRouting()
|
|
64
|
+
const { pathname } = useLocation()
|
|
65
|
+
|
|
50
66
|
useEffect(() => {
|
|
51
67
|
const tracking = getUniweb()?.tracking
|
|
52
68
|
// Skip the listener entirely when there is nowhere to report — the calls
|
|
@@ -54,6 +70,9 @@ export function useScrollDepth(options = {}) {
|
|
|
54
70
|
if (!enabled || !tracking?.isEnabled?.()) return
|
|
55
71
|
|
|
56
72
|
reported.current.clear()
|
|
73
|
+
// Reset the throttle too: a navigation within the throttle window would
|
|
74
|
+
// otherwise make the immediate check below return early and miss the fold.
|
|
75
|
+
lastCheck.current = 0
|
|
57
76
|
|
|
58
77
|
const handleScroll = () => {
|
|
59
78
|
const now = Date.now()
|
|
@@ -72,7 +91,7 @@ export function useScrollDepth(options = {}) {
|
|
|
72
91
|
handleScroll() // a page that fits the viewport is already at 100
|
|
73
92
|
window.addEventListener('scroll', handleScroll, { passive: true })
|
|
74
93
|
return () => window.removeEventListener('scroll', handleScroll)
|
|
75
|
-
}, [enabled, throttleMs, event])
|
|
94
|
+
}, [enabled, throttleMs, event, pathname])
|
|
76
95
|
}
|
|
77
96
|
|
|
78
97
|
export default useScrollDepth
|
|
@@ -50,8 +50,12 @@ export function useTrackingConsent() {
|
|
|
50
50
|
|
|
51
51
|
const set = useCallback((granted) => {
|
|
52
52
|
getUniweb()?.tracking?.setConsent(granted)
|
|
53
|
-
// Read back rather than assuming
|
|
54
|
-
//
|
|
53
|
+
// Read back rather than assuming. The tracker is the authority on its own
|
|
54
|
+
// state, and a site that never asked for a gate starts — and stays —
|
|
55
|
+
// 'granted', so a banner following the pattern above never renders and this
|
|
56
|
+
// never runs. Recording a decision does not depend on the tracker having
|
|
57
|
+
// anywhere to send, so the status moves in a framed document too — where
|
|
58
|
+
// the tracker is disabled and nothing is transmitted either way.
|
|
55
59
|
setStatus(readStatus())
|
|
56
60
|
}, [])
|
|
57
61
|
|