Skip to content

Commit 77aa75f

Browse files
authored
Package v2.0.0 in TypeScript (#10)
Library Rewritten in TypeScript Now createUseContext returns only hook, to actually use Context in a type-safe manner All the wrappers for Providers removed Helper createWithContext removed as non actual
1 parent b81dd6d commit 77aa75f

15 files changed

+369
-1192
lines changed

.babelrc

Lines changed: 0 additions & 3 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Changelog
2+
3+
## 2.0.0
4+
5+
### New features
6+
7+
- Library Rewritten in TypeScript
8+
- Now `createUseContext` returns only hook, to actually use `Context` in a type-safe manner
9+
- All the wrappers for Providers removed
10+
- Helper `createWithContext` removed as non actual

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2019 Eugene Mickhnitskyy
3+
Copyright (c) 2023 Yevgenii Mikhnytskyi
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 39 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,59 @@
11
# create-use-context
22

3-
A helper method which wraps original React `createContext` method and provides additional functionality like wrapping a `Context.Provider`, `useContext` helper, etc.
3+
A helper method which wraps original React `createContext` method and type-safe `useContext` hook which will throw if used outside of `Provider`.
44

55
## Installation
66

7-
```
8-
# with NPM:
7+
Using NPM:
98

9+
```sh
1010
npm install create-use-context
11+
```
1112

12-
# with Yarn:
13+
Using Yarn:
1314

15+
```sh
1416
yarn add create-use-context
1517
```
1618

19+
## Screenshot
20+
21+
Mind the `useMyContext` return type is `NonNullable` context value. It will throw if used outside of `Provider`
22+
23+
![Screenshot](Screenshot.png)
24+
1725
## Usage
1826

19-
```javascript
20-
import React, { Component, useState } from 'react';
27+
```tsx
28+
import React, { createContext, useState, FC, Dispatch, SetStateAction } from 'react';
29+
import { createUseContext } from 'create-use-context';
30+
31+
type Counter = number;
2132

22-
import { createUseContext, createWithContext } from 'create-use-context';
33+
const INITIAL_COUNT: Counter = 0;
2334

24-
const {
25-
Context: MyContext,
26-
ContextProvider: MyContextProvider,
27-
ContextConsumer: MyContextConsumer,
28-
useContext: useMyContext,
29-
} = createUseContext((Provider) => ({ children }) => {
30-
const [counter, setCounter] = useState(0);
35+
export interface MyContextValue {
36+
counter: Counter;
37+
setCounter: Dispatch<SetStateAction<Counter>>;
38+
}
39+
40+
export const MyContext = createContext<MyContextValue | null>(null);
41+
42+
MyContext.displayName = 'MyContext';
43+
44+
export const MyContextProvider: FC = ({ children }) => {
45+
const [counter, setCounter] = useState(INITIAL_COUNT);
46+
47+
return (
48+
<MyContext.Provider value={{ counter, setCounter }}>
49+
{children}
50+
</MyContext.Provider>
51+
);
52+
};
3153

32-
return <Provider value={{ counter, setCounter }}>{children}</Provider>;
33-
});
54+
export const useMyContext = createUseContext(MyContext);
3455

35-
function ComponentWithHook() {
56+
export function ComponentWithHook() {
3657
const { counter, setCounter } = useMyContext();
3758

3859
return (
@@ -46,56 +67,11 @@ function ComponentWithHook() {
4667
);
4768
}
4869

49-
function ComponentWithConsumer() {
50-
return (
51-
<MyContextConsumer>
52-
{({ counter, setCounter }) => (
53-
<button
54-
onClick={() => {
55-
setCounter(counter + 1);
56-
}}
57-
>
58-
{counter} - add one
59-
</button>
60-
)}
61-
</MyContextConsumer>
62-
);
63-
}
64-
65-
// You might also need a High Order Component to wrap your class Components
66-
// if you don't line Render Prop pattern with a Consumer Component.
67-
68-
// So you can use `createWithContext` helper function:
69-
70-
const withMyContext = createWithContext(MyContext, 'my');
71-
72-
class ClassComponent extends Component {
73-
render() {
74-
const { counter, setCounter } = this.props.my;
75-
76-
return (
77-
<button
78-
onClick={() => {
79-
setCounter(counter + 1);
80-
}}
81-
>
82-
{counter} - add one
83-
</button>
84-
);
85-
}
86-
}
87-
88-
const ClassComponentWithHOC = withMyContext(ClassComponent);
89-
90-
function App() {
70+
export function App() {
9171
return (
9272
<MyContextProvider>
9373
<ComponentWithHook />
94-
<ComponentWithConsumer />
95-
<ClassComponentWithHOC />
9674
</MyContextProvider>
9775
);
9876
}
99-
100-
export default App;
10177
```

Screenshot.png

80.8 KB
Loading

package.json

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
{
2-
"author": "Eugene Mickhnitskyy",
3-
"dependencies": {
4-
"react-display-name": "0.2.4"
5-
},
2+
"author": "Yevgenii Mikhnytskyi",
3+
"dependencies": {},
4+
"type": "module",
65
"description": "A helper method which wraps original React `createContext` method and provides additional functionality like wrapping a `Context.Provider`, `useContext` helper, etc.",
76
"devDependencies": {
8-
"@babel/core": "7.7.4",
9-
"@babel/preset-env": "7.7.4",
10-
"@babel/preset-react": "7.7.4",
7+
"@rollup/plugin-terser": "^0.4.0",
8+
"@rollup/plugin-typescript": "^11.0.0",
9+
"@types/react": "^18.0.33",
10+
"install-peers-cli": "^2.2.0",
1111
"prettier": "1.19.1",
12-
"rollup": "1.27.5",
13-
"rollup-plugin-babel": "4.3.3"
12+
"rollup": "^3.20.2",
13+
"rollup-plugin-peer-deps-external": "^2.2.4",
14+
"tslib": "^2.5.0",
15+
"typescript": "^5.0.3"
1416
},
1517
"files": [
1618
"dist/cjs/*",
@@ -24,20 +26,22 @@
2426
],
2527
"license": "MIT",
2628
"main": "dist/cjs/index.js",
29+
"types": "dist/cjs/index.d.ts",
2730
"module": "dist/esm/index.js",
31+
"browser": "dist/esm/index.js",
2832
"name": "create-use-context",
2933
"peerDependencies": {
30-
"hoist-non-react-statics": "^3.3.0",
3134
"react": "^16.8.0"
3235
},
3336
"repository": {
3437
"type": "git",
3538
"url": "https://github.com/todesstoss/create-use-context.git"
3639
},
3740
"scripts": {
38-
"build": "rollup -c",
41+
"prepare": "install-peers",
42+
"build": "rollup -c --environment BUILD:production",
3943
"dev": "rollup -c -w",
4044
"test": "echo \"Error: no test specified\" && exit 1"
4145
},
42-
"version": "1.0.2"
46+
"version": "2.0.0"
4347
}

rollup.config.js

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
1-
import babel from 'rollup-plugin-babel';
1+
import typescript from '@rollup/plugin-typescript';
2+
import terser from '@rollup/plugin-terser';
3+
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
24

3-
export default [
4-
{
5-
input: {
6-
index: 'src/index.js',
7-
'create-use-context': 'src/createUseContext.js',
8-
'create-with-context': 'src/createWithContext.js',
5+
const production = process.env.BUILD === 'production';
6+
7+
function getConfig({ dir, format }) {
8+
return {
9+
input: 'src/index.ts',
10+
output: {
11+
exports: 'named',
12+
dir,
13+
format,
14+
sourcemap: true,
915
},
1016
plugins: [
11-
babel({
12-
exclude: 'node_modules/**',
13-
}),
14-
],
15-
output: [
16-
{
17-
exports: 'named',
18-
dir: 'dist/cjs',
19-
format: 'cjs',
20-
},
21-
{
22-
dir: 'dist/esm',
23-
format: 'esm',
24-
},
17+
peerDepsExternal(),
18+
typescript({ outDir: dir }),
19+
production && terser(),
2520
],
26-
external: ['react', 'hoist-non-react-statics', 'react-display-name'],
27-
},
21+
}
22+
}
23+
24+
export default [
25+
getConfig({ dir: 'dist/cjs', format: 'cjs' }),
26+
getConfig({ dir: 'dist/esm', format: 'esm' }),
2827
];

src/createUseContext.js

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/createUseContext.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useContext, Context } from 'react';
2+
3+
export function createUseContext<T>(context: Context<T>) {
4+
const value = useContext(context);
5+
6+
if (!value) {
7+
throw new Error(composeErrorMessage(context.displayName || 'Context'));
8+
}
9+
10+
return value;
11+
}
12+
13+
function composeErrorMessage(name: string) {
14+
return `use${name} has to be used within <${name}.Provider>`;
15+
}

src/createWithContext.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)