{"bugs":{"url":"https://github.com/renatorib/react-powerplug/issues"},"dist":{"shasum":"16f6789a92f22e7c1c770da9093ac62890867ef0","tarball":"https://registry.npmjs.org/react-powerplug/-/react-powerplug-1.0.0-alpha.2.tgz","fileCount":78,"integrity":"sha512-PerhoNhnX2o1E7BICGaOBx1QXdGKwfvjffz0CeM3xtvM/doHcYM7p/5DPfsvqC/UTmYG97Wd4TWc+9pwcz2uwg==","signatures":[{"sig":"MEQCIATkFIxq2CEH+cpw2G85MpIzB3Qaw71jWBO0jElx5TKKAiBA/EwbcuJDFeEDu9z0UVpfjuONA+xGrNi7rV72QnAI/w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":122186},"jest":{"transformIgnorePatterns":["/node_modules/","/lib/","/dist/"]},"main":"lib/index.js","name":"react-powerplug","files":["dist","lib","src","es"],"author":{"url":"http://github.com/renatorib","name":"Renato Ribeiro"},"module":"es/index.js","readme":"<p align=\"center\">\n  <img src=\"./logo.png\" alt=\"react-powerplug\" />\n</p>\n\n<h1 align=\"center\"></h1>\n\n<br />\n\n> This branch is **unstable** and is in **active development**.  \n> To the latest stable version go to [0.1-stable branch](/tree/0.1-stable)\n\n[![npm](https://img.shields.io/npm/v/react-powerplug.svg?style=flat-square)](https://www.npmjs.com/package/react-powerplug)\n[![npm](https://img.shields.io/npm/dt/react-powerplug.svg?style=flat-square)](https://www.npmjs.com/package/react-powerplug)\n[![GitHub issues](https://img.shields.io/github/issues/renatorib/react-powerplug.svg?style=flat-square)](https://github.com/renatorib/react-powerplug/issues)\n[![GitHub stars](https://img.shields.io/github/stars/renatorib/react-powerplug.svg?style=flat-square)](https://github.com/renatorib/react-powerplug/stargazers)\n[![Twitter](https://img.shields.io/twitter/url/https/github.com/renatorib/react-powerplug.svg?style=social&style=flat-square)](https://twitter.com/intent/tweet?url=https://github.com/renatorib/react-powerplug)\n\n:electric_plug: Renderless Pluggable State Containers\n\n---\n\n**React PowerPlug is a set of pluggable renderless components** that provides different types of state and logics so you can use with your dumb components. It creates a state and pass down the logic to the children, so you can handle your data/callbacks.\n\nIt's has been created to (but not limited to) use with **storybook, react styleguidist, documentations, prototypes**. You can also use to create a bunch of uncontrolled components where the outside app don't care about your state, for example a menu dropdown.\n\n### Quick examples:\n\n```jsx\nimport { State, Toggle } from 'react-powerplug'\nimport { Pagination, Tabs, Checkbox } from './MyDumbComponents'\n\n<State initial={{ offset: 0, limit: 10, totalCount: 200 }}>\n  {({ state, setState }) => (\n    <Pagination {...state} onChange={(offset) => setState({ offset })} />\n  )}\n</State>\n\n<Toggle initial={true}>\n  {({ on, toggle }) => (\n    <Checkbox checked={on} onChange={toggle} />\n  )}\n</Toggle>\n\n// You can also use a `render` prop instead\n\n<Toggle\n  initial={false}\n  render={({ on, toggle }) => (\n    <Checkbox checked={on} onChange={toggle}>\n  )}\n/>\n```\n\n# Renderless Components\n\nNote: Also known as `render props` or `children as function`.  \nFor most people, this may look pretty weird. **But it's extremely powerful**. Usually you render some element whitin your component, but if you are creating an 'agnostic' component or a kind of abstraction component you can not simply render elements, you don't know what the user wants to render. So you render values, actions, states, data... props. You pick these props passing a function to children (or render prop) and now with this data you have total control of what you want to do. Now render what you want to render and do what you want to do. **Renderless components are about abstracting some logic without any UI.**\n\nReact PowerPlug brings to you a bunch of components that act as state and logic containers, so you can get this powerful abstraction and use it any way you want.\n\n**Note:** with PowerPlug you can use `children` or `render` prop.  \nYou decide which one is best for you.\n\n# Components\n\n**_Note:_** _This is a kind of a cheat sheet for fast search._  \n_If you want a more detailed **API Reference** and examples for each component see the [Docs](/docs)_\n\n## State Containers\n\n### State\n\n**Component Props:** `{ initial, onChange }`  \n**Render Props:** `{ state, setState }`  \n[see docs](docs/components/State.md)\n\n```jsx\n<State initial={{ isLoading: false, data: null }}>\n  {({ state, setState }) => (\n    <DataReceiver\n      data={state.data}\n      onStart={() => setState({ isLoading: true })}\n      onFinish={data => setState({ data, isLoading: false })}\n    />\n  )}\n</State>\n```\n\n### Toggle\n\n**Component Props:** `{ initial, onChange }`  \n**Render Props:** `{ on, off, toggle, setOn }`  \n[see docs](docs/components/Toggle.md)\n\n```jsx\n<Toggle initial={true}>\n  {({ on, toggle }) => <Checkbox checked={on} onChange={toggle} />}\n</Toggle>\n```\n\n### Loading\n\n**Component Props:** `{ initial, onChange }`  \n**Render Props:** `{ isLoading, toggle, setLoading }`  \n[see docs](docs/components/Loading.md)\n\n```jsx\n<Loading initial={false}>\n  {({ isLoading, toggleLoading }) => (\n    <Button onClick={toggleLoading}>\n      {isLoading ? 'Loading...' : 'Click me'}\n    </Button>\n  )}\n</Loading>\n```\n\n### Value\n\n**Component Props:** `{ initial, onChange }`  \n**Render Props:** `{ value, setValue }`  \n[see docs](docs/components/Value.md)\n\n```jsx\n<Value initial=\"React\">\n  {({ value, setValue }) => (\n    <Select\n      label=\"Choose one\"\n      options={['React', 'Preact', 'Vue']}\n      value={value}\n      onChange={setValue}\n    />\n  )}\n</Value>\n```\n\n### Map\n\n**Component Props:** `{ initial, onChange }`  \n**Render Props:** `{ set, get, values }`  \n[see docs](docs/components/Map.md)\n\n```jsx\n<Map initial={{ sounds: true, graphics: 'medium' }}>\n  {({ set, get }) => (\n    <Maptings>\n      <ToggleCheck checked={get('sounds')} onChange={c => set('sounds', c)}>\n        Game Sounds\n      </ToggleCheck>\n      <Select\n        label=\"Graphics\"\n        options={['low', 'medium', 'high']}\n        selected={get('graphics')}\n        onSelect={value => set('graphics', value)}\n      />\n    </Maptings>\n  )}\n</Map>\n```\n\n### List\n\n**Component Props:** `{ initial, onChange }`  \n**Render Props:** `{ list, push, pull, sort, setList }`  \n[see docs](docs/components/List.md)\n\n```jsx\n<List initial={['react', 'babel']}>\n  {({ list, pull, push }) => (\n    <div>\n      <FormInput onSubmit={push} />\n      {list.map(tag => (\n        <Tag onRemove={() => pull(value => value === tag)}>\n          {tag}\n        </Tag>\n      )}\n    </div>\n  )}\n</List>\n```\n\n## Feedback Containers\n\n### Hover\n\n**Component Props:** `{ onChange }`  \n**Render Props:** `{ isHover, bindHover }`  \n[see docs](docs/components/Hover.md)\n\n```jsx\n<Hover>\n  {({ isHover, bindHover }) => (\n    <div {...bindHover}>\n      You are {isHover ? 'hovering' : 'not hovering'} this div.\n    </div>\n  )}\n</Hover>\n```\n\n### Active\n\n**Component Props:** `{ onChange }`  \n**Render Props:** `{ isActive, bindActive }`  \n[see docs](docs/components/Active.md)\n\n```jsx\n<Active>\n  {({ isActive, bindActive }) => (\n    <div {...bindActive}>\n      You are {isActive ? 'clicking' : 'not clicking'} this div.\n    </div>\n  )}\n</Active>\n```\n\n### Focus\n\n**Component Props:** `{ onChange }`  \n**Render Props:** `{ isFocus, bindFocus }`  \n[see docs](docs/components/Focus.md)\n\n```jsx\n<Focus>\n  {({ isFocus, bindFocus }) => (\n    <div>\n      <input {...bindFocus} placeholder=\"Focus me\" />\n      <div>You are {isFocus ? 'focusing' : 'not focusing'} the input.</div>\n    </div>\n  )}\n</Focus>\n```\n\n### Touch\n\n**Component Props:** `{ onChange }`  \n**Render Props:** `{ isTouched, bind }`  \n[see docs](docs/components/Touch.md)\n\n```jsx\n<Touch>\n  {({ isTouched, bind }) => (\n    <div {...bind}>\n      You are {isTouched ? 'touching' : 'not touching'} this div.\n    </div>\n  )}\n</Touch>\n```\n\n## Form Containers\n\n### Input\n\n**Component Props:** `{ initial, onChange, getValue }`  \n**Render Props:** `{ value, set, bind }`  \n[see docs](docs/components/Input.md)\n\n```jsx\n<Input initial=\"hello world\">\n  {({ bind, value }) => (\n    <div>\n      <ControlledInput {...bind} />\n      <div>You typed {value}</div>\n    </div>\n  )}\n</Input>\n```\n\n### Form\n\n**Component Props:** `{ initial, onChange, getValue }`  \n**Render Props:** `{ input }`  \n[see docs](docs/components/Form.md)\n\n```jsx\n<Form initial={{ subject: '', message: '' }}>\n  {({ input }) => {\n    const subject = input('subject')\n    const message = input('message')\n\n    return (\n      <div>\n        <ControlledInput\n          placeholder=\"Subject\"\n          {...subject.bind}\n        />\n        <ControlledTextArea\n          placeholder=\"Message\"\n          {...message.bind}\n        />\n        <Submit>Send</Submit>\n\n        {/*\n          input(id) => { bind, set, value }\n        */}\n      </div>\n    )\n  }\n</Form>\n```\n\n# Composing Components\n\nIf you want to merge two of more components functionalities, you can compose they in a single one.  \nFor complete guide [see Compose docs](docs/components/Compose.md)\n\n```jsx\nimport { compose } from 'react-powerplug'\n\nconst ToggleCounter = compose(Toggle, Counter)\n\n<ToggleCounter>\n  {({ toggle, on }, { count, inc, dec }) => (\n    <ProductCard\n      {...productInfo}\n      isFavorited={on}\n      onFavorite={toggle}\n      count={count}\n      onAdd={inc}\n      onRemove={dec}\n    />\n  )}\n</ToggleCounter>\n```\n\nIf you need to pass props, especially for `initial`, just pass a created element. Internals this will be cloned.\n\n```jsx\nconst ToggleCounter = compose(\n  <Toggle initial={false} />,\n  <Counter initial={2} />\n)\n\n// or just mix it\nconst ToggleCounter = compose(Toggle, <Counter initial={3} />)\n```\n\nAlso, you can use a built-in Compose component and pass components on `states` prop\n\n```jsx\nimport { Compose } from 'react-powerplug'\n\n<Compose states={[Toggle, Counter]}>\n  {(toggle, counter) => (\n    <ProductCard {...} />\n  )}\n</Compose>\n```\n\nBehind the scenes, that's what happens:\n\n```jsx\n<Counter /* passed props */>\n  {counter => (\n    <Toggle /* passed props */>\n      {toggle => (\n        <ProductCard\n          {...productInfo}\n          isFavorited={toggle.on}\n          onFavorite={toggle.toggle}\n          count={counter.count}\n          onAdd={counter.inc}\n          onRemove={counter.dec}\n        />\n      )}\n    </Toggle>\n  )}\n</Counter>\n```\n\nBecause of that, when you use `toggle` function, only `<Toggle>` will be rerendered, but if you use `inc` or `dec` functions, both `<Counter>` and `<Toggle>` will be rerendered. **Even** using `compose()` utility.\n\n# CodeSandbox examples\n\n[Using Toggle in a Checkbox](https://codesandbox.io/s/jp890p2x7w)  \n[Using State in a Pagination](https://codesandbox.io/s/8x9m4893l2)\n\n# Install\n\n### Node Module\n\n```\nyarn add react-powerplug\n```\n\n```\nnpm i react-powerplug\n```\n\n### UMD library\n\n```html\n<script src=\"https://unpkg.com/react-powerplug/dist/react-powerplug.min.js\"></script>\n```\n\nexposed as `ReactPowerPlug`\n\n# Contribute\n\nYou can help improving this project sending PRs and helping with issues.  \nAlso you can ping me at [Twitter](http://twitter.com/renatorib_)\n","license":"MIT","scripts":{"lint":"eslint src","test":"npm run test:all","build":"npm run clean && npm run build:all","clean":"rimraf lib dist es","build:es":"cross-env BABEL_ENV=es babel src --out-dir es","test:all":"npm run lint && npm run test:only && npm run build && npm run test:bundle && npm run test:lib && npm run clean","test:lib":"jest --setupTestFrameworkScriptFile ./tests/jestLibSetup.js","build:all":"npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min && npm run build:flow","build:umd":"cross-env BABEL_ENV=es NODE_ENV=development rollup -c -o dist/react-powerplug.js","precommit":"lint-staged","test:only":"jest","build:flow":"cpy src/index.js.flow lib & cpy src/index.js.flow es","test:bundle":"jest --setupTestFrameworkScriptFile ./tests/jestBundleSetup.js","build:umd:min":"cross-env BABEL_ENV=es NODE_ENV=production rollup -c -o dist/react-powerplug.min.js","build:commonjs":"cross-env BABEL_ENV=commonjs babel src --out-dir lib","prepublishOnly":"npm run clean && npm run build","typecheck:flow":"flow check && [[ $(flow check) == 'Found 0 errors' ]]"},"_npmUser":{"name":"renatorib","email":"renatoribroman@gmail.com"},"homepage":"https://github.com/renatorib/react-powerplug","keywords":["react","reactjs","components","dumb","state"],"repository":{"url":"https://github.com/renatorib/react-powerplug.git","type":"git"},"description":"Give life to your dumb components","directories":{},"jsnext:main":"es/index.js","lint-staged":{"*.{js,md}":["prettier --write","git add"]},"maintainers":[{"name":"renatorib","email":"ola@rena.to"}],"sideEffects":false,"dependencies":{"@babel/runtime":"^7.0.0-beta.37"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^22.1.1","husky":"^0.14.3","react":"^16.2.0","eslint":"^4.6.1","rimraf":"^2.6.1","rollup":"^0.53.4","cpy-cli":"^1.0.1","flow-bin":"^0.63.1","prettier":"^1.10.2","cross-env":"^5.0.5","react-dom":"^16.2.0","@babel/cli":"^7.0.0-beta.37","babel-core":"^7.0.0-bridge.0","babel-jest":"^22.1.0","@babel/core":"^7.0.0-beta.37","lint-staged":"^6.0.0","babel-eslint":"^7.2.3","@babel/preset-env":"^7.0.0-beta.37","@babel/preset-react":"^7.0.0-beta.37","eslint-plugin-react":"^7.3.0","react-test-renderer":"^16.2.0","rollup-plugin-babel":"^4.0.0-beta.0","eslint-plugin-import":"^2.7.0","rollup-plugin-uglify":"^2.0.1","@babel/preset-stage-3":"^7.0.0-beta.37","rollup-plugin-replace":"^2.0.0","rollup-plugin-node-resolve":"^3.0.2","@babel/plugin-transform-runtime":"^7.0.0-beta.37","@babel/plugin-transform-modules-commonjs":"^7.0.0-beta.37"},"peerDependencies":{"react":"^0.14.0 || ^15.0.0-0 || ^16.0.0-0"},"_npmOperationalInternal":{"tmp":"tmp/react-powerplug_1.0.0-alpha.2_1518624426513_0.24791250930014597","host":"s3://npm-registry-packages"},"_id":"react-powerplug@1.0.0-alpha.2","version":"1.0.0-alpha.2"}