Comparing version 0.0.2 to 1.0.0-alpha.1
{ | ||
"name": "reusable", | ||
"version": "0.0.2", | ||
"description": "Library of highly reusable CSS classes for design, performance, and maintainability.", | ||
"main": "index.html", | ||
"version": "1.0.0-alpha.1", | ||
"description": "", | ||
"keywords": [], | ||
"main": "dist/reuse.js", | ||
"source": "src/index.js", | ||
"module": "dist/reuse.mjs", | ||
"unpkg": "dist/reuse.umd.js", | ||
"dependencies": {}, | ||
"peerDependencies": { | ||
"react": ">= 16.8", | ||
"react-dom": ">= 16.8" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.4.0", | ||
"@babel/preset-env": "^7.4.2", | ||
"@babel/preset-react": "^7.0.0", | ||
"concurrently": "^4.1.0", | ||
"jest": "^24.5.0", | ||
"lodash": "^4.17.11", | ||
"microbundle": "^0.11.0", | ||
"parcel": "^1.12.3", | ||
"react": "^16.8.5", | ||
"react-dom": "^16.8.5" | ||
}, | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"example": "parcel ./example/index.html --out-dir exampleDist", | ||
"build": "microbundle --jsx React.createElement", | ||
"build:dev": "microbundle watch --jsx React.createElement", | ||
"dev": "concurrently \"npm run build:dev\" \"npm run example\"", | ||
"test": "jest" | ||
}, | ||
"keywords": [ | ||
"atomic css", | ||
"functional css", | ||
"OOCSS", | ||
"reusable css" | ||
], | ||
"author": "Brian Zelip", | ||
"license": "MIT", | ||
"homepage": "https://reusablecss.github.io", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/reusablecss/reusablecss.github.io.git" | ||
} | ||
"browserslist": [ | ||
">0.2%", | ||
"not dead", | ||
"not ie <= 11", | ||
"not op_mini all" | ||
] | ||
} |
265
README.md
@@ -1,5 +0,264 @@ | ||
# Reusable CSS | ||
## What?! | ||
## Library of highly reusable CSS classes for design, performance, and maintainability. | ||
Reuse is a library for reusing state between React components. | ||
### Coming soon by [@bzelip](https://twitter.com/bzelip). | ||
## Why? | ||
Reuse solves the problems that state management is meant for, without unnecessary boilerplate or magic. | ||
React hooks introduced new ways of thinking about state and side-effects. | ||
These new ways made old habits obsolete, and require a new type of state management tool that embraces the same concepts: | ||
- Separation of concerns | ||
- Reusability | ||
- Simplicity | ||
While still providing the developers with structure and architecture with large-scale apps in mind. | ||
## Features | ||
- single-store | ||
- immutable | ||
- reactive | ||
- simple | ||
- predictable | ||
- performant | ||
- allow for reuse, encapsulation and modularity | ||
- gradually adoptable | ||
- SSR | ||
- Time travelling | ||
- extendable | ||
## What about Context API? | ||
The answer is pretty much the same for people asking about "Redux vs. Context API?" | ||
Using Context API directly gives a simple API to share state between components, but it doesn't provide other benefits that reuse provides, such as: | ||
- Time Travelling | ||
- Single Store | ||
- Compound Selectors | ||
- Structure | ||
- Easily reuse code that needs state management using custom hooks | ||
- Easily provide open source components that allow control of state | ||
## Is Reuse designed for large apps? | ||
Reuse is built with large-scale apps in mind. | ||
This is what affected most of the considerations when designing the solution: | ||
- The benefits of a single store and immutable data: | ||
- Allow a maintainable architecture and prevent tangled cross-stores access | ||
- Easier to reach deep UI states during development by overriding initial state | ||
- Easier to achieve undo/redo, state persistence | ||
- The ability to do code reuse using custom hooks to prevent code duplication | ||
- Supporting Redux DevTools for better debugging & QA | ||
- Support lazy-loaded modules | ||
## Basic Usage | ||
```javascript | ||
// App.js: | ||
import { ReuseProvider, createStore } from "reuse"; | ||
const initialState = { | ||
counter: 1 | ||
}; | ||
const store = createStore(initialState); // no reducer?! | ||
const App = () => ( | ||
<ReuseProvider store={store}> | ||
); | ||
// component #1: | ||
import { reuseState } from "reuse"; | ||
const CompOne = () => { | ||
const [counter, setCounter] = reuseState('counter'); | ||
return ... | ||
} | ||
// component #2: | ||
import { reuseState } from "reuse"; | ||
const CompOne = () => { | ||
const [counter, setCounter] = reuseState('counter'); // Yup, same counter as above | ||
return ... | ||
} | ||
``` | ||
## Custom Hooks | ||
```javascript | ||
// counter.state.js: | ||
import { reuseState } from "reuse"; | ||
const useCounterState = () => { | ||
const [counter, setCounter] = reuseState('counter'); | ||
return { | ||
value: counter, | ||
increment: () => setCounter(val => val + 1), | ||
decrement: () => setCounter(val => val - 1), | ||
reset: () => setCounter(1) | ||
} | ||
} | ||
// component: | ||
import {useCounterState} from '../states/counter.state'; | ||
const Comp = () => { | ||
const counterState = useCounterState(); | ||
return ... // Just use it! | ||
} | ||
``` | ||
## Compound selectors, memoizing: | ||
```javascript | ||
// No special tricks - just use hooks | ||
export const useCurrentUserBalance = () => { | ||
const [transactions] = reuseState("transactions"); | ||
const [currentUser] = reuseState("currentUser"); | ||
return useMemo( | ||
() => | ||
transactions | ||
.filter(({ userId }) => userId === currentUser.id) | ||
.reduce((sum, { amount }) => amount + sum, 0), | ||
[transactions, currentUser.id] | ||
); | ||
}; | ||
``` | ||
## Reusable components / NPM libraries: | ||
library | ||
```javascript | ||
import React, { useCallback } from "react"; | ||
import { reuseState } from "reuse"; | ||
// ControlledComponent | ||
export const Input = ({ value = "", setValue, placeholder = "" }) => { | ||
const onChange = useCallback(e => setValue(e.target.value), []); | ||
return <input value={value} onChange={onChange} placeholder={placeholder} />; | ||
}; | ||
// Reusable State Controller: | ||
export const reuseInputState = (path = "_my_lib_input_path") => { | ||
const state = reuseState(path); | ||
return controller(state); | ||
}; | ||
// Local State Controller: | ||
export const useInputState = () => { | ||
const state = useState(''); | ||
return controller(state); | ||
} | ||
const controller = [value, setValue] => ( | ||
{ | ||
value, | ||
setValue, | ||
clear: () => setValue("") | ||
}); | ||
``` | ||
Consumer: | ||
```javascript | ||
// Using the lib with re-used state: | ||
import { Input, reuseInputState } from "my-form-lib"; | ||
const Comp = () => { | ||
const inputState = reuseInputState("forms.user.0"); | ||
return <Input {...inputState} />; | ||
}; | ||
// Using the lib with local state: | ||
import { Input, useInputState } from "my-form-lib"; | ||
const Comp = () => { | ||
const inputState = useInputState(); | ||
return <Input {...inputState} />; | ||
}; | ||
``` | ||
## Time Travelling, Undo/Redo | ||
```javascript | ||
// App.js: | ||
import { ReuseProvider, createStore } from "reuse"; | ||
import { withHistory } from "reuse-history"; | ||
const initialState = { | ||
counter: 1 | ||
}; | ||
const store = withHistory(createStore)(initialState); // Oooh, cool | ||
const App = () => ( | ||
<ReuseProvider store={store}> | ||
); | ||
// component: | ||
import React from "react"; | ||
import { useHistory } from "reuse-history"; | ||
export const TimeTravel = () => { | ||
const { undo, redo, canUndo, canRedo } = useHistory(); // Oh! Even Cooler!! | ||
return ( | ||
<div> | ||
<button disabled={!canUndo()} onClick={undo}> | ||
Undo | ||
</button> | ||
<button disabled={!canRedo()} onClick={redo}> | ||
Redo | ||
</button> | ||
</div> | ||
); | ||
}; | ||
``` | ||
## Using a reducer (because why not) | ||
```javascript | ||
// counter.state.js: | ||
export const useCounterState = () => { | ||
const [counter, dispatch] = reuseState("ui.counter", (state, action) => { | ||
switch (action.type) { | ||
case "DECREMENT": | ||
return state - 1; | ||
case "INCREMENT": | ||
return state + 1; | ||
default: | ||
return state; | ||
} | ||
}); | ||
return { | ||
counter, | ||
decrement: () => dispatch({ type: "DECREMENT" }), | ||
increment: () => dispatch({ type: "INCREMENT" }) | ||
}; | ||
}; | ||
``` | ||
## Feedback: | ||
https://goo.gl/forms/Jza0XsM7F3shvWhD2 | ||
## What's missing: | ||
- Release to NPM | ||
- Support lazy-loaded modules | ||
- Async actions example | ||
- Tests | ||
- Redux DevTools integrations | ||
- Docs | ||
- Examples | ||
## Problems: | ||
- Save/Load state without keys |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
82119
27
601
265
2
10
1
2
4
1
3