use-descendants
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -1,1 +0,1 @@ | ||
var e,r,t=require("react");function n(){return(n=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var u="undefined"!=typeof window&&(null==(e=window)||null==(r=e.document)?void 0:r.createElement)?t.useLayoutEffect:t.useEffect;exports.createDescendants=function(){return t.createContext({})},exports.useDescendant=function(e,r){var c,a=t.useRef(-1),o=t.useRef(),i=t.useContext(e),f=i.list,s=i.map,d=i.force,l=t.useRef("_"+Math.random().toString(36).substr(2,9));return u(function(){return s.current[l.current]=n({},r,{_internalId:l.current}),d({}),function(){delete s.current[l.current],f.current=f.current.filter(function(e){return e._internalId!==l.current}),a.current=-1,l.current=void 0}},[]),u(function(){o.current&&o.current.setAttribute("data-descendant",l.current)}),(null==(c=s.current)?void 0:c[l.current])&&(s.current[l.current]=n({},r,{_internalId:l.current})),a.current=f.current.findIndex(function(e){return e._internalId===l.current}),{index:a.current,ref:o,id:l.current}},exports.useDescendants=function(){var e=t.useRef([]),r=t.useRef({}),c=t.useState()[1],a=t.useRef();return u(function(){if(a.current){var t=Array.from(a.current.querySelectorAll("[data-descendant]"));(t.length!==e.current.length||!t.every(function(r,t){return e.current[t].element===r}))&&(e.current=t.map(function(e){var t=r.current[e.getAttribute("data-descendant")];return n({element:e},t)}),c({}))}}),{ref:a,list:e,map:r,force:c}},exports.useIsomorphicLayoutEffect=u; | ||
var e,r,t=require("react");function n(){return(n=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}var u="undefined"!=typeof window&&(null==(e=window)||null==(r=e.document)?void 0:r.createElement)?t.useLayoutEffect:t.useEffect;exports.createDescendants=function(){return t.createContext({})},exports.useDescendant=function(e,r){var c,a=t.useRef(-1),o=t.useRef(),i=t.useContext(e),f=i.list,s=i.map,d=i.force,l=t.useRef("_"+Math.random().toString(36).substr(2,9));return u(function(){return s.current[l.current]=n({},r,{_internalId:l.current}),d({}),function(){delete s.current[l.current],f.current=f.current.filter(function(e){return e._internalId!==l.current}),a.current=-1,l.current=void 0,d({})}},[]),u(function(){o.current&&o.current.setAttribute("data-descendant",l.current)}),(null==(c=s.current)?void 0:c[l.current])&&(s.current[l.current]=n({},r,{_internalId:l.current})),a.current=f.current.findIndex(function(e){return e._internalId===l.current}),{index:a.current,ref:o,id:l.current}},exports.useDescendants=function(){var e=t.useRef([]),r=t.useRef({}),c=t.useState()[1],a=t.useRef();return u(function(){if(a.current){var t=Array.from(a.current.querySelectorAll("[data-descendant]"));(t.length!==e.current.length||!t.every(function(r,t){return e.current[t].element===r}))&&(e.current=t.map(function(e){var t=r.current[e.getAttribute("data-descendant")];return n({element:e},t)}),c({}))}}),{ref:a,list:e,map:r,force:c}},exports.useIsomorphicLayoutEffect=u; |
@@ -1,1 +0,1 @@ | ||
import{createContext as r,useRef as n,useState as t,useContext as e,useLayoutEffect as u,useEffect as c}from"react";function i(){return(i=Object.assign||function(r){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(r[e]=t[e])}return r}).apply(this,arguments)}var o,a,d=function(){return r({})},f=function(){var r=n([]),e=n({}),u=t()[1],c=n();return s(function(){if(c.current){var n=Array.from(c.current.querySelectorAll("[data-descendant]"));(n.length!==r.current.length||!n.every(function(n,t){return r.current[t].element===n}))&&(r.current=n.map(function(r){var n=e.current[r.getAttribute("data-descendant")];return i({element:r},n)}),u({}))}}),{ref:c,list:r,map:e,force:u}},l=function(r,t){var u,c=n(-1),o=n(),a=e(r),d=a.list,f=a.map,l=a.force,v=n("_"+Math.random().toString(36).substr(2,9));return s(function(){return f.current[v.current]=i({},t,{_internalId:v.current}),l({}),function(){delete f.current[v.current],d.current=d.current.filter(function(r){return r._internalId!==v.current}),c.current=-1,v.current=void 0}},[]),s(function(){o.current&&o.current.setAttribute("data-descendant",v.current)}),(null==(u=f.current)?void 0:u[v.current])&&(f.current[v.current]=i({},t,{_internalId:v.current})),c.current=d.current.findIndex(function(r){return r._internalId===v.current}),{index:c.current,ref:o,id:v.current}},s="undefined"!=typeof window&&(null==(o=window)||null==(a=o.document)?void 0:a.createElement)?u:c;export{d as createDescendants,l as useDescendant,f as useDescendants,s as useIsomorphicLayoutEffect}; | ||
import{createContext as r,useRef as n,useState as t,useContext as e,useLayoutEffect as u,useEffect as c}from"react";function i(){return(i=Object.assign||function(r){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var e in t)Object.prototype.hasOwnProperty.call(t,e)&&(r[e]=t[e])}return r}).apply(this,arguments)}var o,a,d=function(){return r({})},f=function(){var r=n([]),e=n({}),u=t()[1],c=n();return s(function(){if(c.current){var n=Array.from(c.current.querySelectorAll("[data-descendant]"));(n.length!==r.current.length||!n.every(function(n,t){return r.current[t].element===n}))&&(r.current=n.map(function(r){var n=e.current[r.getAttribute("data-descendant")];return i({element:r},n)}),u({}))}}),{ref:c,list:r,map:e,force:u}},l=function(r,t){var u,c=n(-1),o=n(),a=e(r),d=a.list,f=a.map,l=a.force,v=n("_"+Math.random().toString(36).substr(2,9));return s(function(){return f.current[v.current]=i({},t,{_internalId:v.current}),l({}),function(){delete f.current[v.current],d.current=d.current.filter(function(r){return r._internalId!==v.current}),c.current=-1,v.current=void 0,l({})}},[]),s(function(){o.current&&o.current.setAttribute("data-descendant",v.current)}),(null==(u=f.current)?void 0:u[v.current])&&(f.current[v.current]=i({},t,{_internalId:v.current})),c.current=d.current.findIndex(function(r){return r._internalId===v.current}),{index:c.current,ref:o,id:v.current}},s="undefined"!=typeof window&&(null==(o=window)||null==(a=o.document)?void 0:a.createElement)?u:c;export{d as createDescendants,l as useDescendant,f as useDescendants,s as useIsomorphicLayoutEffect}; |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e=e||self).useDescendants={},e.react)}(this,function(e,t){var r,n;function u(){return(u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}var c="undefined"!=typeof window&&(null==(r=window)||null==(n=r.document)?void 0:n.createElement)?t.useLayoutEffect:t.useEffect;e.createDescendants=function(){return t.createContext({})},e.useDescendant=function(e,r){var n,f=t.useRef(-1),o=t.useRef(),a=t.useContext(e),i=a.list,s=a.map,d=a.force,l=t.useRef("_"+Math.random().toString(36).substr(2,9));return c(function(){return s.current[l.current]=u({},r,{_internalId:l.current}),d({}),function(){delete s.current[l.current],i.current=i.current.filter(function(e){return e._internalId!==l.current}),f.current=-1,l.current=void 0}},[]),c(function(){o.current&&o.current.setAttribute("data-descendant",l.current)}),(null==(n=s.current)?void 0:n[l.current])&&(s.current[l.current]=u({},r,{_internalId:l.current})),f.current=i.current.findIndex(function(e){return e._internalId===l.current}),{index:f.current,ref:o,id:l.current}},e.useDescendants=function(){var e=t.useRef([]),r=t.useRef({}),n=t.useState()[1],f=t.useRef();return c(function(){if(f.current){var t=Array.from(f.current.querySelectorAll("[data-descendant]"));(t.length!==e.current.length||!t.every(function(t,r){return e.current[r].element===t}))&&(e.current=t.map(function(e){var t=r.current[e.getAttribute("data-descendant")];return u({element:e},t)}),n({}))}}),{ref:f,list:e,map:r,force:n}},e.useIsomorphicLayoutEffect=c}); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e=e||self).useDescendants={},e.react)}(this,function(e,t){var r,n;function u(){return(u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}var c="undefined"!=typeof window&&(null==(r=window)||null==(n=r.document)?void 0:n.createElement)?t.useLayoutEffect:t.useEffect;e.createDescendants=function(){return t.createContext({})},e.useDescendant=function(e,r){var n,f=t.useRef(-1),o=t.useRef(),a=t.useContext(e),i=a.list,s=a.map,d=a.force,l=t.useRef("_"+Math.random().toString(36).substr(2,9));return c(function(){return s.current[l.current]=u({},r,{_internalId:l.current}),d({}),function(){delete s.current[l.current],i.current=i.current.filter(function(e){return e._internalId!==l.current}),f.current=-1,l.current=void 0,d({})}},[]),c(function(){o.current&&o.current.setAttribute("data-descendant",l.current)}),(null==(n=s.current)?void 0:n[l.current])&&(s.current[l.current]=u({},r,{_internalId:l.current})),f.current=i.current.findIndex(function(e){return e._internalId===l.current}),{index:f.current,ref:o,id:l.current}},e.useDescendants=function(){var e=t.useRef([]),r=t.useRef({}),n=t.useState()[1],f=t.useRef();return c(function(){if(f.current){var t=Array.from(f.current.querySelectorAll("[data-descendant]"));(t.length!==e.current.length||!t.every(function(t,r){return e.current[r].element===t}))&&(e.current=t.map(function(e){var t=r.current[e.getAttribute("data-descendant")];return u({element:e},t)}),n({}))}}),{ref:f,list:e,map:r,force:n}},e.useIsomorphicLayoutEffect=c}); |
{ | ||
"name": "use-descendants", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
145
README.md
@@ -5,3 +5,3 @@ # useDescendants ![npm bundle size](https://img.shields.io/bundlephobia/minzip/use-descendants) | ||
useDescendants is a react hook for keeping track of descendant components and their relative indeces. It's based off the [@reach/descendants](https://www.npmjs.com/package/@reach/descendants) package, but is much faster and smaller. | ||
useDescendants is a react hook for keeping track of descendant components and their relative indeces. It's based off the [@reach/descendants](https://www.npmjs.com/package/@reach/descendants) package, but is much faster and half the size, with no dependencies. | ||
@@ -35,66 +35,4 @@ If you want to understand more about what this package does or why we need it, read the [Problem Complex](https://www.npmjs.com/package/@reach/descendants) from the @reach/descendants package. | ||
## Usage | ||
## Example ([live](https://codesandbox.io/s/use-descendants-demo-wi96j?file=/src/App.js)) | ||
There are two hooks: `useDescendants` (used in the parent) and `useDescendant` (used in each child). You will also need to use `createDescendants` to wrap each child with context. | ||
### useDescendants | ||
Maintains state related to the list of descendants. | ||
```js | ||
const { ref, ...contextProps } = useDescendants() | ||
<ul ref={ref}> | ||
// ... | ||
</ul> | ||
``` | ||
The returned `ref` should be applied to the DOM element of your parent. The rest of the values returned from `useDescendants` should be passed via context. | ||
The context props: | ||
- `list`: a ref with an array of currently rendered descendants | ||
- `map`: a ref with an object of every mounted (even if not rendered) descendant, keyed by component id | ||
- `force`: a way to forcefully re-render the parent | ||
Learn more about `list` and `map` in the [Advanced](#advanced) section. | ||
### createDescendants | ||
Creates a new descendant context. | ||
```js | ||
const DescendantContext = createDescendants() | ||
<DescendantContext.Provider value={contextProps}> | ||
// ... | ||
</DescendantContext.Provider> | ||
``` | ||
The created context must be passed to `useDescendant` below. | ||
### useDescendant | ||
useDescendant accepts two arguments: `context`, the context you created with `createDescendants`, and `props`, arbitrary props that you want available in the parent. | ||
Any props you pass will be available in the parent in `contextProps.map[id]`, where `id` is the component id returned below. | ||
useDescendant returns three values: | ||
- `ref` should be applied to the DOM element of this child. | ||
- `index` is the relative index of this child in the list | ||
- `id` is the unique id of this component | ||
```js | ||
const { ref, index, id } = useDescendant(context, props?) | ||
<li ref={ref}> | ||
// ... | ||
</li> | ||
``` | ||
<br /> | ||
## Example | ||
In this example, we'll create a menu with items that can be selected on hover. | ||
@@ -114,3 +52,3 @@ | ||
const { ref, ...contextProps } = useDescendants() | ||
const [selected, setSelected] = useState(-1) | ||
const [selected, setSelected] = useState(0) | ||
@@ -149,8 +87,12 @@ return ( | ||
```js | ||
```jsx | ||
// Before | ||
<Menu> | ||
{items.map(item => <MenuItem>{item}</MenuItem>)} | ||
{items.map(item => ( | ||
<MenuItem>{item}</MenuItem> | ||
))} | ||
</Menu> | ||
``` | ||
```jsx | ||
// After, use any component tree | ||
@@ -160,3 +102,3 @@ <Menu> | ||
<BlogMenuItems /> | ||
<RedItem>I'm Red</RedItem> | ||
<RedItem>Im Red</RedItem> | ||
@@ -175,2 +117,64 @@ <> | ||
## Usage | ||
There are two hooks: `useDescendants` (used in the parent) and `useDescendant` (used in each child). You will also need to use `createDescendants` to wrap each child with context. | ||
### useDescendants | ||
Maintains state related to the list of descendants. | ||
```js | ||
const { ref, ...contextProps } = useDescendants() | ||
<ul ref={ref}> | ||
// ... | ||
</ul> | ||
``` | ||
The returned `ref` should be applied to the DOM element of your parent. The rest of the values returned from `useDescendants` should be passed via context. | ||
The context props: | ||
- `list`: a ref with an array of currently rendered descendants | ||
- `map`: a ref with an object of every mounted (even if not rendered) descendant, keyed by component id | ||
- `force`: a way to forcefully re-render the parent | ||
Learn more about `list` and `map` in the [Advanced](#advanced) section. | ||
### createDescendants | ||
Creates a new descendant context. | ||
```js | ||
const DescendantContext = createDescendants() | ||
<DescendantContext.Provider value={contextProps}> | ||
// ... | ||
</DescendantContext.Provider> | ||
``` | ||
The created context must be passed to `useDescendant` below. | ||
### useDescendant | ||
useDescendant accepts two arguments: `context`, the context you created with `createDescendants`, and `props`, arbitrary props that you want available in the parent. | ||
Any props you pass will be available in the parent in `contextProps.map[id]`, where `id` is the component id returned below. | ||
useDescendant returns three values: | ||
- `ref` should be applied to the DOM element of this child. | ||
- `index` is the relative index of this child in the list | ||
- `id` is the unique id of this component | ||
```js | ||
const { ref, index, id } = useDescendant(context, props?) | ||
<li ref={ref}> | ||
// ... | ||
</li> | ||
``` | ||
<br /> | ||
## Why? | ||
@@ -199,3 +203,3 @@ | ||
```js | ||
const id = list.current[3] | ||
const id = list.current[3]._internalId | ||
const props = map.current[id] // All of the props passed to `useDescendant` by the fourth descendant | ||
@@ -206,1 +210,4 @@ ``` | ||
## Credits | ||
- [@reach/descendants](https://www.npmjs.com/package/@reach/descendants) and [Chance](https://twitter.com/chancethedev), who introduced me to this concept |
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
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
12287
206