@eightshift/frontend-libs-tailwind 1.0.0

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.
Files changed (275) hide show
  1. package/.gitattributes +37 -0
  2. package/.github/CODEOWNERS +1 -0
  3. package/.github/CONTRIBUTING.md +17 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +10 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +10 -0
  6. package/.github/ISSUE_TEMPLATE/question.md +10 -0
  7. package/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  8. package/.github/workflows/ci.yml +31 -0
  9. package/.husky/pre-commit +1 -0
  10. package/.prettierrc +14 -0
  11. package/.stylelintrc +4 -0
  12. package/CHANGELOG.md +13 -0
  13. package/CODE_OF_CONDUCT.md +76 -0
  14. package/LICENSE +21 -0
  15. package/README.md +24 -0
  16. package/blocks/init/assets/application-admin.js +10 -0
  17. package/blocks/init/assets/application.js +13 -0
  18. package/blocks/init/assets/images/index.js +5 -0
  19. package/blocks/init/assets/scripts/application-admin.js +7 -0
  20. package/blocks/init/assets/scripts/application.js +3 -0
  21. package/blocks/init/assets/scripts/theme-colors.js +39 -0
  22. package/blocks/init/assets/styles/application-admin.css +6 -0
  23. package/blocks/init/assets/styles/application.css +3 -0
  24. package/blocks/init/src/Blocks/assets/application-blocks-editor.js +14 -0
  25. package/blocks/init/src/Blocks/assets/application-blocks-frontend.js +13 -0
  26. package/blocks/init/src/Blocks/assets/application-blocks.js +9 -0
  27. package/blocks/init/src/Blocks/assets/scripts/application-blocks-editor.js +65 -0
  28. package/blocks/init/src/Blocks/assets/scripts/application-blocks-frontend.js +24 -0
  29. package/blocks/init/src/Blocks/assets/scripts/link-section-editor.js +258 -0
  30. package/blocks/init/src/Blocks/assets/scripts/shared.js +25 -0
  31. package/blocks/init/src/Blocks/assets/styles/application-blocks-editor.css +15 -0
  32. package/blocks/init/src/Blocks/assets/styles/application-blocks-frontend.css +12 -0
  33. package/blocks/init/src/Blocks/assets/styles/application-blocks.css +0 -0
  34. package/blocks/init/src/Blocks/assets/styles/editor/editor-overrides.css +15 -0
  35. package/blocks/init/src/Blocks/assets/styles/tailwind.css +34 -0
  36. package/blocks/init/src/Blocks/components/admin-theme-options/admin-theme-options.php +20 -0
  37. package/blocks/init/src/Blocks/components/admin-theme-options/assets-admin/index.js +36 -0
  38. package/blocks/init/src/Blocks/components/admin-theme-options/assets-admin/pages/parts.js +55 -0
  39. package/blocks/init/src/Blocks/components/admin-theme-options/manifest.json +5 -0
  40. package/blocks/init/src/Blocks/components/button/assets/index.js +22 -0
  41. package/blocks/init/src/Blocks/components/button/button.php +77 -0
  42. package/blocks/init/src/Blocks/components/button/components/button-editor.js +40 -0
  43. package/blocks/init/src/Blocks/components/button/components/button-options.js +135 -0
  44. package/blocks/init/src/Blocks/components/button/manifest.json +299 -0
  45. package/blocks/init/src/Blocks/components/card/card.php +42 -0
  46. package/blocks/init/src/Blocks/components/card/components/card-editor.js +39 -0
  47. package/blocks/init/src/Blocks/components/card/components/card-options.js +56 -0
  48. package/blocks/init/src/Blocks/components/card/manifest.json +111 -0
  49. package/blocks/init/src/Blocks/components/head/head.php +52 -0
  50. package/blocks/init/src/Blocks/components/head/manifest.json +17 -0
  51. package/blocks/init/src/Blocks/components/heading/components/heading-editor.js +30 -0
  52. package/blocks/init/src/Blocks/components/heading/components/heading-options.js +62 -0
  53. package/blocks/init/src/Blocks/components/heading/heading.php +45 -0
  54. package/blocks/init/src/Blocks/components/heading/manifest.json +76 -0
  55. package/blocks/init/src/Blocks/components/hero/components/hero-editor.js +42 -0
  56. package/blocks/init/src/Blocks/components/hero/components/hero-options.js +100 -0
  57. package/blocks/init/src/Blocks/components/hero/hero.php +45 -0
  58. package/blocks/init/src/Blocks/components/hero/manifest.json +96 -0
  59. package/blocks/init/src/Blocks/components/icon/components/icon-editor.js +23 -0
  60. package/blocks/init/src/Blocks/components/icon/components/icon-options.js +65 -0
  61. package/blocks/init/src/Blocks/components/icon/icon.php +34 -0
  62. package/blocks/init/src/Blocks/components/icon/manifest.json +1234 -0
  63. package/blocks/init/src/Blocks/components/image/components/image-editor.js +65 -0
  64. package/blocks/init/src/Blocks/components/image/components/image-options.js +111 -0
  65. package/blocks/init/src/Blocks/components/image/image.php +62 -0
  66. package/blocks/init/src/Blocks/components/image/manifest.json +125 -0
  67. package/blocks/init/src/Blocks/components/list/components/list-editor.js +30 -0
  68. package/blocks/init/src/Blocks/components/list/components/list-options.js +62 -0
  69. package/blocks/init/src/Blocks/components/list/list.php +32 -0
  70. package/blocks/init/src/Blocks/components/list/manifest.json +127 -0
  71. package/blocks/init/src/Blocks/components/load-more/assets/index.js +19 -0
  72. package/blocks/init/src/Blocks/components/load-more/assets/load-more.js +147 -0
  73. package/blocks/init/src/Blocks/components/load-more/components/load-more-editor.js +14 -0
  74. package/blocks/init/src/Blocks/components/load-more/components/load-more-options.js +18 -0
  75. package/blocks/init/src/Blocks/components/load-more/load-more.php +47 -0
  76. package/blocks/init/src/Blocks/components/load-more/manifest.json +39 -0
  77. package/blocks/init/src/Blocks/components/modal/assets/index.js +27 -0
  78. package/blocks/init/src/Blocks/components/modal/manifest.json +48 -0
  79. package/blocks/init/src/Blocks/components/modal/modal.php +46 -0
  80. package/blocks/init/src/Blocks/components/paragraph/components/paragraph-editor.js +40 -0
  81. package/blocks/init/src/Blocks/components/paragraph/components/paragraph-options.js +48 -0
  82. package/blocks/init/src/Blocks/components/paragraph/manifest.json +83 -0
  83. package/blocks/init/src/Blocks/components/paragraph/paragraph.php +33 -0
  84. package/blocks/init/src/Blocks/components/post-header/manifest.json +5 -0
  85. package/blocks/init/src/Blocks/components/post-header/post-header.php +24 -0
  86. package/blocks/init/src/Blocks/components/quote/components/quote-editor.js +53 -0
  87. package/blocks/init/src/Blocks/components/quote/components/quote-options.js +29 -0
  88. package/blocks/init/src/Blocks/components/quote/manifest.json +47 -0
  89. package/blocks/init/src/Blocks/components/quote/quote.php +49 -0
  90. package/blocks/init/src/Blocks/components/share/assets/index.js +39 -0
  91. package/blocks/init/src/Blocks/components/share/components/share-editor.js +25 -0
  92. package/blocks/init/src/Blocks/components/share/components/share-options.js +112 -0
  93. package/blocks/init/src/Blocks/components/share/manifest.json +72 -0
  94. package/blocks/init/src/Blocks/components/share/share.php +66 -0
  95. package/blocks/init/src/Blocks/components/tracking-before-body-end/manifest.json +5 -0
  96. package/blocks/init/src/Blocks/components/tracking-before-body-end/tracking-before-body-end.php +9 -0
  97. package/blocks/init/src/Blocks/components/tracking-head/manifest.json +5 -0
  98. package/blocks/init/src/Blocks/components/tracking-head/tracking-head.php +9 -0
  99. package/blocks/init/src/Blocks/components/video/components/video-editor.js +74 -0
  100. package/blocks/init/src/Blocks/components/video/components/video-options.js +280 -0
  101. package/blocks/init/src/Blocks/components/video/manifest.json +116 -0
  102. package/blocks/init/src/Blocks/components/video/video.php +72 -0
  103. package/blocks/init/src/Blocks/custom/accordion/accordion-block.js +15 -0
  104. package/blocks/init/src/Blocks/custom/accordion/accordion.php +28 -0
  105. package/blocks/init/src/Blocks/custom/accordion/assets/index.js +37 -0
  106. package/blocks/init/src/Blocks/custom/accordion/components/accordion-editor.js +17 -0
  107. package/blocks/init/src/Blocks/custom/accordion/components/accordion-options.js +18 -0
  108. package/blocks/init/src/Blocks/custom/accordion/manifest.json +32 -0
  109. package/blocks/init/src/Blocks/custom/accordion-item/accordion-item-block.js +19 -0
  110. package/blocks/init/src/Blocks/custom/accordion-item/accordion-item.php +46 -0
  111. package/blocks/init/src/Blocks/custom/accordion-item/components/accordion-item-editor.js +60 -0
  112. package/blocks/init/src/Blocks/custom/accordion-item/manifest.json +69 -0
  113. package/blocks/init/src/Blocks/custom/button/button-block.js +13 -0
  114. package/blocks/init/src/Blocks/custom/button/button.php +11 -0
  115. package/blocks/init/src/Blocks/custom/button/components/button-editor.js +12 -0
  116. package/blocks/init/src/Blocks/custom/button/components/button-options.js +12 -0
  117. package/blocks/init/src/Blocks/custom/button/manifest.json +18 -0
  118. package/blocks/init/src/Blocks/custom/card/card-block.js +13 -0
  119. package/blocks/init/src/Blocks/custom/card/card.php +11 -0
  120. package/blocks/init/src/Blocks/custom/card/components/card-editor.js +12 -0
  121. package/blocks/init/src/Blocks/custom/card/components/card-options.js +15 -0
  122. package/blocks/init/src/Blocks/custom/card/manifest.json +18 -0
  123. package/blocks/init/src/Blocks/custom/carousel/assets/index.js +46 -0
  124. package/blocks/init/src/Blocks/custom/carousel/assets/navigation.js +31 -0
  125. package/blocks/init/src/Blocks/custom/carousel/assets/pagination.js +39 -0
  126. package/blocks/init/src/Blocks/custom/carousel/carousel-block.js +21 -0
  127. package/blocks/init/src/Blocks/custom/carousel/carousel.php +61 -0
  128. package/blocks/init/src/Blocks/custom/carousel/components/carousel-editor.js +25 -0
  129. package/blocks/init/src/Blocks/custom/carousel/components/carousel-options.js +47 -0
  130. package/blocks/init/src/Blocks/custom/carousel/manifest.json +130 -0
  131. package/blocks/init/src/Blocks/custom/column/column-block.js +21 -0
  132. package/blocks/init/src/Blocks/custom/column/column-hooks.js +32 -0
  133. package/blocks/init/src/Blocks/custom/column/column.php +21 -0
  134. package/blocks/init/src/Blocks/custom/column/components/column-editor.js +19 -0
  135. package/blocks/init/src/Blocks/custom/column/components/column-options.js +579 -0
  136. package/blocks/init/src/Blocks/custom/column/manifest.json +625 -0
  137. package/blocks/init/src/Blocks/custom/columns/columns-block.js +20 -0
  138. package/blocks/init/src/Blocks/custom/columns/columns.php +21 -0
  139. package/blocks/init/src/Blocks/custom/columns/components/columns-editor.js +81 -0
  140. package/blocks/init/src/Blocks/custom/columns/components/columns-options.js +104 -0
  141. package/blocks/init/src/Blocks/custom/columns/manifest.json +555 -0
  142. package/blocks/init/src/Blocks/custom/featured-content/components/featured-content-editor.js +28 -0
  143. package/blocks/init/src/Blocks/custom/featured-content/components/featured-content-options.js +239 -0
  144. package/blocks/init/src/Blocks/custom/featured-content/featured-content-block.js +13 -0
  145. package/blocks/init/src/Blocks/custom/featured-content/featured-content.php +139 -0
  146. package/blocks/init/src/Blocks/custom/featured-content/manifest.json +131 -0
  147. package/blocks/init/src/Blocks/custom/featured-content/partials/cards.php +39 -0
  148. package/blocks/init/src/Blocks/custom/group/components/group-editor.js +8 -0
  149. package/blocks/init/src/Blocks/custom/group/group-block.js +14 -0
  150. package/blocks/init/src/Blocks/custom/group/group.php +10 -0
  151. package/blocks/init/src/Blocks/custom/group/manifest.json +32 -0
  152. package/blocks/init/src/Blocks/custom/heading/components/heading-editor.js +15 -0
  153. package/blocks/init/src/Blocks/custom/heading/components/heading-options.js +38 -0
  154. package/blocks/init/src/Blocks/custom/heading/heading-block.js +13 -0
  155. package/blocks/init/src/Blocks/custom/heading/heading-transforms.js +25 -0
  156. package/blocks/init/src/Blocks/custom/heading/heading.php +15 -0
  157. package/blocks/init/src/Blocks/custom/heading/manifest.json +79 -0
  158. package/blocks/init/src/Blocks/custom/hero/components/hero-editor.js +12 -0
  159. package/blocks/init/src/Blocks/custom/hero/components/hero-options.js +14 -0
  160. package/blocks/init/src/Blocks/custom/hero/hero-block.js +13 -0
  161. package/blocks/init/src/Blocks/custom/hero/hero.php +11 -0
  162. package/blocks/init/src/Blocks/custom/hero/manifest.json +17 -0
  163. package/blocks/init/src/Blocks/custom/image/components/image-editor.js +12 -0
  164. package/blocks/init/src/Blocks/custom/image/components/image-options.js +14 -0
  165. package/blocks/init/src/Blocks/custom/image/image-block.js +13 -0
  166. package/blocks/init/src/Blocks/custom/image/image.php +11 -0
  167. package/blocks/init/src/Blocks/custom/image/manifest.json +105 -0
  168. package/blocks/init/src/Blocks/custom/list/components/list-editor.js +14 -0
  169. package/blocks/init/src/Blocks/custom/list/components/list-options.js +39 -0
  170. package/blocks/init/src/Blocks/custom/list/list-block.js +13 -0
  171. package/blocks/init/src/Blocks/custom/list/list.php +15 -0
  172. package/blocks/init/src/Blocks/custom/list/manifest.json +58 -0
  173. package/blocks/init/src/Blocks/custom/map/assets/index.js +20 -0
  174. package/blocks/init/src/Blocks/custom/map/assets/map-controller.js +42 -0
  175. package/blocks/init/src/Blocks/custom/map/assets/utils.js +161 -0
  176. package/blocks/init/src/Blocks/custom/map/components/map-components.js +403 -0
  177. package/blocks/init/src/Blocks/custom/map/components/map-editor.js +56 -0
  178. package/blocks/init/src/Blocks/custom/map/components/map-options.js +557 -0
  179. package/blocks/init/src/Blocks/custom/map/manifest.json +79 -0
  180. package/blocks/init/src/Blocks/custom/map/map-block.js +13 -0
  181. package/blocks/init/src/Blocks/custom/map/map.php +52 -0
  182. package/blocks/init/src/Blocks/custom/map/styles.css +2 -0
  183. package/blocks/init/src/Blocks/custom/modal/components/modal-editor.js +90 -0
  184. package/blocks/init/src/Blocks/custom/modal/manifest.json +51 -0
  185. package/blocks/init/src/Blocks/custom/modal/modal-block.js +14 -0
  186. package/blocks/init/src/Blocks/custom/modal/modal.php +20 -0
  187. package/blocks/init/src/Blocks/custom/paragraph/components/paragraph-editor.js +41 -0
  188. package/blocks/init/src/Blocks/custom/paragraph/components/paragraph-options.js +38 -0
  189. package/blocks/init/src/Blocks/custom/paragraph/manifest.json +79 -0
  190. package/blocks/init/src/Blocks/custom/paragraph/paragraph-block.js +13 -0
  191. package/blocks/init/src/Blocks/custom/paragraph/paragraph-transforms.js +45 -0
  192. package/blocks/init/src/Blocks/custom/paragraph/paragraph.php +15 -0
  193. package/blocks/init/src/Blocks/custom/quote/components/quote-editor.js +12 -0
  194. package/blocks/init/src/Blocks/custom/quote/components/quote-options.js +14 -0
  195. package/blocks/init/src/Blocks/custom/quote/manifest.json +17 -0
  196. package/blocks/init/src/Blocks/custom/quote/quote-block.js +13 -0
  197. package/blocks/init/src/Blocks/custom/quote/quote.php +13 -0
  198. package/blocks/init/src/Blocks/custom/share/components/share-editor.js +6 -0
  199. package/blocks/init/src/Blocks/custom/share/components/share-options.js +12 -0
  200. package/blocks/init/src/Blocks/custom/share/manifest.json +19 -0
  201. package/blocks/init/src/Blocks/custom/share/share-block.js +13 -0
  202. package/blocks/init/src/Blocks/custom/share/share.php +11 -0
  203. package/blocks/init/src/Blocks/custom/site-footer/components/site-footer-editor.js +57 -0
  204. package/blocks/init/src/Blocks/custom/site-footer/components/site-footer-options.js +106 -0
  205. package/blocks/init/src/Blocks/custom/site-footer/manifest.json +73 -0
  206. package/blocks/init/src/Blocks/custom/site-footer/site-footer-block.js +13 -0
  207. package/blocks/init/src/Blocks/custom/site-footer/site-footer.php +72 -0
  208. package/blocks/init/src/Blocks/custom/site-navigation/assets/index.js +9 -0
  209. package/blocks/init/src/Blocks/custom/site-navigation/components/site-navigation-editor.js +42 -0
  210. package/blocks/init/src/Blocks/custom/site-navigation/components/site-navigation-options.js +73 -0
  211. package/blocks/init/src/Blocks/custom/site-navigation/manifest.json +77 -0
  212. package/blocks/init/src/Blocks/custom/site-navigation/site-navigation-block.js +13 -0
  213. package/blocks/init/src/Blocks/custom/site-navigation/site-navigation.php +99 -0
  214. package/blocks/init/src/Blocks/custom/table-of-contents/assets/index.js +58 -0
  215. package/blocks/init/src/Blocks/custom/table-of-contents/components/table-of-contents-editor.js +38 -0
  216. package/blocks/init/src/Blocks/custom/table-of-contents/components/table-of-contents-options.js +32 -0
  217. package/blocks/init/src/Blocks/custom/table-of-contents/manifest.json +48 -0
  218. package/blocks/init/src/Blocks/custom/table-of-contents/table-of-contents-block.js +13 -0
  219. package/blocks/init/src/Blocks/custom/table-of-contents/table-of-contents.php +31 -0
  220. package/blocks/init/src/Blocks/custom/video/components/video-editor.js +6 -0
  221. package/blocks/init/src/Blocks/custom/video/components/video-options.js +12 -0
  222. package/blocks/init/src/Blocks/custom/video/manifest.json +105 -0
  223. package/blocks/init/src/Blocks/custom/video/video-block.js +13 -0
  224. package/blocks/init/src/Blocks/custom/video/video.php +22 -0
  225. package/blocks/init/src/Blocks/manifest.json +14 -0
  226. package/blocks/init/src/Blocks/variations/card-simple/manifest.json +17 -0
  227. package/blocks/init/src/Blocks/wrapper/components/wrapper-editor.js +12 -0
  228. package/blocks/init/src/Blocks/wrapper/components/wrapper-options.js +348 -0
  229. package/blocks/init/src/Blocks/wrapper/manifest.json +450 -0
  230. package/blocks/init/src/Blocks/wrapper/styles-editor.css +13 -0
  231. package/blocks/init/src/Blocks/wrapper/styles.css +19 -0
  232. package/blocks/init/src/Blocks/wrapper/wrapper.js +30 -0
  233. package/blocks/init/src/Blocks/wrapper/wrapper.php +34 -0
  234. package/eslint.config.mjs +3 -0
  235. package/linters/base.config.mjs +81 -0
  236. package/linters/eslint.config.mjs +4 -0
  237. package/linters/ignore-gitignored.mjs +9 -0
  238. package/linters/stylelint.config.js +146 -0
  239. package/package.json +93 -0
  240. package/readme/packages.md +74 -0
  241. package/schemas/block.json +302 -0
  242. package/schemas/component.json +240 -0
  243. package/schemas/globalManifest.json +73 -0
  244. package/schemas/variation.json +83 -0
  245. package/scripts/components/block-inserter.js +70 -0
  246. package/scripts/components/file-picker.js +243 -0
  247. package/scripts/components/index.js +6 -0
  248. package/scripts/components/link-section-editor.js +319 -0
  249. package/scripts/components/media-picker.js +86 -0
  250. package/scripts/components/server-side-render.js +37 -0
  251. package/scripts/components/settings/settings.js +48 -0
  252. package/scripts/components/settings/use-theme-options.js +52 -0
  253. package/scripts/editor/attributes.js +304 -0
  254. package/scripts/editor/colors.js +64 -0
  255. package/scripts/editor/editor.js +139 -0
  256. package/scripts/editor/fetch.js +102 -0
  257. package/scripts/editor/hooks.js +44 -0
  258. package/scripts/editor/index.js +11 -0
  259. package/scripts/editor/options.js +152 -0
  260. package/scripts/editor/registration.js +901 -0
  261. package/scripts/editor/store.js +213 -0
  262. package/scripts/editor/tailwindcss.js +224 -0
  263. package/scripts/editor/utility.js +47 -0
  264. package/scripts/helpers/breakpoints.js +48 -0
  265. package/scripts/helpers/cookies.js +65 -0
  266. package/scripts/helpers/dynamic-import.js +19 -0
  267. package/scripts/helpers/index.js +11 -0
  268. package/scripts/index.js +22 -0
  269. package/scripts/plugins/index.js +3 -0
  270. package/scripts/plugins/yoast-seo.js +70 -0
  271. package/webpack/base.mjs +138 -0
  272. package/webpack/helpers.mjs +67 -0
  273. package/webpack/index.mjs +52 -0
  274. package/webpack/production.mjs +60 -0
  275. package/webpack/project.mjs +55 -0
