├── .npmrc
├── .gitignore
├── jest.setup.js
├── .npmignore
├── .eslintrc.json
├── __tests__
└── index.js
├── lib
└── index.js
├── package.json
└── README.md
/.npmrc:
--------------------------------------------------------------------------------
1 | @evilfactory:registry=https://npm.pkg.github.com/
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | *.swp
3 | *.swp
4 | dist/
5 | *.log
6 |
--------------------------------------------------------------------------------
/jest.setup.js:
--------------------------------------------------------------------------------
1 | import '@testing-library/jest-dom/extend-expect'
2 | import '@testing-library/react/cleanup-after-each';
3 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | coverage
2 | fixtures
3 | __test__
4 | .*
5 | *.log
6 | docs/
7 | examples/
8 | rollup.config.js
9 | jest.config.js
10 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "jest": true
6 | },
7 | "extends": [
8 | "eslint:recommended",
9 | "plugin:react/recommended"
10 | ],
11 | "globals": {
12 | "Atomics": "readonly",
13 | "SharedArrayBuffer": "readonly"
14 | },
15 | "parserOptions": {
16 | "ecmaFeatures": {
17 | "jsx": true
18 | },
19 | "ecmaVersion": 2018,
20 | "sourceType": "module"
21 | },
22 | "plugins": [
23 | "react",
24 | "jest"
25 | ],
26 | "rules": {}
27 | }
28 |
--------------------------------------------------------------------------------
/__tests__/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {useGlobalState, StateProvider} from '../lib'
3 | import {fireEvent, render} from '@testing-library/react'
4 |
5 | const Provider = jest.fn(StateProvider)
6 |
7 | test('StateProvider & useGlobalState test', () => {
8 |
9 | const Props ={
10 | reducer: (state, action) => {
11 | switch(action.type){
12 | case 'TEST': return {
13 | ...state,
14 | test: true
15 | }
16 | default: return state
17 | }
18 | },
19 | initialState: {test: false}
20 | }
21 |
22 | const ShowTest = () => {
23 | const [{test}] = useGlobalState()
24 | return (
25 |
26 | {JSON.stringify(test)}
27 |
28 | )
29 | }
30 |
31 | const ChangeTest = () => {
32 | const [, dispatch] = useGlobalState()
33 |
34 | const handleClick = () => {
35 | dispatch({
36 | type: 'TEST'
37 | })
38 | }
39 |
40 | return ()
41 | }
42 |
43 | const {container, getByTestId } = render(
44 |
45 |
46 |
47 |
48 | )
49 |
50 | const showTest = getByTestId('showTest')
51 | const changeTest = getByTestId('changeTest')
52 |
53 | expect(Provider).toHaveBeenCalled()
54 | expect(showTest).toHaveTextContent('false')
55 | expect(container).toBeInTheDocument()
56 |
57 | fireEvent.click(changeTest)
58 | expect(showTest).toHaveTextContent('true')
59 |
60 | })
61 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @ignore
3 | * Main Function of useGlobalState
4 | *
5 | * https://github.com/evilfactorylabs/useGlobalState
6 | *
7 | * @version 1.0.0
8 | */
9 | import {
10 | createElement,
11 | createContext,
12 | useContext,
13 | useReducer,
14 | } from 'react'
15 |
16 |
17 | /**
18 | * @ignore
19 | * @var {createContext} StateContext
20 | */
21 | const StateContext = createContext()
22 |
23 | /**
24 | * @name
25 | * @param {Object} props
26 | * @property {Function} reducer **{@link https://reactjs.org/docs/hooks-reference.html#usereducer | useReducer}**
27 | * @property {Object} initialState
28 | * @property {Element} children **{@link https://reactjs.org/docs/react-api.html#createelement | createElement}**
29 | * @description
30 | * **** as Wrapper of your `React` Application.
31 | *
32 | * @example
Example Use of ``.
33 | * import React from 'react'
34 | * import App from './you-app.js'
35 | * import {StateProvider} from 'evilfactorylabs/global-state'
36 | *
37 | * const initialState = { todo: [] }
38 | *
39 | * function todoReducer(state, action) {
40 | * switch (action.type) {
41 | * case "ADD_TODO":
42 | * return {
43 | * ...state,
44 | * todo: [...state.todo, action.todo]
45 | * };
46 | * default:
47 | * return state;
48 | * }
49 | * }
50 | *
51 | * ReactDOM.render(
52 | *
53 | *
54 | *
55 | * , document.getElementById('root'))
56 | *
57 | */
58 | export const StateProvider = ({reducer, initialState, children }) => createElement(StateContext.Provider, {
59 | value: useReducer(reducer, initialState)
60 | }, children)
61 |
62 |
63 | /**
64 | * @function useGlobalState
65 | * @name useGlobalState
66 | * @param {Function=} newAction [optional]
67 | * @example
68 | * import {useGlobalState} from '@evilfactorylabs/global-state'
69 | *
70 | * ...
71 | * const createTodo = (state, action, todo) => {
72 | * return action({
73 | * type: 'ADD_TODO',
74 | * data: todo,
75 | * })
76 | * }
77 | *
78 | * const [,addTodo] = useGlobalState(createTodo)
79 | *
80 | * addTodo({title: 'New Task'})
81 | * ...
82 | */
83 |
84 | export const useGlobalState = (newAction) => {
85 | const [state, action] = useContext(StateContext)
86 | // newAction is action injector
87 | return [state, newAction ? newAction.bind(null, state, action) : action ]
88 | }
89 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@evilfactory/global-state",
3 | "version": "0.0.1",
4 | "description": "⚛️ Simple State Management from react to react powered by React Hook.",
5 | "repository": "git@github.com:evilfactorylabs/useGlobalState.git",
6 | "author": "ri7nz ",
7 | "license": "MIT",
8 | "private": false,
9 | "peerDependencies": {
10 | "react": "^16.8.0"
11 | },
12 | "files": [
13 | "lib",
14 | "dist"
15 | ],
16 | "jest": {
17 | "bail": true,
18 | "browser": true,
19 | "displayName": "global-state v0.0.1",
20 | "testEnvironment": "jest-environment-jsdom",
21 | "transform": {
22 | "^.+\\.[t|j]sx?$": "babel-jest"
23 | },
24 | "setupFilesAfterEnv": [
25 | "./jest.setup.js"
26 | ],
27 | "testMatch": [
28 | "**/__tests__/**/*.js?(x)"
29 | ],
30 | "verbose": true
31 | },
32 | "babel": {
33 | "presets": [
34 | [
35 | "@babel/preset-env",
36 | {
37 | "targets": {
38 | "node": true
39 | }
40 | }
41 | ],
42 | "@babel/preset-react"
43 | ],
44 | "plugins": []
45 | },
46 | "source": "lib/index.js",
47 | "main": "dist/index.js",
48 | "module": "dist/index.m.js",
49 | "unpkg": "dist/index.umd.js",
50 | "scripts": {
51 | "build": "npm-run-all --silent -p build:* -s size",
52 | "build:microbundle": "microbundle",
53 | "size": "strip-json-comments --no-whitespace dist/*.js | gzip-size ",
54 | "build:docs": "documentation readme lib/*.js -q --section API && yarn fixreadme",
55 | "dev": "microbundle --watch",
56 | "lint": "eslint ./lib --fix",
57 | "prepare": "rm -rf dist && yarn test && yarn build",
58 | "release": "yarn -s prepare && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish",
59 | "test": "jest",
60 | "test:watch": "jest --watch",
61 | "fixreadme": "node -e 'var fs=require(\"fs\");fs.writeFileSync(\"README.md\", fs.readFileSync(\"README.md\", \"utf8\").replace(/^- /gm, \"- \"))'",
62 | "docs": "documentation readme lib/*.js -q --section API && yarn fixreadme"
63 | },
64 | "devDependencies": {
65 | "@babel/core": "^7.5.5",
66 | "@babel/preset-env": "7.5.5",
67 | "@babel/preset-react": "7.0.0",
68 | "@testing-library/jest-dom": "4.0.0",
69 | "@testing-library/react": "8.0.7",
70 | "babel-jest": "24.8.0",
71 | "documentation": "12.0.3",
72 | "eslint": "6.1.0",
73 | "eslint-plugin-jest": "22.14.0",
74 | "eslint-plugin-react": "7.14.3",
75 | "gzip-size-cli": "3.0.0",
76 | "jest": "24.8.0",
77 | "microbundle": "0.11.0",
78 | "npm-run-all": "4.1.5",
79 | "react": "16.11.0",
80 | "react-dom": "16.8.6",
81 | "strip-json-comments-cli": "1.0.1"
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # `@evilfactory/global-state`
2 |
3 | ⚛️ Simple State Management from react to react powered by React Hook.
4 |
5 | # Install
6 |
7 | - [Yarn](https://yarnpkg.com/en/)
8 |
9 | ```bash
10 | $ yarn add -E @evilfactory/global-state
11 | ```
12 |
13 | - [NPM](https://www.npmjs.com/)
14 |
15 | ```bash
16 | $ npm i @evilfactory/global-state
17 | ```
18 |
19 | ## Usage
20 |
21 | - [Example CodeSandbox](https://codesandbox.io/s/evilfactoryglobal-state-example-rc4b4)
22 |
23 |
24 |
25 | # Features
26 |
27 | - [x] Zero configuration ✅.
28 | - [x] React hooks based API ✅.
29 | - [x] React Native supported ✅.
30 | - [x] Global State & shareable ✅.
31 | - [ ] Redux Dev Tools supported 🙏.
32 |
33 | # API
34 |
35 |
36 |
37 | ### Table of Contents
38 |
39 | - [StateProvider](#stateprovider)
40 | - [Parameters](#parameters)
41 | - [Properties](#properties)
42 | - [Examples](#examples)
43 | - [useGlobalState](#useglobalstate)
44 | - [Parameters](#parameters-1)
45 | - [Examples](#examples-1)
46 |
47 | ## StateProvider
48 |
49 | **** as Wrapper of your `React` Application.
50 |
51 | ### Parameters
52 |
53 | - `props` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
54 | - `props.reducer`
55 | - `props.initialState`
56 | - `props.children`
57 |
58 | ### Properties
59 |
60 | - `reducer` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** **[| useReducer](https://reactjs.org/docs/hooks-reference.html#usereducer)**
61 | - `initialState` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
62 | - `children` **[Element](https://developer.mozilla.org/docs/Web/API/Element)** **[| createElement](https://reactjs.org/docs/react-api.html#createelement)**
63 |
64 | ### Examples
65 |
66 | Example Use of ``.
67 |
68 |
69 | ```javascript
70 | import React from 'react'
71 | import App from './you-app.js'
72 | import {StateProvider} from 'evilfactorylabs/global-state'
73 |
74 | const initialState = { todo: [] }
75 |
76 | function todoReducer(state, action) {
77 | switch (action.type) {
78 | case "ADD_TODO":
79 | return {
80 | ...state,
81 | todo: [...state.todo, action.todo]
82 | };
83 | default:
84 | return state;
85 | }
86 | }
87 |
88 | ReactDOM.render(
89 |
90 |
91 |
92 | , document.getElementById('root'))
93 | ```
94 |
95 | ## useGlobalState
96 |
97 | ### Parameters
98 |
99 | - `newAction` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** [optional]
100 |
101 | ### Examples
102 |
103 | ```javascript
104 | import {useGlobalState} from '@evilfactorylabs/global-state'
105 |
106 | ...
107 | const createTodo = (state, action, todo) => {
108 | return action({
109 | type: 'ADD_TODO',
110 | data: todo,
111 | })
112 | }
113 |
114 | const [,addTodo] = useGlobalState(createTodo)
115 |
116 | addTodo({title: 'New Task'})
117 | ...
118 | ```
119 |
--------------------------------------------------------------------------------