Skip to content

Commit 5d31f94

Browse files
committed
release 1.0.4
1 parent 5785c86 commit 5d31f94

File tree

4 files changed

+36
-54
lines changed

4 files changed

+36
-54
lines changed

demo/Header.vue

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
11
<script setup lang="ts">
2-
import { ref, watchEffect } from 'vue'
2+
import { ref } from 'vue'
33
import { useFixedHeader } from '../src'
44
55
const headerRef = ref<HTMLElement | null>(null)
66
7-
const { styles, isEnter, isLeave } = useFixedHeader(headerRef, {
8-
toggleVisibility: true,
9-
})
10-
11-
watchEffect(() => {
12-
console.table([
13-
{
14-
isEnter: isEnter.value,
15-
isLeave: isLeave.value,
16-
},
17-
])
18-
})
7+
const { styles } = useFixedHeader(headerRef)
198
</script>
209

2110
<template>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "vue-use-fixed-header",
33
"description": "Turn your boring fixed header into a smart one with three lines of code.",
44
"private": false,
5-
"version": "1.0.3",
5+
"version": "1.0.4",
66
"type": "module",
77
"keywords": [
88
"vue",

src/useFixedHeader.ts

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
watch,
77
computed,
88
readonly,
9-
type CSSProperties,
9+
type CSSProperties as CSS,
1010
} from 'vue'
1111

1212
import { mergeDefined, isSSR, isReducedMotion } from './utils'
@@ -15,9 +15,9 @@ import { CAPTURE_DELTA_FRAME_COUNT, defaultOptions } from './constants'
1515
import type { UseFixedHeaderOptions, MaybeTemplateRef, UseFixedHeaderReturn } from './types'
1616

1717
enum State {
18-
READY = 'READY',
19-
ENTER = 'ENTER',
20-
LEAVE = 'LEAVE',
18+
READY,
19+
ENTER,
20+
LEAVE,
2121
}
2222

2323
export function useFixedHeader(
@@ -30,14 +30,13 @@ export function useFixedHeader(
3030

3131
let isListeningScroll = false
3232
let isHovering = false
33-
let isInstantRestoration = true
3433

3534
// Internal state
3635

37-
const styles = shallowRef<CSSProperties>({})
36+
const styles = shallowRef<CSS>({})
3837
const state = ref<State>(State.READY)
3938

40-
function setStyles(newStyles: CSSProperties) {
39+
function setStyles(newStyles: CSS) {
4140
styles.value = newStyles
4241
}
4342

@@ -88,21 +87,24 @@ export function useFixedHeader(
8887
// Callbacks
8988

9089
/**
91-
* Hides the header on page load before it has a chance to paint,
92-
* only if scroll restoration is instant.
93-
*
94-
* If not instant (smooth-scroll) 'isBelowHeader' will resolve
95-
* to false and the header will be visible until next scroll.
90+
* Hides the header on page load before it has a chance to paint
91+
* if scroll restoration is instant. If not, applies the enter
92+
* styles immediately (without transitions).
9693
*/
97-
function onInstantScrollRestoration() {
98-
if (!mergedOptions.toggleVisibility) return
99-
if (!isInstantRestoration) return
100-
94+
function onScrollRestoration() {
10195
requestAnimationFrame(() => {
102-
const isBelowHeader = getScrollTop() > getHeaderHeight() * 1.2
103-
if (isBelowHeader) setStyles({ ...mergedOptions.leaveStyles, visibility: 'hidden' })
96+
const isInstant = getScrollTop() > getHeaderHeight() * 1.2 // Resolves to false if scroll is smooth
97+
98+
if (isInstant) {
99+
setStyles({
100+
...mergedOptions.leaveStyles,
101+
...(mergedOptions.toggleVisibility ? { visibility: 'hidden' } : {}),
102+
transition: '', // We don't want transitions to play on page load...
103+
})
104+
} else {
105+
setStyles({ ...mergedOptions.enterStyles, transition: '' }) //...same here
106+
}
104107
})
105-
isInstantRestoration = false
106108
}
107109

108110
function onVisible() {
@@ -112,9 +114,7 @@ export function useFixedHeader(
112114

113115
setStyles({
114116
...mergedOptions.enterStyles,
115-
...(mergedOptions.toggleVisibility
116-
? { visibility: '' as CSSProperties['visibility'] }
117-
: {}),
117+
...(mergedOptions.toggleVisibility ? { visibility: '' as CSS['visibility'] } : {}),
118118
...(isReducedMotion() ? { transition: 'none' } : {}),
119119
})
120120

@@ -140,12 +140,13 @@ export function useFixedHeader(
140140

141141
if (e.target !== unref(target)) return
142142

143-
setStyles({ ...mergedOptions.leaveStyles, visibility: 'hidden' })
143+
setStyles({
144+
...mergedOptions.leaveStyles,
145+
...(mergedOptions.toggleVisibility ? { visibility: 'hidden' } : {}),
146+
})
144147
}
145148

146149
function toggleTransitionListener(isRemove = false) {
147-
if (!mergedOptions.toggleVisibility) return
148-
149150
const el = unref(target)
150151
if (!el) return
151152

@@ -313,17 +314,7 @@ export function useFixedHeader(
313314
addResizeObserver()
314315
if (!isFixed()) return
315316

316-
/**
317-
* Immediately hides the header on page load, this has effect
318-
* only if scroll restoration is not smooth and 'toggleVisibility'
319-
* is set to true.
320-
*/
321-
onInstantScrollRestoration()
322-
323-
/**
324-
* Start listening scroll events, it will hide the header
325-
* in case of smooth-scroll restoration.
326-
*/
317+
onScrollRestoration()
327318
toggleListeners()
328319
}
329320

tests/transitions.cy.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ import { defaultOptions } from '../src/constants'
33

44
describe('Transitions', () => {
55
describe('Page load', () => {
6-
it('Styles are not applied if header is visible', () => {
7-
cy.mountApp().get('header').should('be.visible').and('not.have.attr', 'style')
6+
it('Styles are applied if header is visible, except transition', () => {
7+
const { transition, ...enterStyles } = defaultOptions.enterStyles
8+
cy.mountApp().get('header').should('be.visible').checkStyles(enterStyles)
89
})
910

10-
it('Styles are applied if header is hidden (in order to trigger futher enter transition)', () => {
11+
it('Styles are applied if header is hidden (in order to trigger further enter transition)', () => {
1112
cy.mountApp({
1213
props: {
1314
simulateInstantRestoration: true,
1415
},
1516
})
1617

17-
cy.get('header').should('be.hidden').checkStyles(defaultOptions.leaveStyles)
18+
const { transition, ...leaveStyles } = defaultOptions.leaveStyles
19+
cy.get('header').should('be.hidden').checkStyles(leaveStyles)
1820
})
1921
})
2022

0 commit comments

Comments
 (0)