@rimelight/ui 0.0.20 → 0.0.22

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.
@@ -0,0 +1,88 @@
1
+ export interface HeaderLayer {
2
+ id: string
3
+ order: number
4
+ naturalHeight: number
5
+ isVisible: boolean
6
+ el: HTMLElement | null
7
+ }
8
+
9
+ export interface HeaderStackManager {
10
+ layers: HeaderLayer[]
11
+ register: (
12
+ id: string,
13
+ order: number,
14
+ naturalHeight: number,
15
+ isVisible: boolean,
16
+ el: HTMLElement | null
17
+ ) => void
18
+ unregister: (id: string) => void
19
+ update: () => void
20
+ }
21
+
22
+ /**
23
+ * Initializes and returns a global vanilla JS header stack manager. This ensures Vue and Astro
24
+ * components share the exact same layer state and can dynamically push each other up/down when
25
+ * hiding on scroll.
26
+ */
27
+ export function getHeaderStack(): HeaderStackManager {
28
+ if (typeof window === "undefined") {
29
+ // SSR stub
30
+ return {
31
+ layers: [],
32
+ register() {},
33
+ unregister() {},
34
+ update() {}
35
+ }
36
+ }
37
+
38
+ const win = window as any
39
+ if (!win.RLHeaderStack) {
40
+ win.RLHeaderStack = {
41
+ layers: [] as HeaderLayer[],
42
+ register(
43
+ id: string,
44
+ order: number,
45
+ naturalHeight: number,
46
+ isVisible: boolean,
47
+ el: HTMLElement | null
48
+ ) {
49
+ let layer = this.layers.find((l: HeaderLayer) => l.id === id)
50
+ if (!layer) {
51
+ layer = { id, order, naturalHeight, isVisible, el }
52
+ this.layers.push(layer)
53
+ this.layers.sort((a: HeaderLayer, b: HeaderLayer) => a.order - b.order)
54
+ } else {
55
+ layer.naturalHeight = naturalHeight
56
+ layer.isVisible = isVisible
57
+ layer.el = el
58
+ }
59
+ this.update()
60
+ },
61
+ unregister(id: string) {
62
+ this.layers = this.layers.filter((l: HeaderLayer) => l.id !== id)
63
+ this.update()
64
+ },
65
+ update() {
66
+ let currentTop = 0
67
+ for (const layer of this.layers) {
68
+ if (layer.el) {
69
+ // If hidden, slide it up out of view (or exactly to its negative height so it's ready to slide down)
70
+ const topPx = layer.isVisible ? `${currentTop}px` : `-${layer.naturalHeight}px`
71
+ layer.el.style.top = topPx
72
+ layer.el.style.opacity = layer.isVisible ? "1" : "0"
73
+ layer.el.style.pointerEvents = layer.isVisible ? "auto" : "none"
74
+ layer.el.style.setProperty(
75
+ "--rl-header-bottom",
76
+ `calc(${topPx} + ${layer.naturalHeight}px)`
77
+ )
78
+ }
79
+ if (layer.isVisible) {
80
+ currentTop += layer.naturalHeight
81
+ }
82
+ }
83
+ document.documentElement.style.setProperty("--rl-total-header-height", `${currentTop}px`)
84
+ }
85
+ }
86
+ }
87
+ return win.RLHeaderStack
88
+ }