@secretstache/wordpress-gutenberg 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.editorconfig ADDED
@@ -0,0 +1,18 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 2
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
13
+
14
+ [*.js]
15
+ indent_size = 4
16
+
17
+ [*.scss]
18
+ indent_size = 4
package/build/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{ColorPalette as e,Button as n,Icon as r,BaseControl as t,CheckboxControl as o,ToggleControl as a}from"@wordpress/components";import l from"@wordpress/api-fetch";import{useSelect as i}from"@wordpress/data";import{useRef as c,useEffect as s}from"@wordpress/element";import{jsx as d,jsxs as u,Fragment as m}from"react/jsx-runtime";import{MediaUploadCheck as p,MediaUpload as g,MediaPlaceholder as h,URLInput as v}from"@wordpress/block-editor";import{edit as b,trash as y}from"@wordpress/icons";"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function f(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var w,k,A={exports:{}};(w=A).exports=(k=function(){var e=JSON.parse('{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E\'","Ը":"Y\'","Թ":"T\'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C\'","Կ":"K","Հ":"H","Ձ":"D\'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R\'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P\'","Ք":"Q\'","Օ":"O\'\'","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"\'","’":"\'","“":"\\"","”":"\\"","„":"\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}'),n=JSON.parse('{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Х":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","å":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","å":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","å":"aa","ä":"ae","ö":"oe"}}');function r(r,t){if("string"!=typeof r)throw new Error("slugify: string argument expected");var o=n[(t="string"==typeof t?{replacement:t}:t||{}).locale]||{},a=void 0===t.replacement?"-":t.replacement,l=void 0===t.trim||t.trim,i=r.normalize().split("").reduce((function(n,r){var l=o[r];return void 0===l&&(l=e[r]),void 0===l&&(l=r),l===a&&(l=" "),n+l.replace(t.remove||/[^\w\s$*_+~.()'"!\-:@]+/g,"")}),"");return t.strict&&(i=i.replace(/[^A-Za-z0-9\s]/g,"")),l&&(i=i.trim()),i=i.replace(/\s+/g,a),t.lower&&(i=i.toLowerCase()),i}return r.extend=function(n){Object.assign(e,n)},r})(),w.exports.default=k();var E=f(A.exports);const C=async function(e,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;const t=await l({path:"/wp/v2/".concat(n,"?search=").concat(encodeURIComponent(e))});return r?null==t?void 0:t.map(r):null==t?void 0:t.map((e=>{var n;const r=document.createElement("div");return r.innerHTML=null==e||null===(n=e.title)||void 0===n?void 0:n.rendered,{value:e.id,label:r.textContent||r.innerText||""}}))},I=function(e,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return i((t=>{const{getBlock:o,getBlockRootClientId:a,getBlockHierarchyRootClientId:l}=t("core/block-editor");if(!e)return null;const{rootBlockId:i="",includeSelf:c=!1}=r;if(i){if(l(e)!==i)return null}let s=e,d=o(s);if(c&&(null==d?void 0:d.name)===n)return d;let u=a(s),m=o(u);for(;m&&(!i||u!==i)&&u;){if(m.name===n)return m;s=u,u=a(s),m=o(u)}return null}),[e,n,r.rootBlockId,r.includeSelf])},O=e=>E(e,{replacement:"-",lower:!0,strict:!0}),S=e=>{if(e.startsWith("<?xml")){const n=e.indexOf("?>");-1!==n&&(e=e.substring(n+2))}return e=e.trim()},_="image/svg+xml",N=async e=>{const n=(null==e?void 0:e.mime)===_||(null==e?void 0:e.mime_type)===_,r={isSvg:n,imageUrl:null,svgCode:null,width:null==e?void 0:e.width,height:null==e?void 0:e.height};return n?r.svgCode=await fetch(e.url).then((e=>e.text())).then(S):r.imageUrl=null==e?void 0:e.url,r},U=e=>{if(!e)return"";let n=e;const r=e.match(/^\+\d(\d{3})(\d{3})(\d{4})$/);return r&&(n="".concat(r[1],"-").concat(r[2],"-").concat(r[3])),n},T=e=>{const{street_number:n="",street_name:r="",city:t="",state_short:o="",post_code:a=""}=e;let l=["".concat(n," ").concat(r).trim()];t&&l.push("<br>".concat(t));let i=[];o&&i.push(o),a&&i.push(a);let c=i.join(" ");return c&&l.push("".concat(l.length>0?", ":"").concat(c)),l.join("")},R=(e,n,r)=>{const t=c(null);return s((()=>{let o;return e&&null!=n&&n.length&&null!=t&&t.current&&(o=r(t.current)),()=>{var e;null===(e=o)||void 0===e||e.destroy()}}),[e,n]),t},Y=(e,n,r)=>{const{query:t,curatedItems:o,selectedCategories:a,categoryKey:l,numberOfItems:c,order:s="desc",orderby:d="date"}=r,{records:u,isLoading:m}=i((r=>{const i={order:s,orderby:d,_embed:!0};null!=t&&t.LATEST_BY_CATEGORY&&null!=a&&a.length?i[l]=a.join(","):null!=t&&t.BY_CATEGORY&&null!=a&&a.length?i[l]=a.map((e=>e.value)).join(","):null!=t&&t.CURATED&&null!=o&&o.length&&(i.include=o.map((e=>e.value)),i.orderby="include"),c&&(i.per_page=c);const u=r("core").getEntityRecords(e,n,i);return{records:u,isLoading:r("core/data").isResolving("core","getEntityRecords",[e,n,i])||void 0===u}}),[t,o,a,l,c,s,d]);return{records:u,isLoading:m}},z=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return i((n=>{var r;const{getSettings:t}=n("core/block-editor"),o=null===(r=t())||void 0===r?void 0:r.colors;return e.length>0?null==o?void 0:o.filter((n=>e.includes(n.slug))):o}),[])},j=(e,n)=>(r,t)=>{const o=e.find((e=>e.color===r));n({[t]:o?{value:r,slug:o.slug}:null})},x=e=>(n,r)=>{e({[r]:n})},H=n=>{let{allowedColors:r,colorAttribute:t,attributeName:o,setAttributes:a}=n;const l=z(r),i=j(l,a);return d(e,{colors:l,value:null==t?void 0:t.value,disableCustomColors:!0,onChange:e=>i(e,o)})},D=e=>{let{imageId:t,imageUrl:o,imageAlt:a,svgCode:l,onSelect:i,onRemove:c}=e;const s=t&&o,m=s&&l;return d(p,{children:d(g,{onSelect:i,allowedTypes:["image"],value:t,render:e=>{let{open:t}=e;return s?u("div",{className:"bc-image-wrapper",children:[s&&(m?d("div",{className:"svg-container",dangerouslySetInnerHTML:{__html:l}}):d("img",{src:o,alt:a||"icon"})),u("div",{className:"bc-image-wrapper__actions",children:[d(n,{className:"bc-image-wrapper__btn bc-image-wrapper__replace-btn",type:"button",onClick:t,children:d(r,{icon:b,size:20,className:"bc-image-wrapper__btn-icon"})}),d(n,{className:"bc-image-wrapper__btn bc-image-wrapper__remove-btn",type:"button",onClick:c,children:d(r,{icon:y,size:20,className:"bc-image-wrapper__btn-icon"})})]}),d("div",{className:"bc-image-wrapper__overlay"})]}):d(h,{icon:"format-image",onSelect:i,allowedTypes:["image","image/svg+xml"],labels:{title:"Icon Image"}})}})})},L=e=>{let{imageId:r,imageUrl:t,imageAlt:o,placeholder:a=!1,onSelectImage:l,onRemoveImage:i,className:c=""}=e;const s=r&&t;return d(p,{children:d(g,{onSelect:l,allowedTypes:["image"],value:r,render:e=>{let{open:r}=e;return s?u("div",{className:"bc-image-wrapper ".concat(c),children:[d("img",{src:t,alt:o,onClick:r}),u("div",{className:"bc-image-wrapper__actions",children:[d(n,{className:"bc-image-wrapper__btn bc-image-wrapper__replace-btn",type:"button",onClick:r,children:"Replace"}),d(n,{className:"bc-image-wrapper__btn bc-image-wrapper__remove-btn",type:"button",onClick:i,children:"Remove"})]}),d("div",{className:"bc-image-wrapper__overlay"})]}):a?d(h,{className:"media-placeholder",icon:"format-image",onSelect:l,allowedTypes:["image"],labels:{title:"Image",instructions:"Upload an image file or pick one from your media library."}}):null}})})},G=e=>{let{buttonSource:n,isButtonOpenInNewTab:r,setAttributes:a}=e;const l=x(a);return u(m,{children:[d(t,{label:"Source",children:d(v,{className:"bc-url-input",value:n,onChange:e=>l(e,"buttonSource")})}),d(o,{checked:r,label:"Open in a new tab",onChange:e=>l(e,"isButtonOpenInNewTab")})]})},B=e=>{let{imageId:r,imageUrl:t,onImageClick:o,onRemoveClick:a,onSelectClick:l}=e;return r&&t?u(m,{children:[d("div",{className:"bc-selected-media-wrapper",children:d("img",{src:t,className:"bc-selected-media bc-selected-media--image",alt:"Selected Image",onClick:o})}),d(n,{className:"bc-remove-btn",onClick:a,isSecondary:!0,isDestructive:!0,children:"Remove Image"})]}):d(n,{variant:"secondary",onClick:l,className:"bc-select-btn",children:"Select Image"})},J=e=>{let{videoId:r,videoUrl:t,onRemoveClick:o,onSelectClick:a}=e;return r&&t?u(m,{children:[d("div",{className:"bc-selected-media-wrapper",children:d("video",{src:t,className:"bc-selected-media bc-selected-media--video",controls:!0})}),d(n,{className:"bc-remove-btn",onClick:o,isSecondary:!0,isDestructive:!0,children:"Remove Video"})]}):d(n,{variant:"secondary",onClick:a,className:"bc-select-btn",children:"Select Video"})},P={IMAGE:"image",VIDEO:"video"},M=e=>{let{mediaId:n,mediaUrl:r,onSelect:t,onRemove:o,type:a=P.IMAGE,...l}=e;if(a===P.IMAGE)return d(p,{children:d(g,{onSelect:t,allowedTypes:["image","image/svg+xml"],accept:"image/*",value:n,render:e=>{let{open:t}=e;return d(B,{imageId:n,imageUrl:r,onImageClick:t,onSelectClick:t,onRemoveClick:o})},...l})});if(a===P.VIDEO)return d(p,{children:d(g,{onSelect:t,allowedTypes:["video"],value:n,render:e=>{let{open:t}=e;return d(J,{videoId:n,videoUrl:r,onSelectClick:t,onRemoveClick:o})},...l})});throw new Error("Unrecognized media type.")},Z=e=>{let{attributes:n,setAttributes:r,disabled:t}=e;const{isPreview:o}=n;return d(m,{children:d(a,{label:"Enable Preview",help:"Please check this option to see how the block will actually look and behave on the frontend.",checked:o,onChange:()=>{r({isPreview:!o})},disabled:t})})};export{B as BCImageRenderer,M as BCMediaPicker,J as BCVideoRenderer,H as ColorPaletteControl,D as IconPicker,L as ImageActions,G as LinkControl,Z as PreviewToggle,S as cleanSvgString,N as getImage,T as getLocationAddress,U as getPhoneNumber,O as getSlug,C as loadSelectOptions,j as useColorChange,Y as useEntityRecords,x as useLinkChange,I as useParentBlock,R as useSlider,z as useThemeColors};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../node_modules/slugify/slugify.js","../src/utils/index.js","../src/components/ColorPaletteControl.js","../src/components/IconPicker.js","../src/components/ImageActions.js","../src/components/LinkControl.js","../src/components/MediaPicker.js","../src/components/PreviewToggle.js"],"sourcesContent":["\n;(function (name, root, factory) {\n if (typeof exports === 'object') {\n module.exports = factory()\n module.exports['default'] = factory()\n }\n /* istanbul ignore next */\n else if (typeof define === 'function' && define.amd) {\n define(factory)\n }\n else {\n root[name] = factory()\n }\n}('slugify', this, function () {\n var charMap = JSON.parse('{\"$\":\"dollar\",\"%\":\"percent\",\"&\":\"and\",\"<\":\"less\",\">\":\"greater\",\"|\":\"or\",\"¢\":\"cent\",\"£\":\"pound\",\"¤\":\"currency\",\"¥\":\"yen\",\"©\":\"(c)\",\"ª\":\"a\",\"®\":\"(r)\",\"º\":\"o\",\"À\":\"A\",\"Á\":\"A\",\"Â\":\"A\",\"Ã\":\"A\",\"Ä\":\"A\",\"Å\":\"A\",\"Æ\":\"AE\",\"Ç\":\"C\",\"È\":\"E\",\"É\":\"E\",\"Ê\":\"E\",\"Ë\":\"E\",\"Ì\":\"I\",\"Í\":\"I\",\"Î\":\"I\",\"Ï\":\"I\",\"Ð\":\"D\",\"Ñ\":\"N\",\"Ò\":\"O\",\"Ó\":\"O\",\"Ô\":\"O\",\"Õ\":\"O\",\"Ö\":\"O\",\"Ø\":\"O\",\"Ù\":\"U\",\"Ú\":\"U\",\"Û\":\"U\",\"Ü\":\"U\",\"Ý\":\"Y\",\"Þ\":\"TH\",\"ß\":\"ss\",\"à\":\"a\",\"á\":\"a\",\"â\":\"a\",\"ã\":\"a\",\"ä\":\"a\",\"å\":\"a\",\"æ\":\"ae\",\"ç\":\"c\",\"è\":\"e\",\"é\":\"e\",\"ê\":\"e\",\"ë\":\"e\",\"ì\":\"i\",\"í\":\"i\",\"î\":\"i\",\"ï\":\"i\",\"ð\":\"d\",\"ñ\":\"n\",\"ò\":\"o\",\"ó\":\"o\",\"ô\":\"o\",\"õ\":\"o\",\"ö\":\"o\",\"ø\":\"o\",\"ù\":\"u\",\"ú\":\"u\",\"û\":\"u\",\"ü\":\"u\",\"ý\":\"y\",\"þ\":\"th\",\"ÿ\":\"y\",\"Ā\":\"A\",\"ā\":\"a\",\"Ă\":\"A\",\"ă\":\"a\",\"Ą\":\"A\",\"ą\":\"a\",\"Ć\":\"C\",\"ć\":\"c\",\"Č\":\"C\",\"č\":\"c\",\"Ď\":\"D\",\"ď\":\"d\",\"Đ\":\"DJ\",\"đ\":\"dj\",\"Ē\":\"E\",\"ē\":\"e\",\"Ė\":\"E\",\"ė\":\"e\",\"Ę\":\"e\",\"ę\":\"e\",\"Ě\":\"E\",\"ě\":\"e\",\"Ğ\":\"G\",\"ğ\":\"g\",\"Ģ\":\"G\",\"ģ\":\"g\",\"Ĩ\":\"I\",\"ĩ\":\"i\",\"Ī\":\"i\",\"ī\":\"i\",\"Į\":\"I\",\"į\":\"i\",\"İ\":\"I\",\"ı\":\"i\",\"Ķ\":\"k\",\"ķ\":\"k\",\"Ļ\":\"L\",\"ļ\":\"l\",\"Ľ\":\"L\",\"ľ\":\"l\",\"Ł\":\"L\",\"ł\":\"l\",\"Ń\":\"N\",\"ń\":\"n\",\"Ņ\":\"N\",\"ņ\":\"n\",\"Ň\":\"N\",\"ň\":\"n\",\"Ō\":\"O\",\"ō\":\"o\",\"Ő\":\"O\",\"ő\":\"o\",\"Œ\":\"OE\",\"œ\":\"oe\",\"Ŕ\":\"R\",\"ŕ\":\"r\",\"Ř\":\"R\",\"ř\":\"r\",\"Ś\":\"S\",\"ś\":\"s\",\"Ş\":\"S\",\"ş\":\"s\",\"Š\":\"S\",\"š\":\"s\",\"Ţ\":\"T\",\"ţ\":\"t\",\"Ť\":\"T\",\"ť\":\"t\",\"Ũ\":\"U\",\"ũ\":\"u\",\"Ū\":\"u\",\"ū\":\"u\",\"Ů\":\"U\",\"ů\":\"u\",\"Ű\":\"U\",\"ű\":\"u\",\"Ų\":\"U\",\"ų\":\"u\",\"Ŵ\":\"W\",\"ŵ\":\"w\",\"Ŷ\":\"Y\",\"ŷ\":\"y\",\"Ÿ\":\"Y\",\"Ź\":\"Z\",\"ź\":\"z\",\"Ż\":\"Z\",\"ż\":\"z\",\"Ž\":\"Z\",\"ž\":\"z\",\"Ə\":\"E\",\"ƒ\":\"f\",\"Ơ\":\"O\",\"ơ\":\"o\",\"Ư\":\"U\",\"ư\":\"u\",\"Lj\":\"LJ\",\"lj\":\"lj\",\"Nj\":\"NJ\",\"nj\":\"nj\",\"Ș\":\"S\",\"ș\":\"s\",\"Ț\":\"T\",\"ț\":\"t\",\"ə\":\"e\",\"˚\":\"o\",\"Ά\":\"A\",\"Έ\":\"E\",\"Ή\":\"H\",\"Ί\":\"I\",\"Ό\":\"O\",\"Ύ\":\"Y\",\"Ώ\":\"W\",\"ΐ\":\"i\",\"Α\":\"A\",\"Β\":\"B\",\"Γ\":\"G\",\"Δ\":\"D\",\"Ε\":\"E\",\"Ζ\":\"Z\",\"Η\":\"H\",\"Θ\":\"8\",\"Ι\":\"I\",\"Κ\":\"K\",\"Λ\":\"L\",\"Μ\":\"M\",\"Ν\":\"N\",\"Ξ\":\"3\",\"Ο\":\"O\",\"Π\":\"P\",\"Ρ\":\"R\",\"Σ\":\"S\",\"Τ\":\"T\",\"Υ\":\"Y\",\"Φ\":\"F\",\"Χ\":\"X\",\"Ψ\":\"PS\",\"Ω\":\"W\",\"Ϊ\":\"I\",\"Ϋ\":\"Y\",\"ά\":\"a\",\"έ\":\"e\",\"ή\":\"h\",\"ί\":\"i\",\"ΰ\":\"y\",\"α\":\"a\",\"β\":\"b\",\"γ\":\"g\",\"δ\":\"d\",\"ε\":\"e\",\"ζ\":\"z\",\"η\":\"h\",\"θ\":\"8\",\"ι\":\"i\",\"κ\":\"k\",\"λ\":\"l\",\"μ\":\"m\",\"ν\":\"n\",\"ξ\":\"3\",\"ο\":\"o\",\"π\":\"p\",\"ρ\":\"r\",\"ς\":\"s\",\"σ\":\"s\",\"τ\":\"t\",\"υ\":\"y\",\"φ\":\"f\",\"χ\":\"x\",\"ψ\":\"ps\",\"ω\":\"w\",\"ϊ\":\"i\",\"ϋ\":\"y\",\"ό\":\"o\",\"ύ\":\"y\",\"ώ\":\"w\",\"Ё\":\"Yo\",\"Ђ\":\"DJ\",\"Є\":\"Ye\",\"І\":\"I\",\"Ї\":\"Yi\",\"Ј\":\"J\",\"Љ\":\"LJ\",\"Њ\":\"NJ\",\"Ћ\":\"C\",\"Џ\":\"DZ\",\"А\":\"A\",\"Б\":\"B\",\"В\":\"V\",\"Г\":\"G\",\"Д\":\"D\",\"Е\":\"E\",\"Ж\":\"Zh\",\"З\":\"Z\",\"И\":\"I\",\"Й\":\"J\",\"К\":\"K\",\"Л\":\"L\",\"М\":\"M\",\"Н\":\"N\",\"О\":\"O\",\"П\":\"P\",\"Р\":\"R\",\"С\":\"S\",\"Т\":\"T\",\"У\":\"U\",\"Ф\":\"F\",\"Х\":\"H\",\"Ц\":\"C\",\"Ч\":\"Ch\",\"Ш\":\"Sh\",\"Щ\":\"Sh\",\"Ъ\":\"U\",\"Ы\":\"Y\",\"Ь\":\"\",\"Э\":\"E\",\"Ю\":\"Yu\",\"Я\":\"Ya\",\"а\":\"a\",\"б\":\"b\",\"в\":\"v\",\"г\":\"g\",\"д\":\"d\",\"е\":\"e\",\"ж\":\"zh\",\"з\":\"z\",\"и\":\"i\",\"й\":\"j\",\"к\":\"k\",\"л\":\"l\",\"м\":\"m\",\"н\":\"n\",\"о\":\"o\",\"п\":\"p\",\"р\":\"r\",\"с\":\"s\",\"т\":\"t\",\"у\":\"u\",\"ф\":\"f\",\"х\":\"h\",\"ц\":\"c\",\"ч\":\"ch\",\"ш\":\"sh\",\"щ\":\"sh\",\"ъ\":\"u\",\"ы\":\"y\",\"ь\":\"\",\"э\":\"e\",\"ю\":\"yu\",\"я\":\"ya\",\"ё\":\"yo\",\"ђ\":\"dj\",\"є\":\"ye\",\"і\":\"i\",\"ї\":\"yi\",\"ј\":\"j\",\"љ\":\"lj\",\"њ\":\"nj\",\"ћ\":\"c\",\"ѝ\":\"u\",\"џ\":\"dz\",\"Ґ\":\"G\",\"ґ\":\"g\",\"Ғ\":\"GH\",\"ғ\":\"gh\",\"Қ\":\"KH\",\"қ\":\"kh\",\"Ң\":\"NG\",\"ң\":\"ng\",\"Ү\":\"UE\",\"ү\":\"ue\",\"Ұ\":\"U\",\"ұ\":\"u\",\"Һ\":\"H\",\"һ\":\"h\",\"Ә\":\"AE\",\"ә\":\"ae\",\"Ө\":\"OE\",\"ө\":\"oe\",\"Ա\":\"A\",\"Բ\":\"B\",\"Գ\":\"G\",\"Դ\":\"D\",\"Ե\":\"E\",\"Զ\":\"Z\",\"Է\":\"E\\'\",\"Ը\":\"Y\\'\",\"Թ\":\"T\\'\",\"Ժ\":\"JH\",\"Ի\":\"I\",\"Լ\":\"L\",\"Խ\":\"X\",\"Ծ\":\"C\\'\",\"Կ\":\"K\",\"Հ\":\"H\",\"Ձ\":\"D\\'\",\"Ղ\":\"GH\",\"Ճ\":\"TW\",\"Մ\":\"M\",\"Յ\":\"Y\",\"Ն\":\"N\",\"Շ\":\"SH\",\"Չ\":\"CH\",\"Պ\":\"P\",\"Ջ\":\"J\",\"Ռ\":\"R\\'\",\"Ս\":\"S\",\"Վ\":\"V\",\"Տ\":\"T\",\"Ր\":\"R\",\"Ց\":\"C\",\"Փ\":\"P\\'\",\"Ք\":\"Q\\'\",\"Օ\":\"O\\'\\'\",\"Ֆ\":\"F\",\"և\":\"EV\",\"ء\":\"a\",\"آ\":\"aa\",\"أ\":\"a\",\"ؤ\":\"u\",\"إ\":\"i\",\"ئ\":\"e\",\"ا\":\"a\",\"ب\":\"b\",\"ة\":\"h\",\"ت\":\"t\",\"ث\":\"th\",\"ج\":\"j\",\"ح\":\"h\",\"خ\":\"kh\",\"د\":\"d\",\"ذ\":\"th\",\"ر\":\"r\",\"ز\":\"z\",\"س\":\"s\",\"ش\":\"sh\",\"ص\":\"s\",\"ض\":\"dh\",\"ط\":\"t\",\"ظ\":\"z\",\"ع\":\"a\",\"غ\":\"gh\",\"ف\":\"f\",\"ق\":\"q\",\"ك\":\"k\",\"ل\":\"l\",\"م\":\"m\",\"ن\":\"n\",\"ه\":\"h\",\"و\":\"w\",\"ى\":\"a\",\"ي\":\"y\",\"ً\":\"an\",\"ٌ\":\"on\",\"ٍ\":\"en\",\"َ\":\"a\",\"ُ\":\"u\",\"ِ\":\"e\",\"ْ\":\"\",\"٠\":\"0\",\"١\":\"1\",\"٢\":\"2\",\"٣\":\"3\",\"٤\":\"4\",\"٥\":\"5\",\"٦\":\"6\",\"٧\":\"7\",\"٨\":\"8\",\"٩\":\"9\",\"پ\":\"p\",\"چ\":\"ch\",\"ژ\":\"zh\",\"ک\":\"k\",\"گ\":\"g\",\"ی\":\"y\",\"۰\":\"0\",\"۱\":\"1\",\"۲\":\"2\",\"۳\":\"3\",\"۴\":\"4\",\"۵\":\"5\",\"۶\":\"6\",\"۷\":\"7\",\"۸\":\"8\",\"۹\":\"9\",\"฿\":\"baht\",\"ა\":\"a\",\"ბ\":\"b\",\"გ\":\"g\",\"დ\":\"d\",\"ე\":\"e\",\"ვ\":\"v\",\"ზ\":\"z\",\"თ\":\"t\",\"ი\":\"i\",\"კ\":\"k\",\"ლ\":\"l\",\"მ\":\"m\",\"ნ\":\"n\",\"ო\":\"o\",\"პ\":\"p\",\"ჟ\":\"zh\",\"რ\":\"r\",\"ს\":\"s\",\"ტ\":\"t\",\"უ\":\"u\",\"ფ\":\"f\",\"ქ\":\"k\",\"ღ\":\"gh\",\"ყ\":\"q\",\"შ\":\"sh\",\"ჩ\":\"ch\",\"ც\":\"ts\",\"ძ\":\"dz\",\"წ\":\"ts\",\"ჭ\":\"ch\",\"ხ\":\"kh\",\"ჯ\":\"j\",\"ჰ\":\"h\",\"Ṣ\":\"S\",\"ṣ\":\"s\",\"Ẁ\":\"W\",\"ẁ\":\"w\",\"Ẃ\":\"W\",\"ẃ\":\"w\",\"Ẅ\":\"W\",\"ẅ\":\"w\",\"ẞ\":\"SS\",\"Ạ\":\"A\",\"ạ\":\"a\",\"Ả\":\"A\",\"ả\":\"a\",\"Ấ\":\"A\",\"ấ\":\"a\",\"Ầ\":\"A\",\"ầ\":\"a\",\"Ẩ\":\"A\",\"ẩ\":\"a\",\"Ẫ\":\"A\",\"ẫ\":\"a\",\"Ậ\":\"A\",\"ậ\":\"a\",\"Ắ\":\"A\",\"ắ\":\"a\",\"Ằ\":\"A\",\"ằ\":\"a\",\"Ẳ\":\"A\",\"ẳ\":\"a\",\"Ẵ\":\"A\",\"ẵ\":\"a\",\"Ặ\":\"A\",\"ặ\":\"a\",\"Ẹ\":\"E\",\"ẹ\":\"e\",\"Ẻ\":\"E\",\"ẻ\":\"e\",\"Ẽ\":\"E\",\"ẽ\":\"e\",\"Ế\":\"E\",\"ế\":\"e\",\"Ề\":\"E\",\"ề\":\"e\",\"Ể\":\"E\",\"ể\":\"e\",\"Ễ\":\"E\",\"ễ\":\"e\",\"Ệ\":\"E\",\"ệ\":\"e\",\"Ỉ\":\"I\",\"ỉ\":\"i\",\"Ị\":\"I\",\"ị\":\"i\",\"Ọ\":\"O\",\"ọ\":\"o\",\"Ỏ\":\"O\",\"ỏ\":\"o\",\"Ố\":\"O\",\"ố\":\"o\",\"Ồ\":\"O\",\"ồ\":\"o\",\"Ổ\":\"O\",\"ổ\":\"o\",\"Ỗ\":\"O\",\"ỗ\":\"o\",\"Ộ\":\"O\",\"ộ\":\"o\",\"Ớ\":\"O\",\"ớ\":\"o\",\"Ờ\":\"O\",\"ờ\":\"o\",\"Ở\":\"O\",\"ở\":\"o\",\"Ỡ\":\"O\",\"ỡ\":\"o\",\"Ợ\":\"O\",\"ợ\":\"o\",\"Ụ\":\"U\",\"ụ\":\"u\",\"Ủ\":\"U\",\"ủ\":\"u\",\"Ứ\":\"U\",\"ứ\":\"u\",\"Ừ\":\"U\",\"ừ\":\"u\",\"Ử\":\"U\",\"ử\":\"u\",\"Ữ\":\"U\",\"ữ\":\"u\",\"Ự\":\"U\",\"ự\":\"u\",\"Ỳ\":\"Y\",\"ỳ\":\"y\",\"Ỵ\":\"Y\",\"ỵ\":\"y\",\"Ỷ\":\"Y\",\"ỷ\":\"y\",\"Ỹ\":\"Y\",\"ỹ\":\"y\",\"–\":\"-\",\"‘\":\"\\'\",\"’\":\"\\'\",\"“\":\"\\\\\\\"\",\"”\":\"\\\\\\\"\",\"„\":\"\\\\\\\"\",\"†\":\"+\",\"•\":\"*\",\"…\":\"...\",\"₠\":\"ecu\",\"₢\":\"cruzeiro\",\"₣\":\"french franc\",\"₤\":\"lira\",\"₥\":\"mill\",\"₦\":\"naira\",\"₧\":\"peseta\",\"₨\":\"rupee\",\"₩\":\"won\",\"₪\":\"new shequel\",\"₫\":\"dong\",\"€\":\"euro\",\"₭\":\"kip\",\"₮\":\"tugrik\",\"₯\":\"drachma\",\"₰\":\"penny\",\"₱\":\"peso\",\"₲\":\"guarani\",\"₳\":\"austral\",\"₴\":\"hryvnia\",\"₵\":\"cedi\",\"₸\":\"kazakhstani tenge\",\"₹\":\"indian rupee\",\"₺\":\"turkish lira\",\"₽\":\"russian ruble\",\"₿\":\"bitcoin\",\"℠\":\"sm\",\"™\":\"tm\",\"∂\":\"d\",\"∆\":\"delta\",\"∑\":\"sum\",\"∞\":\"infinity\",\"♥\":\"love\",\"元\":\"yuan\",\"円\":\"yen\",\"﷼\":\"rial\",\"ﻵ\":\"laa\",\"ﻷ\":\"laa\",\"ﻹ\":\"lai\",\"ﻻ\":\"la\"}')\n var locales = JSON.parse('{\"bg\":{\"Й\":\"Y\",\"Ц\":\"Ts\",\"Щ\":\"Sht\",\"Ъ\":\"A\",\"Ь\":\"Y\",\"й\":\"y\",\"ц\":\"ts\",\"щ\":\"sht\",\"ъ\":\"a\",\"ь\":\"y\"},\"de\":{\"Ä\":\"AE\",\"ä\":\"ae\",\"Ö\":\"OE\",\"ö\":\"oe\",\"Ü\":\"UE\",\"ü\":\"ue\",\"ß\":\"ss\",\"%\":\"prozent\",\"&\":\"und\",\"|\":\"oder\",\"∑\":\"summe\",\"∞\":\"unendlich\",\"♥\":\"liebe\"},\"es\":{\"%\":\"por ciento\",\"&\":\"y\",\"<\":\"menor que\",\">\":\"mayor que\",\"|\":\"o\",\"¢\":\"centavos\",\"£\":\"libras\",\"¤\":\"moneda\",\"₣\":\"francos\",\"∑\":\"suma\",\"∞\":\"infinito\",\"♥\":\"amor\"},\"fr\":{\"%\":\"pourcent\",\"&\":\"et\",\"<\":\"plus petit\",\">\":\"plus grand\",\"|\":\"ou\",\"¢\":\"centime\",\"£\":\"livre\",\"¤\":\"devise\",\"₣\":\"franc\",\"∑\":\"somme\",\"∞\":\"infini\",\"♥\":\"amour\"},\"pt\":{\"%\":\"porcento\",\"&\":\"e\",\"<\":\"menor\",\">\":\"maior\",\"|\":\"ou\",\"¢\":\"centavo\",\"∑\":\"soma\",\"£\":\"libra\",\"∞\":\"infinito\",\"♥\":\"amor\"},\"uk\":{\"И\":\"Y\",\"и\":\"y\",\"Й\":\"Y\",\"й\":\"y\",\"Ц\":\"Ts\",\"ц\":\"ts\",\"Х\":\"Kh\",\"х\":\"kh\",\"Щ\":\"Shch\",\"щ\":\"shch\",\"Г\":\"H\",\"г\":\"h\"},\"vi\":{\"Đ\":\"D\",\"đ\":\"d\"},\"da\":{\"Ø\":\"OE\",\"ø\":\"oe\",\"Å\":\"AA\",\"å\":\"aa\",\"%\":\"procent\",\"&\":\"og\",\"|\":\"eller\",\"$\":\"dollar\",\"<\":\"mindre end\",\">\":\"større end\"},\"nb\":{\"&\":\"og\",\"Å\":\"AA\",\"Æ\":\"AE\",\"Ø\":\"OE\",\"å\":\"aa\",\"æ\":\"ae\",\"ø\":\"oe\"},\"it\":{\"&\":\"e\"},\"nl\":{\"&\":\"en\"},\"sv\":{\"&\":\"och\",\"Å\":\"AA\",\"Ä\":\"AE\",\"Ö\":\"OE\",\"å\":\"aa\",\"ä\":\"ae\",\"ö\":\"oe\"}}')\n\n function replace (string, options) {\n if (typeof string !== 'string') {\n throw new Error('slugify: string argument expected')\n }\n\n options = (typeof options === 'string')\n ? {replacement: options}\n : options || {}\n\n var locale = locales[options.locale] || {}\n\n var replacement = options.replacement === undefined ? '-' : options.replacement\n\n var trim = options.trim === undefined ? true : options.trim\n\n var slug = string.normalize().split('')\n // replace characters based on charMap\n .reduce(function (result, ch) {\n var appendChar = locale[ch];\n if (appendChar === undefined) appendChar = charMap[ch];\n if (appendChar === undefined) appendChar = ch;\n if (appendChar === replacement) appendChar = ' ';\n return result + appendChar\n // remove not allowed characters\n .replace(options.remove || /[^\\w\\s$*_+~.()'\"!\\-:@]+/g, '')\n }, '');\n\n if (options.strict) {\n slug = slug.replace(/[^A-Za-z0-9\\s]/g, '');\n }\n\n if (trim) {\n slug = slug.trim()\n }\n\n // Replace spaces with replacement character, treating multiple consecutive\n // spaces as a single space.\n slug = slug.replace(/\\s+/g, replacement);\n\n if (options.lower) {\n slug = slug.toLowerCase()\n }\n\n return slug\n }\n\n replace.extend = function (customMap) {\n Object.assign(charMap, customMap)\n }\n\n return replace\n}))\n","import apiFetch from '@wordpress/api-fetch';\nimport { useSelect } from '@wordpress/data';\nimport { useEffect, useRef } from '@wordpress/element';\nimport slugify from 'slugify';\n\nexport const loadSelectOptions = async (inputValue, postType, mapper = null) => {\n const response = await apiFetch({\n path: `/wp/v2/${postType}?search=${encodeURIComponent(inputValue)}`,\n });\n\n if (mapper) {\n return response?.map(mapper);\n } else {\n return response?.map((post) => {\n // Create a temporary DOM element to decode HTML entities\n const tempElement = document.createElement('div');\n tempElement.innerHTML = post?.title?.rendered;\n\n return {\n value: post.id,\n label: tempElement.textContent || tempElement.innerText || '',\n };\n });\n }\n};\n\n/**\n * Hook to find a parent block of a specific type, optionally scoped within a certain root block.\n *\n * @param {string} selectedBlockId - The clientId of the currently selected block.\n * @param {string} parentBlockName - The block type name to search for as a parent.\n * @param {Object} options - Optional settings for the search.\n * @param {string} [options.rootBlockId] - The clientId of the block to limit the search within. If not provided, searches the entire block tree.\n * @param {boolean} [options.includeSelf] - Whether to include the selected block itself if it matches the parentBlockName.\n * @returns {Object|null} The matching parent block, or null if none is found.\n */\nexport const useParentBlock = (selectedBlockId, parentBlockName, options = {}) => {\n return useSelect((select) => {\n const { getBlock, getBlockRootClientId, getBlockHierarchyRootClientId } = select('core/block-editor');\n\n if (!selectedBlockId) {\n return null;\n }\n\n // Destructure with default values to handle optional parameters.\n const { rootBlockId = '', includeSelf = false } = options;\n\n // If rootBlockId is provided, verify the selected block is within its scope.\n if (rootBlockId) {\n const hierarchyRootClientId = getBlockHierarchyRootClientId(selectedBlockId);\n if (hierarchyRootClientId !== rootBlockId) {\n return null; // The selected block is out of the scope of the root block.\n }\n }\n\n let currentBlockId = selectedBlockId;\n let currentBlock = getBlock(currentBlockId);\n\n // Optionally include the selected block if it matches the target type.\n if (includeSelf && currentBlock?.name === parentBlockName) {\n return currentBlock;\n }\n\n let parentBlockId = getBlockRootClientId(currentBlockId);\n let parentBlock = getBlock(parentBlockId);\n\n // Traverse up the hierarchy to find the target parent block.\n while (parentBlock && (rootBlockId ? parentBlockId !== rootBlockId : true) && parentBlockId) {\n if (parentBlock.name === parentBlockName) {\n return parentBlock; // Target parent found.\n }\n currentBlockId = parentBlockId;\n parentBlockId = getBlockRootClientId(currentBlockId);\n parentBlock = getBlock(parentBlockId);\n }\n\n return null; // No matching parent found within the constraints.\n }, [selectedBlockId, parentBlockName, options.rootBlockId, options.includeSelf]);\n};\n\nexport const getSlug = (name) => slugify(name, {\n replacement: '-',\n lower: true,\n strict: true,\n});\n\nexport const cleanSvgString = (svgString) => {\n if (svgString.startsWith('<?xml')) {\n const endOfXml = svgString.indexOf('?>');\n\n if (endOfXml !== -1) {\n svgString = svgString.substring(endOfXml + 2);\n }\n }\n\n svgString = svgString.trim();\n\n return svgString;\n};\n\n\nconst SVG_MIME_TYPE = 'image/svg+xml';\n\nexport const getImage = async (mediaData) => {\n const isSvg = mediaData?.mime === SVG_MIME_TYPE || mediaData?.mime_type === SVG_MIME_TYPE;\n const imagePayload = {\n isSvg,\n imageUrl: null,\n svgCode: null,\n width: mediaData?.width,\n height: mediaData?.height,\n };\n\n if (isSvg) {\n imagePayload.svgCode = await fetch(mediaData.url).then(response => response.text()).then(cleanSvgString);\n } else {\n imagePayload.imageUrl = mediaData?.url;\n }\n\n return imagePayload;\n};\n\nexport const getPhoneNumber = (phone) => {\n if (!phone) return '';\n\n let formatted = phone;\n\n const pattern = /^\\+\\d(\\d{3})(\\d{3})(\\d{4})$/;\n const match = phone.match(pattern);\n\n if (match) {\n formatted = `${match[1]}-${match[2]}-${match[3]}`;\n }\n\n return formatted;\n};\n\nexport const getLocationAddress = (location) => {\n const {\n street_number = '',\n street_name = '',\n city = '',\n state_short = '',\n post_code = '',\n } = location;\n\n // Start with the street number and name, trimming to remove extra spaces if one is missing\n let addressParts = [`${street_number} ${street_name}`.trim()];\n\n // Add the city with a line break, but only if there is a city name.\n if (city) {\n addressParts.push(`<br>${city}`);\n }\n\n // Combine state and postal code intelligently, adding only if they exist\n let statePostalParts = [];\n if (state_short) statePostalParts.push(state_short);\n if (post_code) statePostalParts.push(post_code);\n let statePostal = statePostalParts.join(' ');\n\n if (statePostal) {\n // Add a comma only if there's something before this part\n addressParts.push(`${addressParts.length > 0 ? ', ' : ''}${statePostal}`);\n }\n\n return addressParts.join('');\n};\n\n//for package\n\nexport const useSlider = (isPreview, items, setup) => {\n const ref = useRef(null);\n\n useEffect(() => {\n let instance;\n\n if (isPreview && items?.length && ref?.current) {\n instance = setup(ref.current);\n }\n\n return () => {\n instance?.destroy();\n };\n }, [isPreview, items]);\n\n return ref;\n};\n\n\nexport const useEntityRecords = (entityType, postType, options) => {\n const {\n query,\n curatedItems,\n selectedCategories,\n categoryKey,\n numberOfItems,\n order = 'desc',\n orderby = 'date',\n } = options;\n\n const {\n records,\n isLoading,\n } = useSelect((select) => {\n const queryArgs = {\n order,\n orderby,\n _embed: true,\n };\n\n // TODO: refactor\n if (query?.LATEST_BY_CATEGORY && selectedCategories?.length) {\n queryArgs[categoryKey] = selectedCategories.join(',');\n } else if (query?.BY_CATEGORY && selectedCategories?.length) {\n queryArgs[categoryKey] = selectedCategories.map((category) => category.value).join(',');\n } else if (query?.CURATED && curatedItems?.length) {\n queryArgs.include = curatedItems.map((item) => item.value);\n queryArgs.orderby = 'include';\n }\n\n if (numberOfItems) {\n queryArgs.per_page = numberOfItems;\n }\n\n const records = select('core').getEntityRecords(entityType, postType, queryArgs);\n const isResolving = select('core/data').isResolving('core', 'getEntityRecords', [entityType, postType, queryArgs]);\n const isLoading = isResolving || records === undefined;\n\n return {\n records,\n isLoading,\n };\n }, [query, curatedItems, selectedCategories, categoryKey, numberOfItems, order, orderby]);\n\n return {\n records,\n isLoading,\n };\n};\n\nexport const useThemeColors = (allowedColors = []) => {\n return useSelect((select) => {\n const { getSettings } = select('core/block-editor');\n const colors = getSettings()?.colors;\n\n return allowedColors.length > 0\n ? colors?.filter((color) => allowedColors.includes(color.slug))\n : colors;\n }, []);\n};\n\nexport const useColorChange = (colors, setAttributes) => (colorValue, property) => {\n const selectedColor = colors.find(color => color.color === colorValue);\n\n setAttributes({\n [property]: selectedColor\n ? {\n value: colorValue,\n slug: selectedColor.slug,\n }\n : null,\n });\n};\n\n// TODO: refactor fn name\nexport const useLinkChange = (setAttributes) => (value, property) => {\n setAttributes({ [property]: value });\n};\n\n","import { ColorPalette } from '@wordpress/components';\nimport { useThemeColors, useColorChange } from '../utils/index';\n\nexport const ColorPaletteControl = ({ allowedColors, colorAttribute, attributeName, setAttributes }) => {\n const colors = useThemeColors(allowedColors);\n const onColorChange = useColorChange(colors, setAttributes);\n\n return (\n <ColorPalette\n colors={colors}\n value={colorAttribute?.value}\n disableCustomColors={true}\n onChange={(colorValue) => onColorChange(colorValue, attributeName)}\n />\n );\n};\n","import {\n\tMediaPlaceholder,\n\tMediaUpload,\n\tMediaUploadCheck,\n} from '@wordpress/block-editor';\nimport { Button, Icon } from '@wordpress/components';\nimport { edit as editIcon, trash as trashIcon } from '@wordpress/icons';\n\nexport const IconPicker = ({ imageId, imageUrl, imageAlt, svgCode, onSelect, onRemove }) => {\n\tconst hasImage = imageId && imageUrl;\n\tconst isSvg = hasImage && svgCode;\n\n\treturn (\n\t\t<MediaUploadCheck>\n\t\t\t<MediaUpload\n\t\t\t\tonSelect={onSelect}\n\t\t\t\tallowedTypes={['image']}\n\t\t\t\tvalue={imageId}\n\t\t\t\trender={({ open }) => {\n\t\t\t\t\treturn hasImage ? (\n\t\t\t\t\t\t<div className=\"bc-image-wrapper\">\n\t\t\t\t\t\t\t{hasImage && (\n\t\t\t\t\t\t\t\tisSvg ? (\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tclassName=\"svg-container\"\n\t\t\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: svgCode }}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<img src={imageUrl} alt={imageAlt || 'icon'} />\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t<div className=\"bc-image-wrapper__actions\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tclassName=\"bc-image-wrapper__btn bc-image-wrapper__replace-btn\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={open}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\t\t\ticon={editIcon}\n\t\t\t\t\t\t\t\t\t\tsize={20}\n\t\t\t\t\t\t\t\t\t\tclassName=\"bc-image-wrapper__btn-icon\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</Button>\n\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tclassName=\"bc-image-wrapper__btn bc-image-wrapper__remove-btn\"\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={onRemove}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\t\t\t\ticon={trashIcon}\n\t\t\t\t\t\t\t\t\t\tsize={20}\n\t\t\t\t\t\t\t\t\t\tclassName=\"bc-image-wrapper__btn-icon\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div className=\"bc-image-wrapper__overlay\" />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<MediaPlaceholder\n\t\t\t\t\t\t\ticon=\"format-image\"\n\t\t\t\t\t\t\tonSelect={onSelect}\n\t\t\t\t\t\t\tallowedTypes={['image', 'image/svg+xml']}\n\t\t\t\t\t\t\tlabels={{ title: 'Icon Image' }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t}}\n\t\t\t/>\n\t\t</MediaUploadCheck>\n\t);\n};\n","import { MediaUpload, MediaUploadCheck, MediaPlaceholder } from '@wordpress/block-editor';\nimport { Button } from '@wordpress/components';\n\nexport const ImageActions = ({\n imageId,\n imageUrl,\n imageAlt,\n placeholder = false,\n onSelectImage,\n onRemoveImage,\n className = '',\n}) => {\n const hasImage = imageId && imageUrl;\n\n return (\n <MediaUploadCheck>\n <MediaUpload\n onSelect={onSelectImage}\n allowedTypes={['image']}\n value={imageId}\n render={({ open }) => {\n return hasImage ? (\n <div className={`bc-image-wrapper ${className}`}>\n <img src={imageUrl} alt={imageAlt} onClick={open} />\n <div className=\"bc-image-wrapper__actions\">\n <Button\n className=\"bc-image-wrapper__btn bc-image-wrapper__replace-btn\"\n type=\"button\"\n onClick={open}\n >\n Replace\n </Button>\n <Button\n className=\"bc-image-wrapper__btn bc-image-wrapper__remove-btn\"\n type=\"button\"\n onClick={onRemoveImage}\n >\n Remove\n </Button>\n </div>\n <div className=\"bc-image-wrapper__overlay\" />\n </div>\n ) : placeholder ? (\n <MediaPlaceholder\n className=\"media-placeholder\"\n icon=\"format-image\"\n onSelect={onSelectImage}\n allowedTypes={['image']}\n labels={{\n title: 'Image',\n instructions: 'Upload an image file or pick one from your media library.',\n }}\n />\n ) : null;\n }}\n />\n </MediaUploadCheck>\n );\n};\n","import { BaseControl, CheckboxControl } from '@wordpress/components';\nimport { URLInput } from '@wordpress/block-editor';\nimport { useLinkChange } from '../utils/index';\n\n// TODO: refactor props names\nexport const LinkControl = ({\n buttonSource,\n isButtonOpenInNewTab,\n setAttributes,\n}) => {\n const onLinkChange = useLinkChange(setAttributes);\n\n return (\n <>\n <BaseControl label=\"Source\">\n <URLInput\n className=\"bc-url-input\"\n value={buttonSource}\n // TODO: this doesn't work if the attribute has a different name\n onChange={(newUrl) => onLinkChange(newUrl, 'buttonSource')}\n />\n </BaseControl>\n <CheckboxControl\n checked={isButtonOpenInNewTab}\n label=\"Open in a new tab\"\n onChange={(newIsOpenInNewTab) =>\n onLinkChange(newIsOpenInNewTab, 'isButtonOpenInNewTab')}\n />\n </>\n );\n};\n","import { Button } from '@wordpress/components';\nimport { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';\n\nexport const BCImageRenderer = ({\n imageId,\n imageUrl,\n onImageClick,\n onRemoveClick,\n onSelectClick,\n}) => {\n return imageId && imageUrl ? (\n <>\n <div className=\"bc-selected-media-wrapper\">\n <img\n src={imageUrl}\n className=\"bc-selected-media bc-selected-media--image\"\n alt=\"Selected Image\"\n onClick={onImageClick}\n />\n </div>\n\n <Button\n className=\"bc-remove-btn\"\n onClick={onRemoveClick}\n isSecondary\n isDestructive\n >\n Remove Image\n </Button>\n </>\n ) : (\n <Button\n variant=\"secondary\"\n onClick={onSelectClick}\n className=\"bc-select-btn\"\n >\n Select Image\n </Button>\n );\n};\n\nexport const BCVideoRenderer = ({\n videoId,\n videoUrl,\n onRemoveClick,\n onSelectClick,\n}) => {\n return videoId && videoUrl ? (\n <>\n <div className=\"bc-selected-media-wrapper\">\n <video src={videoUrl} className=\"bc-selected-media bc-selected-media--video\" controls />\n </div>\n\n <Button\n className=\"bc-remove-btn\"\n onClick={onRemoveClick}\n isSecondary\n isDestructive\n >\n Remove Video\n </Button>\n </>\n ) : (\n <Button\n variant=\"secondary\"\n onClick={onSelectClick}\n className=\"bc-select-btn\"\n >\n Select Video\n </Button>\n );\n};\n\nconst MEDIA_TYPES = {\n IMAGE: 'image',\n VIDEO: 'video',\n};\n\nexport const BCMediaPicker = ({\n mediaId,\n mediaUrl,\n onSelect,\n onRemove,\n type = MEDIA_TYPES.IMAGE,\n ...other\n}) => {\n if (type === MEDIA_TYPES.IMAGE) {\n return (\n <MediaUploadCheck>\n <MediaUpload\n onSelect={onSelect}\n allowedTypes={['image', 'image/svg+xml']}\n accept=\"image/*\"\n value={mediaId}\n render={({ open }) => (\n <BCImageRenderer\n imageId={mediaId}\n imageUrl={mediaUrl}\n onImageClick={open}\n onSelectClick={open}\n onRemoveClick={onRemove}\n />\n )}\n { ...other }\n />\n </MediaUploadCheck>\n );\n } else if (type === MEDIA_TYPES.VIDEO) {\n return (\n <MediaUploadCheck>\n <MediaUpload\n onSelect={onSelect}\n allowedTypes={['video']}\n value={mediaId}\n render={({ open }) => (\n <BCVideoRenderer\n videoId={mediaId}\n videoUrl={mediaUrl}\n onSelectClick={open}\n onRemoveClick={onRemove}\n />\n )}\n { ...other }\n />\n </MediaUploadCheck>\n );\n } else {\n throw new Error('Unrecognized media type.');\n }\n};\n","import { ToggleControl } from '@wordpress/components';\n\nexport const PreviewToggle = ({ attributes, setAttributes, disabled }) => {\n const { isPreview } = attributes;\n\n // TODO: useState instead of attributes\n const handlePreviewChange = () => {\n setAttributes({ isPreview: !isPreview });\n };\n\n // TODO: <BlockControls> will be duplicated if the parent block has the another one <BlockControls>\n return (\n <>\n <ToggleControl\n label=\"Enable Preview\"\n help=\"Please check this option to see how the block will actually look and behave on the frontend.\"\n checked={isPreview}\n onChange={handlePreviewChange}\n disabled={disabled}\n />\n </>\n );\n};\n"],"names":["factory","exports","charMap","JSON","parse","locales","replace","string","options","Error","locale","replacement","undefined","trim","slug","normalize","split","reduce","result","ch","appendChar","remove","strict","lower","toLowerCase","extend","customMap","Object","assign","module","loadSelectOptions","async","inputValue","postType","mapper","arguments","length","response","apiFetch","path","concat","encodeURIComponent","map","post","_post$title","tempElement","document","createElement","innerHTML","title","rendered","value","id","label","textContent","innerText","useParentBlock","selectedBlockId","parentBlockName","useSelect","select","getBlock","getBlockRootClientId","getBlockHierarchyRootClientId","rootBlockId","includeSelf","currentBlockId","currentBlock","name","parentBlockId","parentBlock","getSlug","slugify","cleanSvgString","svgString","startsWith","endOfXml","indexOf","substring","SVG_MIME_TYPE","getImage","isSvg","mediaData","mime","mime_type","imagePayload","imageUrl","svgCode","width","height","fetch","url","then","text","getPhoneNumber","phone","formatted","match","getLocationAddress","location","street_number","street_name","city","state_short","post_code","addressParts","push","statePostalParts","statePostal","join","useSlider","isPreview","items","setup","ref","useRef","useEffect","instance","current","_instance","destroy","useEntityRecords","entityType","query","curatedItems","selectedCategories","categoryKey","numberOfItems","order","orderby","records","isLoading","queryArgs","_embed","LATEST_BY_CATEGORY","BY_CATEGORY","category","CURATED","include","item","per_page","getEntityRecords","isResolving","useThemeColors","allowedColors","_getSettings","getSettings","colors","filter","color","includes","useColorChange","setAttributes","colorValue","property","selectedColor","find","useLinkChange","ColorPaletteControl","_ref","colorAttribute","attributeName","onColorChange","_jsx","ColorPalette","disableCustomColors","onChange","IconPicker","imageId","imageAlt","onSelect","onRemove","hasImage","MediaUploadCheck","children","MediaUpload","allowedTypes","render","_ref2","open","_jsxs","className","dangerouslySetInnerHTML","__html","src","alt","Button","type","onClick","Icon","icon","editIcon","size","trashIcon","MediaPlaceholder","labels","ImageActions","placeholder","onSelectImage","onRemoveImage","instructions","LinkControl","buttonSource","isButtonOpenInNewTab","onLinkChange","_Fragment","BaseControl","URLInput","newUrl","CheckboxControl","checked","newIsOpenInNewTab","BCImageRenderer","onImageClick","onRemoveClick","onSelectClick","isSecondary","isDestructive","variant","BCVideoRenderer","videoId","videoUrl","controls","MEDIA_TYPES","IMAGE","VIDEO","BCMediaPicker","_ref3","mediaId","mediaUrl","other","accept","_ref4","_ref5","PreviewToggle","attributes","disabled","ToggleControl","help","handlePreviewChange"],"mappings":"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","x_google_ignoreList":[0]}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@secretstache/wordpress-gutenberg",
3
+ "version": "0.1.2",
4
+ "description": "",
5
+ "author": "Secret Stache",
6
+ "license": "GPL-2.0-or-later",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/secretstache/wordpress-gutenberg"
10
+ },
11
+ "engines": {
12
+ "node": ">=20"
13
+ },
14
+ "main": "build/index.js",
15
+ "type": "module",
16
+ "scripts": {
17
+ "build": "rollup -c",
18
+ "start": "rollup -c -w",
19
+ "prepublishOnly": "yarn build"
20
+ },
21
+ "devDependencies": {
22
+ "@babel/core": "^7.24.4",
23
+ "@babel/plugin-transform-runtime": "^7.24.3",
24
+ "@babel/preset-env": "^7.24.4",
25
+ "@babel/preset-react": "^7.24.1",
26
+ "@babel/runtime": "^7.24.4",
27
+ "@rollup/plugin-babel": "^6.0.4",
28
+ "@rollup/plugin-commonjs": "^25.0.7",
29
+ "@rollup/plugin-node-resolve": "^15.2.3",
30
+ "@rollup/plugin-terser": "^0.4.4",
31
+ "@wordpress/api-fetch": "^6.52.0",
32
+ "@wordpress/block-editor": "^12.22.0",
33
+ "@wordpress/components": "^27.2.0",
34
+ "@wordpress/data": "^9.24.0",
35
+ "@wordpress/element": "^5.32.0",
36
+ "@wordpress/icons": "^9.45.0",
37
+ "babel-core": "^6.26.3",
38
+ "babel-loader": "^9.1.3",
39
+ "rollup": "^4.16.4",
40
+ "rollup-plugin-peer-deps-external": "^2.2.4"
41
+ },
42
+ "dependencies": {
43
+ "slugify": "^1.6.6"
44
+ },
45
+ "peerDependencies": {
46
+ "@wordpress/api-fetch": "^6.52.0",
47
+ "@wordpress/block-editor": "^12.22.0",
48
+ "@wordpress/components": "^27.2.0",
49
+ "@wordpress/data": "^9.24.0",
50
+ "@wordpress/element": "^5.32.0",
51
+ "@wordpress/icons": "^9.45.0",
52
+ "react": "^18.0.0",
53
+ "react-dom": "^18.0.0"
54
+ },
55
+ "browserslist": [
56
+ "> 0.2%",
57
+ "not dead",
58
+ "not ie <= 11",
59
+ "not op_mini all"
60
+ ],
61
+ "publishConfig": {
62
+ "access": "public"
63
+ }
64
+ }
@@ -0,0 +1,40 @@
1
+ import resolve from '@rollup/plugin-node-resolve';
2
+ import commonjs from '@rollup/plugin-commonjs';
3
+ import babel from '@rollup/plugin-babel';
4
+ import terser from '@rollup/plugin-terser';
5
+ import external from 'rollup-plugin-peer-deps-external';
6
+
7
+ export default {
8
+ input: './src/index.js',
9
+ output: {
10
+ dir: 'build',
11
+ format: 'es',
12
+ exports: 'named',
13
+ sourcemap: true,
14
+ },
15
+ plugins: [
16
+ external(),
17
+ babel({
18
+ babelHelpers: 'runtime',
19
+ exclude: /node_modules/,
20
+ presets: [
21
+ '@babel/preset-env',
22
+ ['@babel/preset-react', {
23
+ runtime: 'automatic',
24
+ }],
25
+ ],
26
+ plugins: [
27
+ ['@babel/plugin-transform-runtime', {
28
+ helpers: true,
29
+ regenerator: true,
30
+ }],
31
+ ],
32
+ extensions: ['.js', '.jsx'],
33
+ }),
34
+ commonjs({
35
+ extensions: ['.js', '.jsx'],
36
+ }),
37
+ resolve({ extensions: ['.js', '.jsx'] }),
38
+ terser(),
39
+ ],
40
+ };
@@ -0,0 +1,16 @@
1
+ import { ColorPalette } from '@wordpress/components';
2
+ import { useThemeColors, useColorChange } from '../utils/index';
3
+
4
+ export const ColorPaletteControl = ({ allowedColors, colorAttribute, attributeName, setAttributes }) => {
5
+ const colors = useThemeColors(allowedColors);
6
+ const onColorChange = useColorChange(colors, setAttributes);
7
+
8
+ return (
9
+ <ColorPalette
10
+ colors={colors}
11
+ value={colorAttribute?.value}
12
+ disableCustomColors={true}
13
+ onChange={(colorValue) => onColorChange(colorValue, attributeName)}
14
+ />
15
+ );
16
+ };
@@ -0,0 +1,73 @@
1
+ import {
2
+ MediaPlaceholder,
3
+ MediaUpload,
4
+ MediaUploadCheck,
5
+ } from '@wordpress/block-editor';
6
+ import { Button, Icon } from '@wordpress/components';
7
+ import { edit as editIcon, trash as trashIcon } from '@wordpress/icons';
8
+
9
+ export const IconPicker = ({ imageId, imageUrl, imageAlt, svgCode, onSelect, onRemove }) => {
10
+ const hasImage = imageId && imageUrl;
11
+ const isSvg = hasImage && svgCode;
12
+
13
+ return (
14
+ <MediaUploadCheck>
15
+ <MediaUpload
16
+ onSelect={onSelect}
17
+ allowedTypes={['image']}
18
+ value={imageId}
19
+ render={({ open }) => {
20
+ return hasImage ? (
21
+ <div className="bc-image-wrapper">
22
+ {hasImage && (
23
+ isSvg ? (
24
+ <div
25
+ className="svg-container"
26
+ dangerouslySetInnerHTML={{ __html: svgCode }}
27
+ />
28
+ ) : (
29
+ <img src={imageUrl} alt={imageAlt || 'icon'} />
30
+ )
31
+ )}
32
+
33
+ <div className="bc-image-wrapper__actions">
34
+ <Button
35
+ className="bc-image-wrapper__btn bc-image-wrapper__replace-btn"
36
+ type="button"
37
+ onClick={open}
38
+ >
39
+ <Icon
40
+ icon={editIcon}
41
+ size={20}
42
+ className="bc-image-wrapper__btn-icon"
43
+ />
44
+ </Button>
45
+
46
+ <Button
47
+ className="bc-image-wrapper__btn bc-image-wrapper__remove-btn"
48
+ type="button"
49
+ onClick={onRemove}
50
+ >
51
+ <Icon
52
+ icon={trashIcon}
53
+ size={20}
54
+ className="bc-image-wrapper__btn-icon"
55
+ />
56
+ </Button>
57
+ </div>
58
+
59
+ <div className="bc-image-wrapper__overlay" />
60
+ </div>
61
+ ) : (
62
+ <MediaPlaceholder
63
+ icon="format-image"
64
+ onSelect={onSelect}
65
+ allowedTypes={['image', 'image/svg+xml']}
66
+ labels={{ title: 'Icon Image' }}
67
+ />
68
+ );
69
+ }}
70
+ />
71
+ </MediaUploadCheck>
72
+ );
73
+ };
@@ -0,0 +1,59 @@
1
+ import { MediaUpload, MediaUploadCheck, MediaPlaceholder } from '@wordpress/block-editor';
2
+ import { Button } from '@wordpress/components';
3
+
4
+ export const ImageActions = ({
5
+ imageId,
6
+ imageUrl,
7
+ imageAlt,
8
+ placeholder = false,
9
+ onSelectImage,
10
+ onRemoveImage,
11
+ className = '',
12
+ }) => {
13
+ const hasImage = imageId && imageUrl;
14
+
15
+ return (
16
+ <MediaUploadCheck>
17
+ <MediaUpload
18
+ onSelect={onSelectImage}
19
+ allowedTypes={['image']}
20
+ value={imageId}
21
+ render={({ open }) => {
22
+ return hasImage ? (
23
+ <div className={`bc-image-wrapper ${className}`}>
24
+ <img src={imageUrl} alt={imageAlt} onClick={open} />
25
+ <div className="bc-image-wrapper__actions">
26
+ <Button
27
+ className="bc-image-wrapper__btn bc-image-wrapper__replace-btn"
28
+ type="button"
29
+ onClick={open}
30
+ >
31
+ Replace
32
+ </Button>
33
+ <Button
34
+ className="bc-image-wrapper__btn bc-image-wrapper__remove-btn"
35
+ type="button"
36
+ onClick={onRemoveImage}
37
+ >
38
+ Remove
39
+ </Button>
40
+ </div>
41
+ <div className="bc-image-wrapper__overlay" />
42
+ </div>
43
+ ) : placeholder ? (
44
+ <MediaPlaceholder
45
+ className="media-placeholder"
46
+ icon="format-image"
47
+ onSelect={onSelectImage}
48
+ allowedTypes={['image']}
49
+ labels={{
50
+ title: 'Image',
51
+ instructions: 'Upload an image file or pick one from your media library.',
52
+ }}
53
+ />
54
+ ) : null;
55
+ }}
56
+ />
57
+ </MediaUploadCheck>
58
+ );
59
+ };
@@ -0,0 +1,31 @@
1
+ import { BaseControl, CheckboxControl } from '@wordpress/components';
2
+ import { URLInput } from '@wordpress/block-editor';
3
+ import { useLinkChange } from '../utils/index';
4
+
5
+ // TODO: refactor props names
6
+ export const LinkControl = ({
7
+ buttonSource,
8
+ isButtonOpenInNewTab,
9
+ setAttributes,
10
+ }) => {
11
+ const onLinkChange = useLinkChange(setAttributes);
12
+
13
+ return (
14
+ <>
15
+ <BaseControl label="Source">
16
+ <URLInput
17
+ className="bc-url-input"
18
+ value={buttonSource}
19
+ // TODO: this doesn't work if the attribute has a different name
20
+ onChange={(newUrl) => onLinkChange(newUrl, 'buttonSource')}
21
+ />
22
+ </BaseControl>
23
+ <CheckboxControl
24
+ checked={isButtonOpenInNewTab}
25
+ label="Open in a new tab"
26
+ onChange={(newIsOpenInNewTab) =>
27
+ onLinkChange(newIsOpenInNewTab, 'isButtonOpenInNewTab')}
28
+ />
29
+ </>
30
+ );
31
+ };
@@ -0,0 +1,130 @@
1
+ import { Button } from '@wordpress/components';
2
+ import { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';
3
+
4
+ export const BCImageRenderer = ({
5
+ imageId,
6
+ imageUrl,
7
+ onImageClick,
8
+ onRemoveClick,
9
+ onSelectClick,
10
+ }) => {
11
+ return imageId && imageUrl ? (
12
+ <>
13
+ <div className="bc-selected-media-wrapper">
14
+ <img
15
+ src={imageUrl}
16
+ className="bc-selected-media bc-selected-media--image"
17
+ alt="Selected Image"
18
+ onClick={onImageClick}
19
+ />
20
+ </div>
21
+
22
+ <Button
23
+ className="bc-remove-btn"
24
+ onClick={onRemoveClick}
25
+ isSecondary
26
+ isDestructive
27
+ >
28
+ Remove Image
29
+ </Button>
30
+ </>
31
+ ) : (
32
+ <Button
33
+ variant="secondary"
34
+ onClick={onSelectClick}
35
+ className="bc-select-btn"
36
+ >
37
+ Select Image
38
+ </Button>
39
+ );
40
+ };
41
+
42
+ export const BCVideoRenderer = ({
43
+ videoId,
44
+ videoUrl,
45
+ onRemoveClick,
46
+ onSelectClick,
47
+ }) => {
48
+ return videoId && videoUrl ? (
49
+ <>
50
+ <div className="bc-selected-media-wrapper">
51
+ <video src={videoUrl} className="bc-selected-media bc-selected-media--video" controls />
52
+ </div>
53
+
54
+ <Button
55
+ className="bc-remove-btn"
56
+ onClick={onRemoveClick}
57
+ isSecondary
58
+ isDestructive
59
+ >
60
+ Remove Video
61
+ </Button>
62
+ </>
63
+ ) : (
64
+ <Button
65
+ variant="secondary"
66
+ onClick={onSelectClick}
67
+ className="bc-select-btn"
68
+ >
69
+ Select Video
70
+ </Button>
71
+ );
72
+ };
73
+
74
+ const MEDIA_TYPES = {
75
+ IMAGE: 'image',
76
+ VIDEO: 'video',
77
+ };
78
+
79
+ export const BCMediaPicker = ({
80
+ mediaId,
81
+ mediaUrl,
82
+ onSelect,
83
+ onRemove,
84
+ type = MEDIA_TYPES.IMAGE,
85
+ ...other
86
+ }) => {
87
+ if (type === MEDIA_TYPES.IMAGE) {
88
+ return (
89
+ <MediaUploadCheck>
90
+ <MediaUpload
91
+ onSelect={onSelect}
92
+ allowedTypes={['image', 'image/svg+xml']}
93
+ accept="image/*"
94
+ value={mediaId}
95
+ render={({ open }) => (
96
+ <BCImageRenderer
97
+ imageId={mediaId}
98
+ imageUrl={mediaUrl}
99
+ onImageClick={open}
100
+ onSelectClick={open}
101
+ onRemoveClick={onRemove}
102
+ />
103
+ )}
104
+ { ...other }
105
+ />
106
+ </MediaUploadCheck>
107
+ );
108
+ } else if (type === MEDIA_TYPES.VIDEO) {
109
+ return (
110
+ <MediaUploadCheck>
111
+ <MediaUpload
112
+ onSelect={onSelect}
113
+ allowedTypes={['video']}
114
+ value={mediaId}
115
+ render={({ open }) => (
116
+ <BCVideoRenderer
117
+ videoId={mediaId}
118
+ videoUrl={mediaUrl}
119
+ onSelectClick={open}
120
+ onRemoveClick={onRemove}
121
+ />
122
+ )}
123
+ { ...other }
124
+ />
125
+ </MediaUploadCheck>
126
+ );
127
+ } else {
128
+ throw new Error('Unrecognized media type.');
129
+ }
130
+ };
@@ -0,0 +1,23 @@
1
+ import { ToggleControl } from '@wordpress/components';
2
+
3
+ export const PreviewToggle = ({ attributes, setAttributes, disabled }) => {
4
+ const { isPreview } = attributes;
5
+
6
+ // TODO: useState instead of attributes
7
+ const handlePreviewChange = () => {
8
+ setAttributes({ isPreview: !isPreview });
9
+ };
10
+
11
+ // TODO: <BlockControls> will be duplicated if the parent block has the another one <BlockControls>
12
+ return (
13
+ <>
14
+ <ToggleControl
15
+ label="Enable Preview"
16
+ help="Please check this option to see how the block will actually look and behave on the frontend."
17
+ checked={isPreview}
18
+ onChange={handlePreviewChange}
19
+ disabled={disabled}
20
+ />
21
+ </>
22
+ );
23
+ };
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { ColorPaletteControl } from './components/ColorPaletteControl';
2
+ export { IconPicker } from './components/IconPicker';
3
+ export { ImageActions } from './components/ImageActions';
4
+ export { LinkControl } from './components/LinkControl';
5
+ export { BCImageRenderer, BCVideoRenderer, BCMediaPicker } from './components/MediaPicker';
6
+ export { PreviewToggle } from './components/PreviewToggle';
7
+
8
+ export * from './utils';
@@ -0,0 +1,269 @@
1
+ import apiFetch from '@wordpress/api-fetch';
2
+ import { useSelect } from '@wordpress/data';
3
+ import { useEffect, useRef } from '@wordpress/element';
4
+ import slugify from 'slugify';
5
+
6
+ export const loadSelectOptions = async (inputValue, postType, mapper = null) => {
7
+ const response = await apiFetch({
8
+ path: `/wp/v2/${postType}?search=${encodeURIComponent(inputValue)}`,
9
+ });
10
+
11
+ if (mapper) {
12
+ return response?.map(mapper);
13
+ } else {
14
+ return response?.map((post) => {
15
+ // Create a temporary DOM element to decode HTML entities
16
+ const tempElement = document.createElement('div');
17
+ tempElement.innerHTML = post?.title?.rendered;
18
+
19
+ return {
20
+ value: post.id,
21
+ label: tempElement.textContent || tempElement.innerText || '',
22
+ };
23
+ });
24
+ }
25
+ };
26
+
27
+ /**
28
+ * Hook to find a parent block of a specific type, optionally scoped within a certain root block.
29
+ *
30
+ * @param {string} selectedBlockId - The clientId of the currently selected block.
31
+ * @param {string} parentBlockName - The block type name to search for as a parent.
32
+ * @param {Object} options - Optional settings for the search.
33
+ * @param {string} [options.rootBlockId] - The clientId of the block to limit the search within. If not provided, searches the entire block tree.
34
+ * @param {boolean} [options.includeSelf] - Whether to include the selected block itself if it matches the parentBlockName.
35
+ * @returns {Object|null} The matching parent block, or null if none is found.
36
+ */
37
+ export const useParentBlock = (selectedBlockId, parentBlockName, options = {}) => {
38
+ return useSelect((select) => {
39
+ const { getBlock, getBlockRootClientId, getBlockHierarchyRootClientId } = select('core/block-editor');
40
+
41
+ if (!selectedBlockId) {
42
+ return null;
43
+ }
44
+
45
+ // Destructure with default values to handle optional parameters.
46
+ const { rootBlockId = '', includeSelf = false } = options;
47
+
48
+ // If rootBlockId is provided, verify the selected block is within its scope.
49
+ if (rootBlockId) {
50
+ const hierarchyRootClientId = getBlockHierarchyRootClientId(selectedBlockId);
51
+ if (hierarchyRootClientId !== rootBlockId) {
52
+ return null; // The selected block is out of the scope of the root block.
53
+ }
54
+ }
55
+
56
+ let currentBlockId = selectedBlockId;
57
+ let currentBlock = getBlock(currentBlockId);
58
+
59
+ // Optionally include the selected block if it matches the target type.
60
+ if (includeSelf && currentBlock?.name === parentBlockName) {
61
+ return currentBlock;
62
+ }
63
+
64
+ let parentBlockId = getBlockRootClientId(currentBlockId);
65
+ let parentBlock = getBlock(parentBlockId);
66
+
67
+ // Traverse up the hierarchy to find the target parent block.
68
+ while (parentBlock && (rootBlockId ? parentBlockId !== rootBlockId : true) && parentBlockId) {
69
+ if (parentBlock.name === parentBlockName) {
70
+ return parentBlock; // Target parent found.
71
+ }
72
+ currentBlockId = parentBlockId;
73
+ parentBlockId = getBlockRootClientId(currentBlockId);
74
+ parentBlock = getBlock(parentBlockId);
75
+ }
76
+
77
+ return null; // No matching parent found within the constraints.
78
+ }, [selectedBlockId, parentBlockName, options.rootBlockId, options.includeSelf]);
79
+ };
80
+
81
+ export const getSlug = (name) => slugify(name, {
82
+ replacement: '-',
83
+ lower: true,
84
+ strict: true,
85
+ });
86
+
87
+ export const cleanSvgString = (svgString) => {
88
+ if (svgString.startsWith('<?xml')) {
89
+ const endOfXml = svgString.indexOf('?>');
90
+
91
+ if (endOfXml !== -1) {
92
+ svgString = svgString.substring(endOfXml + 2);
93
+ }
94
+ }
95
+
96
+ svgString = svgString.trim();
97
+
98
+ return svgString;
99
+ };
100
+
101
+
102
+ const SVG_MIME_TYPE = 'image/svg+xml';
103
+
104
+ export const getImage = async (mediaData) => {
105
+ const isSvg = mediaData?.mime === SVG_MIME_TYPE || mediaData?.mime_type === SVG_MIME_TYPE;
106
+ const imagePayload = {
107
+ isSvg,
108
+ imageUrl: null,
109
+ svgCode: null,
110
+ width: mediaData?.width,
111
+ height: mediaData?.height,
112
+ };
113
+
114
+ if (isSvg) {
115
+ imagePayload.svgCode = await fetch(mediaData.url).then(response => response.text()).then(cleanSvgString);
116
+ } else {
117
+ imagePayload.imageUrl = mediaData?.url;
118
+ }
119
+
120
+ return imagePayload;
121
+ };
122
+
123
+ export const getPhoneNumber = (phone) => {
124
+ if (!phone) return '';
125
+
126
+ let formatted = phone;
127
+
128
+ const pattern = /^\+\d(\d{3})(\d{3})(\d{4})$/;
129
+ const match = phone.match(pattern);
130
+
131
+ if (match) {
132
+ formatted = `${match[1]}-${match[2]}-${match[3]}`;
133
+ }
134
+
135
+ return formatted;
136
+ };
137
+
138
+ export const getLocationAddress = (location) => {
139
+ const {
140
+ street_number = '',
141
+ street_name = '',
142
+ city = '',
143
+ state_short = '',
144
+ post_code = '',
145
+ } = location;
146
+
147
+ // Start with the street number and name, trimming to remove extra spaces if one is missing
148
+ let addressParts = [`${street_number} ${street_name}`.trim()];
149
+
150
+ // Add the city with a line break, but only if there is a city name.
151
+ if (city) {
152
+ addressParts.push(`<br>${city}`);
153
+ }
154
+
155
+ // Combine state and postal code intelligently, adding only if they exist
156
+ let statePostalParts = [];
157
+ if (state_short) statePostalParts.push(state_short);
158
+ if (post_code) statePostalParts.push(post_code);
159
+ let statePostal = statePostalParts.join(' ');
160
+
161
+ if (statePostal) {
162
+ // Add a comma only if there's something before this part
163
+ addressParts.push(`${addressParts.length > 0 ? ', ' : ''}${statePostal}`);
164
+ }
165
+
166
+ return addressParts.join('');
167
+ };
168
+
169
+ //for package
170
+
171
+ export const useSlider = (isPreview, items, setup) => {
172
+ const ref = useRef(null);
173
+
174
+ useEffect(() => {
175
+ let instance;
176
+
177
+ if (isPreview && items?.length && ref?.current) {
178
+ instance = setup(ref.current);
179
+ }
180
+
181
+ return () => {
182
+ instance?.destroy();
183
+ };
184
+ }, [isPreview, items]);
185
+
186
+ return ref;
187
+ };
188
+
189
+
190
+ export const useEntityRecords = (entityType, postType, options) => {
191
+ const {
192
+ query,
193
+ curatedItems,
194
+ selectedCategories,
195
+ categoryKey,
196
+ numberOfItems,
197
+ order = 'desc',
198
+ orderby = 'date',
199
+ } = options;
200
+
201
+ const {
202
+ records,
203
+ isLoading,
204
+ } = useSelect((select) => {
205
+ const queryArgs = {
206
+ order,
207
+ orderby,
208
+ _embed: true,
209
+ };
210
+
211
+ // TODO: refactor
212
+ if (query?.LATEST_BY_CATEGORY && selectedCategories?.length) {
213
+ queryArgs[categoryKey] = selectedCategories.join(',');
214
+ } else if (query?.BY_CATEGORY && selectedCategories?.length) {
215
+ queryArgs[categoryKey] = selectedCategories.map((category) => category.value).join(',');
216
+ } else if (query?.CURATED && curatedItems?.length) {
217
+ queryArgs.include = curatedItems.map((item) => item.value);
218
+ queryArgs.orderby = 'include';
219
+ }
220
+
221
+ if (numberOfItems) {
222
+ queryArgs.per_page = numberOfItems;
223
+ }
224
+
225
+ const records = select('core').getEntityRecords(entityType, postType, queryArgs);
226
+ const isResolving = select('core/data').isResolving('core', 'getEntityRecords', [entityType, postType, queryArgs]);
227
+ const isLoading = isResolving || records === undefined;
228
+
229
+ return {
230
+ records,
231
+ isLoading,
232
+ };
233
+ }, [query, curatedItems, selectedCategories, categoryKey, numberOfItems, order, orderby]);
234
+
235
+ return {
236
+ records,
237
+ isLoading,
238
+ };
239
+ };
240
+
241
+ export const useThemeColors = (allowedColors = []) => {
242
+ return useSelect((select) => {
243
+ const { getSettings } = select('core/block-editor');
244
+ const colors = getSettings()?.colors;
245
+
246
+ return allowedColors.length > 0
247
+ ? colors?.filter((color) => allowedColors.includes(color.slug))
248
+ : colors;
249
+ }, []);
250
+ };
251
+
252
+ export const useColorChange = (colors, setAttributes) => (colorValue, property) => {
253
+ const selectedColor = colors.find(color => color.color === colorValue);
254
+
255
+ setAttributes({
256
+ [property]: selectedColor
257
+ ? {
258
+ value: colorValue,
259
+ slug: selectedColor.slug,
260
+ }
261
+ : null,
262
+ });
263
+ };
264
+
265
+ // TODO: refactor fn name
266
+ export const useLinkChange = (setAttributes) => (value, property) => {
267
+ setAttributes({ [property]: value });
268
+ };
269
+