@ws-ui/craftjs-layers
Version:
A Photoshop-like layers panel for your page editor
86 lines (82 loc) • 15.2 kB
JavaScript
;Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@ws-ui/craftjs-utils"),t=require("react"),n=require("@ws-ui/craftjs-core"),r=require("styled-components"),a=require("react-contenteditable");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function d(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var i=o(t),s=d(t),l=o(r),c=o(a);const u=i.default.createContext({}),p=t.createContext({});function f(n){const{store:r}=t.useContext(p),a=e.useCollector(r,n);return t.useMemo((()=>({store:r,...a})),[r,a])}function v(r){const{id:a,depth:o,connectors:d}=t.useContext(u),{actions:i,...s}=f((e=>a&&e.layers[a]&&r&&r(e.layers[a]))),{children:l}=n.useEditor(((e,t)=>({children:e.nodes[a]&&t.node(a).descendants()}))),c=t.useMemo((()=>({toggleLayer:()=>i.toggleLayer(a),setExpandedState:e=>i.setExpandedState(a,e)})),[i,a]),p=t.useMemo((()=>e.wrapConnectorHooks({layer:e=>d.layer(e,a),drag:e=>d.drag(e,a),layerHeader:e=>d.layerHeader(e,a)})),[d,a]);return{id:a,depth:o,children:l,actions:c,connectors:p,...s}}const g=()=>{const{id:e,depth:r,children:a,expanded:o}=v((e=>({expanded:e.expanded}))),{data:d,shouldBeExpanded:s}=n.useEditor(((t,n)=>{const r=n.getEvent("selected").first();return{data:t.nodes[e]&&t.nodes[e].data,shouldBeExpanded:r&&n.node(r).ancestors(!0).includes(e)}})),{actions:{registerLayer:l,toggleLayer:c},renderLayer:u,expandRootOnLoad:p}=f((e=>({renderLayer:e.options.renderLayer,expandRootOnLoad:e.options.expandRootOnLoad}))),[g,h]=t.useState(!1);t.useLayoutEffect((()=>{l(e),h(!0)}),[l,e]);const y=t.useRef(o);y.current=o;const x=t.useRef(p&&e===n.ROOT_NODE);return t.useEffect((()=>{!y.current&&s&&c(e)}),[c,e,s]),t.useEffect((()=>{x.current&&c(e)}),[c,e]),d&&g?i.default.createElement("div",{className:`craft-layer-node ${e}`},i.default.createElement(u,{},a&&o?a.map((e=>i.default.createElement(m,{key:e,id:e,depth:r+1}))):null)):null},h=t.createContext(null),m=({id:r,depth:a})=>{const o=t.useContext(h),{store:d}=t.useContext(p);t.useRef(d).current=d;const s=t.useMemo((()=>o.createConnectorsUsage()),[o]),l=t.useMemo((()=>e.wrapConnectorHooks(s.connectors)),[s]);t.useEffect((()=>(s.register(),()=>{s.cleanup()})),[s]);const{exists:c}=n.useEditor((e=>({exists:!!e.nodes[r]})));return c?i.default.createElement(u.Provider,{value:{id:r,depth:a,connectors:l}},i.default.createElement(g,null)):null},y=e=>({setLayerEvent:(t,n)=>{if(null!==n&&!e.layers[n])return;const r=e.events[t];r&&n!==r&&(e.layers[r].event[t]=!1),n?(e.layers[n].event[t]=!0,e.events[t]=n):e.events[t]=null},registerLayer:t=>{e.layers[t]||(e.layers[t]={dom:null,headingDom:null,expanded:!1,id:t,event:{selected:!1,hovered:!1}})},setDOM:(t,n)=>{e.layers[t]={...e.layers[t],...n.dom?{dom:n.dom}:{},...n.headingDom?{headingDom:n.headingDom}:{}}},toggleLayer:t=>{e.layers[t].expanded=!e.layers[t].expanded},setExpandedState:(t,n)=>{e.layers[t].expanded=n},setIndicator:t=>{e.events.indicator=t}});function x(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function b(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?x(Object(n),!0).forEach((function(t){E(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):x(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function E(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class w extends n.DerivedCoreEventHandlers{getLayer(e){return this.options.layerStore.getState().layers[e]}handlers(){const e=this.derived.options.store,{layerStore:t}=this.options;return{layer:(n,r)=>{t.actions.setDOM(r,{dom:n});const a=this.inherit((e=>{e.select(n,r),e.hover(n,r),e.drag(n,r)})),o=this.addCraftEventListener(n,"mouseover",(e=>{e.craft.stopPropagation(),t.actions.setLayerEvent("hovered",r)})),d=this.addCraftEventListener(n,"drop",(e=>{t.actions.setIndicator(null)})),i=this.addCraftEventListener(n,"dragover",(n=>{n.craft.stopPropagation(),n.preventDefault();const{indicator:r,currentCanvasHovered:a}=w.events;if(a&&r){var o;const d=null===(o=this.getLayer(a.id))||void 0===o?void 0:o.getBoundingClientRect();if(n.clientY>((null==d?void 0:d.top)||0)+10&&n.clientY<((null==d?void 0:d.bottom)||0)-10){const n=a.data.nodes[a.data.nodes.length-1];if(!n)return void(w.events.indicator=b(b({},r),{},{placement:b(b({},r.placement),{},{index:0,where:"before",parent:a}),onCanvas:!0}));w.events.indicator=b(b({},r),{},{placement:{currentNode:e.query.node(n).get(),index:a.data.nodes.length,where:"after",parent:a},onCanvas:!0}),t.actions.setIndicator(w.events.indicator)}}})),s=this.addCraftEventListener(n,"dragenter",(n=>{n.craft.stopPropagation(),n.preventDefault();const a=w.draggedElement;if(!a)return;const o=e.query.getDropPlaceholder(a,r,{x:n.clientX,y:n.clientY},(e=>{const t=this.getLayer(e.id);return t&&t.dom}));if(o){const{placement:{parent:r}}=o;let a;try{var d,i;a=null===(d=this.getLayer(r.id))||void 0===d||null===(i=d.headingDom)||void 0===i?void 0:i.getBoundingClientRect()}catch(n){}if(w.events.currentCanvasHovered=null,e.query.node(r.id).isCanvas()&&r.data.parent){const t=e.query.node(r.data.parent).get();var s,l,c,u;e.query.node(t.id).isCanvas()&&(w.events.currentCanvasHovered=r,(n.clientY>((null===(s=a)||void 0===s?void 0:s.bottom)||0)-10&&!this.getLayer(r.id).expanded||n.clientY<((null===(l=a)||void 0===l?void 0:l.top)||0)+10)&&(o.placement.parent=t,o.placement.currentNode=r,o.placement.index=t.data.nodes?t.data.nodes.indexOf(r.id):0,n.clientY>((null===(c=a)||void 0===c?void 0:c.bottom)||0)-10&&!this.getLayer(r.id).expanded?o.placement.where="after":n.clientY<((null===(u=a)||void 0===u?void 0:u.top)||0)+10&&(o.placement.where="before")))}w.events.indicator=b(b({},o),{},{onCanvas:!1}),t.actions.setIndicator(w.events.indicator)}}));return()=>{a(),o(),i(),s(),d()}},layerHeader:(e,n)=>{t.actions.setDOM(n,{headingDom:e})},drag:(n,r)=>{n.setAttribute("draggable","true");const a=this.addCraftEventListener(n,"dragstart",(e=>{e.craft.stopPropagation(),w.draggedElement=r})),o=this.addCraftEventListener(n,"dragend",(n=>{n.craft.stopPropagation();const r=w.events;if(r.indicator&&!r.indicator.error){const{placement:t}=r.indicator,{parent:n,index:a,where:o}=t,{id:d}=n;e.actions.move(w.draggedElement,d,a+("after"===o?1:0))}w.draggedElement=null,w.events.indicator=null,t.actions.setIndicator(null)}));return()=>{n.removeAttribute("draggable"),a(),o(),t.actions.setIndicator(null)}}}}}E(w,"draggedElement",void 0),E(w,"events",{indicator:null,currentCanvasHovered:null});const C=({children:t})=>{const{layers:r,events:a}=f((e=>e)),{query:o}=n.useEditor((e=>({enabled:e.options.enabled}))),{indicator:d}=o.getOptions();let s;try{s=(()=>{const{indicator:e}=a;if(e){const{placement:{where:t,parent:n,currentNode:a},error:o}=e,i=a?a.id:n.id;let s;const l=o?d.error:d.success;if(e.onCanvas&&null!=r[n.id].dom){const e=r[n.id]?.dom?.getBoundingClientRect(),t=r[n.id]?.headingDom?.getBoundingClientRect();return{top:t?.top,left:e?.left,width:e?.width,height:t?.height,background:"transparent",borderWidth:"1px",borderColor:l}}{if(!r[i]&&null==r[i].headingDom)return;const e=r[i]?.headingDom?.getBoundingClientRect(),n=r[i]?.dom?.getBoundingClientRect();return s="after"!==t&&a?n?.top:n?.top+n?.height,{top:s,left:e?.left,width:n.width+n?.left-e?.left,height:2,borderWidth:0,background:l}}}})()}catch(e){}return i.default.createElement("div",null,a.indicator?i.default.createElement(e.RenderIndicator,{style:s}):null,t)},O=({children:e})=>{const{store:r}=f(),a=n.useEventHandler(),o=t.useMemo((()=>a.derive(w,{layerStore:r})),[a,r]);return i.default.createElement(h.Provider,{value:o},i.default.createElement(C,null),e)},L=()=>{const{id:e}=v(),{displayName:r,actions:a}=n.useEditor((t=>({displayName:t.nodes[e]&&t.nodes[e].data.custom.displayName?t.nodes[e].data.custom.displayName:t.nodes[e].data.displayName,hidden:t.nodes[e]&&t.nodes[e].data.hidden}))),[o,d]=t.useState(!1),s=t.useRef(null),l=t.useCallback((e=>{s.current&&!s.current.contains(e.target)&&d(!1)}),[]);return t.useEffect((()=>()=>{window.removeEventListener("click",l)}),[l]),i.default.createElement(c.default,{html:r,disabled:!o,ref:e=>{e&&(s.current=e.el.current,window.removeEventListener("click",l),window.addEventListener("click",l))},onChange:t=>{a.setCustom(e,(e=>e.displayName=t.target.value))},tagName:"h2",onDoubleClick:()=>{o||d(!0)}})};var j;function D(){return D=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},D.apply(this,arguments)}var P,k,H=function(e){return s.createElement("svg",D({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 10 6"},e),j||(j=s.createElement("path",{d:"M9.99 1.01A1 1 0 0 0 8.283.303L5 3.586 1.717.303A1 1 0 1 0 .303 1.717l3.99 3.98a1 1 0 0 0 1.414 0l3.99-3.98a.997.997 0 0 0 .293-.707Z"})))};function N(){return N=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},N.apply(this,arguments)}var M,R,$=function(e){return s.createElement("svg",N({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:16,height:16},e),P||(P=s.createElement("path",{fill:"none",d:"M0 0h24v24H0z"})),k||(k=s.createElement("path",{d:"M1.181 12C2.121 6.88 6.608 3 12 3c5.392 0 9.878 3.88 10.819 9-.94 5.12-5.427 9-10.819 9-5.392 0-9.878-3.88-10.819-9zM12 17a5 5 0 1 0 0-10 5 5 0 0 0 0 10zm0-2a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"})))};function S(){return S=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},S.apply(this,arguments)}var _=function(e){return s.createElement("svg",S({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 18 18"},e),M||(M=s.createElement("path",{className:"linked_svg__a",d:"M16.5 9h-1a.5.5 0 0 0-.5.5V15H3V3h5.5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-7a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5h15a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.5-.5Z"})),R||(R=s.createElement("path",{className:"linked_svg__a",d:"M16.75 1h-5.373a.4.4 0 0 0-.377.4.392.392 0 0 0 .117.28l1.893 1.895-3.52 3.521a.5.5 0 0 0 0 .707l.706.708a.5.5 0 0 0 .708 0l3.521-3.521 1.893 1.892A.39.39 0 0 0 16.6 7a.4.4 0 0 0 .4-.377V1.25a.25.25 0 0 0-.25-.25Z"})))};const q=l.default.div`
display: flex;
flex-direction: row;
align-items: center;
padding: 4px 10px;
background: ${e=>e.selected?"#2680eb":"transparent"};
color: ${e=>e.selected?"#fff":"inherit"};
svg {
fill: ${e=>e.selected?"#fff":"#808184"};
margin-top: 2px;
}
.inner {
flex: 1;
> div {
padding: 0px;
flex: 1;
display: flex;
margin-left: ${e=>10*e.depth}px;
align-items: center;
div.layer-name {
flex: 1;
h2 {
font-size: 15px;
line-height: 26px;
}
}
}
}
`,B=l.default.a`
width: 8px;
height: 8px;
display: flex;
align-items: center;
justify-content: center;
transform-origin: center;
transition: 0.4s cubic-bezier(0.19, 1, 0.22, 1);
transform: rotate(${e=>e.expanded?180:0}deg);
opacity: 0.7;
cursor: pointer;
`,z=l.default.a`
width: 14px;
height: 14px;
margin-right: 10px;
position: relative;
transition: 0.4s cubic-bezier(0.19, 1, 0.22, 1);
cursor: pointer;
svg {
width: 100%;
height: 100%;
object-fit: contain;
opacity: ${e=>e.isHidden?.2:1};
}
&:after {
content: ' ';
width: 2px;
height: ${e=>e.isHidden?100:0}%;
position: absolute;
left: 2px;
top: 3px;
background: ${e=>e.selected?"#fff":"#808184"};
transform: rotate(-45deg);
transition: 0.4s cubic-bezier(0.19, 1, 0.22, 1);
transform-origin: 0% 0%;
opacity: ${e=>e.isHidden?.4:1};
}
`,I=l.default.div`
margin-left: -22px;
margin-right: 10px;
svg {
width: 12px;
height: 12px;
}
`,Y=()=>{const{id:e,depth:t,expanded:r,children:a,connectors:{drag:o,layerHeader:d},actions:{toggleLayer:s}}=v((e=>({expanded:e.expanded}))),{hidden:l,actions:c,selected:u,topLevel:p}=n.useEditor(((t,n)=>{const r=n.getEvent("selected").first()===e;return{hidden:t.nodes[e]&&t.nodes[e].data.hidden,selected:r,topLevel:n.node(e).isTopLevelCanvas()}}));return i.default.createElement(q,{selected:u,ref:o,depth:t},i.default.createElement(z,{selected:u,isHidden:l,onClick:()=>c.setHidden(e,!l)},i.default.createElement($,null)),i.default.createElement("div",{className:"inner"},i.default.createElement("div",{ref:d},p?i.default.createElement(I,null,i.default.createElement(_,null)):null,i.default.createElement("div",{className:"layer-name s"},i.default.createElement(L,null)),i.default.createElement("div",null,a&&a.length?i.default.createElement(B,{expanded:r,onMouseDown:()=>s()},i.default.createElement(H,null)):null))))},A=l.default.div`
background: ${e=>e.hovered?"#f1f1f1":"transparent"};
display: block;
padding-bottom: ${e=>e.hasCanvases&&e.expanded?5:0}px;
`,T=l.default.div`
margin: 0 0 0 ${e=>e.hasCanvases?35:0}px;
background: ${e=>e.hasCanvases?"rgba(255, 255, 255, 0.02)":"transparent"};
position: relative;
${e=>e.hasCanvases?'\n \n box-shadow: 0px 0px 44px -1px #00000014;\n border-radius: 10px;\n margin-right: 5px;\n margin-bottom:5px;\n margin-top:5px; \n > * { overflow:hidden; }\n &:before { \n position:absolute;\n left:-19px;\n width: 2px;\n height:100%;\n content: " ";\n background:#00000012;\n }\n ':""}
`,V=({children:e})=>{const{id:t,expanded:r,hovered:a,connectors:{layer:o}}=v((e=>({hovered:e.event.hovered,expanded:e.expanded}))),{hasChildCanvases:d}=n.useEditor(((e,n)=>({hasChildCanvases:n.node(t).isParentOfTopLevelNodes()})));return i.default.createElement(A,{ref:o,expanded:r,hasCanvases:d,hovered:a},i.default.createElement(Y,null),e?i.default.createElement(T,{hasCanvases:d,className:"craft-layer-children"},e):null)},Z=({children:t,options:n})=>{const r=e.useMethods(y,{layers:{},events:{selected:null,dragged:null,hovered:null},options:{renderLayer:V,...n}});return i.default.createElement(p.Provider,{value:{store:r}},i.default.createElement(O,null,t))};exports.DefaultLayer=V,exports.DefaultLayerHeader=Y,exports.EditableLayerName=L,exports.Layers=({...t})=>i.default.createElement(Z,{options:t},i.default.createElement(m,{id:e.ROOT_NODE,depth:0})),exports.useLayer=v;