From 5d31f949072d16d0a54723a44bd5d8ec9f607dd9 Mon Sep 17 00:00:00 2001
From: smastrom <60471784+smastrom@users.noreply.github.com>
Date: Fri, 18 Aug 2023 02:38:02 +0200
Subject: [PATCH] release 1.0.4
---
demo/Header.vue | 15 ++--------
package.json | 2 +-
src/useFixedHeader.ts | 63 ++++++++++++++++++-----------------------
tests/transitions.cy.ts | 10 ++++---
4 files changed, 36 insertions(+), 54 deletions(-)
diff --git a/demo/Header.vue b/demo/Header.vue
index 36a4026..71824ed 100644
--- a/demo/Header.vue
+++ b/demo/Header.vue
@@ -1,21 +1,10 @@
diff --git a/package.json b/package.json
index 9da3a14..4e38cf6 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "vue-use-fixed-header",
"description": "Turn your boring fixed header into a smart one with three lines of code.",
"private": false,
- "version": "1.0.3",
+ "version": "1.0.4",
"type": "module",
"keywords": [
"vue",
diff --git a/src/useFixedHeader.ts b/src/useFixedHeader.ts
index 9cd24aa..bc57055 100644
--- a/src/useFixedHeader.ts
+++ b/src/useFixedHeader.ts
@@ -6,7 +6,7 @@ import {
watch,
computed,
readonly,
- type CSSProperties,
+ type CSSProperties as CSS,
} from 'vue'
import { mergeDefined, isSSR, isReducedMotion } from './utils'
@@ -15,9 +15,9 @@ import { CAPTURE_DELTA_FRAME_COUNT, defaultOptions } from './constants'
import type { UseFixedHeaderOptions, MaybeTemplateRef, UseFixedHeaderReturn } from './types'
enum State {
- READY = 'READY',
- ENTER = 'ENTER',
- LEAVE = 'LEAVE',
+ READY,
+ ENTER,
+ LEAVE,
}
export function useFixedHeader(
@@ -30,14 +30,13 @@ export function useFixedHeader(
let isListeningScroll = false
let isHovering = false
- let isInstantRestoration = true
// Internal state
- const styles = shallowRef({})
+ const styles = shallowRef({})
const state = ref(State.READY)
- function setStyles(newStyles: CSSProperties) {
+ function setStyles(newStyles: CSS) {
styles.value = newStyles
}
@@ -88,21 +87,24 @@ export function useFixedHeader(
// Callbacks
/**
- * Hides the header on page load before it has a chance to paint,
- * only if scroll restoration is instant.
- *
- * If not instant (smooth-scroll) 'isBelowHeader' will resolve
- * to false and the header will be visible until next scroll.
+ * Hides the header on page load before it has a chance to paint
+ * if scroll restoration is instant. If not, applies the enter
+ * styles immediately (without transitions).
*/
- function onInstantScrollRestoration() {
- if (!mergedOptions.toggleVisibility) return
- if (!isInstantRestoration) return
-
+ function onScrollRestoration() {
requestAnimationFrame(() => {
- const isBelowHeader = getScrollTop() > getHeaderHeight() * 1.2
- if (isBelowHeader) setStyles({ ...mergedOptions.leaveStyles, visibility: 'hidden' })
+ const isInstant = getScrollTop() > getHeaderHeight() * 1.2 // Resolves to false if scroll is smooth
+
+ if (isInstant) {
+ setStyles({
+ ...mergedOptions.leaveStyles,
+ ...(mergedOptions.toggleVisibility ? { visibility: 'hidden' } : {}),
+ transition: '', // We don't want transitions to play on page load...
+ })
+ } else {
+ setStyles({ ...mergedOptions.enterStyles, transition: '' }) //...same here
+ }
})
- isInstantRestoration = false
}
function onVisible() {
@@ -112,9 +114,7 @@ export function useFixedHeader(
setStyles({
...mergedOptions.enterStyles,
- ...(mergedOptions.toggleVisibility
- ? { visibility: '' as CSSProperties['visibility'] }
- : {}),
+ ...(mergedOptions.toggleVisibility ? { visibility: '' as CSS['visibility'] } : {}),
...(isReducedMotion() ? { transition: 'none' } : {}),
})
@@ -140,12 +140,13 @@ export function useFixedHeader(
if (e.target !== unref(target)) return
- setStyles({ ...mergedOptions.leaveStyles, visibility: 'hidden' })
+ setStyles({
+ ...mergedOptions.leaveStyles,
+ ...(mergedOptions.toggleVisibility ? { visibility: 'hidden' } : {}),
+ })
}
function toggleTransitionListener(isRemove = false) {
- if (!mergedOptions.toggleVisibility) return
-
const el = unref(target)
if (!el) return
@@ -313,17 +314,7 @@ export function useFixedHeader(
addResizeObserver()
if (!isFixed()) return
- /**
- * Immediately hides the header on page load, this has effect
- * only if scroll restoration is not smooth and 'toggleVisibility'
- * is set to true.
- */
- onInstantScrollRestoration()
-
- /**
- * Start listening scroll events, it will hide the header
- * in case of smooth-scroll restoration.
- */
+ onScrollRestoration()
toggleListeners()
}
diff --git a/tests/transitions.cy.ts b/tests/transitions.cy.ts
index 9ea69e5..15452ad 100644
--- a/tests/transitions.cy.ts
+++ b/tests/transitions.cy.ts
@@ -3,18 +3,20 @@ import { defaultOptions } from '../src/constants'
describe('Transitions', () => {
describe('Page load', () => {
- it('Styles are not applied if header is visible', () => {
- cy.mountApp().get('header').should('be.visible').and('not.have.attr', 'style')
+ it('Styles are applied if header is visible, except transition', () => {
+ const { transition, ...enterStyles } = defaultOptions.enterStyles
+ cy.mountApp().get('header').should('be.visible').checkStyles(enterStyles)
})
- it('Styles are applied if header is hidden (in order to trigger futher enter transition)', () => {
+ it('Styles are applied if header is hidden (in order to trigger further enter transition)', () => {
cy.mountApp({
props: {
simulateInstantRestoration: true,
},
})
- cy.get('header').should('be.hidden').checkStyles(defaultOptions.leaveStyles)
+ const { transition, ...leaveStyles } = defaultOptions.leaveStyles
+ cy.get('header').should('be.hidden').checkStyles(leaveStyles)
})
})