| 1 |
/** |
| 2 |
* WordPress dependencies |
| 3 |
*/ |
| 4 |
import { registerPlugin } from "@wordpress/plugins"; |
| 5 |
import { debounce } from "@wordpress/compose"; |
| 6 |
import { subscribe } from "@wordpress/data"; |
| 7 |
import { createRoot } from "@wordpress/element"; |
| 8 |
import Library from "./Library"; |
| 9 |
import { LibraryButtonIcon } from "./icons"; |
| 10 |
import { CSS_CLASSES, DEFAULTS, KEYBOARD_KEYS } from "./constants"; |
| 11 |
|
| 12 |
import "./editor.scss"; |
| 13 |
import { SmartPostShowLogoIcon } from "../icons/icons"; |
| 14 |
|
| 15 |
/** |
| 16 |
* Add Prebuilt Library button to Gutenberg toolbar |
| 17 |
*/ |
| 18 |
|
| 19 |
let modalRoot; |
| 20 |
|
| 21 |
function ToolbarLibrary() { |
| 22 |
const renderButton = (selector) => { |
| 23 |
|
| 24 |
const enableDesignLibraryModule = sp_smart_post_block_localize?.modulesOptions?.["template-library"]; |
| 25 |
if ( ! enableDesignLibraryModule ) { |
| 26 |
return; |
| 27 |
} |
| 28 |
// Avoid adding duplicate buttons. |
| 29 |
if (selector.querySelector(`.${CSS_CLASSES.TOOLBAR_LIBRARY}`) ) return; |
| 30 |
|
| 31 |
const patternButton = document.createElement("div"); |
| 32 |
patternButton.classList.add(CSS_CLASSES.TOOLBAR_LIBRARY); |
| 33 |
selector.appendChild(patternButton); |
| 34 |
|
| 35 |
const root = createRoot(patternButton); |
| 36 |
root.render( |
| 37 |
<span id="smart-post-library-modal-button" className="popup-button" onClick={onInsertButtonClick}> |
| 38 |
<SmartPostShowLogoIcon /> Smart Design Library |
| 39 |
</span> |
| 40 |
); |
| 41 |
}; |
| 42 |
|
| 43 |
const onInsertButtonClick = (e) => { |
| 44 |
e.preventDefault(); |
| 45 |
// If modal already exists, don't create another. |
| 46 |
if (document.querySelector(`.${CSS_CLASSES.MODAL}`)) return; |
| 47 |
|
| 48 |
const node = document.createElement("div"); |
| 49 |
node.className = `${CSS_CLASSES.MODAL} sp-smart-blocks-layouts`; |
| 50 |
document.body.appendChild(node); |
| 51 |
|
| 52 |
modalRoot = createRoot(node); |
| 53 |
modalRoot.render(<Library isShow={true} onClose={removeModal} />); |
| 54 |
document.body.classList.add(CSS_CLASSES.POPUP_OPEN); |
| 55 |
|
| 56 |
// Optional: close when clicking outside |
| 57 |
setTimeout(() => { |
| 58 |
node.addEventListener("click", (e) => { |
| 59 |
if (e.target === node) removeModal(); |
| 60 |
}); |
| 61 |
}, 0); |
| 62 |
}; |
| 63 |
|
| 64 |
const removeModal = () => { |
| 65 |
const modal = document.querySelector(`.${CSS_CLASSES.MODAL}`); |
| 66 |
if (modal) { |
| 67 |
// Unmount React component first. |
| 68 |
if (modalRoot) { |
| 69 |
modalRoot.unmount(); |
| 70 |
} |
| 71 |
|
| 72 |
// Then remove modal from DOM. |
| 73 |
modal.remove(); |
| 74 |
document.body.classList.remove(CSS_CLASSES.POPUP_OPEN); |
| 75 |
} |
| 76 |
}; |
| 77 |
|
| 78 |
const debouncedRender = debounce(() => { |
| 79 |
const editToolbar = document.querySelector(".edit-post-header-toolbar"); |
| 80 |
if (editToolbar) { |
| 81 |
renderButton(editToolbar); |
| 82 |
} |
| 83 |
}, DEFAULTS.DEBOUNCE_DELAY); |
| 84 |
|
| 85 |
const unsubscribe = subscribe(() => { |
| 86 |
debouncedRender(); |
| 87 |
unsubscribe(); |
| 88 |
}); |
| 89 |
|
| 90 |
return null; |
| 91 |
} |
| 92 |
|
| 93 |
registerPlugin("sp-smart-toolbar-library", { |
| 94 |
render: ToolbarLibrary, |
| 95 |
}); |
| 96 |
|