Skip to content

Commit 91be713

Browse files
committed
refactor(banners): react context doesnt work with generics
1 parent ba4a4b7 commit 91be713

File tree

3 files changed

+38
-39
lines changed

3 files changed

+38
-39
lines changed

packages/banners/src/translators/reactjs/BannersProvider.test.tsx

+14-19
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ import {renderHook, act} from '@testing-library/react-hooks'
1010

1111
import {BannersProvider, useBanners} from './BannersProvider'
1212

13-
const bannersManagerMock: Banners.Manager = {
13+
const bannersManagerMock: Banners.Manager<'t'> = {
1414
dismiss: jest.fn(),
1515
dismissedAt: jest.fn(),
1616
}
1717

18-
type Props = {
18+
type Props<K extends string = string> = {
1919
queryClient: QueryClient
20-
bannersManager?: Banners.Manager
20+
bannersManager?: Banners.Manager<K>
2121
}
2222

2323
export const wrapperManagerFixture =
24-
({queryClient, bannersManager}: Props) =>
24+
<K extends string = string>({queryClient, bannersManager}: Props<K>) =>
2525
({children}: {children: React.ReactNode}) =>
2626
(
2727
<QueryClientProvider client={queryClient}>
@@ -36,7 +36,7 @@ export const wrapperManagerFixture =
3636
)
3737

3838
export const wrapperManagerFixtureMissing =
39-
({queryClient}: Props) =>
39+
({queryClient}: {queryClient: QueryClient}) =>
4040
({children}: {children: React.ReactNode}) =>
4141
(
4242
<QueryClientProvider client={queryClient}>
@@ -46,7 +46,7 @@ export const wrapperManagerFixtureMissing =
4646
</QueryClientProvider>
4747
)
4848

49-
describe('ResolverProvider', () => {
49+
describe('BannersProvider', () => {
5050
let queryClient: QueryClient
5151

5252
beforeEach(() => {
@@ -58,14 +58,13 @@ describe('ResolverProvider', () => {
5858
queryClient.clear()
5959
})
6060

61-
it('works', () => {
61+
it('works when provider is set', () => {
6262
const wrapper = wrapperManagerFixture({
6363
queryClient,
6464
bannersManager: bannersManagerMock,
6565
})
66-
const {result} = renderHook(() => useBanners(), {
67-
wrapper,
68-
})
66+
67+
const {result} = renderHook(() => useBanners(), {wrapper})
6968

7069
act(() => {
7170
result.current.manager.dismiss('test-banner')
@@ -76,15 +75,11 @@ describe('ResolverProvider', () => {
7675
expect(bannersManagerMock.dismissedAt).toHaveBeenCalledWith('test-banner')
7776
})
7877

79-
it('fails', () => {
80-
const wrapper = wrapperManagerFixtureMissing({
81-
queryClient,
82-
})
83-
const {result} = renderHook(() => useBanners(), {
84-
wrapper,
85-
})
78+
it('fails when provider is missing', () => {
79+
const wrapper = wrapperManagerFixtureMissing({queryClient})
80+
81+
const {result} = renderHook(() => useBanners(), {wrapper})
8682

87-
expect(() => result.current.manager.dismiss('test-banner')).toThrow()
88-
expect(() => result.current.manager.dismissedAt('test-banner')).toThrow()
83+
expect(result.current).toBeUndefined()
8984
})
9085
})
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,37 @@
1-
import {invalid} from '@yoroi/common'
21
import {Banners} from '@yoroi/types'
32
import * as React from 'react'
43

5-
interface BannersContextProps {
6-
manager: Readonly<Banners.Manager>
4+
interface BannersContextProps<K extends string = string> {
5+
manager: Readonly<Banners.Manager<K>>
76
}
87

9-
const bannersManagerInitial: Banners.Manager = {
10-
dismiss: (_id: string) => invalid('Banners Manager not provided'),
11-
dismissedAt: (_id: string) => invalid('Banners Manager not provided'),
12-
}
13-
const BannersContext = React.createContext<BannersContextProps>({
14-
manager: bannersManagerInitial,
15-
})
8+
const BannersContext = React.createContext<
9+
BannersContextProps<any> | undefined
10+
>(undefined)
1611

17-
export const BannersProvider = ({
12+
export const BannersProvider = <K extends string>({
1813
children,
1914
manager,
20-
}: {
21-
children: React.ReactNode
22-
manager: Readonly<Banners.Manager>
23-
}) => {
15+
}: React.PropsWithChildren<{
16+
manager: Readonly<Banners.Manager<K>>
17+
}>) => {
2418
const context = React.useMemo(() => ({manager}), [manager])
19+
2520
return (
2621
<BannersContext.Provider value={context}>
2722
{children}
2823
</BannersContext.Provider>
2924
)
3025
}
3126

32-
export const useBanners = (): BannersContextProps =>
33-
React.useContext(BannersContext)
27+
export const useBanners = <
28+
K extends string = string,
29+
>(): BannersContextProps<K> => {
30+
const context = React.useContext(BannersContext)
31+
32+
if (!context) {
33+
throw new Error('useBanners must be used within a BannersProvider')
34+
}
35+
36+
return context as BannersContextProps<K>
37+
}

packages/banners/src/translators/reactjs/useBanner.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import {Banners} from '@yoroi/types'
22
import {freeze} from 'immer'
33
import * as React from 'react'
44

5-
export function useBanner({
5+
export function useBanner<K extends string = string>({
66
id,
77
manager,
88
}: Readonly<{
9-
id: string
10-
manager: Readonly<Banners.Manager>
9+
id: K
10+
manager: Readonly<Banners.Manager<K>>
1111
}>) {
1212
const [dismissedAt, setDismissedAt] = React.useState(manager.dismissedAt(id))
1313
return React.useMemo(() => {

0 commit comments

Comments
 (0)