-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
VersionProvider.tsx
92 lines (79 loc) 路 2.46 KB
/
VersionProvider.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import React, { useEffect } from 'react';
import { createContext, useContext } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import { Dispatch, RootState } from '../../store/store';
import { PackageMetaInterface } from '../../types/packageMeta';
function getRouterPackageName(packageName: string, scope?: string): string {
if (scope) {
return `@${scope}/${packageName}`;
}
return packageName;
}
export interface DetailContextProps {
hasNotBeenFound: boolean;
isLoading: boolean;
packageMeta: PackageMetaInterface;
packageName: string;
packageVersion?: string;
readMe: string;
}
export interface VersionPageConsumerProps {
packageMeta: PackageMetaInterface;
packageName: string;
packageVersion?: string;
readMe: string;
}
export const DetailContext = createContext<Partial<DetailContextProps>>({});
interface Params {
scope?: string;
package: string;
version?: string;
}
/**
*
* @example
Once a component has been wrapped with `VersionProvider`, use the hook `useVersion()` to get an object with:
```jsx
function CustomComponent() {
const { packageMeta, packageName, packageVersion } = useVersion();
return <div />;
}
<Route path={Routes.PACKAGE}>
<VersionProvider>
<CustomComponent />
</VersionProvider>
</Route>;
```
On mount, the provider will fetch data from the store for specific package or version provided via router.
@category Provider
*/
const VersionProvider: React.FC<{ children: any }> = ({ children }) => {
const { version: packageVersion, package: pkgName, scope } = useParams<Params>();
// @ts-ignore
const { manifest, readme, packageName, hasNotBeenFound } = useSelector(
(state: RootState) => state.manifest
);
const isLoading = useSelector((state: RootState) => state?.loading?.models.manifest);
const dispatch = useDispatch<Dispatch>();
useEffect(() => {
const packageName = getRouterPackageName(pkgName, scope);
dispatch.manifest.getManifest({ packageName, packageVersion });
}, [dispatch, packageVersion, pkgName, scope]);
return (
<DetailContext.Provider
value={{
packageMeta: manifest,
packageVersion,
readMe: readme,
packageName,
isLoading,
hasNotBeenFound,
}}
>
{children}
</DetailContext.Provider>
);
};
export default VersionProvider;
export const useVersion = () => useContext(DetailContext);