@saitonakamura/react-three-flex
Version:
`<Flex />` component for the 3D World.
2 lines (1 loc) • 8.78 kB
JavaScript
import e from"@babel/runtime/helpers/esm/extends";import t,{createContext as r,useContext as n,useMemo as i,useCallback as a,useRef as o,useLayoutEffect as s,useState as c}from"react";import l from"yoga-layout-prebuilt";import{useFrame as g,useThree as d}from"@react-three/fiber";import m from"react-merge-refs";import*as u from"three";import{Vector3 as p,Matrix4 as f}from"three";const h=e=>e[0].toUpperCase()+e.slice(1),x=e=>e.toUpperCase().replace("-","_"),w=(e,t,r)=>Object.keys(t).forEach((n=>{const i=t[n];if("string"==typeof i)switch(n){case"flexDir":case"dir":case"flexDirection":return e.setFlexDirection(l[`FLEX_DIRECTION_${x(i)}`]);case"align":return e.setAlignItems(l[`ALIGN_${x(i)}`]),e.setAlignContent(l[`ALIGN_${x(i)}`]);case"alignContent":return e.setAlignContent(l[`ALIGN_${x(i)}`]);case"alignItems":return e.setAlignItems(l[`ALIGN_${x(i)}`]);case"alignSelf":return e.setAlignSelf(l[`ALIGN_${x(i)}`]);case"justify":case"justifyContent":return e.setJustifyContent(l[`JUSTIFY_${x(i)}`]);case"wrap":case"flexWrap":return e.setFlexWrap(l[`WRAP_${x(i)}`]);case"basis":case"flexBasis":return e.setFlexBasis(i);default:return e[`set${h(n)}`](i)}else if("number"==typeof i){const t=i*r;switch(n){case"basis":case"flexBasis":return e.setFlexBasis(t);case"grow":case"flexGrow":return e.setFlexGrow(t);case"shrink":case"flexShrink":return e.setFlexShrink(t);case"align":return e.setAlignItems(i);case"justify":return e.setJustifyContent(i);case"flexDir":case"dir":return e.setFlexDirection(i);case"wrap":return e.setFlexWrap(i);case"padding":case"p":return e.setPadding(l.EDGE_ALL,t);case"paddingLeft":case"pl":return e.setPadding(l.EDGE_LEFT,t);case"paddingRight":case"pr":return e.setPadding(l.EDGE_RIGHT,t);case"paddingTop":case"pt":return e.setPadding(l.EDGE_TOP,t);case"paddingBottom":case"pb":return e.setPadding(l.EDGE_BOTTOM,t);case"margin":case"m":return e.setMargin(l.EDGE_ALL,t);case"marginLeft":case"ml":return e.setMargin(l.EDGE_LEFT,t);case"marginRight":case"mr":return e.setMargin(l.EDGE_RIGHT,t);case"marginTop":case"mt":return e.setMargin(l.EDGE_TOP,t);case"marginBottom":case"mb":return e.setMargin(l.EDGE_BOTTOM,t);default:return e[`set${h(n)}`](t)}}}));const y=e=>Object.keys(e).forEach((t=>void 0===e[t]?delete e[t]:{})),E=r({scaleFactor:100,requestReflow(){console.warn("Flex not initialized! Please report")},registerBox(){console.warn("Flex not initialized! Please report")},unregisterBox(){console.warn("Flex not initialized! Please report")},notInitialized:!0}),b=r({node:null,size:[0,0],notInitialized:!0});function B(e){let t=n(e);return t.notInitialized&&console.warn("You must place this hook/component under a <Flex/> component!"),t}function C(){const{requestReflow:e}=B(E);return e}function D(){const{size:[e,t],centerAnchor:r}=B(b);return i((()=>[e,t,r]),[e,t,r])}function I(){const{node:e}=B(b);return e}function L(){const{requestReflow:e,scaleFactor:t}=B(E),r=I();return a(((n,i)=>{if(null==r)throw new Error("yoga node is null. sync size is impossible");r.setWidth(n*t),r.setHeight(i*t),e()}),[r,e])}const R=new p;function T(){const e=L();return a((t=>{if(t.updateMatrixWorld(),R.setFromMatrixScale(t.matrixWorld),Math.abs(R.x-R.y)>.001||Math.abs(R.y-R.z)>.001)throw new Error("object was not scaled uniformly");const r=R.x;t.geometry.computeBoundingBox();const n=t.geometry.boundingBox;e((n.max.x-n.min.x)*r,(n.max.y-n.min.y)*r)}),[e])}function A({children:r,centerAnchor:n,flexDirection:a,flexDir:d,dir:u,alignContent:p,alignItems:f,alignSelf:h,align:x,justifyContent:D,justify:I,flexBasis:L,basis:R,flexGrow:T,grow:A,flexShrink:F,shrink:W,flexWrap:G,wrap:_,margin:z,m:M,marginBottom:P,marginLeft:S,marginRight:j,marginTop:v,mb:H,ml:k,mr:O,mt:N,padding:$,p:U,paddingBottom:q,paddingLeft:J,paddingRight:Y,paddingTop:V,pb:X,pl:K,pr:Q,pt:Z,height:ee,width:te,maxHeight:re,maxWidth:ne,minHeight:ie,minWidth:ae,...oe},se){const ce=i((()=>{const e={flexDirection:a,flexDir:d,dir:u,alignContent:p,alignItems:f,alignSelf:h,align:x,justifyContent:D,justify:I,flexBasis:L,basis:R,flexGrow:T,grow:A,flexShrink:F,shrink:W,flexWrap:G,wrap:_,margin:z,m:M,marginBottom:P,marginLeft:S,marginRight:j,marginTop:v,mb:H,ml:k,mr:O,mt:N,padding:$,p:U,paddingBottom:q,paddingLeft:J,paddingRight:Y,paddingTop:V,pb:X,pl:K,pr:Q,pt:Z,height:ee,width:te,maxHeight:re,maxWidth:ne,minHeight:ie,minWidth:ae};return y(e),e}),[x,p,f,h,u,L,R,d,a,T,A,F,W,G,ee,I,D,M,z,P,S,j,v,re,ne,H,ie,ae,k,O,N,U,$,q,J,Y,V,X,K,Q,Z,te,_]),{registerBox:le,unregisterBox:ge,scaleFactor:de}=B(E),{node:me}=B(b),ue=o(),pe=i((()=>l.Node.create()),[]),fe=C();s((()=>{w(pe,ce,de)}),[ce,pe,de]),s((()=>{if(ue.current&&me)return me.insertChild(pe,me.getChildCount()),le(pe,ue.current,ce,n),()=>{me.removeChild(pe),ge(pe)}}),[pe,me,ce,n,le,ge]),s((()=>{fe()}),[r,ce,fe]);const[he,xe]=c([0,0]),we=1/de;g((()=>{const e=("number"==typeof ce.width?ce.width:null)||pe.getComputedWidth().valueOf()/de,t=("number"==typeof ce.height?ce.height:null)||pe.getComputedHeight().valueOf()/de;(Math.abs(e-he[0])>we||Math.abs(t-he[1])>we)&&xe([e,t])}));const ye=i((()=>({node:pe,size:he,centerAnchor:n})),[pe,he,n]);return t.createElement("group",e({ref:m([ue,se])},oe),t.createElement(b.Provider,{value:ye},"function"==typeof r?r(he[0],he[1],n):r))}const F=t.forwardRef(A);function W({size:r=[1,1,1],yogaDirection:n="ltr",plane:c="xy",children:h,scaleFactor:x=100,onReflow:B,disableSizeRecalc:C,centerAnchor:D,flexDirection:I,flexDir:L,dir:R,alignContent:T,alignItems:A,alignSelf:F,align:W,justifyContent:G,justify:_,flexBasis:z,basis:M,flexGrow:P,grow:S,flexShrink:j,shrink:v,flexWrap:H,wrap:k,margin:O,m:N,marginBottom:$,marginLeft:U,marginRight:q,marginTop:J,mb:Y,ml:V,mr:X,mt:K,padding:Q,p:Z,paddingBottom:ee,paddingLeft:te,paddingRight:re,paddingTop:ne,pb:ie,pl:ae,pr:oe,pt:se,height:ce,width:le,maxHeight:ge,maxWidth:de,minHeight:me,minWidth:ue,...pe},fe){const he=i((()=>{const e={flexDirection:I,flexDir:L,dir:R,alignContent:T,alignItems:A,alignSelf:F,align:W,justifyContent:G,justify:_,flexBasis:z,basis:M,flexGrow:P,grow:S,flexShrink:j,shrink:v,flexWrap:H,wrap:k,margin:O,m:N,marginBottom:$,marginLeft:U,marginRight:q,marginTop:J,mb:Y,ml:V,mr:X,mt:K,padding:Q,p:Z,paddingBottom:ee,paddingLeft:te,paddingRight:re,paddingTop:ne,pb:ie,pl:ae,pr:oe,pt:se,height:ce,width:le,maxHeight:ge,maxWidth:de,minHeight:me,minWidth:ue};return y(e),e}),[W,T,A,F,R,z,M,L,I,P,S,j,v,H,ce,_,G,N,O,$,U,q,J,ge,de,Y,me,ue,V,X,K,Z,Q,ee,te,re,ne,ie,ae,oe,se,le,k]),xe=o(),we=o([]),ye=a(((e,t,r,n=!1)=>{const i=we.current.findIndex((t=>t.node===e));-1!==i&&we.current.splice(i,1),we.current.push({group:t,node:e,flexProps:r,centerAnchor:n})}),[]),Ee=a((e=>{const t=we.current.findIndex((t=>t.node===e));-1!==t&&we.current.splice(t,1)}),[]),be=i((()=>l.Node.create()),[]);s((()=>{w(be,he,x)}),[be,he,x]);const{invalidate:Be}=d(),Ce=o(!0),De=a((()=>{Ce.current=!0,Be()}),[Be]);s((()=>{De()}),[h,he,De]);const Ie=i((()=>new u.Box3),[]),Le=i((()=>new u.Vector3),[]),Re=c[0],Te=c[1],Ae=function(e){switch(e){case"xy":return"z";case"yz":return"x";case"xz":return"y"}}(c),[Fe,We]=function(e,t){switch(t){case"xy":return[e[0],e[1]];case"yz":return[e[1],e[2]];case"xz":return[e[0],e[2]]}}(r,c),Ge="ltr"===n?l.DIRECTION_LTR:"rtl"===n?l.DIRECTION_RTL:n,_e=i((()=>({requestReflow:De,registerBox:ye,unregisterBox:Ee,scaleFactor:x})),[De,ye,Ee,x]),ze=i((()=>({node:be,size:[Fe,We],centerAnchor:D})),[be,Fe,We,D]);function Me(){C||we.current.forEach((({group:e,node:t,flexProps:r})=>{const n="number"==typeof r.width?r.width*x:r.width,i="number"==typeof r.height?r.height*x:r.height;void 0!==n&&void 0!==i?(t.setWidth(n),t.setHeight(i)):0===t.getChildCount()&&(((e,t,r)=>{e.updateMatrix();const n=e.matrix,i=e.matrixAutoUpdate,a=(new f).copy(e.matrixWorld).invert();e.matrix=a,e.matrixAutoUpdate=!1,t.setFromObject(e).getSize(r),e.matrix=n,e.matrixAutoUpdate=i})(e,Ie,Le),t.setWidth(n||Le[Re]*x),t.setHeight(i||Le[Te]*x))})),be.calculateLayout(Fe*x,We*x,Ge);const e=be.getComputedWidth(),t=be.getComputedHeight();let r=0,n=0,i=0,a=0;we.current.forEach((({group:o,node:s,centerAnchor:c})=>{const{left:l,top:g,width:d,height:m}=s.getComputedLayout(),[u,f]=((e,t,r,n)=>e&&(e=>{var t;return!(null!=(t=e.getParent())&&t.getParent())})(n)?[-t/2,-r/2]:[0,0])(D,e,t,s),h=(({x:e,y:t,z:r})=>new p(e,t,r))({[Re]:(u+l+(c?d/2:0))/x,[Te]:-(f+g+(c?m/2:0))/x,[Ae]:0});r=Math.min(r,l),i=Math.min(i,g),n=Math.max(n,l+d),a=Math.max(a,g+m),o.position.copy(h)})),B&&B((n-r)/x,(a-i)/x),Be()}return g((()=>{Ce.current&&(Ce.current=!1,Me())})),t.createElement("group",e({ref:m([xe,fe])},pe),t.createElement(E.Provider,{value:_e},t.createElement(b.Provider,{value:ze},h)))}F.displayName="Box";const G=t.forwardRef(W);G.displayName="Flex";export{F as Box,G as Flex,B as useContext,I as useFlexNode,D as useFlexSize,C as useReflow,L as useSetSize,T as useSyncGeometrySize};