Skip to content

Commit 653ecb1

Browse files
committed
feat: add loading
1 parent 6ade9d8 commit 653ecb1

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
<a href="https://www.npmjs.com/package/ionic-react-header-parallax"><img src="https://img.shields.io/npm/dt/ionic-react-header-parallax.svg?style=for-the-badge"></a>
2222
</p>
2323

24-
2524
## [Live Demo](https://github-mjaqg5-pzh6fv.stackblitz.io)
2625

2726
## [Stackblitz Editor URL](https://stackblitz.com/edit/github-mjaqg5-pzh6fv?file=src/pages/Home.tsx)

src/useIonicHeaderParallax.ts

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,38 @@ export type UseIonHeaderParallaxInput = {
55
expandedColor?: string
66
titleColor?: string
77
maximumHeight?: number
8+
defaultImage: string
9+
showBarButtons?: boolean
810
}
911

1012
export type UseIonHeaderParallaxResult = {
1113
ref: React.RefObject<any>
14+
loading: boolean
1215
}
1316

1417
export function useIonHeaderParallax({
1518
image,
19+
defaultImage = image,
1620
titleColor = '#AAA',
1721
expandedColor = '#313131',
1822
maximumHeight = 300,
23+
showBarButtons = false,
1924
}: UseIonHeaderParallaxInput): UseIonHeaderParallaxResult {
20-
/** styles */
2125
const [ticking, setTicking] = React.useState<boolean>(false)
26+
const [loading, setLoading] = React.useState<boolean>(true)
2227

2328
const ref: React.RefObject<any> = React.useRef<any>(null)
2429

2530
React.useEffect(() => {
26-
setTimeout(() => {
31+
setLoading(true)
32+
const timeout = setTimeout(() => {
2733
initElements()
34+
setLoading(false)
2835
}, 300)
29-
}, [image, titleColor, expandedColor, maximumHeight, ref])
36+
return () => {
37+
clearTimeout(timeout)
38+
}
39+
}, [image, titleColor, expandedColor, maximumHeight, ref.current])
3040

3141
const initElements = () => {
3242
// ion-header
@@ -37,7 +47,7 @@ export function useIonHeaderParallax({
3747

3848
// ion-toolbar
3949
const toolbar = header.querySelector('ion-toolbar') as HTMLElement
40-
if (!toolbar) throw new Error('No <ion-toolbar>')
50+
if (!toolbar) throw new Error('Parallax requires an <ion-toolbar> element on the page to work')
4151

4252
// ion-toolbar background
4353
const toolbarShadowRoot = toolbar.shadowRoot
@@ -56,10 +66,11 @@ export function useIonHeaderParallax({
5666
if (!ionContent) throw new Error('Parallax requires an <ion-content> element on the page to work.')
5767
const scrollContent = ionContent.shadowRoot?.querySelector('.inner-scroll') as HTMLElement
5868
if (!scrollContent) {
59-
throw new Error('Parallax directive requires an <ion-content> element on the page to work.')
69+
return
70+
//throw new Error('Parallax directive requires an <ion-content> element on the page to work.')
6071
}
6172

62-
// create image overly
73+
// create image overlay
6374
const imageOverlay = document.createElement('div')
6475
imageOverlay.classList.add('image-overlay')
6576
const colorOverlay = document.createElement('div')
@@ -69,20 +80,6 @@ export function useIonHeaderParallax({
6980

7081
const overlayTitle = ionTitle && (ionTitle.cloneNode(true) as HTMLElement)
7182

72-
if (overlayTitle) {
73-
overlayTitle.classList.add('parallax-title')
74-
75-
setTimeout(() => {
76-
if (overlayTitle.shadowRoot) {
77-
const toolbarTitle = overlayTitle.shadowRoot.querySelector('.toolbar-title') as HTMLElement
78-
toolbarTitle.style.pointerEvents = 'unset'
79-
}
80-
}, 200)
81-
}
82-
83-
if (overlayTitle) {
84-
imageOverlay.appendChild(overlayTitle)
85-
}
8683
if (barButtons) {
8784
imageOverlay.appendChild(barButtons)
8885
}
@@ -91,10 +88,9 @@ export function useIonHeaderParallax({
9188
// still in init use JS DOM
9289
setTicking(false)
9390

94-
// fetch styles
9591
maximumHeight = parseFloat(maximumHeight.toString())
9692
let headerMinHeight = toolbar.offsetHeight
97-
93+
// fetch styles
9894
const originalToolbarBgColor = window.getComputedStyle(toolbarBackground as Element, null).backgroundColor
9995
if (!originalToolbarBgColor) {
10096
throw new Error('Error: toolbarBackround is null.')
@@ -104,6 +100,13 @@ export function useIonHeaderParallax({
104100
header.style.position = 'relative'
105101

106102
if (overlayTitle) {
103+
setTimeout(() => {
104+
if (overlayTitle.shadowRoot) {
105+
const toolbarTitle = overlayTitle.shadowRoot.querySelector('.toolbar-title') as HTMLElement
106+
toolbarTitle.style.pointerEvents = 'unset'
107+
}
108+
}, 200)
109+
imageOverlay.appendChild(overlayTitle)
107110
overlayTitle.style.color = titleColor
108111
overlayTitle.style.position = 'absolute'
109112
overlayTitle.style.width = '100%'
@@ -123,7 +126,7 @@ export function useIonHeaderParallax({
123126

124127
// image overlay
125128
imageOverlay.style.backgroundColor = expandedColor
126-
imageOverlay.style.backgroundImage = `url(${image})`
129+
imageOverlay.style.backgroundImage = `url(${image || defaultImage})`
127130
imageOverlay.style.height = '100%'
128131
imageOverlay.style.width = '100%'
129132
imageOverlay.style.pointerEvents = 'none'
@@ -136,7 +139,6 @@ export function useIonHeaderParallax({
136139
// .bar-buttons
137140
if (barButtons) {
138141
barButtons.style.pointerEvents = 'all'
139-
140142
Array.from(barButtons.children).forEach((btn) => {
141143
// console.log(btn, btn as HTMLElement)
142144
const htmlBtn = btn as HTMLElement
@@ -146,11 +148,7 @@ export function useIonHeaderParallax({
146148

147149
// .scroll-content
148150
if (scrollContent) {
149-
scrollContent.setAttribute('parallax', '')
150151
scrollContent.style.paddingTop = `${maximumHeight}px`
151-
}
152-
153-
if (scrollContent) {
154152
scrollContent.addEventListener('scroll', (_e) => {
155153
if (!ticking) {
156154
window.requestAnimationFrame(() => {
@@ -172,22 +170,30 @@ export function useIonHeaderParallax({
172170
imageOverlay.style.opacity = `${progress}`
173171
colorOverlay.style.height = `${targetHeight}px`
174172
colorOverlay.style.opacity = targetHeight > headerMinHeight ? '1' : '0'
173+
174+
/* TODO: add support for dark mode for toolbar*/
175175
toolbarBackground.style.backgroundColor =
176176
targetHeight > headerMinHeight ? 'transparent' : originalToolbarBgColor
177177

178178
// .bar-buttons
179-
if (barButtons) {
179+
if (barButtons && showBarButtons) {
180180
if (targetHeight > headerMinHeight) {
181181
imageOverlay.append(barButtons)
182182
Array.from(barButtons.children).forEach((btn) => {
183183
const htmlBtn = btn as HTMLElement
184-
htmlBtn.style.color = titleColor
184+
if (htmlBtn) {
185+
htmlBtn.style.color = titleColor
186+
// allow custom styles TODO
187+
}
185188
})
186189
} else {
187190
toolbar.append(barButtons)
188191
Array.from(barButtons.children).forEach((btn) => {
189192
const htmlBtn = btn as HTMLElement
190-
htmlBtn.style.color = 'unset'
193+
if (htmlBtn) {
194+
htmlBtn.style.color = 'unset'
195+
// allow custom styles TODO
196+
}
191197
})
192198
}
193199
}
@@ -201,5 +207,6 @@ export function useIonHeaderParallax({
201207

202208
return {
203209
ref,
210+
loading,
204211
}
205212
}

types/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ export type UseIonHeaderParallaxInput = {
55
expandedColor?: string
66
titleColor?: string
77
maximumHeight?: number
8+
defaultImage: string
9+
showBarButtons?: boolean
810
}
911

1012
export type UseIonHeaderParallaxResult = {
1113
ref: React.RefObject<any>
14+
loading: boolean
1215
}
1316

1417
export function useIonHeaderParallax(input: UseIonHeaderParallaxInput): UseIonHeaderParallaxResult

0 commit comments

Comments
 (0)