{"_id":"@elmarburke/merge-props","_rev":"1-6c3611c58d89af6de0f997b2d1008913","name":"@elmarburke/merge-props","dist-tags":{"latest":"5.0.2"},"versions":{"5.0.2":{"name":"@elmarburke/merge-props","version":"5.0.2","description":"[FORK OF merge-props] Merges className, style, and DOM event handlers for React elements","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"test":"jest --coverage","build":"tsc -p .","prepare":"npm run test && npm run build"},"repository":{"type":"git","url":"git+https://github.com/andrewbranch/merge-props.git"},"keywords":["React","merge","props"],"author":{"name":"Andrew Branch","email":"andrew@wheream.io"},"license":"MIT","bugs":{"url":"https://github.com/andrewbranch/merge-props/issues"},"homepage":"https://github.com/andrewbranch/merge-props#readme","devDependencies":{"@types/jest":"^24.0.13","jest":"^24.8.0","ts-jest":"^24.0.2","typescript":"^3.5.1"},"jest":{"moduleFileExtensions":["ts","tsx","js"],"transform":{"^.+\\.(ts|tsx)$":"ts-jest"},"testMatch":["**/?(*.)(spec|test).ts?(x)"],"coveragePathIgnorePatterns":["<rootDir>/test/","/node_modules/"]},"dependencies":{},"gitHead":"ff9751d9ae4120e8a55e49002a67c78adbf6296f","_id":"@elmarburke/merge-props@5.0.2","_nodeVersion":"14.4.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-NRSsFMriLxkvBSghN70EJMaYRiB6ifQwqUkXeZ2L/1CD6ZjhAafps9/7rHkcY3nvnHGG1/Y4c1Pciq9x3dp9Pg==","shasum":"b5e9f6824370806eccf5a345499e2389fdd32a1f","tarball":"https://registry.npmjs.org/@elmarburke/merge-props/-/merge-props-5.0.2.tgz","fileCount":11,"unpackedSize":17750,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfHo6ZCRA9TVsSAnZWagAAmp8P/iDjlzPTypg9MVU1x9E8\nkHIQoQwBqvgS2zXEFtBSgyiWNzgiLqrQRp9FWvM8mpNUR1VSDRdErP3swE6N\nGQQe6x5OEyLxNnf9yg4rC2mpEHMXftir1VeCnfBpQzu0T6zt15TMBvmkn8Xg\nY3HK1M8M7IFcklfTFGos0wFN8V8OgCa7yyTLxL6ggeRT9UuK2NxdE0lXocT2\nsm9DCMbfXr/x1+RyEkpZ8YvwvENPKOrQX3m0j180YNjiaqYHp6eK6qPzCMnS\nFDID16HKnBS4natxV3WZ0bGkdoaAN4TkE25IsJmz7/IpBMYwPIAkqwQY9vxW\n8sjI4onDlgpUL5lzrsMlbCsMa2QqQN4CT2P91lt/aElINgFFGKSwtVPVSkHi\nIJFQrVSI7YU35DDrsRpZgEZ+2sYxo75Mv/UriL3ITbozxkKDunKU5zl194c/\n7+2bdq/iTqO3jCuDmvU/zCbxkSF+UxM8zjHSeAbVPbeqrpq0pvoDBEeW59+5\nT6ISPrwLA5c8RwuBowoTZ0juQerXc89YPPvIWAQwDlLvyTNSMjH56YepXkzS\nftSV3YyU+VVAkLo18k2aKnmHWrLLnLOSDZWyHRTKw9z05MPCQIV+vgPynoz3\nxPgLmKLfaAlT0tbdGEnP/6xgVS2Het8xL+rfBeaeFYhxKgvx3C3avwLXdz5z\nf42f\r\n=73f0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBo+e0DDGPmkCKxxdDv4LkcRkVqlJAU7cAl4nGfoS1bgIgZD1CiwVyeR/9MOjQkNaJH8CiWV8KOqC19mrOLKtSrYI="}]},"maintainers":[{"name":"elmarburke","email":"hi@elmar.codes"}],"_npmUser":{"name":"elmarburke","email":"hi@elmar.codes"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/merge-props_5.0.2_1595838105065_0.7675384766953899"},"_hasShrinkwrap":false}},"time":{"created":"2020-07-27T08:21:45.028Z","5.0.2":"2020-07-27T08:21:45.266Z","modified":"2022-04-05T07:22:04.386Z"},"maintainers":[{"name":"elmarburke","email":"hi@elmar.codes"}],"description":"[FORK OF merge-props] Merges className, style, and DOM event handlers for React elements","homepage":"https://github.com/andrewbranch/merge-props#readme","keywords":["React","merge","props"],"repository":{"type":"git","url":"git+https://github.com/andrewbranch/merge-props.git"},"author":{"name":"Andrew Branch","email":"andrew@wheream.io"},"bugs":{"url":"https://github.com/andrewbranch/merge-props/issues"},"license":"MIT","readme":"# merge-props [![Build Status](https://travis-ci.org/andrewbranch/merge-props.svg?branch=master)](https://travis-ci.org/andrewbranch/merge-props) [![codecov](https://codecov.io/gh/andrewbranch/merge-props/branch/master/graph/badge.svg)](https://codecov.io/gh/andrewbranch/merge-props) [![npm](https://img.shields.io/npm/v/merge-props.svg)](https://www.npmjs.com/package/merge-props) ![size](https://img.shields.io/bundlephobia/minzip/merge-props.svg)\n\nFork of [merge-props](https://www.npmjs.com/package/merge-props).\n\nFix undefined function callbacks [fixed in this PR](https://github.com/andrewbranch/merge-props/pull/25)\n\nMerges React `className`, `style`, and event handlers (`onClick`, `onFocus`, `on{LiterallyEveryEvent}`) by the following rules:\n\n- `className` props are concatenated\n- `style` props are shallow merged with later values taking precedence\n- functions are run in sequence from left to right.\n\n## Installation\n\n```\nnpm install merge-props\n```\n\n## Example usage\n\n```js\nconst props = mergeProps(\n  { onClick: fn1 },\n  { onClick: fn2, className: \"blue\" },\n  { onClick: fn3, className: \"button\", styles: { display: \"block\" } },\n  { styles: { display: \"flex\", color: \"red\" } }\n);\n\n<button {...props}>Best button ever</button>;\n```\n\nThe button will have a `className` of `\"blue button\"`, a `style` equal to `{ display: 'flex', color: 'red' }`,and when it is clicked, it will execute `fn1`, then `fn2`, then `fn3`, in that order.\n\n## Why is this useful?\n\nOne useful pattern for [render props](https://reactjs.org/docs/render-props.html) is having them pass props that are meant to be spread over the returned element to facilitate communication between the parent component and the render prop element. For example, consider a Tooltip component that decorate any DOM element or React component that accepts event handlers. If the Tooltip wants to avoid rendering a wrapper around its “trigger” element, it could use a render prop to inject `onMouseEnter`, `onMouseLeave`, `onFocus`, `onBlur`, and various WAI-ARIA attributes:\n\n```jsx\n<Tooltip text=\"Some extra information about this button\">\n  {(props) => <button {...props}>Hovering this is great</button>}\n</Tooltip>\n```\n\nThis is a nifty pattern in environments where flexibility, reusability, and ability to customize are highly valued, because Tooltip can pass event handlers as `props` in order to attach what it needs to the target element while allowing the consumer to retain full control over what actually happens to those `props`.\n\nHowever, one minor weakness of this pattern is the level of boilerplate that needs to be introduced if you needed to merge those injected `props` with props of your own in an intelligent way. For example, lets say that Tooltip also injects a `className` (perhaps to change the cursor appearance of whatever is being hovered), but you also need to pass your own `className` to the button in order to turn it a pretty shade of blue. You’d have to do something like\n\n```jsx\n<Tooltip text=\"Some extra information about this button\">\n  {({ className, ...props }) => (\n    <button {...props} className={className + \" pretty-blue\"}>\n      Hovering this is great\n    </button>\n  )}\n</Tooltip>\n```\n\nAnd it gets much messier if you needed to run your own event handlers in addition to the injected event handlers:\n\n```jsx\n<Tooltip text=\"Some extra information about this button\">\n  {({ className, onFocus, onBlur, ...props }) => (\n    <button\n      {...props}\n      className={className + \" pretty-blue\"}\n      onFocus={(event) => {\n        // BTW if Tooltip’s API changed to not inject this, it would break\n        onFocus(event);\n        myOwnOnFocus(event);\n      }}\n      onBlur={(event) => {\n        onBlur(event); // Sure hope this exists forever\n        myOwnOnBlur(event);\n      }}\n    >\n      Hovering this is kind of sad\n    </button>\n  )}\n</Tooltip>\n```\n\nEnter `mergeProps`:\n\n```jsx\n<Tooltip text=\"Some extra information about this button\">\n  {(props) => (\n    <button\n      {...mergeProps(props, {\n        onFocus: myOwnOnFocus,\n        onBlur: myOwnOnBlur,\n        className: \"pretty-blue\",\n        style: { alignSelf: \"flex-start\" },\n      })}\n    >\n      I love button\n    </button>\n  )}\n</Tooltip>\n```\n\nIt runs Tooltip’s `onFocus` and `onBlur` right before your own handlers, combines Tooltip’s `className` with `pretty-blue`, and even merges your `style` prop with one that Tooltip might want to add.\n\n## Gotchas\n\n**I got an error like `Didn’t know how to merge prop 'foo'`. What?**\n\n`mergeProps` knows how to merge `className`, `style`, and event handlers (any functions, in practice). If you pass it anything else, it will happily pass it through:\n\n```jsx\nconst merged = mergeProps(\n  { className: \"one\" },\n  { className: \"two\", role: \"button\" }\n);\nmerged.role; // 'button'\n```\n\nHowever, if it receives _two_ instances of the same prop by an unknown name, `mergeProps` is faced with a decision of how to merge two props that it knows nothing about. Rather than risk making a bad decision, especially one that may be hard to debug, it throws an error saying that it doesn’t know what to do:\n\n```jsx\n// What? How to merge two `role` props? ¯\\_(ツ)_/¯\nconst merged = mergeProps({ role: \"button\" }, { role: \"presentation\" });\n// Error: Didn’t know how to merge prop 'role'.\n```\n\n## Related\n\n- [babel-plugin-jsx-merge-props](https://github.com/hooriza/babel-plugin-jsx-merge-props): Use merge-props automatically via a Babel plugin\n\n## Contributing\n\nChanges should be tested and have 100% coverage:\n\n```\nnpm test\n```\n\nDesign changes may be considered via an issue or PR.\n","readmeFilename":"README.md"}