-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
83 Show-hide user search bar on scroll (#85)
* initial scroll context provider * hide/show search toolbar on scroll * tests * tests * fixes
- Loading branch information
Showing
8 changed files
with
207 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { renderHook as renderHookWithoutWrapper } from '@testing-library/react'; | ||
|
||
import { act, renderHook, waitFor } from 'test/test-utils'; | ||
|
||
import { useScrollContext } from '../useScrollContext'; | ||
|
||
describe('useScrollContext', () => { | ||
it('should return context', async () => { | ||
// ARRANGE | ||
const { result } = renderHook(() => useScrollContext()); | ||
await waitFor(() => expect(result.current).not.toBeNull()); | ||
|
||
// ASSERT | ||
expect(result.current).toBeDefined(); | ||
expect(result.current.handleIonScroll).toBeDefined(); | ||
expect(result.current.scrollDirection).toBeUndefined(); | ||
}); | ||
|
||
it('should return default context', async () => { | ||
// ARRANGE | ||
const { result } = renderHookWithoutWrapper(() => useScrollContext()); | ||
await waitFor(() => expect(result.current).not.toBeNull()); | ||
|
||
// ACT | ||
act(() => | ||
result.current.handleIonScroll({ | ||
// @ts-expect-error required detail attributes only | ||
detail: { | ||
startY: 0, | ||
currentY: 100, | ||
}, | ||
}), | ||
); | ||
|
||
// ASSERT | ||
expect(result.current).toBeDefined(); | ||
expect(result.current.handleIonScroll).toBeDefined(); | ||
expect(result.current.scrollDirection).toBeUndefined(); | ||
}); | ||
|
||
it('should set scroll direction down', async () => { | ||
// ARRANGE | ||
const { result } = renderHook(() => useScrollContext()); | ||
await waitFor(() => expect(result.current).not.toBeNull()); | ||
|
||
// ACT | ||
act(() => | ||
result.current.handleIonScroll({ | ||
// @ts-expect-error required detail attributes only | ||
detail: { | ||
startY: 0, | ||
currentY: 100, | ||
}, | ||
}), | ||
); | ||
|
||
// ASSERT | ||
expect(result.current).toBeDefined(); | ||
expect(result.current.handleIonScroll).toBeDefined(); | ||
expect(result.current.scrollDirection).toBe('down'); | ||
}); | ||
|
||
it('should set scroll direction up', async () => { | ||
// ARRANGE | ||
const { result } = renderHook(() => useScrollContext()); | ||
await waitFor(() => expect(result.current).not.toBeNull()); | ||
|
||
// ACT | ||
act(() => | ||
result.current.handleIonScroll({ | ||
// @ts-expect-error required detail attributes only | ||
detail: { | ||
startY: 100, | ||
currentY: 0, | ||
}, | ||
}), | ||
); | ||
|
||
// ASSERT | ||
expect(result.current).toBeDefined(); | ||
expect(result.current.handleIonScroll).toBeDefined(); | ||
expect(result.current.scrollDirection).toBe('up'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { useContext } from 'react'; | ||
|
||
import { ScrollContext, ScrollContextValue } from 'common/providers/ScrollProvider'; | ||
|
||
/** | ||
* The `useScrollContext` hook returns the current `ScrollContext` value. | ||
* @returns {ScrollContextValue} The current `ScrollContext` value, a | ||
* `ScrollContextValue` object. | ||
* @see {@link ScrollContextValue} | ||
*/ | ||
export const useScrollContext = (): ScrollContextValue => { | ||
const context = useContext(ScrollContext); | ||
|
||
return context; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { createContext, PropsWithChildren, useState } from 'react'; | ||
import { ScrollCustomEvent } from '@ionic/core'; | ||
|
||
/** | ||
* The `ScrollDirection` type describes the direction of the scroll. | ||
*/ | ||
export type ScrollDirection = 'down' | 'up'; | ||
|
||
/** | ||
* The `value` provided by the `ScrollContext`. | ||
*/ | ||
export type ScrollContextValue = { | ||
scrollDirection?: ScrollDirection; | ||
handleIonScroll: (e: ScrollCustomEvent) => void; | ||
}; | ||
|
||
/** | ||
* Default value for the `ScrollContext`. | ||
*/ | ||
const DEFAULT_VALUE: ScrollContextValue = { | ||
handleIonScroll: () => {}, | ||
}; | ||
|
||
/** | ||
* The `ScrollContext` instance. | ||
*/ | ||
export const ScrollContext = createContext<ScrollContextValue>(DEFAULT_VALUE); | ||
|
||
/** | ||
* The `ScrollProvider` component creates and provides access to the `ScrollContext` | ||
* value. Provides information regarding scroll events. | ||
* | ||
* Useful when integrated with scroll events emitted by components such as `IonContent`. | ||
* | ||
* *Example:* | ||
* ``` | ||
* const { handleIonScroll, scrollDirection } = useScrollContext(); | ||
* ... | ||
* <IonContent scrollEvents onIonScroll={handleIonScroll}> | ||
* <IonText className={classNames('ion-hide', scrollDirection==='down')}> | ||
* I am hidden when scrolling down! | ||
* </IonText> | ||
* </IonContent> | ||
* ``` | ||
* @param {PropsWithChildren} props - Component properties. | ||
* @returns {JSX.Element} JSX | ||
*/ | ||
const ScrollProvider = ({ children }: PropsWithChildren): JSX.Element => { | ||
const [scrollDirection, setScrollDirection] = useState<ScrollDirection | undefined>(undefined); | ||
|
||
const handleIonScroll = (event: ScrollCustomEvent) => { | ||
const { currentY, startY } = event.detail; | ||
const scrollY = currentY - startY; | ||
if (scrollY > 0) { | ||
setScrollDirection('down'); | ||
} else if (scrollY < 0) { | ||
setScrollDirection('up'); | ||
} | ||
}; | ||
|
||
const contextValue: ScrollContextValue = { | ||
scrollDirection: scrollDirection, | ||
handleIonScroll: handleIonScroll, | ||
}; | ||
|
||
return <ScrollContext.Provider value={contextValue}>{children}</ScrollContext.Provider>; | ||
}; | ||
|
||
export default ScrollProvider; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
|
||
import { render, screen } from 'test/test-utils'; | ||
|
||
import ScrollProvider from '../ScrollProvider'; | ||
|
||
describe('ScrollProvider', () => { | ||
it('should render successfully', async () => { | ||
// ARRANGE | ||
render( | ||
<ScrollProvider> | ||
<div data-testid="scroll-provider-children"></div> | ||
</ScrollProvider>, | ||
); | ||
await screen.findByTestId('scroll-provider-children'); | ||
|
||
// ASSERT | ||
expect(screen.getByTestId('scroll-provider-children')).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters