Full Site Editing - Version 0.10

Version Description

  • Update page template selector with template preview.
Download this release

Release Info

Developer obenland
Plugin Icon wp plugin Full Site Editing
Version 0.10
Comparing to
See all releases

Code changes from version 0.9 to 0.10

Files changed (22) hide show
  1. full-site-editing-plugin.php +2 -2
  2. full-site-editing/dist/full-site-editing.js +1 -1
  3. readme.txt +4 -3
  4. starter-page-templates/class-starter-page-templates.php +51 -4
  5. starter-page-templates/dist/starter-page-templates.css +1 -1
  6. starter-page-templates/dist/starter-page-templates.deps.json +1 -1
  7. starter-page-templates/dist/starter-page-templates.js +2 -2
  8. starter-page-templates/dist/starter-page-templates.rtl.css +1 -1
  9. starter-page-templates/page-template-modal/components/block-preview.js +27 -0
  10. starter-page-templates/page-template-modal/components/block-template-preview.js +4 -2
  11. starter-page-templates/page-template-modal/components/preview-template-title.js +2 -2
  12. starter-page-templates/page-template-modal/components/template-selector-control.js +51 -32
  13. starter-page-templates/page-template-modal/components/template-selector-item.js +41 -12
  14. starter-page-templates/page-template-modal/components/template-selector-preview.js +35 -9
  15. starter-page-templates/page-template-modal/components/test/__snapshots__/template-selector-control-test.js.snap +124 -0
  16. starter-page-templates/page-template-modal/components/test/__snapshots__/template-selector-preview-test.js.snap +44 -0
  17. starter-page-templates/page-template-modal/components/test/helpers/templates-blocks-helpers.js +58 -0
  18. starter-page-templates/page-template-modal/components/test/template-selector-control-test.js +200 -0
  19. starter-page-templates/page-template-modal/components/test/template-selector-preview-test.js +65 -0
  20. starter-page-templates/page-template-modal/index.js +185 -56
  21. starter-page-templates/page-template-modal/styles/starter-page-templates-editor.scss +343 -23
  22. starter-page-templates/page-template-modal/utils/replace-placeholders.js +4 -0
full-site-editing-plugin.php CHANGED
@@ -2,7 +2,7 @@
2
/**
3
* Plugin Name: Full Site Editing
4
* Description: Enhances your page creation workflow within the Block Editor.
5
- * Version: 0.9
6
* Author: Automattic
7
* Author URI: https://automattic.com/wordpress-plugins/
8
* License: GPLv2 or later
@@ -20,7 +20,7 @@ namespace A8C\FSE;
20
*
21
* @var string
22
*/
23
- define( 'PLUGIN_VERSION', '0.9' );
24
25
// Themes which are supported by Full Site Editing (not the same as the SPT themes).
26
const SUPPORTED_THEMES = [ 'maywood' ];
2
/**
3
* Plugin Name: Full Site Editing
4
* Description: Enhances your page creation workflow within the Block Editor.
5
+ * Version: 0.10
6
* Author: Automattic
7
* Author URI: https://automattic.com/wordpress-plugins/
8
* License: GPLv2 or later
20
*
21
* @var string
22
*/
23
+ define( 'PLUGIN_VERSION', '0.10' );
24
25
// Themes which are supported by Full Site Editing (not the same as the SPT themes).
26
const SUPPORTED_THEMES = [ 'maywood' ];
full-site-editing/dist/full-site-editing.js CHANGED
@@ -9,4 +9,4 @@
9
Licensed under the MIT License (MIT), see
10
http://jedwatson.github.io/classnames
11
*/
12
- !function(){"use strict";var n={}.hasOwnProperty;function o(){for(var t=[],e=0;e<arguments.length;e++){var r=arguments[e];if(r){var i=typeof r;if("string"===i||"number"===i)t.push(r);else if(Array.isArray(r)&&r.length){var c=o.apply(null,r);c&&t.push(c)}else if("object"===i)for(var a in r)n.call(r,a)&&r[a]&&t.push(a)}}return t.join(" ")}t.exports?(o.default=o,t.exports=o):void 0===(r=function(){return o}.apply(e,[]))||(t.exports=r)}()},function(t,e){!function(){t.exports=this.wp.hooks}()},function(t,e){t.exports=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}},function(t,e){!function(){t.exports=this.wp.components}()},function(t,e){function n(){return t.exports=n=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},n.apply(this,arguments)}t.exports=n},function(t,e){!function(){t.exports=this.wp.domReady}()},function(t,e){!function(){t.exports=this.wp.keycodes}()},function(t,e,n){var r=n(33),o=n(34),i=n(35);t.exports=function(t,e){return r(t)||o(t,e)||i()}},function(t,e){!function(){t.exports=this.wp.apiFetch}()},function(t,e){!function(){t.exports=this.wp.htmlEntities}()},function(t,e,n){},function(t,e){!function(){t.exports=this.wp.serverSideRender}()},function(t,e){t.exports=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}},function(t,e){function n(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}t.exports=function(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),t}},function(t,e,n){var r=n(29),o=n(30);t.exports=function(t,e){return!e||"object"!==r(e)&&"function"!=typeof e?o(t):e}},function(t,e){function n(e){return t.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},n(e)}t.exports=n},function(t,e,n){var r=n(31);t.exports=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&r(t,e)}},function(t,e){!function(){t.exports=this.wp.url}()},function(t,e,n){var r=n(38),o=n(39),i=n(40);t.exports=function(t){return r(t)||o(t)||i()}},function(t,e){!function(){t.exports=this.wp.plugins}()},function(t,e,n){},function(t,e){function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function r(e){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?t.exports=r=function(t){return n(t)}:t.exports=r=function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":n(t)},r(e)}t.exports=r},function(t,e){t.exports=function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}},function(t,e){function n(e,r){return t.exports=n=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},n(e,r)}t.exports=n},function(t,e,n){},function(t,e){t.exports=function(t){if(Array.isArray(t))return t}},function(t,e){t.exports=function(t,e){var n=[],r=!0,o=!1,i=void 0;try{for(var c,a=t[Symbol.iterator]();!(r=(c=a.next()).done)&&(n.push(c.value),!e||n.length!==e);r=!0);}catch(l){o=!0,i=l}finally{try{r||null==a.return||a.return()}finally{if(o)throw i}}return n}},function(t,e){t.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}},function(t,e,n){},function(t,e,n){},function(t,e){t.exports=function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}},function(t,e){t.exports=function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}},function(t,e){t.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}},function(t,e,n){},function(t,e,n){"use strict";n.r(e);var r=n(0),o=n(4),i=n(1),c=n(19),a=n.n(c),l=function(){return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(a.a,{block:"a8c/navigation-menu"}))},s=(n(28),Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(r.createElement)("path",{fill:"none",d:"M0 0h24v24H0V0z"}),Object(r.createElement)("path",{d:"M12 7.27l4.28 10.43-3.47-1.53-.81-.36-.81.36-3.47 1.53L12 7.27M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z"})));Object(o.registerBlockType)("a8c/navigation-menu",{title:Object(i.__)("Navigation Menu"),description:Object(i.__)("Visual placeholder for site-wide navigation and menus."),icon:s,category:"layout",supports:{align:["wide","full"],html:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:l,save:function(){return null}});var u=n(12),p=n.n(u),d=n(3),f=n(9),b=n(10),m=n.n(b),O=n(20),g=n.n(O),v=n(21),y=n.n(v),h=n(22),j=n.n(h),E=n(23),_=n.n(E),w=n(24),S=n.n(w),k=n(8),P=n.n(k),x=n(2),T=n(5),I=function(t){function e(){return g()(this,e),j()(this,_()(e).apply(this,arguments))}return S()(e,t),y()(e,[{key:"toggleEditing",value:function(){var t=this.props,e=t.isEditing;(0,t.setState)({isEditing:!e})}},{key:"onSelectPost",value:function(t){var e=t.id,n=t.type;this.props.setState({isEditing:!1,selectedPostId:e,selectedPostType:n})}},{key:"render",value:function(){var t=this.props.attributes.align;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)("div",{className:P()("post-content-block",m()({},"align".concat(t),t))},Object(r.createElement)(T.PostTitle,null),Object(r.createElement)(T.InnerBlocks,{templateLock:!1})))}}]),e}(r.Component),B=Object(d.compose)([Object(d.withState)({isEditing:!1,selectedPostId:void 0,selectedPostType:void 0}),Object(x.withSelect)(function(t,e){var n=e.selectedPostId,r=e.selectedPostType;return{selectedPost:(0,t("core").getEntityRecord)("postType",r,n)}})])(I);n(32);Object(o.registerBlockType)("a8c/post-content",{title:Object(i.__)("Content"),description:Object(i.__)("The page content."),icon:"layout",category:"layout",supports:{align:["full"],anchor:!1,customClassName:!1,html:!1,inserter:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"full"}},edit:B,save:function(){return Object(r.createElement)(T.InnerBlocks.Content,null)}});var C=Object(d.createHigherOrderComponent)(function(t){return function(e){return"a8c/post-content"!==e.name?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"post-content__block"}))}},"addContentSlotClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/post-content",C,9);var D=n(14),N=n(6),L=n.n(N),A=n(15),F=n.n(A),M=n(16),R=n.n(M),U=n(17);function H(t){var e=Object(r.useRef)();return Object(r.useEffect)(function(){e.current=t},[t]),e.current}function q(t,e,n,o,c,a){var l=Object(r.useState)({option:e,previousOption:"",loaded:!1,error:!1}),s=F()(l,2),u=s[0],p=s[1],d=H(o),f=H(c);function b(){p(L()({},u,{option:u.previousOption,isSaving:!1}))}return Object(r.useEffect)(function(){u.loaded||u.error?function(){var e=u.option,r=u.previousOption,a=e&&e.trim()===r.trim(),l=!e||0===e.trim().length;!o&&d&&l&&b();if(!c||a)return;!f&&c&&function(e){p(L()({},u,{isSaving:!0})),R()({path:"/wp/v2/settings",method:"POST",data:m()({},t,e)}).then(function(){return function(t){p(L()({},u,{previousOption:t,isDirty:!1,isSaving:!1}))}(e)}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to save site %s"),t)),b()})}(e)}():R()({path:"/wp/v2/settings"}).then(function(e){return p(L()({},u,{option:Object(U.decodeEntities)(e[t]),previousOption:Object(U.decodeEntities)(e[t]),loaded:!0,error:!1}))}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to load site %s"),t)),p(L()({},u,{option:Object(i.sprintf)(Object(i.__)("Error loading site %s"),t),error:!0}))})}),{siteOptions:u,handleChange:function(t){a({updated:Date.now()}),p(L()({},u,{option:t}))}}}var z=Object(d.compose)([Object(x.withSelect)(function(t,e){var n=e.clientId,r=t("core/editor"),o=r.isSavingPost,i=r.isPublishingPost,c=r.isAutosavingPost,a=r.isCurrentPostPublished,l=t("core/block-editor"),s=l.getBlockIndex,u=l.getBlockRootClientId,p=l.getTemplateLock,d=u(n);return{blockIndex:s(n,d),isLocked:!!p(d),rootClientId:d,shouldUpdateSiteOption:(o()&&a()||i())&&!c()}}),Object(x.withDispatch)(function(t,e){var n=e.blockIndex,r=e.rootClientId;return{createErrorNotice:t("core/notices").createErrorNotice,insertDefaultBlock:function(){return t("core/block-editor").insertDefaultBlock({},r,n+1)}}})])(function(t){var e=t.className,n=t.createErrorNotice,o=t.shouldUpdateSiteOption,c=t.isSelected,a=t.setAttributes,l=t.isLocked,s=t.insertDefaultBlock,u=q("description",Object(i.__)("Site description loading…"),n,c,o,a),p=u.siteOptions,d=u.handleChange,f=p.option;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(T.PlainText,{className:P()("site-description",e),value:f,onChange:function(t){return d(t)},onKeyDown:function(t){t.keyCode===D.ENTER&&(t.preventDefault(),l||s())},placeholder:Object(i.__)("Add a Site Description"),"aria-label":Object(i.__)("Site Description")}))});n(36);Object(o.registerBlockType)("a8c/site-description",{title:Object(i.__)("Site Description"),description:Object(i.__)("Site description, also known as the tagline."),icon:Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24"},Object(r.createElement)("path",{fill:"none",d:"M0 0h24v24H0z"}),Object(r.createElement)("path",{d:"M4 9h16v2H4V9zm0 4h10v2H4v-2z"})),category:"layout",supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:z,save:function(){return null}});var V=Object(d.compose)([Object(x.withSelect)(function(t,e){var n=e.clientId,r=t("core/editor"),o=r.isSavingPost,i=r.isPublishingPost,c=r.isAutosavingPost,a=r.isCurrentPostPublished,l=t("core/block-editor"),s=l.getBlockIndex,u=l.getBlockRootClientId,p=l.getTemplateLock,d=u(n);return{blockIndex:s(n,d),isLocked:!!p(d),rootClientId:d,shouldUpdateSiteOption:(o()&&a()||i())&&!c()}}),Object(x.withDispatch)(function(t,e){var n=e.blockIndex,r=e.rootClientId;return{createErrorNotice:t("core/notices").createErrorNotice,insertDefaultBlock:function(){return t("core/block-editor").insertDefaultBlock({},r,n+1)}}})])(function(t){var e=t.className,n=t.createErrorNotice,o=t.shouldUpdateSiteOption,c=t.isSelected,a=t.setAttributes,l=t.isLocked,s=t.insertDefaultBlock,u=q("title",Object(i.__)("Site title loading…"),n,c,o,a),p=u.siteOptions,d=u.handleChange,f=p.option;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(T.PlainText,{className:P()("site-title",e),value:f,onChange:function(t){return d(t)},onKeyDown:function(t){t.keyCode===D.ENTER&&(t.preventDefault(),l||s())},placeholder:Object(i.__)("Add a Site Title"),"aria-label":Object(i.__)("Site Title")}))});n(37);Object(o.registerBlockType)("a8c/site-title",{title:Object(i.__)("Site Title"),description:Object(i.__)("Your site title."),icon:"layout",category:"layout",supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:V,save:function(){return null}});var G=n(7),W=n(11),K=n(25),Q=(n(18),Object(d.compose)(Object(d.withState)({templateClientId:null}),Object(x.withSelect)(function(t,e){var n=e.attributes,r=e.templateClientId,o=t("core").getEntityRecord,i=t("core/editor"),c=i.getCurrentPostId,a=i.isEditedPostDirty,l=t("core/block-editor"),s=l.getBlock,u=l.getSelectedBlock,p=t("core/edit-post").isEditorSidebarOpened,d=n.templateId,f=c(),b=d&&o("postType","wp_template_part",d),m=Object(K.addQueryArgs)(fullSiteEditing.editTemplateBaseUrl,{post:d,fse_parent_post:f}),O=u();return{currentPostId:f,editTemplateUrl:m,template:b,templateBlock:s(r),templateTitle:Object(G.get)(b,["title","rendered"],""),isDirty:a(),isEditorSidebarOpened:!!p(),isAnyTemplateBlockSelected:O&&"a8c/template"===O.name}}),Object(x.withDispatch)(function(t,e){var n=t("core/block-editor").receiveBlocks,r=t("core/edit-post").openGeneralSidebar,i=e.template,c=e.templateClientId,a=e.setState;return{savePost:t("core/editor").savePost,receiveTemplateBlocks:function(){if(i&&!c){var t=Object(o.parse)(Object(G.get)(i,["content","raw"],"")),e=Object(o.createBlock)("core/group",{},t);n([e]),a({templateClientId:e.clientId})}},openGeneralSidebar:r}}))(function(t){var e,n=t.attributes,o=t.editTemplateUrl,c=t.receiveTemplateBlocks,a=t.template,l=t.templateBlock,s=t.templateTitle,u=t.isDirty,p=t.savePost,d=t.isEditorSidebarOpened,f=t.openGeneralSidebar,b=t.isAnyTemplateBlockSelected;if(!a)return Object(r.createElement)(W.Placeholder,null,Object(r.createElement)(W.Spinner,null));var O=Object(r.createRef)(),g=Object(r.useState)(!1),v=F()(g,2),y=v[0],h=v[1];Object(r.useEffect)(function(){y&&!u&&O.current.click(),c()}),Object(r.useEffect)(function(){var t=document.querySelector(".edit-post-sidebar__panel-tabs ul li:last-child");if(d&&t){if(b)return f("edit-post/document"),void t.classList.add("hidden");t.classList.remove("hidden")}},[b,d,f]);var j=n.align,E=n.className;return Object(r.createElement)("div",{className:P()("template-block",(e={},m()(e,"align".concat(j),j),m()(e,"is-navigating-to-template",y),e))},l&&Object(r.createElement)(r.Fragment,null,Object(r.createElement)(W.Disabled,null,Object(r.createElement)("div",{className:E},Object(r.createElement)(T.BlockEdit,{attributes:l.attributes,block:l,clientId:l.clientId,isSelected:!1,name:l.name,setAttributes:G.noop}))),Object(r.createElement)(W.Placeholder,{className:"template-block__overlay"},y&&Object(r.createElement)("div",{className:"template-block__loading"},Object(r.createElement)(W.Spinner,null)," ",Object(i.sprintf)(Object(i.__)("Loading %s Editor"),s)),Object(r.createElement)(W.Button,{className:y?"hidden":null,href:o,onClick:function(t){h(!0),u&&(t.preventDefault(),p())},isDefault:!0,isLarge:!0,ref:O},Object(i.sprintf)(Object(i.__)("Edit %s"),s)))))})),Y=Object(d.createHigherOrderComponent)(function(t){return function(e){return"fse-site-logo"!==e.attributes.className?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"template__site-logo"}))}},"addFSESiteLogoClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",Y),"wp_template_part"!==fullSiteEditing.editorPostType&&Object(o.registerBlockType)("a8c/template",{title:Object(i.__)("Template Part"),description:Object(i.__)("Display a Template Part."),icon:"layout",category:"layout",attributes:{templateId:{type:"number"},className:{type:"string"}},supports:{anchor:!1,customClassName:!1,html:!1,inserter:!1,reusable:!1},edit:Q,save:function(){return null},getEditWrapperProps:function(){return{"data-align":"full"}}});var J=Object(d.createHigherOrderComponent)(function(t){return function(e){return"a8c/template"!==e.name?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"template__block-container"}))}},"addFSETemplateClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",J,9);var X=n(13),Z=n.n(X);Z()(function(){var t=fullSiteEditing,e=t.closeButtonLabel,n=t.closeButtonUrl,r=t.editorPostType,o=setInterval(function(){var t=document.querySelector(".edit-post-fullscreen-mode-close__toolbar a");if(t&&(clearInterval(o),"wp_template_part"===r&&n)){var i=document.createElement("a");i.href=n,i.innerHTML=e,i.className="components-button components-icon-button is-button is-default",i.setAttribute("aria-label",e),document.querySelector(".edit-post-fullscreen-mode-close__toolbar").replaceChild(i,t)}})});var $=n(26),tt=n.n($),et=n(27),nt=Object(x.withSelect)(function(t){var e=t("core").getEntityRecord,n=t("core/editor").getEditedPostAttribute;return{templateClasses:Object(G.map)(n("template_part_types"),function(t){var n=Object(G.get)(e("taxonomy","wp_template_part_type",t),"name","");return Object(G.endsWith)(n,"-header")?"site-header site-branding":Object(G.endsWith)(n,"-footer")?"site-footer":void 0})}})(function(t){var e=t.templateClasses,n=setInterval(function(){var t=document.querySelector(".block-editor-writing-flow.editor-writing-flow > div");t&&(clearInterval(n),t.className=P.a.apply(void 0,["a8c-template-editor"].concat(tt()(e))))});return null});"wp_template_part"===fullSiteEditing.editorPostType&&Object(et.registerPlugin)("fse-editor-template-classes",{render:nt}),Z()(function(){"wp_template_part"===fullSiteEditing.editorPostType&&Object(x.dispatch)("core/notices").createNotice("info",Object(i.__)("Updates to this template will affect all pages on your site."),{isDismissible:!1})});var rt=Object(d.compose)(Object(x.withSelect)(function(t){var e=t("core/editor"),n=e.getBlocks,r=e.getEditorSettings,o=t("core/edit-post").getEditorMode,i=n().find(function(t){return"a8c/post-content"===t.name});return{rootClientId:i?i.clientId:"",showInserter:"visual"===o()&&r().richEditingEnabled}}))(function(t){var e=t.rootClientId,n=t.showInserter;return Object(r.createElement)(T.Inserter,{rootClientId:e,disabled:!n,position:"bottom right"})});Z()(function(){return function(){if("page"===fullSiteEditing.editorPostType)var t=setInterval(function(){var e=document.querySelector(".edit-post-header-toolbar");if(e){clearInterval(t);var n=document.createElement("div");n.classList.add("fse-post-content-block-inserter"),e.insertBefore(n,e.firstChild),Object(r.render)(Object(r.createElement)(rt,null),n)}})}()});var ot=Object(x.subscribe)(function(){if("page"!==fullSiteEditing.editorPostType)return ot();!1===Object(x.select)("core/editor").isValidTemplate()&&Object(x.dispatch)("core/editor").setTemplateValidity(!0)}),it=["logo","brand","emblem","hallmark"];Object(f.addFilter)("blocks.registerBlockType","full-site-editing/editor/image-block-keywords",function(t,e){return"core/image"!==e?t:t=Object(G.assign)({},t,{keywords:t.keywords.concat(it)})});n(41);Object(x.use)(function(t){return{dispatch:function(e){var n=L()({},t.dispatch(e)),r=fullSiteEditing.editorPostType;return"core/editor"===e&&n.trashPost&&"wp_template_part"===r&&(n.trashPost=function(){}),n}}}),Object(x.use)(function(t){return{dispatch:function(e){var n=L()({},t.dispatch(e)),r=fullSiteEditing.editorPostType;if("core/editor"===e&&n.editPost&&"wp_template_part"===r){var o=n.editPost;n.editPost=function(t){"draft"!==t.status&&o(t)}}return n}}});var ct=Object(x.subscribe)(function(){var t=Object(x.dispatch)("core/edit-post").removeEditorPanel;return"page"===fullSiteEditing.editorPostType&&t("featured-image"),"wp_template_part"===fullSiteEditing.editorPostType&&t("post-status"),ct()})}]));
9
Licensed under the MIT License (MIT), see
10
http://jedwatson.github.io/classnames
11
*/
12
+ !function(){"use strict";var n={}.hasOwnProperty;function o(){for(var t=[],e=0;e<arguments.length;e++){var r=arguments[e];if(r){var i=typeof r;if("string"===i||"number"===i)t.push(r);else if(Array.isArray(r)&&r.length){var c=o.apply(null,r);c&&t.push(c)}else if("object"===i)for(var a in r)n.call(r,a)&&r[a]&&t.push(a)}}return t.join(" ")}t.exports?(o.default=o,t.exports=o):void 0===(r=function(){return o}.apply(e,[]))||(t.exports=r)}()},function(t,e){!function(){t.exports=this.wp.hooks}()},function(t,e){t.exports=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}},function(t,e){!function(){t.exports=this.wp.components}()},function(t,e){function n(){return t.exports=n=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},n.apply(this,arguments)}t.exports=n},function(t,e){!function(){t.exports=this.wp.domReady}()},function(t,e){!function(){t.exports=this.wp.keycodes}()},function(t,e,n){var r=n(33),o=n(34),i=n(35);t.exports=function(t,e){return r(t)||o(t,e)||i()}},function(t,e){!function(){t.exports=this.wp.apiFetch}()},function(t,e){!function(){t.exports=this.wp.htmlEntities}()},function(t,e,n){},function(t,e){!function(){t.exports=this.wp.serverSideRender}()},function(t,e){t.exports=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}},function(t,e){function n(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}t.exports=function(t,e,r){return e&&n(t.prototype,e),r&&n(t,r),t}},function(t,e,n){var r=n(29),o=n(30);t.exports=function(t,e){return!e||"object"!==r(e)&&"function"!=typeof e?o(t):e}},function(t,e){function n(e){return t.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},n(e)}t.exports=n},function(t,e,n){var r=n(31);t.exports=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&r(t,e)}},function(t,e){!function(){t.exports=this.wp.url}()},function(t,e,n){var r=n(38),o=n(39),i=n(40);t.exports=function(t){return r(t)||o(t)||i()}},function(t,e){!function(){t.exports=this.wp.plugins}()},function(t,e,n){},function(t,e){function n(t){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function r(e){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?t.exports=r=function(t){return n(t)}:t.exports=r=function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":n(t)},r(e)}t.exports=r},function(t,e){t.exports=function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}},function(t,e){function n(e,r){return t.exports=n=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},n(e,r)}t.exports=n},function(t,e,n){},function(t,e){t.exports=function(t){if(Array.isArray(t))return t}},function(t,e){t.exports=function(t,e){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t)){var n=[],r=!0,o=!1,i=void 0;try{for(var c,a=t[Symbol.iterator]();!(r=(c=a.next()).done)&&(n.push(c.value),!e||n.length!==e);r=!0);}catch(l){o=!0,i=l}finally{try{r||null==a.return||a.return()}finally{if(o)throw i}}return n}}},function(t,e){t.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}},function(t,e,n){},function(t,e,n){},function(t,e){t.exports=function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e<t.length;e++)n[e]=t[e];return n}}},function(t,e){t.exports=function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}},function(t,e){t.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}},function(t,e,n){},function(t,e,n){"use strict";n.r(e);var r=n(0),o=n(4),i=n(1),c=n(19),a=n.n(c),l=function(){return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(a.a,{block:"a8c/navigation-menu"}))},s=(n(28),Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"},Object(r.createElement)("path",{fill:"none",d:"M0 0h24v24H0V0z"}),Object(r.createElement)("path",{d:"M12 7.27l4.28 10.43-3.47-1.53-.81-.36-.81.36-3.47 1.53L12 7.27M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71L12 2z"})));Object(o.registerBlockType)("a8c/navigation-menu",{title:Object(i.__)("Navigation Menu"),description:Object(i.__)("Visual placeholder for site-wide navigation and menus."),icon:s,category:"layout",supports:{align:["wide","full"],html:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:l,save:function(){return null}});var u=n(12),p=n.n(u),d=n(3),f=n(9),b=n(10),m=n.n(b),O=n(20),g=n.n(O),y=n(21),v=n.n(y),h=n(22),j=n.n(h),E=n(23),_=n.n(E),w=n(24),S=n.n(w),k=n(8),P=n.n(k),x=n(2),T=n(5),I=function(t){function e(){return g()(this,e),j()(this,_()(e).apply(this,arguments))}return S()(e,t),v()(e,[{key:"toggleEditing",value:function(){var t=this.props,e=t.isEditing;(0,t.setState)({isEditing:!e})}},{key:"onSelectPost",value:function(t){var e=t.id,n=t.type;this.props.setState({isEditing:!1,selectedPostId:e,selectedPostType:n})}},{key:"render",value:function(){var t=this.props.attributes.align;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)("div",{className:P()("post-content-block",m()({},"align".concat(t),t))},Object(r.createElement)(T.PostTitle,null),Object(r.createElement)(T.InnerBlocks,{templateLock:!1})))}}]),e}(r.Component),B=Object(d.compose)([Object(d.withState)({isEditing:!1,selectedPostId:void 0,selectedPostType:void 0}),Object(x.withSelect)(function(t,e){var n=e.selectedPostId,r=e.selectedPostType;return{selectedPost:(0,t("core").getEntityRecord)("postType",r,n)}})])(I);n(32);Object(o.registerBlockType)("a8c/post-content",{title:Object(i.__)("Content"),description:Object(i.__)("The page content."),icon:"layout",category:"layout",supports:{align:["full"],anchor:!1,customClassName:!1,html:!1,inserter:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"full"}},edit:B,save:function(){return Object(r.createElement)(T.InnerBlocks.Content,null)}});var C=Object(d.createHigherOrderComponent)(function(t){return function(e){return"a8c/post-content"!==e.name?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"post-content__block"}))}},"addContentSlotClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/post-content",C,9);var D=n(14),N=n(6),A=n.n(N),L=n(15),F=n.n(L),M=n(16),R=n.n(M),U=n(17);function H(t){var e=Object(r.useRef)();return Object(r.useEffect)(function(){e.current=t},[t]),e.current}function q(t,e,n,o,c,a){var l=Object(r.useState)({option:e,previousOption:"",loaded:!1,error:!1}),s=F()(l,2),u=s[0],p=s[1],d=H(o),f=H(c);function b(){p(A()({},u,{option:u.previousOption,isSaving:!1}))}return Object(r.useEffect)(function(){u.loaded||u.error?function(){var e=u.option,r=u.previousOption,a=e&&e.trim()===r.trim(),l=!e||0===e.trim().length;!o&&d&&l&&b();if(!c||a)return;!f&&c&&function(e){p(A()({},u,{isSaving:!0})),R()({path:"/wp/v2/settings",method:"POST",data:m()({},t,e)}).then(function(){return function(t){p(A()({},u,{previousOption:t,isDirty:!1,isSaving:!1}))}(e)}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to save site %s"),t)),b()})}(e)}():R()({path:"/wp/v2/settings"}).then(function(e){return p(A()({},u,{option:Object(U.decodeEntities)(e[t]),previousOption:Object(U.decodeEntities)(e[t]),loaded:!0,error:!1}))}).catch(function(){n(Object(i.sprintf)(Object(i.__)("Unable to load site %s"),t)),p(A()({},u,{option:Object(i.sprintf)(Object(i.__)("Error loading site %s"),t),error:!0}))})}),{siteOptions:u,handleChange:function(t){a({updated:Date.now()}),p(A()({},u,{option:t}))}}}var z=Object(d.compose)([Object(x.withSelect)(function(t,e){var n=e.clientId,r=t("core/editor"),o=r.isSavingPost,i=r.isPublishingPost,c=r.isAutosavingPost,a=r.isCurrentPostPublished,l=t("core/block-editor"),s=l.getBlockIndex,u=l.getBlockRootClientId,p=l.getTemplateLock,d=u(n);return{blockIndex:s(n,d),isLocked:!!p(d),rootClientId:d,shouldUpdateSiteOption:(o()&&a()||i())&&!c()}}),Object(x.withDispatch)(function(t,e){var n=e.blockIndex,r=e.rootClientId;return{createErrorNotice:t("core/notices").createErrorNotice,insertDefaultBlock:function(){return t("core/block-editor").insertDefaultBlock({},r,n+1)}}})])(function(t){var e=t.className,n=t.createErrorNotice,o=t.shouldUpdateSiteOption,c=t.isSelected,a=t.setAttributes,l=t.isLocked,s=t.insertDefaultBlock,u=q("description",Object(i.__)("Site description loading…"),n,c,o,a),p=u.siteOptions,d=u.handleChange,f=p.option;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(T.PlainText,{className:P()("site-description",e),value:f,onChange:function(t){return d(t)},onKeyDown:function(t){t.keyCode===D.ENTER&&(t.preventDefault(),l||s())},placeholder:Object(i.__)("Add a Site Description"),"aria-label":Object(i.__)("Site Description")}))});n(36);Object(o.registerBlockType)("a8c/site-description",{title:Object(i.__)("Site Description"),description:Object(i.__)("Site description, also known as the tagline."),icon:Object(r.createElement)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24"},Object(r.createElement)("path",{fill:"none",d:"M0 0h24v24H0z"}),Object(r.createElement)("path",{d:"M4 9h16v2H4V9zm0 4h10v2H4v-2z"})),category:"layout",supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:z,save:function(){return null}});var V=Object(d.compose)([Object(x.withSelect)(function(t,e){var n=e.clientId,r=t("core/editor"),o=r.isSavingPost,i=r.isPublishingPost,c=r.isAutosavingPost,a=r.isCurrentPostPublished,l=t("core/block-editor"),s=l.getBlockIndex,u=l.getBlockRootClientId,p=l.getTemplateLock,d=u(n);return{blockIndex:s(n,d),isLocked:!!p(d),rootClientId:d,shouldUpdateSiteOption:(o()&&a()||i())&&!c()}}),Object(x.withDispatch)(function(t,e){var n=e.blockIndex,r=e.rootClientId;return{createErrorNotice:t("core/notices").createErrorNotice,insertDefaultBlock:function(){return t("core/block-editor").insertDefaultBlock({},r,n+1)}}})])(function(t){var e=t.className,n=t.createErrorNotice,o=t.shouldUpdateSiteOption,c=t.isSelected,a=t.setAttributes,l=t.isLocked,s=t.insertDefaultBlock,u=q("title",Object(i.__)("Site title loading…"),n,c,o,a),p=u.siteOptions,d=u.handleChange,f=p.option;return Object(r.createElement)(r.Fragment,null,Object(r.createElement)(T.PlainText,{className:P()("site-title",e),value:f,onChange:function(t){return d(t)},onKeyDown:function(t){t.keyCode===D.ENTER&&(t.preventDefault(),l||s())},placeholder:Object(i.__)("Add a Site Title"),"aria-label":Object(i.__)("Site Title")}))});n(37);Object(o.registerBlockType)("a8c/site-title",{title:Object(i.__)("Site Title"),description:Object(i.__)("Your site title."),icon:"layout",category:"layout",supports:{align:["wide","full"],html:!1,multiple:!1,reusable:!1},attributes:{align:{type:"string",default:"wide"}},edit:V,save:function(){return null}});var G=n(7),W=n(11),K=n(25),Q=(n(18),Object(d.compose)(Object(d.withState)({templateClientId:null}),Object(x.withSelect)(function(t,e){var n=e.attributes,r=e.templateClientId,o=t("core").getEntityRecord,i=t("core/editor"),c=i.getCurrentPostId,a=i.isEditedPostDirty,l=t("core/block-editor"),s=l.getBlock,u=l.getSelectedBlock,p=t("core/edit-post").isEditorSidebarOpened,d=n.templateId,f=c(),b=d&&o("postType","wp_template_part",d),m=Object(K.addQueryArgs)(fullSiteEditing.editTemplateBaseUrl,{post:d,fse_parent_post:f}),O=u();return{currentPostId:f,editTemplateUrl:m,template:b,templateBlock:s(r),templateTitle:Object(G.get)(b,["title","rendered"],""),isDirty:a(),isEditorSidebarOpened:!!p(),isAnyTemplateBlockSelected:O&&"a8c/template"===O.name}}),Object(x.withDispatch)(function(t,e){var n=t("core/block-editor").receiveBlocks,r=t("core/edit-post").openGeneralSidebar,i=e.template,c=e.templateClientId,a=e.setState;return{savePost:t("core/editor").savePost,receiveTemplateBlocks:function(){if(i&&!c){var t=Object(o.parse)(Object(G.get)(i,["content","raw"],"")),e=Object(o.createBlock)("core/group",{},t);n([e]),a({templateClientId:e.clientId})}},openGeneralSidebar:r}}))(function(t){var e,n=t.attributes,o=t.editTemplateUrl,c=t.receiveTemplateBlocks,a=t.template,l=t.templateBlock,s=t.templateTitle,u=t.isDirty,p=t.savePost,d=t.isEditorSidebarOpened,f=t.openGeneralSidebar,b=t.isAnyTemplateBlockSelected;if(!a)return Object(r.createElement)(W.Placeholder,null,Object(r.createElement)(W.Spinner,null));var O=Object(r.createRef)(),g=Object(r.useState)(!1),y=F()(g,2),v=y[0],h=y[1];Object(r.useEffect)(function(){v&&!u&&O.current.click(),c()}),Object(r.useEffect)(function(){var t=document.querySelector(".edit-post-sidebar__panel-tabs ul li:last-child");if(d&&t){if(b)return f("edit-post/document"),void t.classList.add("hidden");t.classList.remove("hidden")}},[b,d,f]);var j=n.align,E=n.className;return Object(r.createElement)("div",{className:P()("template-block",(e={},m()(e,"align".concat(j),j),m()(e,"is-navigating-to-template",v),e))},l&&Object(r.createElement)(r.Fragment,null,Object(r.createElement)(W.Disabled,null,Object(r.createElement)("div",{className:E},Object(r.createElement)(T.BlockEdit,{attributes:l.attributes,block:l,clientId:l.clientId,isSelected:!1,name:l.name,setAttributes:G.noop}))),Object(r.createElement)(W.Placeholder,{className:"template-block__overlay"},v&&Object(r.createElement)("div",{className:"template-block__loading"},Object(r.createElement)(W.Spinner,null)," ",Object(i.sprintf)(Object(i.__)("Loading %s Editor"),s)),Object(r.createElement)(W.Button,{className:v?"hidden":null,href:o,onClick:function(t){h(!0),u&&(t.preventDefault(),p())},isDefault:!0,isLarge:!0,ref:O},Object(i.sprintf)(Object(i.__)("Edit %s"),s)))))})),Y=Object(d.createHigherOrderComponent)(function(t){return function(e){return"fse-site-logo"!==e.attributes.className?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"template__site-logo"}))}},"addFSESiteLogoClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",Y),"wp_template_part"!==fullSiteEditing.editorPostType&&Object(o.registerBlockType)("a8c/template",{title:Object(i.__)("Template Part"),description:Object(i.__)("Display a Template Part."),icon:"layout",category:"layout",attributes:{templateId:{type:"number"},className:{type:"string"}},supports:{anchor:!1,customClassName:!1,html:!1,inserter:!1,reusable:!1},edit:Q,save:function(){return null},getEditWrapperProps:function(){return{"data-align":"full"}}});var J=Object(d.createHigherOrderComponent)(function(t){return function(e){return"a8c/template"!==e.name?Object(r.createElement)(t,e):Object(r.createElement)(t,p()({},e,{className:"template__block-container"}))}},"addFSETemplateClassname");Object(f.addFilter)("editor.BlockListBlock","full-site-editing/blocks/template",J,9);var X=n(13),Z=n.n(X);Z()(function(){var t=fullSiteEditing,e=t.closeButtonLabel,n=t.closeButtonUrl,r=t.editorPostType,o=setInterval(function(){var t=document.querySelector(".edit-post-fullscreen-mode-close__toolbar a");if(t&&(clearInterval(o),"wp_template_part"===r&&n)){var i=document.createElement("a");i.href=n,i.innerHTML=e,i.className="components-button components-icon-button is-button is-default",i.setAttribute("aria-label",e),document.querySelector(".edit-post-fullscreen-mode-close__toolbar").replaceChild(i,t)}})});var $=n(26),tt=n.n($),et=n(27),nt=Object(x.withSelect)(function(t){var e=t("core").getEntityRecord,n=t("core/editor").getEditedPostAttribute;return{templateClasses:Object(G.map)(n("template_part_types"),function(t){var n=Object(G.get)(e("taxonomy","wp_template_part_type",t),"name","");return Object(G.endsWith)(n,"-header")?"site-header site-branding":Object(G.endsWith)(n,"-footer")?"site-footer":void 0})}})(function(t){var e=t.templateClasses,n=setInterval(function(){var t=document.querySelector(".block-editor-writing-flow.editor-writing-flow > div");t&&(clearInterval(n),t.className=P.a.apply(void 0,["a8c-template-editor"].concat(tt()(e))))});return null});"wp_template_part"===fullSiteEditing.editorPostType&&Object(et.registerPlugin)("fse-editor-template-classes",{render:nt}),Z()(function(){"wp_template_part"===fullSiteEditing.editorPostType&&Object(x.dispatch)("core/notices").createNotice("info",Object(i.__)("Updates to this template will affect all pages on your site."),{isDismissible:!1})});var rt=Object(d.compose)(Object(x.withSelect)(function(t){var e=t("core/editor"),n=e.getBlocks,r=e.getEditorSettings,o=t("core/edit-post").getEditorMode,i=n().find(function(t){return"a8c/post-content"===t.name});return{rootClientId:i?i.clientId:"",showInserter:"visual"===o()&&r().richEditingEnabled}}))(function(t){var e=t.rootClientId,n=t.showInserter;return Object(r.createElement)(T.Inserter,{rootClientId:e,disabled:!n,position:"bottom right"})});Z()(function(){return function(){if("page"===fullSiteEditing.editorPostType)var t=setInterval(function(){var e=document.querySelector(".edit-post-header-toolbar");if(e){clearInterval(t);var n=document.createElement("div");n.classList.add("fse-post-content-block-inserter"),e.insertBefore(n,e.firstChild),Object(r.render)(Object(r.createElement)(rt,null),n)}})}()});var ot=Object(x.subscribe)(function(){if("page"!==fullSiteEditing.editorPostType)return ot();!1===Object(x.select)("core/editor").isValidTemplate()&&Object(x.dispatch)("core/editor").setTemplateValidity(!0)}),it=["logo","brand","emblem","hallmark"];Object(f.addFilter)("blocks.registerBlockType","full-site-editing/editor/image-block-keywords",function(t,e){return"core/image"!==e?t:t=Object(G.assign)({},t,{keywords:t.keywords.concat(it)})});n(41);Object(x.use)(function(t){return{dispatch:function(e){var n=A()({},t.dispatch(e)),r=fullSiteEditing.editorPostType;return"core/editor"===e&&n.trashPost&&"wp_template_part"===r&&(n.trashPost=function(){}),n}}}),Object(x.use)(function(t){return{dispatch:function(e){var n=A()({},t.dispatch(e)),r=fullSiteEditing.editorPostType;if("core/editor"===e&&n.editPost&&"wp_template_part"===r){var o=n.editPost;n.editPost=function(t){"draft"!==t.status&&o(t)}}return n}}});var ct=Object(x.subscribe)(function(){var t=Object(x.dispatch)("core/edit-post").removeEditorPanel;return"page"===fullSiteEditing.editorPostType&&t("featured-image"),"wp_template_part"===fullSiteEditing.editorPostType&&t("post-status"),ct()})}]));
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
Contributors: alexislloyd, allancole, automattic, codebykat, copons, dmsnell, get_dave, glendaviesnz, gwwar, iamtakashi, Joen, kwight, marekhrabe, mattwiebe, mmtr86, mppfeiffer, nrqsnchz, obenland, okenobi, vindl, noahtallen, owolski
3
Tags: block, blocks, editor, gutenberg, page
4
Requires at least: 5.0
5
- Tested up to: 5.2
6
- Stable tag: 0.9
7
Requires PHP: 5.6.20
8
License: GPLv2 or later
9
License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -39,9 +39,10 @@ It adds an excerpt! And meta information! It really is much more useful, especia
39
This plugin is experimental, so we don't provide any support for it outside of websites hosted on WordPress.com at this time.
40
41
== Changelog ==
42
43
= 0.9 =
44
-
45
* Rename wp_template CPT to wp_template_part.
46
47
= 0.7 =
2
Contributors: alexislloyd, allancole, automattic, codebykat, copons, dmsnell, get_dave, glendaviesnz, gwwar, iamtakashi, Joen, kwight, marekhrabe, mattwiebe, mmtr86, mppfeiffer, nrqsnchz, obenland, okenobi, vindl, noahtallen, owolski
3
Tags: block, blocks, editor, gutenberg, page
4
Requires at least: 5.0
5
+ Tested up to: 5.3
6
+ Stable tag: 0.10
7
Requires PHP: 5.6.20
8
License: GPLv2 or later
9
License URI: https://www.gnu.org/licenses/gpl-2.0.html
39
This plugin is experimental, so we don't provide any support for it outside of websites hosted on WordPress.com at this time.
40
41
== Changelog ==
42
+ = 0.10 =
43
+ * Update page template selector with template preview.
44
45
= 0.9 =
46
* Rename wp_template CPT to wp_template_part.
47
48
= 0.7 =
starter-page-templates/class-starter-page-templates.php CHANGED
@@ -19,13 +19,33 @@ class Starter_Page_Templates {
19
*/
20
private static $instance = null;
21
22
/**
23
* Starter_Page_Templates constructor.
24
*/
25
private function __construct() {
26
add_action( 'init', [ $this, 'register_scripts' ] );
27
add_action( 'init', [ $this, 'register_meta_field' ] );
28
add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_assets' ] );
29
}
30
31
/**
@@ -71,6 +91,15 @@ class Starter_Page_Templates {
71
register_meta( 'post', '_starter_page_template', $args );
72
}
73
74
/**
75
* Pass error message to frontend JavaScript console.
76
*
@@ -170,12 +199,11 @@ class Starter_Page_Templates {
170
* @return array Containing vertical name and template list or nothing if an error occurred.
171
*/
172
public function fetch_vertical_data() {
173
- $vertical_id = get_option( 'site_vertical', 'default' );
174
- $transient_key = implode( '_', [ 'starter_page_templates', PLUGIN_VERSION, $vertical_id, get_locale() ] );
175
- $vertical_templates = get_transient( $transient_key );
176
177
// Load fresh data if we don't have any or vertical_id doesn't match.
178
if ( false === $vertical_templates || ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ) {
179
$request_url = add_query_arg(
180
[
181
'_locale' => $this->get_iso_639_locale(),
@@ -188,12 +216,31 @@ class Starter_Page_Templates {
188
return [];
189
}
190
$vertical_templates = json_decode( wp_remote_retrieve_body( $response ), true );
191
- set_transient( $transient_key, $vertical_templates, DAY_IN_SECONDS );
192
}
193
194
return $vertical_templates;
195
}
196
197
/**
198
* Returns ISO 639 conforming locale string.
199
*
19
*/
20
private static $instance = null;
21
22
+ /**
23
+ * Cache key for templates array.
24
+ *
25
+ * @var string
26
+ */
27
+ public $templates_cache_key;
28
+
29
/**
30
* Starter_Page_Templates constructor.
31
*/
32
private function __construct() {
33
+ $this->templates_cache_key = implode(
34
+ '_',
35
+ [
36
+ 'starter_page_templates',
37
+ PLUGIN_VERSION,
38
+ get_option( 'site_vertical', 'default' ),
39
+ get_locale(),
40
+ ]
41
+ );
42
+
43
add_action( 'init', [ $this, 'register_scripts' ] );
44
add_action( 'init', [ $this, 'register_meta_field' ] );
45
+ add_action( 'rest_api_init', [ $this, 'register_rest_api' ] );
46
add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_assets' ] );
47
+ add_action( 'delete_attachment', [ $this, 'clear_sideloaded_image_cache' ] );
48
+ add_action( 'switch_theme', [ $this, 'clear_templates_cache' ] );
49
}
50
51
/**
91
register_meta( 'post', '_starter_page_template', $args );
92
}
93
94
+ /**
95
+ * Register rest api endpoint for side-loading images.
96
+ */
97
+ public function register_rest_api() {
98
+ require_once __DIR__ . '/class-wp-rest-sideload-image-controller.php';
99
+
100
+ ( new WP_REST_Sideload_Image_Controller() )->register_routes();
101
+ }
102
+
103
/**
104
* Pass error message to frontend JavaScript console.
105
*
199
* @return array Containing vertical name and template list or nothing if an error occurred.
200
*/
201
public function fetch_vertical_data() {
202
+ $vertical_templates = get_transient( $this->templates_cache_key );
203
204
// Load fresh data if we don't have any or vertical_id doesn't match.
205
if ( false === $vertical_templates || ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ) {
206
+ $vertical_id = get_option( 'site_vertical', 'default' );
207
$request_url = add_query_arg(
208
[
209
'_locale' => $this->get_iso_639_locale(),
216
return [];
217
}
218
$vertical_templates = json_decode( wp_remote_retrieve_body( $response ), true );
219
+ set_transient( $this->templates_cache_key, $vertical_templates, DAY_IN_SECONDS );
220
}
221
222
return $vertical_templates;
223
}
224
225
+ /**
226
+ * Deletes cached attachment data when attachment gets deleted.
227
+ *
228
+ * @param int $id Attachment ID of the attachment to be deleted.
229
+ */
230
+ public function clear_sideloaded_image_cache( $id ) {
231
+ $url = get_post_meta( $id, '_sideloaded_url', true );
232
+ if ( ! empty( $url ) ) {
233
+ delete_transient( 'fse_sideloaded_image_' . hash( 'crc32b', $url ) );
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Deletes cached templates data when theme switches.
239
+ */
240
+ public function clear_templates_cache() {
241
+ delete_transient( $this->templates_cache_key );
242
+ }
243
+
244
/**
245
* Returns ISO 639 conforming locale string.
246
*
starter-page-templates/dist/starter-page-templates.css CHANGED
@@ -1 +1 @@
1
- .page-template-modal-screen-overlay{animation:none}@media screen and (min-width:783px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{left:36px}}@media screen and (min-width:961px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{left:160px}}body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:46px}@media screen and (min-width:783px){body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:32px}}.page-template-modal{width:100%;height:100vh;max-width:800px;animation:none}.page-template-modal .components-modal__header-heading-container{justify-content:center}.page-template-modal .components-modal__content{overflow-y:scroll;-webkit-overflow-scrolling:touch}.page-template-modal__inner{max-width:720px;margin:0 auto;padding:0}@media screen and (max-width:659px){.page-template-modal__inner{padding-bottom:3em}}.page-template-modal__list .components-base-control__label{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__list .template-selector-control__options{display:grid;grid-template-columns:1fr 1fr;grid-gap:1.75em}@media screen and (min-width:660px){.page-template-modal__list .template-selector-control__options{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}}.page-template-modal__list .template-selector-control__option{margin-bottom:4px}.page-template-modal__list .template-selector-control__label{display:block;width:100%;font-size:14px;text-align:center;border:1px solid #a1aab2;border-radius:6px;cursor:pointer;background:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0 0 14px;overflow:hidden}.page-template-modal__list .template-selector-control__label:focus,.page-template-modal__list .template-selector-control__label:hover{border-color:#2562b7;box-shadow:0 0 0 1px #2562b7;outline:1px solid transparent;outline-offset:-1px}.page-template-modal__list .template-selector-control__media-wrap{width:100%;display:block;margin:0 auto 14px;border-bottom:1px solid #a1aab2;background:#f6f6f6;border-radius:0;overflow:hidden;padding-bottom:110%;box-sizing:content-box;position:relative;pointer-events:none}.page-template-modal__list .template-selector-control__media{width:100%;display:block;position:absolute;top:0;left:0}.page-template-modal__actions{display:flex;flex-direction:column;align-items:center}@media screen and (min-width:960px){.page-template-modal__actions{flex-direction:row;justify-content:flex-end}}@media screen and (max-width:960px){.page-template-modal__action{margin-bottom:1em}}@media screen and (min-width:960px){.page-template-modal__action-use{margin-right:1em}}
1
+ .page-template-modal-screen-overlay{animation:none;background-color:transparent}@media screen and (min-width:783px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{left:36px}}@media screen and (min-width:961px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{left:160px}}body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:46px}@media screen and (min-width:783px){body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:32px}}.page-template-modal{width:100%;height:100vh;animation:none;box-shadow:none;border:none;top:0;left:0;right:0;bottom:0;transform:none;max-width:none;max-height:none;background-color:#eee}.page-template-modal .components-modal__header-heading-container{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal .components-modal__header:after,.page-template-modal__close-button{display:none}body.is-fullscreen-mode .page-template-modal__close-button{display:block;position:absolute;z-index:20;top:9px;width:36px;height:36px;left:8px}body.is-fullscreen-mode .page-template-modal .components-modal__header:after{display:block;position:absolute;content:" ";border-right:1px solid #e2e4e7;height:100%;left:54px}.page-template-modal .components-modal__content{overflow-y:scroll;-webkit-overflow-scrolling:touch}.page-template-modal__inner{position:relative;margin:0 auto;padding:0}@media screen and (max-width:659px){.page-template-modal__inner{padding:0 14% 3em}}@media screen and (max-width:440px){.page-template-modal__inner{padding:0 15px 3em}}@media screen and (min-width:1200px){.page-template-modal__inner{max-width:100%}}.page-template-modal__list .components-base-control__label{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__list .template-selector-control__options{display:grid;grid-template-columns:1fr;grid-gap:1.75em}@media screen and (min-width:660px){.page-template-modal__list .template-selector-control__options{margin-top:0;grid-template-columns:repeat(auto-fit,minmax(110px,1fr))}}@media screen and (min-width:1200px){.page-template-modal__list .template-selector-control__options{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}}.page-template-modal__list .template-selector-control__option{margin-bottom:4px}.page-template-modal__list .template-selector-item__label{display:block;width:100%;font-size:14px;text-align:center;border:2px solid #e2e4e7;border-radius:6px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;overflow:hidden;background-color:#fff;position:relative}.page-template-modal__list .template-selector-item__label .template-selector-item__template-title{width:100%;position:absolute;bottom:0;left:0;height:40px;line-height:40px;background-color:#fff}.page-template-modal__list .template-selector-item__label:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #00a0d2;outline:2px solid transparent}.page-template-modal__list .template-selector-item__label:hover{border:2px solid #c9c9ca}.page-template-modal__list .template-selector-item__label.is-selected{border:2px solid #555d66;outline:2px solid transparent;outline-offset:-2px}.page-template-modal__list .template-selector-item__label.is-selected:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #00a0d2;border:2px solid #555d66;outline:4px solid transparent;outline-offset:-4px}.page-template-modal__list .template-selector-item__preview-wrap{width:100%;display:block;margin:0 auto;background:#fff;border-radius:0;overflow:hidden;height:0;padding-top:100%;box-sizing:content-box;position:relative;pointer-events:none;opacity:1}@media screen and (max-width:659px){.page-template-modal__list .template-selector-item__preview-wrap{padding-top:120%}}.page-template-modal__list .template-selector-item__preview-wrap.is-rendering{opacity:.5}.page-template-modal__list .template-selector-item__preview-wrap .block-editor-block-list__block,.page-template-modal__list .template-selector-item__preview-wrap .block-editor-block-list__layout{padding:inherit}.page-template-modal__list .template-selector-item__media{width:100%;display:block;position:absolute;top:0;left:0}@media screen and (max-width:659px){.page-template-modal__list .template-selector-control__template:first-child .template-selector-item__preview-wrap{padding-top:0;height:70px}}@media screen and (max-width:659px){.page-template-modal__list .template-selector-control__template:first-child .template-selector-item__template-title{height:70px;line-height:70px}}.page-template-modal__actions{display:flex;flex-direction:column;align-items:center}@media screen and (min-width:960px){.page-template-modal__actions{flex-direction:row;justify-content:flex-end}}@media screen and (max-width:960px){.page-template-modal__action{margin-bottom:1em}}@media screen and (min-width:960px){.page-template-modal__action-use{margin-right:1em}}@media screen and (min-width:660px){.page-template-modal__form{max-width:50%}}.page-template-modal__form-title{font-weight:700;margin-bottom:1em}@media screen and (max-width:659px){.page-template-modal__form-title{text-align:center}}.page-template-modal__buttons{position:absolute;right:0;top:0;z-index:10;height:56px;display:flex;align-items:center;padding-right:24px}@media screen and (max-width:659px){.page-template-modal__buttons{display:none}}.page-template-modal__buttons.is-visually-hidden{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__buttons .components-button{height:33px;line-height:32px}.template-selector-preview{position:fixed;top:111px;bottom:24px;right:24px;width:calc(50% - 50px);background:#fff;border-radius:2px;overflow-x:hidden;overflow-y:auto;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.12),0 1px 5px 0 rgba(0,0,0,.2)}@media screen and (max-width:659px){.template-selector-preview{display:none}}.template-selector-preview .edit-post-visual-editor{margin:0;padding:0}.template-selector-preview .editor-styles-wrapper .template-selector-preview__offset-correction{position:relative;top:120px}.template-selector-preview .editor-styles-wrapper .editor-post-title{transform-origin:top left;width:960px;display:block;position:absolute;top:0}.template-selector-preview .editor-styles-wrapper .editor-post-title,.template-selector-preview .editor-styles-wrapper .editor-post-title__block,.template-selector-preview .editor-styles-wrapper .editor-post-title__input{padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0}.template-selector-preview .editor-styles-wrapper .editor-post-title .editor-post-title__input,.template-selector-preview .editor-styles-wrapper .editor-post-title__block .editor-post-title__input,.template-selector-preview .editor-styles-wrapper .editor-post-title__input .editor-post-title__input{margin:0;padding:0;height:120px;line-height:120px}@media screen and (min-width:783px){body:not(.is-fullscreen-mode) .template-selector-preview{width:calc(50% - 84px)}}@media screen and (min-width:961px){body:not(.is-fullscreen-mode) .template-selector-preview{width:calc(50% - 160px)}}.template-selector-preview__placeholder{position:absolute;top:50%;left:50%;transform:translateX(-50%);width:80%;text-align:center}.block-editor-block-preview__container .editor-styles-wrapper .wp-block,.template-selector-preview .editor-styles-wrapper .wp-block{width:100%}.block-editor-block-preview__container .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full],.template-selector-preview .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full]{margin:0}.block-editor-block-preview__container .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full] .wp-block-cover,.template-selector-preview .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full] .wp-block-cover{padding:0}.block-editor-block-preview__container .editor-styles-wrapper .wp-block-columns>.editor-inner-blocks>.editor-block-list__layout>[data-type="core/column"]>.editor-block-list__block-edit>div>.block-core-columns>.editor-inner-blocks,.template-selector-preview .editor-styles-wrapper .wp-block-columns>.editor-inner-blocks>.editor-block-list__layout>[data-type="core/column"]>.editor-block-list__block-edit>div>.block-core-columns>.editor-inner-blocks{margin-top:0;margin-bottom:0}.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__block[data-align=full],.template-selector-preview .editor-styles-wrapper .block-editor-block-list__block[data-align=full]{margin:0}@media screen and (min-width:600px){.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__block .block-editor-block-list__block-edit,.template-selector-preview .editor-styles-wrapper .block-editor-block-list__block .block-editor-block-list__block-edit{margin:0}}.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__block,.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__layout,.template-selector-preview .editor-styles-wrapper .block-editor-block-list__block,.template-selector-preview .editor-styles-wrapper .block-editor-block-list__layout{padding:inherit}.template-selector-item__preview-wrap .components-disabled,.template-selector-item__preview-wrap .components-disabled .editor-styles-wrapper,.template-selector-item__preview-wrap .edit-post-visual-editor,.template-selector-item__preview-wrap .edit-post-visual-editor .editor-styles-wrapper,.template-selector-preview .components-disabled,.template-selector-preview .components-disabled .editor-styles-wrapper,.template-selector-preview .edit-post-visual-editor,.template-selector-preview .edit-post-visual-editor .editor-styles-wrapper{height:100%}.page-template-modal__loading{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;align-items:flex-end}.page-template-modal__loading .components-spinner{float:none}
starter-page-templates/dist/starter-page-templates.deps.json CHANGED
@@ -1 +1 @@
1
- ["lodash","wp-blocks","wp-components","wp-compose","wp-data","wp-element","wp-i18n","wp-nux","wp-plugins","wp-polyfill"]
1
+ ["lodash","wp-api-fetch","wp-block-editor","wp-blocks","wp-components","wp-compose","wp-data","wp-element","wp-i18n","wp-nux","wp-plugins","wp-polyfill","wp-url"]
starter-page-templates/dist/starter-page-templates.js CHANGED
@@ -1,4 +1,4 @@
1
- !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=21)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.lodash}()},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t){!function(){e.exports=this.wp.compose}()},function(e,t){!function(){e.exports=this.wp.components}()},function(e,t,n){var o=n(3);function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,o)}return n}e.exports=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(n,!0).forEach(function(t){o(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(n).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}},function(e,t){!function(){e.exports=this.wp.data}()},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}e.exports=function(e,t,o){return t&&n(e.prototype,t),o&&n(e,o),e}},function(e,t,n){var o=n(17),r=n(4);e.exports=function(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?r(e):t}},function(e,t){function n(t){return e.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(t)}e.exports=n},function(e,t,n){var o=n(18);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&o(e,t)}},function(e,t){!function(){e.exports=this.wp.plugins}()},function(e,t){!function(){e.exports=this.wp.blocks}()},function(e,t,n){var o;
2
/*!
3
Copyright (c) 2017 Jed Watson.
4
Licensed under the MIT License (MIT), see
@@ -9,4 +9,4 @@
9
Licensed under the MIT License (MIT), see
10
http://jedwatson.github.io/classnames
11
*/
12
- !function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e=[],t=0;t<arguments.length;t++){var o=arguments[t];if(o){var i=typeof o;if("string"===i||"number"===i)e.push(o);else if(Array.isArray(o)&&o.length){var c=r.apply(null,o);c&&e.push(c)}else if("object"===i)for(var l in o)n.call(o,l)&&o[l]&&e.push(l)}}return e.join(" ")}e.exports?(r.default=r,e.exports=r):void 0===(o=function(){return r}.apply(t,[]))||(e.exports=o)}()},function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(t){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?e.exports=o=function(e){return n(e)}:e.exports=o=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},o(t)}e.exports=o},function(e,t){function n(t,o){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,o)}e.exports=n},function(e,t){!function(){e.exports=this.wp.nux}()},function(e,t,n){},function(e,t,n){"use strict";n.r(t);var o=n(7),r=n.n(o),i=n(9),c=n.n(i),l=n(10),a=n.n(l),s=n(11),u=n.n(s),p=n(12),f=n.n(p),m=n(4),d=n.n(m),b=n(13),y=n.n(b),v=n(3),_=n.n(v),g=n(0),O=n(2),h=n(1),j=n(5),w=n(6),x=n(14),P=n(8),E=n(15),S=(n(19),{Address:Object(h._x)("123 Main St","default address","full-site-editing"),Phone:Object(h._x)("555-555-5555","default phone number","full-site-editing"),CompanyName:Object(h._x)("Your Company Name","default company name","full-site-editing"),Vertical:Object(h._x)("Business","default vertical name","full-site-editing")}),k={CompanyName:"title",Address:"address",Phone:"phone",Vertical:"vertical"},C=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.replace(/{{(\w+)}}/g,function(e,n){var o=S[n];return t[k[n]]||o||n})},N=(n(20),n(16)),T=n.n(N);var M=Object(j.withInstanceId)(function(e){var t=e.label,n=e.className,o=e.help,r=e.instanceId,i=e.onClick,c=e.templates,l=void 0===c?[]:c,a="template-selector-control-".concat(r),s=function(e){return i(e.target.value)};return Object(O.isEmpty)(l)?null:Object(g.createElement)(w.BaseControl,{label:t,id:a,help:o,className:T()(n,"template-selector-control")},Object(g.createElement)("ul",{className:"template-selector-control__options"},l.map(function(e,t){return Object(g.createElement)("li",{key:"".concat(a,"-").concat(t),className:"template-selector-control__option"},Object(g.createElement)("button",{type:"button",id:"".concat(a,"-").concat(t),className:"template-selector-control__label",value:e.value,onClick:s,"aria-describedby":o?"".concat(a,"__help"):void 0},Object(g.createElement)("div",{className:"template-selector-control__media-wrap"},e.preview&&Object(g.createElement)("img",{className:"template-selector-control__media",src:e.preview,alt:e.previewAlt||""})),e.label))})))});window._tkq=window._tkq||[];var I,q=null,A=function(e,t){q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_dismiss",{blog_id:q.blogid,segment_id:e,vertical_id:t}])},B=function(e,t,n){q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_template_selected",{blog_id:q.blogid,segment_id:e,vertical_id:t,template:n}])},D=function(e){function t(e){var n;return c()(this,t),n=u()(this,f()(t).call(this)),_()(d()(n),"state",{isLoading:!1}),_()(d()(n),"selectTemplate",function(e){n.setState({isOpen:!1}),B(n.props.segment.id,n.props.vertical.id,e);var t=n.props.templates[e];if(n.props.saveTemplateChoice(t),Object(O.has)(t,"content")){var o=r()({},t,{title:C(t.title,n.props.siteInformation),content:C(t.content,n.props.siteInformation)});n.props.insertTemplate(o)}}),_()(d()(n),"closeModal",function(){n.setState({isOpen:!1}),A(n.props.segment.id,n.props.vertical.id)}),n.state.isOpen=!Object(O.isEmpty)(e.templates),n}return y()(t,e),a()(t,[{key:"componentDidMount",value:function(){var e,t;this.state.isOpen&&(e=this.props.segment.id,t=this.props.vertical.id,q&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_view",{blog_id:q.blogid,segment_id:e,vertical_id:t}]))}},{key:"render",value:function(){var e=this;return this.state.isOpen?Object(g.createElement)(w.Modal,{title:Object(h.__)("Select Page Template","full-site-editing"),onRequestClose:this.closeModal,className:"page-template-modal",overlayClassName:"page-template-modal-screen-overlay"},Object(g.createElement)("div",{className:"page-template-modal__inner"},Object(g.createElement)("form",{className:"page-template-modal__form"},Object(g.createElement)("fieldset",{className:"page-template-modal__list"},Object(g.createElement)(M,{label:Object(h.__)("Template","full-site-editing"),templates:Object(O.map)(this.props.templates,function(e){return{label:e.title,value:e.slug,preview:e.preview,previewAlt:e.description}}),onClick:function(t){return e.selectTemplate(t)}}))))):null}}]),t}(g.Component),R=Object(j.compose)(Object(P.withSelect)(function(e){return{getMeta:function(){return e("core/editor").getEditedPostAttribute("meta")},postContentBlock:e("core/editor").getBlocks().find(function(e){return"a8c/post-content"===e.name})}}),Object(P.withDispatch)(function(e,t){e("core/nux").disableTips();var n=e("core/editor");return{saveTemplateChoice:function(e){var o=t.getMeta();n.editPost({meta:r()({},o,{_starter_page_template:e.slug})})},insertTemplate:function(e){n.editPost({title:e.title});var o=t.postContentBlock,r=Object(E.parse)(e.content);n.insertBlocks(r,0,o?o.clientId:"",!1)}}}))(D),U=window.starterPageTemplatesConfig,V=U.siteInformation,L=void 0===V?{}:V,Y=U.templates,z=void 0===Y?[]:Y,F=U.vertical,G=U.segment,H=U.tracksUserData;H&&(q=I=H,window._tkq.push(["identifyUser",I.userid,I.username])),Object(x.registerPlugin)("page-templates",{render:function(){return Object(g.createElement)(R,{templates:Object(O.keyBy)(z,"slug"),vertical:F,segment:G,siteInformation:L})}})}]));
1
+ !function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=33)}([function(e,t){!function(){e.exports=this.wp.element}()},function(e,t){!function(){e.exports=this.lodash}()},function(e,t){!function(){e.exports=this.wp.i18n}()},function(e,t){!function(){e.exports=this.wp.components}()},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t,n){var r;
2
/*!
3
Copyright (c) 2017 Jed Watson.
4
Licensed under the MIT License (MIT), see
9
Licensed under the MIT License (MIT), see
10
http://jedwatson.github.io/classnames
11
*/
12
+ !function(){"use strict";var n={}.hasOwnProperty;function i(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var o=typeof r;if("string"===o||"number"===o)e.push(r);else if(Array.isArray(r)&&r.length){var a=i.apply(null,r);a&&e.push(a)}else if("object"===o)for(var c in r)n.call(r,c)&&r[c]&&e.push(c)}}return e.join(" ")}e.exports?(i.default=i,e.exports=i):void 0===(r=function(){return i}.apply(t,[]))||(e.exports=r)}()},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},function(e,t,n){var r=n(4);function i(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}e.exports=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(n,!0).forEach(function(t){r(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(n).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}},function(e,t){!function(){e.exports=this.wp.compose}()},function(e,t){!function(){e.exports=this.wp.blockEditor}()},function(e,t){!function(){e.exports=this.wp.data}()},function(e,t,n){var r=n(27),i=n(28),o=n(29);e.exports=function(e,t){return r(e)||i(e,t)||o()}},function(e,t){function n(e,t,n,r,i,o,a){try{var c=e[o](a),l=c.value}catch(s){return void n(s)}c.done?t(l):Promise.resolve(l).then(r,i)}e.exports=function(e){return function(){var t=this,r=arguments;return new Promise(function(i,o){var a=e.apply(t,r);function c(e){n(a,i,o,c,l,"next",e)}function l(e){n(a,i,o,c,l,"throw",e)}c(void 0)})}}},function(e,t,n){var r=n(30),i=n(31),o=n(32);e.exports=function(e){return r(e)||i(e)||o()}},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t){function n(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}e.exports=function(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}},function(e,t,n){var r=n(23),i=n(6);e.exports=function(e,t){return!t||"object"!==r(t)&&"function"!=typeof t?i(e):t}},function(e,t){function n(t){return e.exports=n=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},n(t)}e.exports=n},function(e,t,n){var r=n(24);e.exports=function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&r(e,t)}},function(e,t){!function(){e.exports=this.wp.plugins}()},function(e,t){!function(){e.exports=this.wp.blocks}()},function(e,t){!function(){e.exports=this.wp.apiFetch}()},function(e,t){!function(){e.exports=this.wp.url}()},function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(t){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?e.exports=r=function(e){return n(e)}:e.exports=r=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},r(t)}e.exports=r},function(e,t){function n(t,r){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,r)}e.exports=n},function(e,t){!function(){e.exports=this.wp.nux}()},function(e,t,n){},function(e,t){e.exports=function(e){if(Array.isArray(e))return e}},function(e,t){e.exports=function(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var n=[],r=!0,i=!1,o=void 0;try{for(var a,c=e[Symbol.iterator]();!(r=(a=c.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(l){i=!0,o=l}finally{try{r||null==c.return||c.return()}finally{if(i)throw o}}return n}}},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}},function(e,t){e.exports=function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}},function(e,t){e.exports=function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}},function(e,t,n){"use strict";n.r(t);var r=n(7),i=n.n(r),o=n(14),a=n.n(o),c=n(15),l=n.n(c),s=n(16),u=n.n(s),p=n(17),m=n.n(p),f=n(6),d=n.n(f),b=n(18),v=n.n(b),y=n(4),g=n.n(y),O=n(0),h=n(1),j=n(5),w=n.n(j),_=(n(25),n(2)),E=n(8),k=n(3),x=n(19),S=n(10),T=n(20),P=(n(26),n(9)),N=function(e){var t=e.blocks,n=void 0===t?[]:t,r=e.viewportWidth;return n&&n.length?Object(O.createElement)("div",{className:"edit-post-visual-editor"},Object(O.createElement)("div",{className:"editor-styles-wrapper"},Object(O.createElement)("div",{className:"editor-writing-flow"},Object(O.createElement)(P.BlockPreview,{blocks:n,viewportWidth:r})))):null},B=function(e){var t=e.id,n=e.value,r=e.onSelect,i=e.label,o=e.useDynamicPreview,a=void 0!==o&&o,c=e.staticPreviewImg,l=e.staticPreviewImgAlt,s=void 0===l?"":l,u=e.blocks,p=void 0===u?[]:u,m=e.isSelected,f=e.handleTemplateConfirmation;if(Object(h.isNil)(t)||Object(h.isNil)(i)||Object(h.isNil)(n))return null;if(a&&(Object(h.isNil)(p)||Object(h.isEmpty)(p)))return null;var d=a?Object(O.createElement)(k.Disabled,null,Object(O.createElement)(N,{blocks:p,viewportWidth:960})):Object(O.createElement)("img",{className:"template-selector-item__media",src:c,alt:s}),b="label-".concat(t,"-").concat(n);return Object(O.createElement)("button",{type:"button",className:w()("template-selector-item__label",{"is-selected":m}),value:n,onClick:function(){var e=window.matchMedia("(min-width: 660px)").matches;r(n),e||f(n)},"aria-labelledby":"".concat(t," ").concat(b)},Object(O.createElement)("div",{className:"template-selector-item__preview-wrap"},d),Object(O.createElement)("span",{className:"template-selector-item__template-title",id:b},i))},C={Address:Object(_._x)("123 Main St","default address","full-site-editing"),Phone:Object(_._x)("555-555-5555","default phone number","full-site-editing"),CompanyName:Object(_._x)("Your Company Name","default company name","full-site-editing"),Vertical:Object(_._x)("Business","default vertical name","full-site-editing")},I={CompanyName:"title",Address:"address",Phone:"phone",Vertical:"vertical"},A=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e?e.replace(/{{(\w+)}}/g,function(e,n){var r=C[n];return t[I[n]]||r||n}):""},D=Object(E.compose)(O.memo,E.withInstanceId)(function(e){var t=e.label,n=e.className,r=e.help,i=e.instanceId,o=e.templates,a=void 0===o?[]:o,c=e.blocksByTemplates,l=void 0===c?{}:c,s=e.useDynamicPreview,u=void 0!==s&&s,p=e.onTemplateSelect,m=void 0===p?h.noop:p,f=e.siteInformation,d=void 0===f?{}:f,b=e.selectedTemplate,v=e.handleTemplateConfirmation,y=void 0===v?h.noop:v;if(Object(h.isEmpty)(a)||!Object(h.isArray)(a))return null;if(!0===u&&Object(h.isEmpty)(l))return null;var g="template-selector-control-".concat(i);return Object(O.createElement)(k.BaseControl,{label:t,id:g,help:r,className:w()(n,"template-selector-control")},Object(O.createElement)("ul",{className:"template-selector-control__options","data-testid":"template-selector-control-options"},Object(h.map)(a,function(e){var t=e.slug,n=e.title,i=e.preview,o=e.previewAlt;return Object(O.createElement)("li",{key:"".concat(g,"-").concat(t),className:"template-selector-control__template"},Object(O.createElement)(B,{id:g,value:t,label:A(n,d),help:r,onSelect:m,staticPreviewImg:i,staticPreviewImgAlt:o,blocks:l.hasOwnProperty(t)?l[t]:[],useDynamicPreview:u,isSelected:t===b,handleTemplateConfirmation:y}))})))}),M=n(11),q=n.n(M),L=function(e){var t=e.title,n=e.transform;return Object(O.createElement)("div",{className:"editor-post-title",style:{transform:n}},Object(O.createElement)("div",{className:"wp-block editor-post-title__block"},Object(O.createElement)("textarea",{className:"editor-post-title__input",value:t,onChange:function(){}})))},R=function(e){return Object(O.createElement)(P.BlockPreview,e)},U=function(e){var t=e.blocks,n=e.viewportWidth,r=e.title,i=w()("template-selector-preview","editor-styles-wrapper"),o=Object(O.useState)("hidden"),a=q()(o,2),c=a[0],l=a[1],s=Object(O.useRef)(null),u=Object(O.useReducer)(function(e){return e+1},0),p=q()(u,2),m=p[0],f=p[1],d=function(){setTimeout(function(){if(s&&s.current){var e=s.current.querySelector(".block-editor-block-preview__content");if(e){var t=window.getComputedStyle(e);if(t&&t.transform){var n=s.current.querySelector(".editor-post-title");n&&(n.style.transform=t.transform);var r=t.transform.replace(/matrix\((.+)\)#x2F;i,"$1").split(",");r=r&&r.length?Number(r[0]):null,r=isNaN(r)?null:r;var i=e.closest(".template-selector-preview__offset-correction");if(i&&r){var o=n?n.offsetHeight:null;i.style.top="".concat(o*r,"px")}}l("visible")}}},300)};return Object(O.useLayoutEffect)(function(){l("hidden"),d()},[t]),Object(O.useEffect)(function(){if(t&&t.length){var e=Object(h.debounce)(function(){d(),f()},300);return window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}},[t]),Object(h.isEmpty)(t)||!Object(h.isArray)(t)?Object(O.createElement)("div",{className:i},Object(O.createElement)("div",{className:"template-selector-preview__placeholder"},Object(_.__)("Select a page template to preview.","full-site-editing"))):Object(O.createElement)("div",{className:i},Object(O.createElement)(k.Disabled,null,Object(O.createElement)("div",{ref:s,className:"edit-post-visual-editor"},Object(O.createElement)("div",{className:"editor-styles-wrapper",style:{visibility:c}},Object(O.createElement)("div",{className:"editor-writing-flow"},Object(O.createElement)(L,{title:r}),Object(O.createElement)("div",{className:"template-selector-preview__offset-correction"},Object(O.createElement)(R,{key:m,blocks:t,viewportWidth:n})))))))};window._tkq=window._tkq||[];var W,V=null,z=function(e,t){V&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_dismiss",{blog_id:V.blogid,segment_id:e,vertical_id:t}])},F=function(e,t,n){V&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_template_selected",{blog_id:V.blogid,segment_id:e,vertical_id:t,template:n}])},G=n(12),$=n.n(G),H=n(13),Q=n.n(H),Y=n(21),J=n.n(Y),K=n(22),X=function(e,t,n){var r=e[t=Object(K.removeQueryArgs)(t,"w","s")]||{url:t,usages:[]};return i()({},e,g()({},t,i()({},r,{usages:[].concat(Q()(r.usages),Q()(n))})))},Z=function e(t,n){switch(t.blocksByClientId[n.clientId]=n,n.name){case"core/cover":case"core/image":var r=n.attributes.url;r&&(t.assets=X(t.assets,r,[{prop:"url",path:[n.clientId,"attributes","url"]},{prop:"id",path:[n.clientId,"attributes","id"]}]));case"core/media-text":var i=n.attributes.mediaUrl;i&&"image"===n.attributes.mediaType&&(t.assets=X(t.assets,i,[{prop:"url",path:[n.clientId,"attributes","mediaUrl"]},{prop:"id",path:[n.clientId,"attributes","mediaId"]}]));case"core/gallery":Object(h.forEach)(n.attributes.images,function(e,r){t.assets=X(t.assets,e.url,[{prop:"url",path:[n.clientId,"attributes","images",r,"url"]},{prop:"url",path:[n.clientId,"attributes","images",r,"link"]},{prop:"id",path:[n.clientId,"attributes","images",r,"id"]},{prop:"id",path:[n.clientId,"attributes","ids",r]}])})}return Object(h.isEmpty)(n.innerBlocks)?t:Object(h.reduce)(n.innerBlocks,e,t)},ee=function(){var e=$()(regeneratorRuntime.mark(function e(t){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,J()({method:"POST",path:"/fse/v1/sideload/image/batch",data:{resources:Object(h.map)(t)}}).then(function(e){return Object(h.reduce)(t,function(t,n){var r=e.shift(),o=r.id,a=r.source_url;return i()({},t,g()({},n.url,{id:o,url:a}))},{})});case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}},e)}));return function(t){return e.apply(this,arguments)}}(),te=function(e,t){return Object(h.forEach)(e.assets,function(n){var r=t[n.url];r&&Object(h.forEach)(n.usages,function(t){Object(h.set)(e.blocksByClientId,t.path,r[t.prop])})}),e.blocks},ne=function(){var e=$()(regeneratorRuntime.mark(function e(t){var n;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(n=Object(h.reduce)(t,Z,{assets:{},blocksByClientId:{},blocks:t}),!Object(h.isEmpty)(n.assets)){e.next=3;break}return e.abrupt("return",t);case 3:return e.abrupt("return",ee(n.assets).then(function(e){return te(n,e)}));case 4:case"end":return e.stop()}},e)}));return function(t){return e.apply(this,arguments)}}(),re=window.starterPageTemplatesConfig,ie=re.templates,oe=void 0===ie?[]:ie,ae=re.vertical,ce=re.segment,le=re.tracksUserData,se=re.siteInformation,ue=void 0===se?{}:se,pe=function(e){function t(e){var n;a()(this,t),n=u()(this,m()(t).call(this)),g()(d()(n),"state",{isLoading:!1,previewedTemplate:null,blocksByTemplateSlug:{},titlesByTemplateSlug:{},error:null,isOpen:!1}),g()(d()(n),"setTemplate",function(e){F(n.props.segment.id,n.props.vertical.id,e),n.props.saveTemplateChoice(e);var t=n.getBlocksByTemplateSlug(e),r=n.getTitleByTemplateSlug(e);t&&t.length?(n.setState({error:null,isLoading:!0}),n.maybePrefetchAssets(t).then(function(e){n.state.isOpen&&(n.props.insertTemplate(r,e),n.setState({isOpen:!1}))}).catch(function(e){n.setState({isLoading:!1,error:e})})):n.setState({isOpen:!1})}),g()(d()(n),"maybePrefetchAssets",function(e){return n.props.shouldPrefetchAssets?ne(e):Promise.resolve(e)}),g()(d()(n),"handleConfirmation",function(e){"string"!=typeof e&&(e=n.state.previewedTemplate),n.setTemplate(e)}),g()(d()(n),"previewTemplate",function(e){return n.setState({previewedTemplate:e})}),g()(d()(n),"closeModal",function(e){if(e.target.matches("button.template-selector-item__label"))return!1;z(n.props.segment.id,n.props.vertical.id);var t=Object(h.get)(window,["calypsoifyGutenberg","closeUrl"]);window.top.location=t||"edit.php?post_type=page"});var r=!Object(h.isEmpty)(e.templates);return n.state.isOpen=r,r&&(n.state.previewedTemplate=Object(h.get)(e.templates,[0,"slug"]),n.state.titlesByTemplateSlug=Object(h.mapValues)(Object(h.keyBy)(e.templates,"slug"),"title")),n}return v()(t,e),l()(t,[{key:"componentDidMount",value:function(){var e,t;this.state.isOpen&&(e=this.props.segment.id,t=this.props.vertical.id,V&&window._tkq.push(["recordEvent","a8c_full_site_editing_template_selector_view",{blog_id:V.blogid,segment_id:e,vertical_id:t}]));var n=Object(h.reduce)(oe,function(e,t){var n=t.slug,r=t.content;return e[n]=r?Object(T.parse)(A(r,ue)):[],e},{});this.setState({blocksByTemplateSlug:n})}},{key:"getBlocksByTemplateSlug",value:function(e){return Object(h.get)(this.state.blocksByTemplateSlug,[e],[])}},{key:"getTitleByTemplateSlug",value:function(e){return Object(h.get)(this.state.titlesByTemplateSlug,[e],"")}},{key:"render",value:function(){var e=this.state,t=e.previewedTemplate,n=e.isOpen,r=e.isLoading,i=e.blocksByTemplateSlug,o=this.props.templates;return n?Object(O.createElement)(k.Modal,{title:Object(_.__)("Select Page Template","full-site-editing"),className:"page-template-modal",overlayClassName:"page-template-modal-screen-overlay",shouldCloseOnClickOutside:!1,isDismissable:!1,isDismissible:!1},Object(O.createElement)(k.IconButton,{className:"page-template-modal__close-button components-icon-button",onClick:this.closeModal,icon:"arrow-left-alt2",label:Object(_.__)("Go back")}),Object(O.createElement)("div",{className:"page-template-modal__inner"},r?Object(O.createElement)("div",{className:"page-template-modal__loading"},Object(O.createElement)(k.Spinner,null),Object(_.__)("Inserting template…","full-site-editing")):Object(O.createElement)(O.Fragment,null,Object(O.createElement)("form",{className:"page-template-modal__form"},Object(O.createElement)("fieldset",{className:"page-template-modal__list"},Object(O.createElement)("legend",{className:"page-template-modal__form-title"},Object(_.__)("Choose a template…","full-site-editing")),Object(O.createElement)(D,{label:Object(_.__)("Template","full-site-editing"),templates:o,blocksByTemplates:i,onTemplateSelect:this.previewTemplate,useDynamicPreview:!1,siteInformation:ue,selectedTemplate:t,handleTemplateConfirmation:this.handleConfirmation}))),Object(O.createElement)(U,{blocks:this.getBlocksByTemplateSlug(t),viewportWidth:960,title:this.getTitleByTemplateSlug(t)}))),Object(O.createElement)("div",{className:w()("page-template-modal__buttons",{"is-visually-hidden":Object(h.isEmpty)(t)||r})},Object(O.createElement)(k.Button,{isPrimary:!0,isLarge:!0,disabled:Object(h.isEmpty)(t)||r,onClick:this.handleConfirmation},Object(_.sprintf)(Object(_.__)("Use %s template","full-site-editing"),this.getTitleByTemplateSlug(t))))):null}}]),t}(O.Component),me=Object(E.compose)(Object(S.withSelect)(function(e){return{getMeta:function(){return e("core/editor").getEditedPostAttribute("meta")},postContentBlock:e("core/editor").getBlocks().find(function(e){return"a8c/post-content"===e.name})}}),Object(S.withDispatch)(function(e,t){e("core/nux").disableTips();var n=e("core/editor");return{saveTemplateChoice:function(e){var r=t.getMeta();n.editPost({meta:i()({},r,{_starter_page_template:e})})},insertTemplate:function(r,i){n.editPost({title:r});var o=t.postContentBlock;e("core/block-editor").insertBlocks(i,0,o?o.clientId:"",!1)}}}))(pe);le&&(V=W=le,window._tkq.push(["identifyUser",W.userid,W.username])),Object(x.registerPlugin)("page-templates",{render:function(){return Object(O.createElement)(me,{shouldPrefetchAssets:!1,templates:oe,vertical:ae,segment:ce})}})}]));
starter-page-templates/dist/starter-page-templates.rtl.css CHANGED
@@ -1 +1 @@
1
- .page-template-modal-screen-overlay{animation:none}@media screen and (min-width:783px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{right:36px}}@media screen and (min-width:961px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{right:160px}}body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:46px}@media screen and (min-width:783px){body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:32px}}.page-template-modal{width:100%;height:100vh;max-width:800px;animation:none}.page-template-modal .components-modal__header-heading-container{justify-content:center}.page-template-modal .components-modal__content{overflow-y:scroll;-webkit-overflow-scrolling:touch}.page-template-modal__inner{max-width:720px;margin:0 auto;padding:0}@media screen and (max-width:659px){.page-template-modal__inner{padding-bottom:3em}}.page-template-modal__list .components-base-control__label{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__list .template-selector-control__options{display:grid;grid-template-columns:1fr 1fr;grid-gap:1.75em}@media screen and (min-width:660px){.page-template-modal__list .template-selector-control__options{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}}.page-template-modal__list .template-selector-control__option{margin-bottom:4px}.page-template-modal__list .template-selector-control__label{display:block;width:100%;font-size:14px;text-align:center;border:1px solid #a1aab2;border-radius:6px;cursor:pointer;background:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0 0 14px;overflow:hidden}.page-template-modal__list .template-selector-control__label:focus,.page-template-modal__list .template-selector-control__label:hover{border-color:#2562b7;box-shadow:0 0 0 1px #2562b7;outline:1px solid transparent;outline-offset:-1px}.page-template-modal__list .template-selector-control__media-wrap{width:100%;display:block;margin:0 auto 14px;border-bottom:1px solid #a1aab2;background:#f6f6f6;border-radius:0;overflow:hidden;padding-bottom:110%;box-sizing:content-box;position:relative;pointer-events:none}.page-template-modal__list .template-selector-control__media{width:100%;display:block;position:absolute;top:0;right:0}.page-template-modal__actions{display:flex;flex-direction:column;align-items:center}@media screen and (min-width:960px){.page-template-modal__actions{flex-direction:row;justify-content:flex-end}}@media screen and (max-width:960px){.page-template-modal__action{margin-bottom:1em}}@media screen and (min-width:960px){.page-template-modal__action-use{margin-left:1em}}
1
+ .page-template-modal-screen-overlay{animation:none;background-color:transparent}@media screen and (min-width:783px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{right:36px}}@media screen and (min-width:961px){body:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{right:160px}}body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:46px}@media screen and (min-width:783px){body.admin-bar:not(.is-fullscreen-mode) .page-template-modal-screen-overlay{top:32px}}.page-template-modal{width:100%;height:100vh;animation:none;box-shadow:none;border:none;top:0;right:0;left:0;bottom:0;transform:none;max-width:none;max-height:none;background-color:#eee}.page-template-modal .components-modal__header-heading-container{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal .components-modal__header:after,.page-template-modal__close-button{display:none}body.is-fullscreen-mode .page-template-modal__close-button{display:block;position:absolute;z-index:20;top:9px;width:36px;height:36px;right:8px}body.is-fullscreen-mode .page-template-modal .components-modal__header:after{display:block;position:absolute;content:" ";border-left:1px solid #e2e4e7;height:100%;right:54px}.page-template-modal .components-modal__content{overflow-y:scroll;-webkit-overflow-scrolling:touch}.page-template-modal__inner{position:relative;margin:0 auto;padding:0}@media screen and (max-width:659px){.page-template-modal__inner{padding:0 14% 3em}}@media screen and (max-width:440px){.page-template-modal__inner{padding:0 15px 3em}}@media screen and (min-width:1200px){.page-template-modal__inner{max-width:100%}}.page-template-modal__list .components-base-control__label{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__list .template-selector-control__options{display:grid;grid-template-columns:1fr;grid-gap:1.75em}@media screen and (min-width:660px){.page-template-modal__list .template-selector-control__options{margin-top:0;grid-template-columns:repeat(auto-fit,minmax(110px,1fr))}}@media screen and (min-width:1200px){.page-template-modal__list .template-selector-control__options{grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}}.page-template-modal__list .template-selector-control__option{margin-bottom:4px}.page-template-modal__list .template-selector-item__label{display:block;width:100%;font-size:14px;text-align:center;border:2px solid #e2e4e7;border-radius:6px;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;overflow:hidden;background-color:#fff;position:relative}.page-template-modal__list .template-selector-item__label .template-selector-item__template-title{width:100%;position:absolute;bottom:0;right:0;height:40px;line-height:40px;background-color:#fff}.page-template-modal__list .template-selector-item__label:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #00a0d2;outline:2px solid transparent}.page-template-modal__list .template-selector-item__label:hover{border:2px solid #c9c9ca}.page-template-modal__list .template-selector-item__label.is-selected{border:2px solid #555d66;outline:2px solid transparent;outline-offset:-2px}.page-template-modal__list .template-selector-item__label.is-selected:focus{box-shadow:0 0 0 1px #fff,0 0 0 3px #00a0d2;border:2px solid #555d66;outline:4px solid transparent;outline-offset:-4px}.page-template-modal__list .template-selector-item__preview-wrap{width:100%;display:block;margin:0 auto;background:#fff;border-radius:0;overflow:hidden;height:0;padding-top:100%;box-sizing:content-box;position:relative;pointer-events:none;opacity:1}@media screen and (max-width:659px){.page-template-modal__list .template-selector-item__preview-wrap{padding-top:120%}}.page-template-modal__list .template-selector-item__preview-wrap.is-rendering{opacity:.5}.page-template-modal__list .template-selector-item__preview-wrap .block-editor-block-list__block,.page-template-modal__list .template-selector-item__preview-wrap .block-editor-block-list__layout{padding:inherit}.page-template-modal__list .template-selector-item__media{width:100%;display:block;position:absolute;top:0;right:0}@media screen and (max-width:659px){.page-template-modal__list .template-selector-control__template:first-child .template-selector-item__preview-wrap{padding-top:0;height:70px}}@media screen and (max-width:659px){.page-template-modal__list .template-selector-control__template:first-child .template-selector-item__template-title{height:70px;line-height:70px}}.page-template-modal__actions{display:flex;flex-direction:column;align-items:center}@media screen and (min-width:960px){.page-template-modal__actions{flex-direction:row;justify-content:flex-end}}@media screen and (max-width:960px){.page-template-modal__action{margin-bottom:1em}}@media screen and (min-width:960px){.page-template-modal__action-use{margin-left:1em}}@media screen and (min-width:660px){.page-template-modal__form{max-width:50%}}.page-template-modal__form-title{font-weight:700;margin-bottom:1em}@media screen and (max-width:659px){.page-template-modal__form-title{text-align:center}}.page-template-modal__buttons{position:absolute;left:0;top:0;z-index:10;height:56px;display:flex;align-items:center;padding-left:24px}@media screen and (max-width:659px){.page-template-modal__buttons{display:none}}.page-template-modal__buttons.is-visually-hidden{border:0;clip:rect(1px,1px,1px,1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.page-template-modal__buttons .components-button{height:33px;line-height:32px}.template-selector-preview{position:fixed;top:111px;bottom:24px;left:24px;width:calc(50% - 50px);background:#fff;border-radius:2px;overflow-x:hidden;overflow-y:auto;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.12),0 1px 5px 0 rgba(0,0,0,.2)}@media screen and (max-width:659px){.template-selector-preview{display:none}}.template-selector-preview .edit-post-visual-editor{margin:0;padding:0}.template-selector-preview .editor-styles-wrapper .template-selector-preview__offset-correction{position:relative;top:120px}.template-selector-preview .editor-styles-wrapper .editor-post-title{transform-origin:top right;width:960px;display:block;position:absolute;top:0}.template-selector-preview .editor-styles-wrapper .editor-post-title,.template-selector-preview .editor-styles-wrapper .editor-post-title__block,.template-selector-preview .editor-styles-wrapper .editor-post-title__input{padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0}.template-selector-preview .editor-styles-wrapper .editor-post-title .editor-post-title__input,.template-selector-preview .editor-styles-wrapper .editor-post-title__block .editor-post-title__input,.template-selector-preview .editor-styles-wrapper .editor-post-title__input .editor-post-title__input{margin:0;padding:0;height:120px;line-height:120px}@media screen and (min-width:783px){body:not(.is-fullscreen-mode) .template-selector-preview{width:calc(50% - 84px)}}@media screen and (min-width:961px){body:not(.is-fullscreen-mode) .template-selector-preview{width:calc(50% - 160px)}}.template-selector-preview__placeholder{position:absolute;top:50%;right:50%;transform:translateX(50%);width:80%;text-align:center}.block-editor-block-preview__container .editor-styles-wrapper .wp-block,.template-selector-preview .editor-styles-wrapper .wp-block{width:100%}.block-editor-block-preview__container .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full],.template-selector-preview .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full]{margin:0}.block-editor-block-preview__container .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full] .wp-block-cover,.template-selector-preview .editor-styles-wrapper .wp-block[data-type="core/cover"][data-align=full] .wp-block-cover{padding:0}.block-editor-block-preview__container .editor-styles-wrapper .wp-block-columns>.editor-inner-blocks>.editor-block-list__layout>[data-type="core/column"]>.editor-block-list__block-edit>div>.block-core-columns>.editor-inner-blocks,.template-selector-preview .editor-styles-wrapper .wp-block-columns>.editor-inner-blocks>.editor-block-list__layout>[data-type="core/column"]>.editor-block-list__block-edit>div>.block-core-columns>.editor-inner-blocks{margin-top:0;margin-bottom:0}.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__block[data-align=full],.template-selector-preview .editor-styles-wrapper .block-editor-block-list__block[data-align=full]{margin:0}@media screen and (min-width:600px){.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__block .block-editor-block-list__block-edit,.template-selector-preview .editor-styles-wrapper .block-editor-block-list__block .block-editor-block-list__block-edit{margin:0}}.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__block,.block-editor-block-preview__container .editor-styles-wrapper .block-editor-block-list__layout,.template-selector-preview .editor-styles-wrapper .block-editor-block-list__block,.template-selector-preview .editor-styles-wrapper .block-editor-block-list__layout{padding:inherit}.template-selector-item__preview-wrap .components-disabled,.template-selector-item__preview-wrap .components-disabled .editor-styles-wrapper,.template-selector-item__preview-wrap .edit-post-visual-editor,.template-selector-item__preview-wrap .edit-post-visual-editor .editor-styles-wrapper,.template-selector-preview .components-disabled,.template-selector-preview .components-disabled .editor-styles-wrapper,.template-selector-preview .edit-post-visual-editor,.template-selector-preview .edit-post-visual-editor .editor-styles-wrapper{height:100%}.page-template-modal__loading{position:absolute;top:50%;right:50%;transform:translate(50%,-50%);display:flex;align-items:flex-end}.page-template-modal__loading .components-spinner{float:none}
starter-page-templates/page-template-modal/components/block-preview.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+
9
+ /**
10
+ * WordPress dependencies
11
+ */
12
+ /* eslint-disable import/no-extraneous-dependencies */
13
+ import { BlockPreview } from '@wordpress/block-editor';
14
+ /* eslint-enable import/no-extraneous-dependencies */
15
+
16
+ // Exists as a pass through component to simplying testing
17
+ // components which consume `BlockPreview` from
18
+ // `@wordpress/block-editor`. This is because jest cannot mock
19
+ // node modules that are not part of the root node modules.
20
+ // Due to the way this projects dependencies are defined
21
+ // `@wordpress/block-editor` does not exist within `node_modules`
22
+ // and it is there impossible to mock it without providing a wrapping
23
+ // component to act as a pass though.
24
+ // See https://jestjs.io/docs/en/manual-mocks
25
+ export default function( props ) {
26
+ return <BlockPreview { ...props } />;
27
+ }
starter-page-templates/page-template-modal/components/block-template-preview.js CHANGED
@@ -9,9 +9,11 @@
9
/**
10
* WordPress dependencies
11
*/
12
import { BlockPreview } from '@wordpress/block-editor';
13
14
- const BlockTemplatePreview = ( { blocks, viewportWidth } ) => {
15
if ( ! blocks || ! blocks.length ) {
16
return null;
17
}
@@ -21,7 +23,7 @@ const BlockTemplatePreview = ( { blocks, viewportWidth } ) => {
21
<div className="edit-post-visual-editor">
22
<div className="editor-styles-wrapper">
23
<div className="editor-writing-flow">
24
- { blocks && <BlockPreview blocks={ blocks } viewportWidth={ viewportWidth } /> }
25
</div>
26
</div>
27
</div>
9
/**
10
* WordPress dependencies
11
*/
12
+ /* eslint-disable import/no-extraneous-dependencies */
13
import { BlockPreview } from '@wordpress/block-editor';
14
+ /* eslint-enable import/no-extraneous-dependencies */
15
16
+ const BlockTemplatePreview = ( { blocks = [], viewportWidth } ) => {
17
if ( ! blocks || ! blocks.length ) {
18
return null;
19
}
23
<div className="edit-post-visual-editor">
24
<div className="editor-styles-wrapper">
25
<div className="editor-writing-flow">
26
+ <BlockPreview blocks={ blocks } viewportWidth={ viewportWidth } />
27
</div>
28
</div>
29
</div>
starter-page-templates/page-template-modal/components/preview-template-title.js CHANGED
@@ -10,8 +10,8 @@
10
const PreviewTemplateTitle = ( { title, transform } ) => (
11
/* eslint-disable wpcalypso/jsx-classname-namespace */
12
<div className="editor-post-title" style={ { transform } }>
13
- <div className="editor-post-title__block">
14
- <textarea className="editor-post-title__input" value={ title } />
15
</div>
16
</div>
17
/* eslint-enable wpcalypso/jsx-classname-namespace */
10
const PreviewTemplateTitle = ( { title, transform } ) => (
11
/* eslint-disable wpcalypso/jsx-classname-namespace */
12
<div className="editor-post-title" style={ { transform } }>
13
+ <div className="wp-block editor-post-title__block">
14
+ <textarea className="editor-post-title__input" value={ title } onChange={ () => {} } />
15
</div>
16
</div>
17
/* eslint-enable wpcalypso/jsx-classname-namespace */
starter-page-templates/page-template-modal/components/template-selector-control.js CHANGED
@@ -1,30 +1,49 @@
1
/**
2
* External dependencies
3
*/
4
- import { isEmpty } from 'lodash';
5
import classnames from 'classnames';
6
7
/**
8
* WordPress dependencies
9
*/
10
- import { withInstanceId } from '@wordpress/compose';
11
import { BaseControl } from '@wordpress/components';
12
13
- function TemplateSelectorControl( {
14
label,
15
className,
16
help,
17
instanceId,
18
- onClick,
19
templates = [],
20
- } ) {
21
- const id = `template-selector-control-${ instanceId }`;
22
- const handleButtonClick = event => onClick( event.target.value );
23
24
- if ( isEmpty( templates ) ) {
25
return null;
26
}
27
28
return (
29
<BaseControl
30
label={ label }
@@ -32,33 +51,33 @@ function TemplateSelectorControl( {
32
help={ help }
33
className={ classnames( className, 'template-selector-control' ) }
34
>
35
- <ul className="template-selector-control__options">
36
- { templates.map( ( option, index ) => (
37
- <li key={ `${ id }-${ index }` } className="template-selector-control__option">
38
- <button
39
- type="button"
40
- id={ `${ id }-${ index }` }
41
- className="template-selector-control__label"
42
- value={ option.value }
43
- onClick={ handleButtonClick }
44
- aria-describedby={ help ? `${ id }__help` : undefined }
45
- >
46
- <div className="template-selector-control__media-wrap">
47
- { option.preview && (
48
- <img
49
- className="template-selector-control__media"
50
- src={ option.preview }
51
- alt={ option.previewAlt || '' }
52
- />
53
- ) }
54
- </div>
55
- { option.label }
56
- </button>
57
</li>
58
) ) }
59
</ul>
60
</BaseControl>
61
);
62
- }
63
64
- export default withInstanceId( TemplateSelectorControl );
1
/**
2
* External dependencies
3
*/
4
+ /* eslint-disable import/no-extraneous-dependencies */
5
+ import { isEmpty, isArray, noop, map } from 'lodash';
6
+ /* eslint-enable import/no-extraneous-dependencies */
7
import classnames from 'classnames';
8
9
/**
10
* WordPress dependencies
11
*/
12
+ /* eslint-disable import/no-extraneous-dependencies */
13
+ import { withInstanceId, compose } from '@wordpress/compose';
14
import { BaseControl } from '@wordpress/components';
15
+ import { memo } from '@wordpress/element';
16
+ /* eslint-enable import/no-extraneous-dependencies */
17
18
+ /**
19
+ * Internal dependencies
20
+ */
21
+ import TemplateSelectorItem from './template-selector-item';
22
+ import replacePlaceholders from '../utils/replace-placeholders';
23
+
24
+ export const TemplateSelectorControl = ( {
25
label,
26
className,
27
help,
28
instanceId,
29
templates = [],
30
+ blocksByTemplates = {},
31
+ useDynamicPreview = false,
32
+ onTemplateSelect = noop,
33
+ siteInformation = {},
34
+ selectedTemplate,
35
+ handleTemplateConfirmation = noop,
36
+ } ) => {
37
+ if ( isEmpty( templates ) || ! isArray( templates ) ) {
38
+ return null;
39
+ }
40
41
+ if ( true === useDynamicPreview && isEmpty( blocksByTemplates ) ) {
42
return null;
43
}
44
45
+ const id = `template-selector-control-${ instanceId }`;
46
+
47
return (
48
<BaseControl
49
label={ label }
51
help={ help }
52
className={ classnames( className, 'template-selector-control' ) }
53
>
54
+ <ul
55
+ className="template-selector-control__options"
56
+ data-testid="template-selector-control-options"
57
+ >
58
+ { map( templates, ( { slug, title, preview, previewAlt } ) => (
59
+ <li key={ `${ id }-${ slug }` } className="template-selector-control__template">
60
+ <TemplateSelectorItem
61
+ id={ id }
62
+ value={ slug }
63
+ label={ replacePlaceholders( title, siteInformation ) }
64
+ help={ help }
65
+ onSelect={ onTemplateSelect }
66
+ staticPreviewImg={ preview }
67
+ staticPreviewImgAlt={ previewAlt }
68
+ blocks={ blocksByTemplates.hasOwnProperty( slug ) ? blocksByTemplates[ slug ] : [] }
69
+ useDynamicPreview={ useDynamicPreview }
70
+ isSelected={ slug === selectedTemplate }
71
+ handleTemplateConfirmation={ handleTemplateConfirmation }
72
+ />
73
</li>
74
) ) }
75
</ul>
76
</BaseControl>
77
);
78
+ };
79
80
+ export default compose(
81
+ memo,
82
+ withInstanceId
83
+ )( TemplateSelectorControl );
starter-page-templates/page-template-modal/components/template-selector-item.js CHANGED
@@ -1,31 +1,41 @@
1
/**
2
* External dependencies
3
*/
4
-
5
- /**
6
- * Internal dependencies
7
- */
8
9
/**
10
* WordPress dependencies
11
*/
12
import BlockPreview from './block-template-preview';
13
import { Disabled } from '@wordpress/components';
14
15
const TemplateSelectorItem = props => {
16
const {
17
id,
18
value,
19
- help,
20
- onFocus,
21
onSelect,
22
label,
23
useDynamicPreview = false,
24
staticPreviewImg,
25
staticPreviewImgAlt = '',
26
blocks = [],
27
} = props;
28
29
// Define static or dynamic preview.
30
const innerPreview = useDynamicPreview ? (
31
<Disabled>
@@ -39,18 +49,37 @@ const TemplateSelectorItem = props => {
39
/>
40
);
41
42
return (
43
<button
44
type="button"
45
- id={ `${ id }-${ value }` }
46
- className="template-selector-item__label"
47
value={ value }
48
- onMouseEnter={ () => onFocus( value, label ) }
49
- onClick={ () => onSelect( value, label ) }
50
- aria-describedby={ help ? `${ id }__help` : undefined }
51
>
52
<div className="template-selector-item__preview-wrap">{ innerPreview }</div>
53
- { label }
54
</button>
55
);
56
};
1
/**
2
* External dependencies
3
*/
4
+ /* eslint-disable import/no-extraneous-dependencies */
5
+ import { isNil, isEmpty } from 'lodash';
6
+ /* eslint-enable import/no-extraneous-dependencies */
7
+ import classnames from 'classnames';
8
9
/**
10
* WordPress dependencies
11
*/
12
import BlockPreview from './block-template-preview';
13
+ /* eslint-disable import/no-extraneous-dependencies */
14
import { Disabled } from '@wordpress/components';
15
+ /* eslint-enable import/no-extraneous-dependencies */
16
17
const TemplateSelectorItem = props => {
18
const {
19
id,
20
value,
21
onSelect,
22
label,
23
useDynamicPreview = false,
24
staticPreviewImg,
25
staticPreviewImgAlt = '',
26
blocks = [],
27
+ isSelected,
28
+ handleTemplateConfirmation,
29
} = props;
30
31
+ if ( isNil( id ) || isNil( label ) || isNil( value ) ) {
32
+ return null;
33
+ }
34
+
35
+ if ( useDynamicPreview && ( isNil( blocks ) || isEmpty( blocks ) ) ) {
36
+ return null;
37
+ }
38
+
39
// Define static or dynamic preview.
40
const innerPreview = useDynamicPreview ? (
41
<Disabled>
49
/>
50
);
51
52
+ const labelId = `label-${ id }-${ value }`;
53
+
54
+ /**
55
+ * Determines (based on whether the large preview is able to be visible at the
56
+ * current breakpoint) whether or not the Template selection UI interaction model
57
+ * should be select _and_ confirm or simply a single "tap to confirm".
58
+ */
59
+ const handleLabelClick = () => {
60
+ const largeTplPreviewVisible = window.matchMedia( '(min-width: 660px)' ).matches;
61
+ // In both cases set the template as being selected
62
+ onSelect( value );
63
+ // Confirm the template when large preview isn't visible
64
+ if ( ! largeTplPreviewVisible ) {
65
+ handleTemplateConfirmation( value );
66
+ }
67
+ };
68
+
69
return (
70
<button
71
type="button"
72
+ className={ classnames( 'template-selector-item__label', {
73
+ 'is-selected': isSelected,
74
+ } ) }
75
value={ value }
76
+ onClick={ handleLabelClick }
77
+ aria-labelledby={ `${ id } ${ labelId }` }
78
>
79
<div className="template-selector-item__preview-wrap">{ innerPreview }</div>
80
+ <span className="template-selector-item__template-title" id={ labelId }>
81
+ { label }
82
+ </span>
83
</button>
84
);
85
};
starter-page-templates/page-template-modal/components/template-selector-preview.js CHANGED
@@ -2,26 +2,29 @@
2
* External dependencies
3
*/
4
import classnames from 'classnames';
5
- import { isEmpty, debounce } from 'lodash';
6
7
/**
8
* WordPress dependencies
9
*/
10
import { __ } from '@wordpress/i18n';
11
- import { BlockPreview } from '@wordpress/block-editor';
12
import { Disabled } from '@wordpress/components';
13
import { useState, useEffect, useLayoutEffect, useRef, useReducer } from '@wordpress/element';
14
15
/**
16
* Internal dependencies
17
*/
18
import PreviewTemplateTitle from './preview-template-title';
19
20
const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
21
const THRESHOLD_RESIZE = 300;
22
23
const previewElClasses = classnames( 'template-selector-preview', 'editor-styles-wrapper' );
24
- const [ transform, setTransform ] = useState( 'none' );
25
const [ visibility, setVisibility ] = useState( 'hidden' );
26
const ref = useRef( null );
27
@@ -42,7 +45,9 @@ const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
42
}
43
44
// Try to get the preview content element.
45
- const previewContainerEl = ref.current.querySelector( '.block-editor-block-preview__content' );
46
if ( ! previewContainerEl ) {
47
return;
48
}
@@ -50,7 +55,26 @@ const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
50
// Try to get the `transform` css rule from the preview container element.
51
const elStyles = window.getComputedStyle( previewContainerEl );
52
if ( elStyles && elStyles.transform ) {
53
- setTransform( elStyles.transform ); // apply the same transform css rule to template title.
54
}
55
56
setVisibility( 'visible' );
@@ -63,7 +87,7 @@ const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
63
}, [ blocks ] );
64
65
useEffect( () => {
66
- if ( ! blocks.length ) {
67
return;
68
}
69
@@ -80,7 +104,7 @@ const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
80
};
81
}, [ blocks ] );
82
83
- if ( isEmpty( blocks ) ) {
84
return (
85
<div className={ previewElClasses }>
86
<div className="template-selector-preview__placeholder">
@@ -97,8 +121,10 @@ const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
97
<div ref={ ref } className="edit-post-visual-editor">
98
<div className="editor-styles-wrapper" style={ { visibility } }>
99
<div className="editor-writing-flow">
100
- <PreviewTemplateTitle title={ title } transform={ transform } />
101
- <BlockPreview key={ recompute } blocks={ blocks } viewportWidth={ viewportWidth } />
102
</div>
103
</div>
104
</div>
2
* External dependencies
3
*/
4
import classnames from 'classnames';
5
+ /* eslint-disable import/no-extraneous-dependencies */
6
+ import { isEmpty, isArray, debounce } from 'lodash';
7
+ /* eslint-enable import/no-extraneous-dependencies */
8
9
/**
10
* WordPress dependencies
11
*/
12
+ /* eslint-disable import/no-extraneous-dependencies */
13
import { __ } from '@wordpress/i18n';
14
import { Disabled } from '@wordpress/components';
15
import { useState, useEffect, useLayoutEffect, useRef, useReducer } from '@wordpress/element';
16
+ /* eslint-enable import/no-extraneous-dependencies */
17
18
/**
19
* Internal dependencies
20
*/
21
import PreviewTemplateTitle from './preview-template-title';
22
+ import BlockPreview from './block-preview';
23
24
const TemplateSelectorPreview = ( { blocks, viewportWidth, title } ) => {
25
const THRESHOLD_RESIZE = 300;
26
27
const previewElClasses = classnames( 'template-selector-preview', 'editor-styles-wrapper' );
28
const [ visibility, setVisibility ] = useState( 'hidden' );
29
const ref = useRef( null );
30
45
}
46
47
// Try to get the preview content element.
48
+ const previewContainerEl = ref.current.querySelector(
49
+ '.block-editor-block-preview__content'
50
+ );
51
if ( ! previewContainerEl ) {
52
return;
53
}
55
// Try to get the `transform` css rule from the preview container element.
56
const elStyles = window.getComputedStyle( previewContainerEl );
57
if ( elStyles && elStyles.transform ) {
58
+ const titleElement = ref.current.querySelector( '.editor-post-title' );
59
+ if ( titleElement ) {
60
+ // Apply the same transform css rule at template title element.
61
+ titleElement.style.transform = elStyles.transform;
62
+ }
63
+
64
+ // Pick up scale factor from `transform` css.
65
+ let scale = elStyles.transform.replace( /matrix\((.+)\)#x2F;i, '$1' ).split( ',' );
66
+ scale = scale && scale.length ? Number( scale[ 0 ] ) : null;
67
+ scale = isNaN( scale ) ? null : scale;
68
+
69
+ // Try to adjust vertical offset of the large preview.
70
+ const offsetCorrectionEl = previewContainerEl.closest(
71
+ '.template-selector-preview__offset-correction'
72
+ );
73
+
74
+ if ( offsetCorrectionEl && scale ) {
75
+ const titleHeight = titleElement ? titleElement.offsetHeight : null;
76
+ offsetCorrectionEl.style.top = `${ titleHeight * scale }px`;
77
+ }
78
}
79
80
setVisibility( 'visible' );
87
}, [ blocks ] );
88
89
useEffect( () => {
90
+ if ( ! blocks || ! blocks.length ) {
91
return;
92
}
93
104
};
105
}, [ blocks ] );
106
107
+ if ( isEmpty( blocks ) || ! isArray( blocks ) ) {
108
return (
109
<div className={ previewElClasses }>
110
<div className="template-selector-preview__placeholder">
121
<div ref={ ref } className="edit-post-visual-editor">
122
<div className="editor-styles-wrapper" style={ { visibility } }>
123
<div className="editor-writing-flow">
124
+ <PreviewTemplateTitle title={ title } />
125
+ <div className="template-selector-preview__offset-correction">
126
+ <BlockPreview key={ recompute } blocks={ blocks } viewportWidth={ viewportWidth } />
127
+ </div>
128
</div>
129
</div>
130
</div>
starter-page-templates/page-template-modal/components/test/__snapshots__/template-selector-control-test.js.snap ADDED
@@ -0,0 +1,124 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TemplateSelectorControl Basic rendering renders with required props 1`] = `
4
+ <div>
5
+ <div
6
+ class="components-base-control template-selector-control"
7
+ >
8
+ <div
9
+ class="components-base-control__field"
10
+ >
11
+ <label
12
+ class="components-base-control__label"
13
+ for="template-selector-control-17"
14
+ >
15
+ Select a Template...
16
+ </label>
17
+ <ul
18
+ class="template-selector-control__options"
19
+ data-testid="template-selector-control-options"
20
+ >
21
+ <li
22
+ class="template-selector-control__template"
23
+ >
24
+ <button
25
+ aria-labelledby="template-selector-control-17 label-template-selector-control-17-blank"
26
+ class="template-selector-item__label"
27
+ type="button"
28
+ value="blank"
29
+ >
30
+ <div
31
+ class="template-selector-item__preview-wrap"
32
+ >
33
+ <img
34
+ alt=""
35
+ class="template-selector-item__media"
36
+ />
37
+ </div>
38
+ <span
39
+ id="label-template-selector-control-17-blank"
40
+ >
41
+ Blank
42
+ </span>
43
+ </button>
44
+ </li>
45
+ <li
46
+ class="template-selector-control__template"
47
+ >
48
+ <button
49
+ aria-labelledby="template-selector-control-17 label-template-selector-control-17-template-1"
50
+ class="template-selector-item__label"
51
+ type="button"
52
+ value="template-1"
53
+ >
54
+ <div
55
+ class="template-selector-item__preview-wrap"
56
+ >
57
+ <img
58
+ alt="Testing alt"
59
+ class="template-selector-item__media"
60
+ src="https://via.placeholder.com/350x150"
61
+ />
62
+ </div>
63
+ <span
64
+ id="label-template-selector-control-17-template-1"
65
+ >
66
+ Template 1
67
+ </span>
68
+ </button>
69
+ </li>
70
+ <li
71
+ class="template-selector-control__template"
72
+ >
73
+ <button
74
+ aria-labelledby="template-selector-control-17 label-template-selector-control-17-template-2"
75
+ class="template-selector-item__label"
76
+ type="button"
77
+ value="template-2"
78
+ >
79
+ <div
80
+ class="template-selector-item__preview-wrap"
81
+ >
82
+ <img
83
+ alt="Testing alt 2"
84
+ class="template-selector-item__media"
85
+ src="https://via.placeholder.com/300x250"
86
+ />
87
+ </div>
88
+ <span
89
+ id="label-template-selector-control-17-template-2"
90
+ >
91
+ Template 2
92
+ </span>
93
+ </button>
94
+ </li>
95
+ <li
96
+ class="template-selector-control__template"
97
+ >
98
+ <button
99
+ aria-labelledby="template-selector-control-17 label-template-selector-control-17-template-3"
100
+ class="template-selector-item__label"
101
+ type="button"
102
+ value="template-3"
103
+ >
104
+ <div
105
+ class="template-selector-item__preview-wrap"
106
+ >
107
+ <img
108
+ alt="Testing alt 3"
109
+ class="template-selector-item__media"
110
+ src="https://via.placeholder.com/500x200"
111
+ />
112
+ </div>
113
+ <span
114
+ id="label-template-selector-control-17-template-3"
115
+ >
116
+ Template 3
117
+ </span>
118
+ </button>
119
+ </li>
120
+ </ul>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ `;
starter-page-templates/page-template-modal/components/test/__snapshots__/template-selector-preview-test.js.snap ADDED
@@ -0,0 +1,44 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TemplateSelectorPreview Basic rendering renders the preview when blocks are provided 1`] = `
4
+ <div>
5
+ <div
6
+ class="template-selector-preview editor-styles-wrapper"
7
+ >
8
+ <div
9
+ class="components-disabled"
10
+ >
11
+ <div
12
+ class="edit-post-visual-editor"
13
+ >
14
+ <div
15
+ class="editor-styles-wrapper"
16
+ style="visibility: hidden;"
17
+ >
18
+ <div
19
+ class="editor-writing-flow"
20
+ >
21
+ <div
22
+ class="editor-post-title"
23
+ style="transform: none;"
24
+ >
25
+ <div
26
+ class="editor-post-title__block"
27
+ >
28
+ <textarea
29
+ class="editor-post-title__input"
30
+ />
31
+ </div>
32
+ </div>
33
+ <div
34
+ data-testid="block-template-preview"
35
+ >
36
+ MockedBlockPreview
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ `;
starter-page-templates/page-template-modal/components/test/helpers/templates-blocks-helpers.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ /* eslint-disable import/no-extraneous-dependencies */
5
+ import { uniqueId, range, toArray } from 'lodash';
6
+ /* eslint-enable import/no-extraneous-dependencies */
7
+
8
+ export const templatesFixture = [
9
+ {
10
+ slug: 'blank',
11
+ title: 'Blank',
12
+ },
13
+ {
14
+ slug: 'template-1',
15
+ title: 'Template 1',
16
+ preview: 'https://via.placeholder.com/350x150',
17
+ previewAlt: 'Testing alt',
18
+ },
19
+ {
20
+ slug: 'template-2',
21
+ title: 'Template 2',
22
+ preview: 'https://via.placeholder.com/300x250',
23
+ previewAlt: 'Testing alt 2',
24
+ },
25
+ {
26
+ slug: 'template-3',
27
+ title: 'Template 3',
28
+ preview: 'https://via.placeholder.com/500x200',
29
+ previewAlt: 'Testing alt 3',
30
+ },
31
+ ];
32
+
33
+ export const blocksByTemplatesFixture = templatesFixture.reduce( ( acc, curr ) => {
34
+ acc[ curr.slug ] = range( 4 ).map( () => {
35
+ return {
36
+ clientId: uniqueId(),
37
+ name: 'core/paragraph',
38
+ isValid: true,
39
+ attributes: {
40
+ align: 'left',
41
+ content:
42
+ 'Visitors will want to know who is on the other side of the page. Use this space to write about yourself, your site, your business, or anything you want. Use the testimonials below to quote others, talking about the same thing – in their own words.',
43
+ dropCap: false,
44
+ fontWeight: '',
45
+ textTransform: '',
46
+ noBottomSpacing: false,
47
+ noTopSpacing: false,
48
+ coblocks: [],
49
+ },
50
+ innerBlocks: [],
51
+ originalContent:
52
+ '<p style="text-align:left;">Visitors will want to know who is on the other side of the page. Use this space to write about yourself, your site, your business, or anything you want. Use the testimonials below to quote others, talking about the same thing – in their own words.</p>',
53
+ };
54
+ } );
55
+ return acc;
56
+ }, {} );
57
+
58
+ export const blocksFixture = toArray( blocksByTemplatesFixture );
starter-page-templates/page-template-modal/components/test/template-selector-control-test.js ADDED
@@ -0,0 +1,200 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ /* eslint-disable import/no-extraneous-dependencies */
5
+ import { uniqueId, omit } from 'lodash';
6
+ /* eslint-enable import/no-extraneous-dependencies */
7
+
8
+ import { render, fireEvent } from '@testing-library/react';
9
+
10
+ import { templatesFixture, blocksByTemplatesFixture } from './helpers/templates-blocks-helpers';
11
+ import { TemplateSelectorControl } from '../template-selector-control';
12
+
13
+ // Mock out this component until @wordpress/block-editor
14
+ // `BlockPreview` component is available as default export.
15
+ // Once available, swap this mock to mocking out `BlockPreview`
16
+ // directly as it causes too many knock on effects when rendering
17
+ jest.mock( '../block-template-preview', () => () => {
18
+ return <div data-testid="block-template-preview">MockedBlockPreview</div>;
19
+ } );
20
+
21
+ // Required to handle `BlockPreview` usage of Mutation Observer
22
+ beforeAll(
23
+ ( global.MutationObserver = jest.fn( () => {
24
+ return {
25
+ observe: jest.fn(),
26
+ disconnect: jest.fn(),
27
+ };
28
+ } ) )
29
+ );
30
+
31
+ afterAll( () => {
32
+ global.MutationObserver.mockRestore();
33
+ } );
34
+
35
+ const testUniqueId = uniqueId();
36
+
37
+ describe( 'TemplateSelectorControl', () => {
38
+ const siteInformation = {
39
+ title: 'gutenberg-training',
40
+ vertical: 'Business',
41
+ };
42
+
43
+ describe( 'Basic rendering', () => {
44
+ it( 'renders with required props', () => {
45
+ const { getByText, container } = render(
46
+ <TemplateSelectorControl
47
+ label="Select a Template..."
48
+ instanceId={ testUniqueId }
49
+ templates={ templatesFixture }
50
+ blocksByTemplates={ blocksByTemplatesFixture }
51
+ siteInformation={ siteInformation }
52
+ />
53
+ );
54
+
55
+ expect( getByText( 'Select a Template...' ) ).toBeInTheDocument();
56
+ expect( getByText( 'Blank' ) ).toBeInTheDocument();
57
+ expect( document.querySelectorAll( 'button.template-selector-item__label' ) ).toHaveLength(
58
+ 4
59
+ );
60
+ expect( document.querySelectorAll( 'button.is-selected' ) ).toHaveLength( 0 );
61
+ expect( container ).toMatchSnapshot();
62
+ } );
63
+
64
+ it( 'highlights the selected template', () => {
65
+ render(
66
+ <TemplateSelectorControl
67
+ label="Select a Template..."
68
+ instanceId={ testUniqueId }
69
+ templates={ templatesFixture }
70
+ blocksByTemplates={ blocksByTemplatesFixture }
71
+ siteInformation={ siteInformation }
72
+ selectedTemplate={ templatesFixture[ 0 ].slug }
73
+ />
74
+ );
75
+
76
+ expect( document.querySelectorAll( 'button.is-selected' ) ).toHaveLength( 1 );
77
+ } );
78
+
79
+ it( 'does not render when missing templates prop', () => {
80
+ const { queryByText, queryByTestId } = render(
81
+ <TemplateSelectorControl
82
+ label="Select a Template..."
83
+ instanceId={ testUniqueId }
84
+ blocksByTemplates={ blocksByTemplatesFixture }
85
+ />
86
+ );
87
+
88
+ // use `queryBy` to avoid throwing an error with `getBy`
89
+ expect( queryByText( 'Select a Template...' ) ).not.toBeInTheDocument();
90
+ expect( queryByTestId( 'template-selector-control-options' ) ).not.toBeInTheDocument();
91
+ } );
92
+
93
+ it( 'does not render when templates prop is not an Array', () => {
94
+ const { queryByText, queryByTestId } = render(
95
+ <TemplateSelectorControl
96
+ label="Select a Template..."
97
+ instanceId={ testUniqueId }
98
+ templates={ 'evil stuff here' }
99
+ blocksByTemplates={ blocksByTemplatesFixture }
100
+ />
101
+ );
102
+
103
+ expect( queryByText( 'Select a Template...' ) ).not.toBeInTheDocument();
104
+ expect( queryByTestId( 'template-selector-control-options' ) ).not.toBeInTheDocument();
105
+ } );
106
+ } );
107
+
108
+ describe( 'Event handlers', () => {
109
+ it( 'calls onTemplateSelect prop when template is clicked', () => {
110
+ const onSelectSpy = jest.fn();
111
+
112
+ const { getByText } = render(
113
+ <TemplateSelectorControl
114
+ label="Select a Template..."
115
+ instanceId={ testUniqueId }
116
+ templates={ templatesFixture }
117
+ blocksByTemplates={ blocksByTemplatesFixture }
118
+ siteInformation={ siteInformation }
119
+ onTemplateSelect={ onSelectSpy }
120
+ />
121
+ );
122
+
123
+ fireEvent.click( getByText( 'Template 3' ) );
124
+
125
+ expect( onSelectSpy ).toHaveBeenCalled();
126
+ } );
127
+ } );
128
+
129
+ describe( 'Static previews', () => {
130
+ it( 'renders in static preview mode by default ', () => {
131
+ const { getByAltText } = render(
132
+ <TemplateSelectorControl
133
+ label="Select a Template..."
134
+ instanceId={ testUniqueId }
135
+ templates={ templatesFixture }
136
+ blocksByTemplates={ blocksByTemplatesFixture }
137
+ siteInformation={ siteInformation }
138
+ />
139
+ );
140
+
141
+ expect( getByAltText( 'Testing alt 2' ) ).toBeInTheDocument();
142
+ expect( document.querySelectorAll( 'img.template-selector-item__media' ) ).toHaveLength( 4 );
143
+ } );
144
+
145
+ it( 'renders in "blank" mode when static preview is not provided ', () => {
146
+ const templatesFixtureWithoutPreviews = templatesFixture.map( template =>
147
+ omit( template, 'preview' )
148
+ );
149
+
150
+ const { getByText } = render(
151
+ <TemplateSelectorControl
152
+ label="Select a Template..."
153
+ instanceId={ testUniqueId }
154
+ templates={ templatesFixtureWithoutPreviews }
155
+ blocksByTemplates={ blocksByTemplatesFixture }
156
+ siteInformation={ siteInformation }
157
+ />
158
+ );
159
+
160
+ expect( getByText( 'Select a Template...' ) ).toBeInTheDocument();
161
+ expect( getByText( 'Blank' ) ).toBeInTheDocument();
162
+ } );
163
+ } );
164
+
165
+ describe( 'Dynamic previews', () => {
166
+ it( 'renders in dynamic preview mode when useDynamicPreview is true', () => {
167
+ const { queryByAltText, getAllByTestId } = render(
168
+ <TemplateSelectorControl
169
+ label="Select a Template..."
170
+ instanceId={ testUniqueId }
171
+ templates={ templatesFixture }
172
+ blocksByTemplates={ blocksByTemplatesFixture }
173
+ siteInformation={ siteInformation }
174
+ useDynamicPreview={ true }
175
+ />
176
+ );
177
+
178
+ const mockedBlockTemplatePreviews = getAllByTestId( 'block-template-preview' );
179
+
180
+ expect( mockedBlockTemplatePreviews ).toHaveLength( 4 );
181
+ expect( queryByAltText( 'Testing alt 2' ) ).not.toBeInTheDocument();
182
+ expect( document.querySelectorAll( 'img.template-selector-item__media' ) ).toHaveLength( 0 );
183
+ } );
184
+
185
+ it( 'does not render without blocksByTemplatesFixture prop when in dynamic mode', () => {
186
+ const { queryByLabelText, queryByTestId } = render(
187
+ <TemplateSelectorControl
188
+ label="Select a Template..."
189
+ instanceId={ testUniqueId }
190
+ templates={ templatesFixture }
191
+ siteInformation={ siteInformation }
192
+ useDynamicPreview={ true }
193
+ />
194
+ );
195
+
196
+ expect( queryByLabelText( 'Select a Template...' ) ).not.toBeInTheDocument();
197
+ expect( queryByTestId( 'template-selector-control-options' ) ).not.toBeInTheDocument();
198
+ } );
199
+ } );
200
+ } );
starter-page-templates/page-template-modal/components/test/template-selector-preview-test.js ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render } from '@testing-library/react';
5
+ import { blocksFixture } from './helpers/templates-blocks-helpers';
6
+ import TemplateSelectorPreview from '../template-selector-preview';
7
+
8
+ // Mock the "pass through" version of the `BlockPreview` component
9
+ // See `components/block-preview.js`
10
+ jest.mock( '../block-preview', () => () => {
11
+ return <div data-testid="block-template-preview">MockedBlockPreview</div>;
12
+ } );
13
+
14
+ // Required to handle `BlockPreview` usage of Mutation Observer
15
+ beforeAll(
16
+ ( global.MutationObserver = jest.fn( () => {
17
+ return {
18
+ observe: jest.fn(),
19
+ disconnect: jest.fn(),
20
+ };
21
+ } ) )
22
+ );
23
+
24
+ afterAll( () => {
25
+ global.MutationObserver.mockRestore();
26
+ } );
27
+
28
+ describe( 'TemplateSelectorPreview', () => {
29
+ describe( 'Basic rendering', () => {
30
+ it( 'renders the preview when blocks are provided', () => {
31
+ const { queryByTestId, container } = render(
32
+ <TemplateSelectorPreview blocks={ blocksFixture } viewportWidth={ 960 } />
33
+ );
34
+
35
+ expect( queryByTestId( 'block-template-preview' ) ).toBeInTheDocument();
36
+ expect( container ).toMatchSnapshot();
37
+ } );
38
+
39
+ it( 'renders placeholder when no blocks are provided', () => {
40
+ const { getByText, queryByTestId } = render(
41
+ <TemplateSelectorPreview viewportWidth={ 960 } />
42
+ );
43
+
44
+ expect( getByText( 'Select a page template to preview.' ) ).toBeInTheDocument();
45
+ expect( queryByTestId( 'block-template-preview' ) ).not.toBeInTheDocument();
46
+ } );
47
+
48
+ it( 'renders placeholder when blocks is not an array', () => {
49
+ const invalidBlocksProp = {
50
+ 'some-block-1': {
51
+ block: 'foo',
52
+ },
53
+ 'some-block-2': {
54
+ block: 'bar',
55
+ },
56
+ };
57
+ const { getByText, queryByTestId } = render(
58
+ <TemplateSelectorPreview blocks={ invalidBlocksProp } viewportWidth={ 960 } />
59
+ );
60
+
61
+ expect( getByText( 'Select a page template to preview.' ) ).toBeInTheDocument();
62
+ expect( queryByTestId( 'block-template-preview' ) ).not.toBeInTheDocument();
63
+ } );
64
+ } );
65
+ } );
starter-page-templates/page-template-modal/index.js CHANGED
@@ -1,93 +1,234 @@
1
/**
2
* External dependencies
3
*/
4
- import { has, isEmpty, keyBy, map } from 'lodash';
5
- import { __ } from '@wordpress/i18n';
6
import { compose } from '@wordpress/compose';
7
- import { Modal } from '@wordpress/components';
8
import { registerPlugin } from '@wordpress/plugins';
9
import { withDispatch, withSelect } from '@wordpress/data';
10
- import { parse as parseBlocks } from '@wordpress/blocks';
11
import { Component } from '@wordpress/element';
12
- import '@wordpress/nux';
13
14
/**
15
* Internal dependencies
16
*/
17
- import replacePlaceholders from './utils/replace-placeholders';
18
import './styles/starter-page-templates-editor.scss';
19
import TemplateSelectorControl from './components/template-selector-control';
20
import { trackDismiss, trackSelection, trackView, initializeWithIdentity } from './utils/tracking';
21
22
class PageTemplateModal extends Component {
23
state = {
24
isLoading: false,
25
};
26
27
constructor( props ) {
28
super();
29
- this.state.isOpen = ! isEmpty( props.templates );
30
}
31
32
componentDidMount() {
33
if ( this.state.isOpen ) {
34
trackView( this.props.segment.id, this.props.vertical.id );
35
}
36
}
37
38
- selectTemplate = newTemplate => {
39
- this.setState( { isOpen: false } );
40
- trackSelection( this.props.segment.id, this.props.vertical.id, newTemplate );
41
42
- const template = this.props.templates[ newTemplate ];
43
- this.props.saveTemplateChoice( template );
44
45
// Skip inserting if there's nothing to insert.
46
- if ( ! has( template, 'content' ) ) {
47
return;
48
}
49
50
- const processedTemplate = {
51
- ...template,
52
- title: replacePlaceholders( template.title, this.props.siteInformation ),
53
- content: replacePlaceholders( template.content, this.props.siteInformation ),
54
- };
55
56
- this.props.insertTemplate( processedTemplate );
57
};
58
59
- closeModal = () => {
60
- this.setState( { isOpen: false } );
61
trackDismiss( this.props.segment.id, this.props.vertical.id );
62
};
63
64
render() {
65
- if ( ! this.state.isOpen ) {
66
return null;
67
}
68
69
return (
70
<Modal
71
title={ __( 'Select Page Template', 'full-site-editing' ) }
72
- onRequestClose={ this.closeModal }
73
className="page-template-modal"
74
overlayClassName="page-template-modal-screen-overlay"
75
>
76
<div className="page-template-modal__inner">
77
- <form className="page-template-modal__form">
78
- <fieldset className="page-template-modal__list">
79
- <TemplateSelectorControl
80
- label={ __( 'Template', 'full-site-editing' ) }
81
- templates={ map( this.props.templates, template => ( {
82
- label: template.title,
83
- value: template.slug,
84
- preview: template.preview,
85
- previewAlt: template.description,
86
- } ) ) }
87
- onClick={ newTemplate => this.selectTemplate( newTemplate ) }
88
/>
89
- </fieldset>
90
- </form>
91
</div>
92
</Modal>
93
);
@@ -107,26 +248,23 @@ const PageTemplatesPlugin = compose(
107
108
const editorDispatcher = dispatch( 'core/editor' );
109
return {
110
- saveTemplateChoice: template => {
111
// Save selected template slug in meta.
112
const currentMeta = ownProps.getMeta();
113
editorDispatcher.editPost( {
114
meta: {
115
...currentMeta,
116
- _starter_page_template: template.slug,
117
},
118
} );
119
},
120
- insertTemplate: template => {
121
// Set post title.
122
- editorDispatcher.editPost( {
123
- title: template.title,
124
- } );
125
126
// Insert blocks.
127
const postContentBlock = ownProps.postContentBlock;
128
- const blocks = parseBlocks( template.content );
129
- editorDispatcher.insertBlocks(
130
blocks,
131
0,
132
postContentBlock ? postContentBlock.clientId : '',
@@ -137,27 +275,18 @@ const PageTemplatesPlugin = compose(
137
} )
138
)( PageTemplateModal );
139
140
- // Load config passed from backend.
141
- const {
142
- siteInformation = {},
143
- templates = [],
144
- vertical,
145
- segment,
146
- tracksUserData,
147
- } = window.starterPageTemplatesConfig;
148
-
149
if ( tracksUserData ) {
150
initializeWithIdentity( tracksUserData );
151
}
152
153
registerPlugin( 'page-templates', {
154
- render: function() {
155
return (
156
<PageTemplatesPlugin
157
- templates={ keyBy( templates, 'slug' ) }
158
vertical={ vertical }
159
segment={ segment }
160
- siteInformation={ siteInformation }
161
/>
162
);
163
},
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
/**
3
* External dependencies
4
*/
5
+ import { isEmpty, reduce, get, keyBy, mapValues } from 'lodash';
6
+ import classnames from 'classnames';
7
+ import '@wordpress/nux';
8
+ import { __, sprintf } from '@wordpress/i18n';
9
import { compose } from '@wordpress/compose';
10
+ import { Button, Modal, Spinner, IconButton } from '@wordpress/components';
11
import { registerPlugin } from '@wordpress/plugins';
12
import { withDispatch, withSelect } from '@wordpress/data';
13
import { Component } from '@wordpress/element';
14
+ import { parse as parseBlocks } from '@wordpress/blocks';
15
16
/**
17
* Internal dependencies
18
*/
19
import './styles/starter-page-templates-editor.scss';
20
import TemplateSelectorControl from './components/template-selector-control';
21
+ import TemplateSelectorPreview from './components/template-selector-preview';
22
import { trackDismiss, trackSelection, trackView, initializeWithIdentity } from './utils/tracking';
23
+ import replacePlaceholders from './utils/replace-placeholders';
24
+ import ensureAssets from './utils/ensure-assets';
25
+ /* eslint-enable import/no-extraneous-dependencies */
26
+
27
+ // Load config passed from backend.
28
+ const {
29
+ templates = [],
30
+ vertical,
31
+ segment,
32
+ tracksUserData,
33
+ siteInformation = {},
34
+ } = window.starterPageTemplatesConfig;
35
36
class PageTemplateModal extends Component {
37
state = {
38
isLoading: false,
39
+ previewedTemplate: null,
40
+ blocksByTemplateSlug: {},
41
+ titlesByTemplateSlug: {},
42
+ error: null,
43
+ isOpen: false,
44
};
45
46
constructor( props ) {
47
super();
48
+ const hasTemplates = ! isEmpty( props.templates );
49
+ this.state.isOpen = hasTemplates;
50
+ if ( hasTemplates ) {
51
+ // Select the first template automatically.
52
+ this.state.previewedTemplate = get( props.templates, [ 0, 'slug' ] );
53
+ // Extract titles for faster lookup.
54
+ this.state.titlesByTemplateSlug = mapValues( keyBy( props.templates, 'slug' ), 'title' );
55
+ }
56
}
57
58
componentDidMount() {
59
if ( this.state.isOpen ) {
60
trackView( this.props.segment.id, this.props.vertical.id );
61
}
62
+
63
+ // Parse templates blocks and store them into the state.
64
+ const blocksByTemplateSlug = reduce(
65
+ templates,
66
+ ( prev, { slug, content } ) => {
67
+ prev[ slug ] = content
68
+ ? parseBlocks( replacePlaceholders( content, siteInformation ) )
69
+ : [];
70
+ return prev;
71
+ },
72
+ {}
73
+ );
74
+
75
+ // eslint-disable-next-line react/no-did-mount-set-state
76
+ this.setState( { blocksByTemplateSlug } );
77
}
78
79
+ setTemplate = slug => {
80
+ // Track selection and mark post as using a template in its postmeta.
81
+ trackSelection( this.props.segment.id, this.props.vertical.id, slug );
82
+ this.props.saveTemplateChoice( slug );
83
84
+ // Load content.
85
+ const blocks = this.getBlocksByTemplateSlug( slug );
86
+ const title = this.getTitleByTemplateSlug( slug );
87
88
// Skip inserting if there's nothing to insert.
89
+ if ( ! blocks || ! blocks.length ) {
90
+ this.setState( { isOpen: false } );
91
return;
92
}
93
94
+ // Show loading state.
95
+ this.setState( {
96
+ error: null,
97
+ isLoading: true,
98
+ } );
99
+
100
+ // Make sure all blocks use local assets before inserting.
101
+ this.maybePrefetchAssets( blocks )
102
+ .then( blocksWithAssets => {
103
+ // Don't insert anything if the user clicked Cancel/Close
104
+ // before we loaded everything.
105
+ if ( ! this.state.isOpen ) {
106
+ return;
107
+ }
108
+
109
+ this.props.insertTemplate( title, blocksWithAssets );
110
+ this.setState( { isOpen: false } );
111
+ } )
112
+ .catch( error => {
113
+ this.setState( {
114
+ isLoading: false,
115
+ error,
116
+ } );
117
+ } );
118
+ };
119
120
+ maybePrefetchAssets = blocks => {
121
+ return this.props.shouldPrefetchAssets ? ensureAssets( blocks ) : Promise.resolve( blocks );
122
};
123
124
+ handleConfirmation = slug => {
125
+ if ( typeof slug !== 'string' ) {
126
+ slug = this.state.previewedTemplate;
127
+ }
128
+
129
+ this.setTemplate( slug );
130
+ };
131
+
132
+ previewTemplate = slug => this.setState( { previewedTemplate: slug } );
133
+
134
+ closeModal = event => {
135
+ // Check to see if the Blur event occurred on the buttons inside of the Modal.
136
+ // If it did then we don't want to dismiss the Modal for this type of Blur.
137
+ if ( event.target.matches( 'button.template-selector-item__label' ) ) {
138
+ return false;
139
+ }
140
+
141
trackDismiss( this.props.segment.id, this.props.vertical.id );
142
+
143
+ // Try if we have specific URL to go back to, otherwise go to the page list.
144
+ const calypsoifyCloseUrl = get( window, [ 'calypsoifyGutenberg', 'closeUrl' ] );
145
+ window.top.location = calypsoifyCloseUrl || 'edit.php?post_type=page';
146
};
147
148
+ getBlocksByTemplateSlug( slug ) {
149
+ return get( this.state.blocksByTemplateSlug, [ slug ], [] );
150
+ }
151
+
152
+ getTitleByTemplateSlug( slug ) {
153
+ return get( this.state.titlesByTemplateSlug, [ slug ], '' );
154
+ }
155
+
156
render() {
157
+ /* eslint-disable no-shadow */
158
+ const { previewedTemplate, isOpen, isLoading, blocksByTemplateSlug } = this.state;
159
+ const { templates } = this.props;
160
+ /* eslint-enable no-shadow */
161
+
162
+ if ( ! isOpen ) {
163
return null;
164
}
165
166
return (
167
<Modal
168
title={ __( 'Select Page Template', 'full-site-editing' ) }
169
className="page-template-modal"
170
overlayClassName="page-template-modal-screen-overlay"
171
+ shouldCloseOnClickOutside={ false }
172
+ // Using both variants here to be compatible with new Gutenberg and old (older than 6.6).
173
+ isDismissable={ false }
174
+ isDismissible={ false }
175
>
176
+ <IconButton
177
+ className="page-template-modal__close-button components-icon-button"
178
+ onClick={ this.closeModal }
179
+ icon="arrow-left-alt2"
180
+ label={ __( 'Go back' ) }
181
+ />
182
+
183
<div className="page-template-modal__inner">
184
+ { isLoading ? (
185
+ <div className="page-template-modal__loading">
186
+ <Spinner />
187
+ { __( 'Inserting template…', 'full-site-editing' ) }
188
+ </div>
189
+ ) : (
190
+ <>
191
+ <form className="page-template-modal__form">
192
+ <fieldset className="page-template-modal__list">
193
+ <legend className="page-template-modal__form-title">
194
+ { __( 'Choose a template…', 'full-site-editing' ) }
195
+ </legend>
196
+ <TemplateSelectorControl
197
+ label={ __( 'Template', 'full-site-editing' ) }
198
+ templates={ templates }
199
+ blocksByTemplates={ blocksByTemplateSlug }
200
+ onTemplateSelect={ this.previewTemplate }
201
+ useDynamicPreview={ false }
202
+ siteInformation={ siteInformation }
203
+ selectedTemplate={ previewedTemplate }
204
+ handleTemplateConfirmation={ this.handleConfirmation }
205
+ />
206
+ </fieldset>
207
+ </form>
208
+ <TemplateSelectorPreview
209
+ blocks={ this.getBlocksByTemplateSlug( previewedTemplate ) }
210
+ viewportWidth={ 960 }
211
+ title={ this.getTitleByTemplateSlug( previewedTemplate ) }
212
/>
213
+ </>
214
+ ) }
215
+ </div>
216
+ <div
217
+ className={ classnames( 'page-template-modal__buttons', {
218
+ 'is-visually-hidden': isEmpty( previewedTemplate ) || isLoading,
219
+ } ) }
220
+ >
221
+ <Button
222
+ isPrimary
223
+ isLarge
224
+ disabled={ isEmpty( previewedTemplate ) || isLoading }
225
+ onClick={ this.handleConfirmation }
226
+ >
227
+ { sprintf(
228
+ __( 'Use %s template', 'full-site-editing' ),
229
+ this.getTitleByTemplateSlug( previewedTemplate )
230
+ ) }
231
+ </Button>
232
</div>
233
</Modal>
234
);
248
249
const editorDispatcher = dispatch( 'core/editor' );
250
return {
251
+ saveTemplateChoice: slug => {
252
// Save selected template slug in meta.
253
const currentMeta = ownProps.getMeta();
254
editorDispatcher.editPost( {
255
meta: {
256
...currentMeta,
257
+ _starter_page_template: slug,
258
},
259
} );
260
},
261
+ insertTemplate: ( title, blocks ) => {
262
// Set post title.
263
+ editorDispatcher.editPost( { title } );
264
265
// Insert blocks.
266
const postContentBlock = ownProps.postContentBlock;
267
+ dispatch( 'core/block-editor' ).insertBlocks(
268
blocks,
269
0,
270
postContentBlock ? postContentBlock.clientId : '',
275
} )
276
)( PageTemplateModal );
277
278
if ( tracksUserData ) {
279
initializeWithIdentity( tracksUserData );
280
}
281
282
registerPlugin( 'page-templates', {
283
+ render: () => {
284
return (
285
<PageTemplatesPlugin
286
+ shouldPrefetchAssets={ false }
287
+ templates={ templates }
288
vertical={ vertical }
289
segment={ segment }
290
/>
291
);
292
},
starter-page-templates/page-template-modal/styles/starter-page-templates-editor.scss CHANGED
@@ -11,19 +11,33 @@
11
word-wrap: normal !important;
12
}
13
14
// Modal Overlay
15
.page-template-modal-screen-overlay {
16
animation: none;
17
}
18
19
// When not in fullscreen mode allow space for WP.org sidebar
20
body:not( .is-fullscreen-mode ) .page-template-modal-screen-overlay {
21
@media screen and ( min-width: 783px ) {
22
- left: 36px;
23
}
24
25
@media screen and ( min-width: 961px ) {
26
- left: 160px;
27
}
28
}
29
@@ -40,12 +54,50 @@ body.admin-bar:not( .is-fullscreen-mode ) .page-template-modal-screen-overlay {
40
.page-template-modal {
41
width: 100%;
42
height: 100vh;
43
- max-width: 800px;
44
animation: none;
45
}
46
47
.page-template-modal .components-modal__header-heading-container {
48
- justify-content: center;
49
}
50
51
.page-template-modal .components-modal__content {
@@ -54,12 +106,20 @@ body.admin-bar:not( .is-fullscreen-mode ) .page-template-modal-screen-overlay {
54
}
55
56
.page-template-modal__inner {
57
- max-width: 720px;
58
margin: 0 auto;
59
padding: 0;
60
61
@media screen and ( max-width: 659px ) {
62
- padding-bottom: 3em;
63
}
64
}
65
@@ -71,14 +131,24 @@ body.admin-bar:not( .is-fullscreen-mode ) .page-template-modal-screen-overlay {
71
.template-selector-control__options {
72
display: grid;
73
// stylelint-disable-next-line unit-whitelist
74
- grid-template-columns: 1fr 1fr; // force 2 col on small screens to ensure blank isn't the only option visible on load
75
grid-gap: 1.75em;
76
77
@media screen and ( min-width: 660px ) {
78
// stylelint-disable unit-whitelist
79
grid-template-columns: repeat(
80
auto-fit,
81
- minmax( 200px, 1fr )
82
); // allow grid to take over number of cols on large screens
83
// stylelint-enable unit-whitelist
84
}
@@ -88,49 +158,112 @@ body.admin-bar:not( .is-fullscreen-mode ) .page-template-modal-screen-overlay {
88
margin-bottom: 4px;
89
}
90
91
- .template-selector-control__label {
92
display: block;
93
width: 100%;
94
font-size: 14px;
95
text-align: center;
96
- border: 1px solid #a1aab2;
97
border-radius: 6px;
98
cursor: pointer;
99
- background: none;
100
appearance: none;
101
- padding: 0 0 14px;
102
overflow: hidden;
103
104
- &:hover,
105
&:focus {
106
- border-color: #2562b7;
107
- box-shadow: 0 0 0 1px #2562b7;
108
- outline: 1px solid transparent;
109
- outline-offset: -1px;
110
}
111
}
112
113
- .template-selector-control__media-wrap {
114
width: 100%;
115
display: block;
116
- margin: 0 auto 14px;
117
- border-bottom: 1px solid #a1aab2;
118
- background: #f6f6f6;
119
border-radius: 0;
120
overflow: hidden;
121
- padding-bottom: 110%;
122
box-sizing: content-box;
123
position: relative;
124
pointer-events: none;
125
}
126
127
- .template-selector-control__media {
128
width: 100%;
129
display: block;
130
position: absolute;
131
top: 0;
132
left: 0;
133
}
134
}
135
136
.page-template-modal__actions {
@@ -155,3 +288,190 @@ body.admin-bar:not( .is-fullscreen-mode ) .page-template-modal-screen-overlay {
155
margin-right: 1em;
156
}
157
}
11
word-wrap: normal !important;
12
}
13
14
+ $template-selector-border-color: #e2e4e7;
15
+ $template-selector-border-color-selected: #555d66;
16
+ $template-selector-border-color-active: #00a0d2;
17
+ $template-selector-border-color-hover: #c9c9ca;
18
+ $template-selector-empty-background: #fff;
19
+ $template-selector-modal-offset-bottom: 25px;
20
+ $template-selector-modal-offset-right: 32px;
21
+ $template-selector-blank-template-mobile-height: 70px;
22
+ $template-large-preview-title-height: 120px;
23
+
24
+ $wp-org-sidebar-reduced: 36px;
25
+ $wp-org-sidebar-full: 160px;
26
+
27
// Modal Overlay
28
.page-template-modal-screen-overlay {
29
animation: none;
30
+ background-color: transparent; // hide the overlay visually
31
}
32
33
// When not in fullscreen mode allow space for WP.org sidebar
34
body:not( .is-fullscreen-mode ) .page-template-modal-screen-overlay {
35
@media screen and ( min-width: 783px ) {
36
+ left: $wp-org-sidebar-reduced;
37
}
38
39
@media screen and ( min-width: 961px ) {
40
+ left: $wp-org-sidebar-full;
41
}
42
}
43
54
.page-template-modal {
55
width: 100%;
56
height: 100vh;
57
animation: none;
58
+ box-shadow: none; // cancel "modal" appearance
59
+ border: none; // cancel "modal" appearance
60
+ top: 0; // overlay the Block Editor toolbar
61
+ left: 0;
62
+ right: 0;
63
+ bottom: 0;
64
+ transform: none;
65
+ max-width: none;
66
+ max-height: none;
67
+ background-color: #eeeeee;
68
}
69
70
.page-template-modal .components-modal__header-heading-container {
71
+ @include screen-reader-text();
72
+ }
73
+
74
+ // Show close button only in full screen mode.
75
+ .page-template-modal .components-modal__header::after,
76
+ .page-template-modal__close-button {
77
+ display: none;
78
+ }
79
+
80
+ body.is-fullscreen-mode {
81
+ .page-template-modal__close-button {
82
+ display: block;
83
+ position: absolute;
84
+ z-index: 20;
85
+ top: 9px;
86
+ width: 36px;
87
+ height: 36px;
88
+ left: 8px;
89
+ }
90
+
91
+ .page-template-modal .components-modal__header {
92
+ &::after {
93
+ display: block;
94
+ position: absolute;
95
+ content: ' ';
96
+ border-right: 1px solid #e2e4e7;
97
+ height: 100%;
98
+ left: 54px;
99
+ }
100
+ }
101
}
102
103
.page-template-modal .components-modal__content {
106
}
107
108
.page-template-modal__inner {
109
+ position: relative;
110
margin: 0 auto;
111
padding: 0;
112
113
@media screen and ( max-width: 659px ) {
114
+ padding: 0 14% 3em;
115
+ }
116
+
117
+ @media screen and ( max-width: 440px ) {
118
+ padding: 0 15px 3em;
119
+ }
120
+
121
+ @media screen and ( min-width: 1200px ) {
122
+ max-width: 100%;
123
}
124
}
125
131
.template-selector-control__options {
132
display: grid;
133
// stylelint-disable-next-line unit-whitelist
134
+ grid-template-columns: 1fr;
135
grid-gap: 1.75em;
136
137
@media screen and ( min-width: 660px ) {
138
+ margin-top: 0;
139
+ // stylelint-disable unit-whitelist
140
+ grid-template-columns: repeat(
141
+ auto-fit,
142
+ minmax( 110px, 1fr )
143
+ ); // allow grid to take over number of cols on large screens
144
+ // stylelint-enable unit-whitelist
145
+ }
146
+
147
+ @media screen and ( min-width: 1200px ) {
148
// stylelint-disable unit-whitelist
149
grid-template-columns: repeat(
150
auto-fit,
151
+ minmax( 150px, 1fr )
152
); // allow grid to take over number of cols on large screens
153
// stylelint-enable unit-whitelist
154
}
158
margin-bottom: 4px;
159
}
160
161
+ .template-selector-item__label {
162
display: block;
163
width: 100%;
164
font-size: 14px;
165
text-align: center;
166
+ border: solid 2px $template-selector-border-color;
167
border-radius: 6px;
168
cursor: pointer;
169
appearance: none;
170
+ padding: 0;
171
overflow: hidden;
172
+ background-color: #fff;
173
+ position: relative;
174
+
175
+ .template-selector-item__template-title {
176
+ width: 100%;
177
+ position: absolute;
178
+ bottom: 0;
179
+ left: 0;
180
+ height: 40px;
181
+ line-height: 40px;
182
+ background-color: #fff;
183
+ }
184
185
&:focus {
186
+ box-shadow: 0 0 0 1px #fff, 0 0 0 3px $template-selector-border-color-active;
187
+
188
+ // Windows High Contrast mode will show this outline, but not the box-shadow.
189
+ outline: 2px solid transparent;
190
}
191
+
192
+ &:hover {
193
+ border: solid 2px $template-selector-border-color-hover;
194
+ }
195
+
196
+ &.is-selected {
197
+ border: solid 2px $template-selector-border-color-selected;
198
+
199
+ // Windows High Contrast mode will show this outline, but not the box-shadow.
200
+ outline: 2px solid transparent;
201
+ outline-offset: -2px;
202
+
203
+ &:focus {
204
+ box-shadow: 0 0 0 1px #fff, 0 0 0 3px $template-selector-border-color-active;
205
+ border: solid 2px $template-selector-border-color-selected;
206
+
207
+ // Windows High Contrast mode will show this outline, but not the box-shadow.
208
+ outline: 4px solid transparent;
209
+ outline-offset: -4px;
210
+ }
211
+ }
212
+
213
+
214
}
215
216
+ .template-selector-item__preview-wrap {
217
width: 100%;
218
display: block;
219
+ margin: 0 auto;
220
+ background: $template-selector-empty-background;
221
border-radius: 0;
222
overflow: hidden;
223
+ height: 0;
224
+ padding-top: 100%; // Aspect radio boxes. It will take the 100% of width.
225
box-sizing: content-box;
226
position: relative;
227
pointer-events: none;
228
+ opacity: 1;
229
+
230
+ @media screen and ( max-width: 659px ) {
231
+ padding-top: 120%;
232
+ }
233
+
234
+ &.is-rendering {
235
+ opacity: 0.5;
236
+ }
237
+
238
+ .block-editor-block-list__layout,
239
+ .block-editor-block-list__block {
240
+ padding: inherit;
241
+ }
242
}
243
244
+ .template-selector-item__media {
245
width: 100%;
246
display: block;
247
position: absolute;
248
top: 0;
249
left: 0;
250
}
251
+
252
+ // Blank template
253
+ .template-selector-control__template:first-child {
254
+ .template-selector-item__preview-wrap {
255
+ @media screen and ( max-width: 659px ) {
256
+ padding-top: 0%;
257
+ height: $template-selector-blank-template-mobile-height;
258
+ }
259
+ }
260
+ .template-selector-item__template-title {
261
+ @media screen and ( max-width: 659px ) {
262
+ height: $template-selector-blank-template-mobile-height;
263
+ line-height: $template-selector-blank-template-mobile-height;
264
+ }
265
+ }
266
+ }
267
}
268
269
.page-template-modal__actions {
288
margin-right: 1em;
289
}
290
}
291
+
292
+ .page-template-modal__form {
293
+ @media screen and ( min-width: 660px ) {
294
+ max-width: 50%;
295
+ }
296
+ }
297
+
298
+ .page-template-modal__form-title {
299
+ font-weight: bold;
300
+ margin-bottom: 1em;
301
+ @media screen and ( max-width: 659px ) {
302
+ text-align: center;
303
+ }
304
+ }
305
+
306
+ .page-template-modal__buttons {
307
+ position: absolute;
308
+ right: 0;
309
+ top: 0;
310
+ z-index: 10;
311
+ height: 56px;
312
+ display: flex;
313
+ align-items: center;
314
+ padding-right: 24px;
315
+
316
+ @media screen and ( max-width: 659px ) {
317
+ display: none;
318
+ }
319
+
320
+ &.is-visually-hidden {
321
+ @include screen-reader-text();
322
+ }
323
+
324
+ .components-button {
325
+ height: 33px; // match to Gutenberg toolbar styles
326
+ line-height: 32px; // match to Gutenberg toolbar styles
327
+ }
328
+ }
329
+
330
+ // Template Selector Preview
331
+ .template-selector-preview {
332
+ @media screen and ( max-width: 659px ) {
333
+ display: none;
334
+ }
335
+
336
+ position: fixed;
337
+ top: 111px;
338
+ bottom: 24px;
339
+ right: 24px;
340
+ width: calc( 50% - 50px );
341
+ background: $template-selector-empty-background;
342
+ border-radius: 2px;
343
+ overflow-x: hidden;