@@ -0,0 +1,901 @@
1
+ import React from 'react';
2
+ import { __ } from '@wordpress/i18n';
3
+ import { InnerBlocks } from '@wordpress/block-editor';
4
+ import { registerBlockType, registerBlockVariation } from '@wordpress/blocks';
5
+ import { dispatch, select } from '@wordpress/data';
6
+ import { addFilter } from '@wordpress/hooks';
7
+ import { createElement } from '@wordpress/element';
8
+ import { blockIcons } from '@eightshift/ui-components/icons';
9
+ import { STORE_NAME, setStoreGlobalWindow, setStore, setConfigFlags } from './store';
10
+ import { camelCase, kebabCase, lowerFirst, upperFirst } from '@eightshift/ui-components/utilities';
11
+
12
+ /**
13
+ * Register all Block Editor blocks using WP `registerBlockType` method.
14
+ * Due to restrictions in dynamic import using dynamic names all blocks are registered using `require.context`.
15
+ *
16
+ * @param {object} globalManifest - Must provide global blocks setting manifest.json.
17
+ * @param {function?} [wrapperComponent] - Callback function that returns a `Wrapper`.
18
+ * @param {object} wrapperManifest - `Wrapper` manifest.
19
+ * @param {function} componentsManifestPath - **Must provide `require.context` for all components `manifest.json`s.**
20
+ * @param {function} blocksManifestPath - **Must provide `require.context` for all blocks manifest.json-s.**
21
+ * @param {function} blocksEditComponentPath - **Must provide `require.context` for all blocks JavaScript files (unable to add only block edit file due to dynamic naming).**
22
+ * @param {function?} [hooksComponentPath] - Function of hooks JavaScript files in a block from `require.context`.
23
+ * @param {function?} [transformsComponentPath] - Function of transforms JavaScript files in a block from `require.context`.
24
+ * @param {function?} [deprecationsComponentPath] - Function of deprecations JavaScript files in a block from `require.context`.
25
+ * @param {function?} [overridesComponentPath] - Function of overrides JavaScript files in a block from `require.context`.
26
+ *
27
+ * @access public
28
+ *
29
+ * @returns {mixed}
30
+ *
31
+ * Usage:
32
+ * ```js
33
+ * registerBlocks(
34
+ * globalSettings,
35
+ * Wrapper,
36
+ * WrapperManifest,
37
+ * require.context('./../../components', true, /manifest.json$/),
38
+ * require.context('./../../custom', true, /manifest.json$/),
39
+ * require.context('./../../custom', true, /-block.js$/),
40
+ * require.context('./../../custom', true, /-hooks.js$/),
41
+ * require.context('./../../custom', true, /-transforms.js$/),
42
+ * require.context('./../../custom', true, /-deprecations.js$/),
43
+ * require.context('./../../custom', true, /-overrides.js$/),
44
+ * );
45
+ * ```
46
+ */
47
+
48
+ export const registerBlocks = (
49
+ globalManifest = {},
50
+ wrapperComponent = null,
51
+ wrapperManifest = {},
52
+ componentsManifestPath,
53
+ blocksManifestPath,
54
+ blocksEditComponentPath,
55
+ hooksComponentPath = null,
56
+ transformsComponentPath = null,
57
+ deprecationsComponentPath = null,
58
+ overridesComponentPath = null,
59
+ ) => {
60
+
61
+ const componentsManifest = componentsManifestPath.keys().map(componentsManifestPath);
62
+ const blocksManifests = blocksManifestPath.keys().map(blocksManifestPath);
63
+
64
+ // Set all store values.
65
+ setStore();
66
+ dispatch(STORE_NAME).setSettings(globalManifest);
67
+ dispatch(STORE_NAME).setBlocks(blocksManifests);
68
+ dispatch(STORE_NAME).setComponents(componentsManifest);
69
+ setConfigFlags();
70
+
71
+ if (select(STORE_NAME).getConfigUseWrapper()) {
72
+ dispatch(STORE_NAME).setWrapper(wrapperManifest);
73
+ }
74
+
75
+ setStoreGlobalWindow();
76
+
77
+ // Iterate blocks to register.
78
+ blocksManifests.map((blockManifest) => {
79
+ const {
80
+ active = true,
81
+ } = blockManifest;
82
+
83
+ // If block has active key set to false the block will not show in the block editor.
84
+ if (active) {
85
+ // Get Block edit component from block name and blocksEditComponentPath.
86
+ const blockComponent = getBlockEditComponent(blockManifest.blockName, blocksEditComponentPath, 'block');
87
+
88
+ // Get Block Transforms component from block name and transformsComponentPath.
89
+ if (transformsComponentPath !== null) {
90
+ const blockTransformsComponent = getBlockGenericComponent(blockManifest.blockName, transformsComponentPath, 'transforms');
91
+
92
+ if (blockTransformsComponent !== null) {
93
+ blockManifest.transforms = blockTransformsComponent;
94
+ }
95
+ }
96
+
97
+ // Get Block Deprecations component from block name and deprecationsComponentPath.
98
+ if (deprecationsComponentPath !== null) {
99
+ const blockDeprecationsComponent = getBlockGenericComponent(blockManifest.blockName, deprecationsComponentPath, 'deprecations');
100
+
101
+ if (blockDeprecationsComponent !== null) {
102
+ blockManifest.deprecated = blockDeprecationsComponent;
103
+ }
104
+ }
105
+
106
+ // Get Block Hooks component from block name and hooksComponentPath.
107
+ if (hooksComponentPath !== null) {
108
+ const blockHooksComponent = getBlockGenericComponent(blockManifest.blockName, hooksComponentPath, 'hooks');
109
+
110
+ if (blockHooksComponent !== null) {
111
+ blockHooksComponent();
112
+ }
113
+ }
114
+
115
+ // Get Block Overrides component from block name and overridesComponentPath.
116
+ if (overridesComponentPath !== null) {
117
+ const blockOverridesComponent = getBlockGenericComponent(blockManifest.blockName, overridesComponentPath, 'overrides');
118
+
119
+ if (blockOverridesComponent !== null) {
120
+ blockManifest = Object.assign(blockManifest, blockOverridesComponent); // eslint-disable-line no-param-reassign
121
+ }
122
+ }
123
+
124
+ // Pass data to registerBlock helper to get final output for registerBlockType.
125
+ const blockDetails = registerBlock(
126
+ globalManifest,
127
+ wrapperManifest,
128
+ componentsManifest,
129
+ blockManifest,
130
+ wrapperComponent,
131
+ blockComponent
132
+ );
133
+
134
+ // Format the 'deprecated' attribute details to match the format Gutenberg wants.
135
+ if (blockDetails?.options?.deprecated) {
136
+ blockDetails.options.deprecated = blockDetails.options.deprecated.map((deprecation) => {
137
+ if (deprecation?.attributes && deprecation?.migrate) {
138
+ return {
139
+ ...deprecation,
140
+ isEligible: deprecation?.isEligible ?? (() => true),
141
+ save: blockDetails.options.save,
142
+ };
143
+ }
144
+
145
+ return {
146
+ attributes: {
147
+ ...getAttributes(globalManifest, wrapperManifest, componentsManifest, blockManifest),
148
+ ...deprecation.oldAttributes,
149
+ },
150
+ migrate: (attributes) => {
151
+ return {
152
+ ...getAttributes(globalManifest, wrapperManifest, componentsManifest, blockManifest),
153
+ ...attributes,
154
+ ...deprecation.newAttributes(attributes),
155
+ };
156
+ },
157
+ // eslint-disable-next-line max-len
158
+ isEligible: deprecation?.isEligible ?? ((attributes) => Object.keys(deprecation.oldAttributes).every((v) => Object.keys(attributes).includes(v))),
159
+ save: blockDetails.options.save,
160
+ };
161
+ });
162
+ }
163
+
164
+ // Native WP method for block registration.
165
+ registerBlockType(blockDetails.blockName, blockDetails.options);
166
+ }
167
+
168
+ return null;
169
+ });
170
+
171
+ // Add icon foreground and background colors as CSS variables for later use.
172
+ const {
173
+ background: backgroundGlobal,
174
+ foreground: foregroundGlobal,
175
+ } = globalManifest;
176
+
177
+ document.documentElement.style.setProperty('--es-admin-block-icon-foreground', foregroundGlobal);
178
+ document.documentElement.style.setProperty('--es-admin-block-icon-background', backgroundGlobal);
179
+
180
+ // Set all data to the dom that is necessary for project.
181
+ if (process.env.NODE_ENV !== 'test') {
182
+ // Require set like this because some import issue with jest unit tests.
183
+ const { blocksFilterHook } = require('./hooks');
184
+
185
+ addFilter('editor.BlockListBlock', `eightshift/${select(STORE_NAME).getSettingsNamespace()}`, blocksFilterHook);
186
+ }
187
+ };
188
+
189
+ /**
190
+ * Register all Variations Editor blocks using WP `registerBlockVariation` method.
191
+ * Due to restrictions in dynamic import using dynamic names all block are register using `require.context`.
192
+ *
193
+ * @param {object} globalManifest - **Must provide global blocks setting `manifest.json`.**
194
+ * @param {function} variationsManifestPath - **Must provide require.context for all variations `manifest.json`s.**
195
+ * @param {function} [blocksManifestPath] - **require.context for all blocks `manifest.json`s.**
196
+ * @param {function?} [overridesComponentPath] - Function of overrides JavaScript files in a block from `require.context`.
197
+ *
198
+ * @access public
199
+ *
200
+ * @returns {null}
201
+ *
202
+ * Usage:
203
+ * ```js
204
+ * registerVariations(
205
+ * globalSettings,
206
+ * require.context('./../../variations', true, /manifest.json$/),
207
+ * require.context('./../../custom', true, /manifest.json$/),
208
+ * require.context('./../../variations', true, /-overrides.js$/),
209
+ * );
210
+ * ```
211
+ */
212
+ export const registerVariations = (
213
+ globalManifest = {},
214
+ variationsManifestPath,
215
+ blocksManifestPath = null,
216
+ overridesComponentPath = null,
217
+ ) => {
218
+
219
+ const variationsManifests = variationsManifestPath.keys().map(variationsManifestPath);
220
+
221
+ // Set all store values.
222
+ dispatch(STORE_NAME).setVariations(variationsManifests);
223
+
224
+ // Iterate blocks to register.
225
+ variationsManifests.map((variationManifest) => {
226
+ const {
227
+ active = true,
228
+ } = variationManifest;
229
+
230
+ // If variation has active key set to false the variation will not show in the block editor.
231
+ if (active) {
232
+ // Get Block Overrides component from block name and overridesComponentPath.
233
+ if (overridesComponentPath !== null) {
234
+ const blockOverridesComponent = getBlockGenericComponent(variationManifest.name, overridesComponentPath, 'overrides');
235
+
236
+ if (blockOverridesComponent !== null) {
237
+ variationManifest = Object.assign(variationManifest, blockOverridesComponent);// eslint-disable-line no-param-reassign
238
+ }
239
+ }
240
+
241
+ // Pass data to registerVariation helper to get final output for registerBlockVariation.
242
+ const blockDetails = registerVariation(
243
+ globalManifest,
244
+ variationManifest,
245
+ (blocksManifestPath !== null) ? blocksManifestPath.keys().map(blocksManifestPath) : []
246
+ );
247
+
248
+ // Native WP method for block registration.
249
+ registerBlockVariation(blockDetails.blockName, blockDetails.options);
250
+ }
251
+
252
+ return null;
253
+ });
254
+ };
255
+
256
+ //---------------------------------------------------------------
257
+ // Private methods
258
+
259
+ /**
260
+ * Filter array of JS paths and get the correct edit components.
261
+ *
262
+ * @param {string} blockName - Provided block name to find corresponding edit component.
263
+ * @param {function} paths - Function of all JavaScript files in a block got from require.context.
264
+ * @param {string} fileName - Block partial name.
265
+ *
266
+ * @access private
267
+ *
268
+ * @returns {function}
269
+ *
270
+ */
271
+ export const getBlockEditComponent = (blockName, paths, fileName) => {
272
+
273
+ // Create an array of all blocks file paths.
274
+ const pathsKeys = paths.keys();
275
+
276
+ // Get Block edit component from block name and pathsKeys.
277
+ const editComponent = pathsKeys.filter((filePath) => filePath === `./${blockName}/${blockName}-${fileName}.js`).map(paths)[0];
278
+
279
+ // If edit component is missing throw and error.
280
+ if (typeof editComponent === 'undefined') {
281
+ // eslint-disable-next-line max-len
282
+ throw Error(`It looks like you are missing block edit component for block: ${blockName}, please check if you have ${blockName}-block.js file in your block folder.`);
283
+ }
284
+
285
+ // No mater if class of functional component is used fetch the first item in an object.
286
+ const editCallback = editComponent[Object.keys(editComponent)[0]];
287
+
288
+ // If edit component callback is missing throw and error.
289
+ if (typeof editCallback === 'undefined') {
290
+ // eslint-disable-next-line max-len
291
+ throw Error(`It looks like you are missing block edit component for block: ${blockName}, please check if you have ${blockName}-block.js file in your block folder.`);
292
+ }
293
+
294
+ return editCallback;
295
+ };
296
+
297
+ /**
298
+ * Filter array of JS paths and get the correct transforms, hooks, etc components.
299
+ *
300
+ * @param {string} blockName - Provided block name to find corresponding edit component.
301
+ * @param {function} paths - Function of all JavaScript files in a block got from require.context.
302
+ * @param {string} fileName - Block partial name.
303
+ *
304
+ * @access private
305
+ *
306
+ * @returns {function}
307
+ *
308
+ */
309
+ export const getBlockGenericComponent = (blockName, paths, fileName) => {
310
+
311
+ // Create an array of all blocks file paths.
312
+ const pathsKeys = paths.keys();
313
+
314
+ // Get Block edit component from block name and pathsKeys.
315
+ const editComponent = pathsKeys.filter((filePath) => filePath === `./${blockName}/${blockName}-${fileName}.js`).map(paths)[0];
316
+
317
+ // If edit component is missing throw and error.
318
+ if (typeof editComponent === 'undefined') {
319
+ return null;
320
+ }
321
+
322
+ // No mater if class of functional component is used fetch the first item in an object.
323
+ return editComponent[Object.keys(editComponent)[0]];
324
+ };
325
+
326
+ /**
327
+ * Check if namespace is defined in block or in global manifest settings and return namespace.
328
+ *
329
+ * @param {object} globalManifest - Global manifest.
330
+ * @param {object} blockManifest - Block manifest.
331
+ *
332
+ * @access private
333
+ *
334
+ * @returns {string?}
335
+ */
336
+ export const getNamespace = (globalManifest, blockManifest) => {
337
+ return (typeof blockManifest.namespace === 'undefined') ? globalManifest.namespace : blockManifest.namespace;
338
+ };
339
+
340
+ /**
341
+ * Return full block name used in Block Editor with correct namespace.
342
+ *
343
+ * @param {object} globalManifest - Global manifest.
344
+ * @param {object} blockManifest - Block manifest.
345
+ *
346
+ * @access private
347
+ *
348
+ * @returns {string}
349
+ */
350
+ export const getFullBlockName = (globalManifest, blockManifest) => {
351
+ return `${getNamespace(globalManifest, blockManifest)}/${blockManifest.blockName}`;
352
+ };
353
+
354
+ /**
355
+ * Return full block name used in Block Editor with correct namespace.
356
+ *
357
+ * @param {object} globalManifest - Global manifest.
358
+ * @param {object} blockManifest - Block manifest.
359
+ *
360
+ * @access private
361
+ *
362
+ * @returns {string}
363
+ */
364
+ export const getFullBlockNameVariation = (globalManifest, blockManifest) => {
365
+ return `${getNamespace(globalManifest, blockManifest)}/${blockManifest.parentName}`;
366
+ };
367
+
368
+ /**
369
+ * Return save function based on hasInnerBlocks option of block.
370
+ *
371
+ * @param {object} blockManifest - Block manifest.
372
+ *
373
+ * @access private
374
+ *
375
+ * @returns {function} Save callback.
376
+ */
377
+ export const getSaveCallback = (blockManifest) => {
378
+ const {
379
+ hasInnerBlocks,
380
+ } = blockManifest;
381
+
382
+ if (hasInnerBlocks && typeof InnerBlocks !== 'undefined') {
383
+ return () => createElement(InnerBlocks.Content);
384
+ }
385
+
386
+ return () => null;
387
+ };
388
+
389
+ /**
390
+ * Return merge function based on existence of `mergeableAttributes` option of block.
391
+ *
392
+ * @access private
393
+ *
394
+ * @param {object} blockManifest - Block manifest.
395
+ */
396
+ export const getMergeCallback = (blockManifest) => {
397
+ const {
398
+ mergeableAttributes,
399
+ } = blockManifest;
400
+
401
+ if (mergeableAttributes) {
402
+ return (receiver, merger) => {
403
+ let outputObject = {};
404
+
405
+ for (const { attribute: attributeName, mergeStrategy } of mergeableAttributes) {
406
+ const attribute = Object.keys(receiver).find((k) => {
407
+ return k?.toLowerCase()?.includes(attributeName.toLowerCase());
408
+ });
409
+
410
+ switch (mergeStrategy) {
411
+ case "append": {
412
+ outputObject[attribute] = `${receiver[attribute] ?? ''}${merger[attribute] ?? ''}`;
413
+ break;
414
+ }
415
+ case "useDestinationAttribute": {
416
+ outputObject[attribute] = merger[attribute] ?? '';
417
+ break;
418
+ }
419
+ case "addNumericIntValue": {
420
+ outputObject[attribute] = parseInt(receiver[attribute] ?? '0') + parseInt(merger[attribute] ?? '0');
421
+ break;
422
+ }
423
+ case "addNumericFloatValue": {
424
+ outputObject[attribute] = parseFloat(receiver[attribute] ?? '0') + parseFloat(merger[attribute] ?? '0');
425
+ break;
426
+ }
427
+ /* eslint-disable no-case-declarations */
428
+ case "addNumericPixelValue": {
429
+ // Remove numbers
430
+ const receiverUnit = (receiver[attribute] ?? '0px').replace(/\d/g, '');
431
+
432
+ // Remove value labels (= everything but numbers)
433
+ const receiverValue = parseInt(receiver[attribute] ?? '0px').replace(/\D/g, '');
434
+ const mergerValue = parseInt(receiver[attribute] ?? '0px').replace(/\D/g, '');
435
+ const calculatedValue = receiverValue + mergerValue;
436
+
437
+ outputObject[attribute] = `${calculatedValue}${receiverUnit}`;
438
+ break;
439
+ }
440
+ /* eslint-enable no-case-declarations */
441
+ default: {
442
+ // "useSourceAttribute" is default
443
+ outputObject[attribute] = receiver[attribute] ?? '';
444
+ break;
445
+ }
446
+ }
447
+ }
448
+
449
+ return outputObject;
450
+ };
451
+ }
452
+
453
+ return () => null;
454
+ };
455
+
456
+ /**
457
+ * Return edit function wrapped with Wrapper component.
458
+ *
459
+ * @param {React.Component} Component - Component to render inside the wrapper.
460
+ * @param {React.Component} Wrapper - Wrapper component.
461
+ *
462
+ * @access private
463
+ *
464
+ * @returns {React.Component}
465
+ */
466
+ export const getEditCallback = (Component, Wrapper) => (props) => {
467
+ const useWrapper = select(STORE_NAME).getConfigUseWrapper();
468
+
469
+ return (
470
+ useWrapper ?
471
+ <Wrapper props={props}>
472
+ <Component {...props} />
473
+ </Wrapper> :
474
+ <Component {...props} />
475
+ );
476
+ };
477
+
478
+ /**
479
+ * Set icon object with icon, background and foreground.
480
+ *
481
+ * @param {object} globalManifest - Global manifest.
482
+ * @param {object} blockManifest - Block manifest.
483
+ *
484
+ * @access private
485
+ *
486
+ * @returns {object}
487
+ */
488
+ export const getIconOptions = (
489
+ globalManifest,
490
+ blockManifest
491
+ ) => {
492
+
493
+ const {
494
+ background: backgroundGlobal,
495
+ foreground: foregroundGlobal,
496
+ } = globalManifest;
497
+
498
+ const {
499
+ icon,
500
+ } = blockManifest;
501
+
502
+ if (typeof icon === 'undefined') {
503
+ return {};
504
+ }
505
+
506
+ // Use built-in icons if 'src' is provided and the
507
+ // icon exists in the library
508
+ if (icon.src !== undefined && blockIcons[icon.src] !== undefined) {
509
+ return {
510
+ background: (typeof icon.background === 'undefined') ? backgroundGlobal : icon.background,
511
+ foreground: (typeof icon.foreground === 'undefined') ? foregroundGlobal : icon.foreground,
512
+ src: <span dangerouslySetInnerHTML={{ __html: blockIcons[icon.src] }} />,
513
+ };
514
+ }
515
+
516
+ return {
517
+ background: (typeof icon.background === 'undefined') ? backgroundGlobal : icon.background,
518
+ foreground: (typeof icon.foreground === 'undefined') ? foregroundGlobal : icon.foreground,
519
+ src: icon.src.includes('<svg') ? <span dangerouslySetInnerHTML={{ __html: icon.src }} /> : icon.src,
520
+ };
521
+ };
522
+
523
+ /**
524
+ * Iterate over attributes or example attributes object in block/component manifest and append the parent prefixes.
525
+ *
526
+ * @param {object} manifest - Object of component/block manifest to get data from.
527
+ * @param {string} newName - New renamed component name.
528
+ * @param {string} realName - Original real component name.
529
+ * @param {boolean} [isExample=false] - Type of items to iterate, if false example key will be use, if true attributes will be used.
530
+ * @param {string} [parent=''] - Parent component key with stacked parent component names for the final output.
531
+ * @param {boolean} [currentAttributes=false] - Check if current attribute is a part of the current component.
532
+ *
533
+ * @access private
534
+ *
535
+ * @returns {object}
536
+ */
537
+ export const prepareComponentAttribute = (manifest, newName, realName, isExample = false, parent = '', currentAttributes = false) => {
538
+ const output = {};
539
+
540
+ // Define different data point for attributes or example.
541
+ const componentAttributes = isExample ? manifest?.example?.attributes : manifest?.attributes;
542
+
543
+ // It can occur that attributes or example key is missing in manifest so bailout.
544
+ if (typeof componentAttributes === 'undefined') {
545
+ return output;
546
+ }
547
+
548
+ // Prepare parent case.
549
+ const newParent = camelCase(parent);
550
+
551
+ // Iterate each attribute and attach parent prefixes.
552
+ for (const [componentAttribute] of Object.entries(componentAttributes)) {
553
+
554
+ let attribute = componentAttribute;
555
+
556
+ // If there is a attribute name switch use the new one.
557
+ if (newName !== realName) {
558
+ attribute = componentAttribute.replace(realName, newName);
559
+ }
560
+
561
+ // Check if current attribute is used strip component prefix from attribute and replace it with parent prefix.
562
+ if (currentAttributes) {
563
+ attribute = componentAttribute.replace(`${lowerFirst(camelCase(realName))}`, '');
564
+ }
565
+
566
+ // Wrapper attributes that should not be modified.
567
+ const isWrapperAttribute = attribute.startsWith('wrapper') || attribute.startsWith('showWrapper');
568
+
569
+ // Determine if parent is empty and if parent name is the same as component/block name and skip wrapper attributes.
570
+ let attributeName = isWrapperAttribute ? attribute : `${newParent}${upperFirst(attribute)}`;
571
+
572
+ // Output new attribute names.
573
+ output[attributeName] = componentAttributes[componentAttribute];
574
+ }
575
+
576
+ return output;
577
+ };
578
+
579
+ /**
580
+ * Iterate over component object in block manifest and check if the component exists in the project.
581
+ * If components contains more component this function will run recursively.
582
+ *
583
+ * @param {object} componentsManifest - Object of components manifest to iterate.
584
+ * @param {object} manifest - Object of component/block manifest to get the data from.
585
+ * @param {boolean} [isExample=false] - Type of items to iterate, if true example key will be used, if false attributes will be used.
586
+ * @param {string} [parent=''] - Parent component key with stacked parent component names for the final output.
587
+ *
588
+ * @access private
589
+ *
590
+ * @returns {object}
591
+ */
592
+ export const prepareComponentAttributes = (
593
+ componentsManifest,
594
+ manifest,
595
+ isExample = false,
596
+ parent = ''
597
+ ) => {
598
+ const output = {};
599
+
600
+ const {
601
+ components = {},
602
+ } = manifest;
603
+
604
+ // Determine if this is component or block and provide the name, not used for anything important but only to output the error msg.
605
+ const name = manifest?.blockName ? manifest.blockName : manifest.componentName;
606
+
607
+ const newParent = (parent === '') ? name : parent;
608
+
609
+ // Iterate over components key in manifest recursively and check component names.
610
+ for (let [newComponentName, realComponentName] of Object.entries(components)) {
611
+
612
+ // Filter components real name.
613
+ const [component] = componentsManifest.filter((item) => item.componentName === kebabCase(realComponentName));
614
+
615
+ // Bailout if component doesn't exist.
616
+ if (!component) {
617
+ // eslint-disable-next-line max-len
618
+ throw Error(`Component specified in "${name}" manifest doesn't exist in your components list. Please check if you project has "${realComponentName}" component.`);
619
+ }
620
+
621
+ let outputAttributes = {};
622
+
623
+ // If component has more components do recursive loop.
624
+ if (component?.components) {
625
+ // eslint-disable-next-line max-len
626
+ outputAttributes = prepareComponentAttributes(componentsManifest, component, isExample, `${newParent}${upperFirst(camelCase(newComponentName))}`);
627
+ } else {
628
+ // Output the component attributes if there is no nesting left, and append the parent prefixes.
629
+ outputAttributes = prepareComponentAttribute(component, newComponentName, realComponentName, isExample, newParent);
630
+ }
631
+
632
+ // Populate the output recursively.
633
+ Object.assign(
634
+ output,
635
+ {
636
+ ...output,
637
+ ...outputAttributes,
638
+ }
639
+ );
640
+ }
641
+
642
+ // Add the current block/component attributes to the output.
643
+ Object.assign(output, prepareComponentAttribute(manifest, '', name, isExample, newParent, true));
644
+
645
+ return output;
646
+ };
647
+
648
+ /**
649
+ * Get Block attributes combined in one: "shared, global, wrapper, components, block".
650
+ *
651
+ * @param {object} globalManifest - Global manifest.
652
+ * @param {object} wrapperManifest - `Wrapper` manifest.
653
+ * @param {object} componentsManifest - Component manifest to iterate through.
654
+ * @param {object} parentManifest - Block or component (parent) manifest.
655
+ *
656
+ * @returns {object} Object of all attributes registered for a specific block.
657
+ *
658
+ * @access private
659
+ *
660
+ * Usage:
661
+ * ```js
662
+ * getAttributes(globalManifest, wrapperManifest, componentManifests, manifest)
663
+ * ```
664
+ */
665
+ export const getAttributes = (
666
+ globalManifest,
667
+ wrapperManifest,
668
+ componentsManifest,
669
+ parentManifest
670
+ ) => {
671
+ const {
672
+ blockName,
673
+ } = parentManifest;
674
+
675
+ const {
676
+ attributes: attributesGlobal,
677
+ blockClassPrefix = 'block',
678
+ } = globalManifest;
679
+
680
+ const output = {
681
+ blockName: {
682
+ type: 'string',
683
+ default: blockName,
684
+ },
685
+ blockClientId: {
686
+ type: 'string'
687
+ },
688
+ blockTopLevelId: { // Used to pass reference to all components.
689
+ type: 'string',
690
+ default: Math.random().toString(36).slice(-6),
691
+ },
692
+ blockFullName: {
693
+ type: 'string',
694
+ default: getFullBlockName(globalManifest, parentManifest),
695
+ },
696
+ blockClass: {
697
+ type: 'string',
698
+ default: `${blockClassPrefix}-${blockName}`,
699
+ },
700
+ blockJsClass: {
701
+ type: 'string',
702
+ default: `js-${blockClassPrefix}-${blockName}`,
703
+ },
704
+ ...((typeof attributesGlobal === 'undefined') ? {} : attributesGlobal),
705
+ ...(wrapperManifest?.attributes ?? {}),
706
+ ...prepareComponentAttributes(componentsManifest, parentManifest),
707
+ };
708
+
709
+ return output;
710
+ };
711
+
712
+ /**
713
+ * Get Block example attributes combined in one: "components and block".
714
+ *
715
+ * @param {object} manifest - Block/component manifest.
716
+ * @param {string} [parent=''] - Parent component key with stacked parent component names for the final output.
717
+ *
718
+ * @returns {object}
719
+ *
720
+ * @access private
721
+ *
722
+ * Manifest:
723
+ * ```js
724
+ * {
725
+ * attributes: {
726
+ * buttonUse: {
727
+ * type: "string",
728
+ * default: true
729
+ * },
730
+ * buttonSize: {
731
+ * type: "string",
732
+ * default: "big"
733
+ * },
734
+ * buttonContent: {
735
+ * type: "string"
736
+ * },
737
+ * }
738
+ * }
739
+ * ```
740
+ *
741
+ * Usage:
742
+ * ```js
743
+ * getExample('button', manifest);
744
+ * ```
745
+ *
746
+ * Output:
747
+ * ```js
748
+ * {
749
+ * "buttonUse": true,
750
+ * "buttonSize": "big",
751
+ * "buttonContent": "",
752
+ * }
753
+ * ```
754
+ */
755
+ export const getExample = (
756
+ parent = '',
757
+ manifest = {}
758
+ ) => {
759
+ return prepareComponentAttributes(select(STORE_NAME).getComponents(), manifest, true, parent);
760
+ };
761
+
762
+ /**
763
+ * Map and prepare all options from block manifest.json file for usage in registerBlockVariation method.
764
+ *
765
+ * @param {object} globalManifest - Global manifest.
766
+ * @param {object} variationManifest - Variation manifest.
767
+ * @param {Array} blocksManifest - Blocks manifests.
768
+ *
769
+ * @access private
770
+ *
771
+ * @returns {object}
772
+ */
773
+ export const registerVariation = (
774
+ globalManifest = {},
775
+ variationManifest = {}
776
+ ) => {
777
+ const parentBlockManifest = select(STORE_NAME).getBlock(variationManifest.parentName);
778
+
779
+ // Append globalManifest data in to output.
780
+ if (variationManifest['icon']) {
781
+ variationManifest['icon'] = getIconOptions(globalManifest, variationManifest);
782
+ } else {
783
+ // There is no icon passed to variation, use it's parent icon instead
784
+ variationManifest['icon'] = parentBlockManifest?.icon;
785
+ }
786
+
787
+ // Set full example list.
788
+ if (typeof variationManifest['example'] === 'undefined') {
789
+ variationManifest['example'] = {};
790
+ }
791
+
792
+ // Set full examples list.
793
+ variationManifest['example'].viewportWidth = 800;
794
+ variationManifest['example'].attributes = {
795
+ ...parentBlockManifest?.example?.attributes,
796
+ ...variationManifest['attributes'],
797
+ ...variationManifest['example']?.attributes,
798
+ };
799
+
800
+ // This is a full block name used in Block Editor.
801
+ const fullBlockName = getFullBlockNameVariation(globalManifest, variationManifest);
802
+
803
+ return {
804
+ blockName: fullBlockName,
805
+ options: {
806
+ ...variationManifest,
807
+ blockName: fullBlockName,
808
+ },
809
+ };
810
+ };
811
+
812
+ /**
813
+ * Map and prepare all options from block manifest.json file for usage in registerBlockType method.
814
+ *
815
+ * @param {object} globalManifest - Global manifest.
816
+ * @param {object} wrapperManifest - `Wrapper` manifest.
817
+ * @param {object} componentsManifest - Manifest of all components in a single object.
818
+ * @param {object} blockManifest - Block manifest.
819
+ * @param {function} wrapperComponent - Callback function that returns a `Wrapper`.
820
+ * @param {function} blockComponent - Edit callback function.
821
+ *
822
+ * @access private
823
+ *
824
+ * @returns {object}
825
+ */
826
+ export const registerBlock = (
827
+ globalManifest = {},
828
+ wrapperManifest = {},
829
+ componentsManifest = {},
830
+ blockManifest = {},
831
+ wrapperComponent,
832
+ blockComponent
833
+ ) => {
834
+
835
+ // Block Icon option.
836
+ blockManifest['icon'] = getIconOptions(globalManifest, blockManifest);
837
+
838
+ // This is a full block name used in Block Editor.
839
+ const fullBlockName = getFullBlockName(globalManifest, blockManifest);
840
+
841
+ // Set full attributes list.
842
+ const attributes = getAttributes(globalManifest, wrapperManifest, componentsManifest, blockManifest);
843
+
844
+ blockManifest['attributes'] = {
845
+ metadata: {
846
+ type: 'object'
847
+ },
848
+ ...attributes,
849
+ };
850
+
851
+ // Set full example list.
852
+ if (typeof blockManifest['example'] === 'undefined') {
853
+ blockManifest['example'] = {};
854
+ }
855
+
856
+ // Find all attributes that have default value and output that to example.
857
+ const exampleAttributes = {};
858
+ for (const [key, value] of Object.entries(attributes)) {
859
+ if (value?.default) {
860
+ exampleAttributes[key] = value.default;
861
+ }
862
+ }
863
+
864
+ // Set full examples list.
865
+ blockManifest['example'].viewportWidth = 800;
866
+ blockManifest['example'].attributes = {
867
+ ...exampleAttributes,
868
+ ...getExample('', blockManifest),
869
+ };
870
+
871
+ return {
872
+ blockName: fullBlockName,
873
+ options: {
874
+ ...blockManifest,
875
+ blockName: fullBlockName,
876
+ edit: getEditCallback(blockComponent, wrapperComponent),
877
+ save: getSaveCallback(blockManifest),
878
+ merge: getMergeCallback(blockManifest),
879
+
880
+ // WP 6.4+ Block renaming support
881
+ __experimentalBlockRenaming: true,
882
+ __experimentalLabel: (attributes, { context }) => {
883
+ const customName = attributes?.metadata?.name ?? blockManifest?.title ?? fullBlockName;
884
+
885
+ if (context === 'visual' && customName !== blockManifest?.title) {
886
+ return `${customName} (${blockManifest?.title})`;
887
+ }
888
+
889
+ if (context === 'accessibility') {
890
+ const { content } = attributes;
891
+ return !content || content?.length === 0 ? __('Empty', 'eightshift-frontend-libs') : content;
892
+ }
893
+
894
+ return customName;
895
+ },
896
+ supports: {
897
+ __experimentalMetadata: true,
898
+ },
899
+ },
900
+ };
901
+ };