@plone/volto 17.0.0-alpha.8 → 17.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 (365) hide show
  1. package/.eslintrc +26 -3
  2. package/CHANGELOG.md +488 -5
  3. package/CONTRIBUTING.md +5 -1
  4. package/README.md +12 -9
  5. package/addon-registry.js +10 -1
  6. package/create-addons-loader.js +1 -1
  7. package/cypress/support/commands.js +70 -14
  8. package/cypress/support/e2e.js +1 -2
  9. package/cypress/support/volto-slate.js +4 -5
  10. package/cypress.config.js +1 -0
  11. package/docker-compose.yml +1 -1
  12. package/locales/ca/LC_MESSAGES/volto.po +276 -53
  13. package/locales/ca.json +1 -1
  14. package/locales/de/LC_MESSAGES/volto.po +284 -61
  15. package/locales/de.json +1 -1
  16. package/locales/en/LC_MESSAGES/volto.po +274 -51
  17. package/locales/en.json +1 -1
  18. package/locales/es/LC_MESSAGES/volto.po +313 -90
  19. package/locales/es.json +1 -1
  20. package/locales/eu/LC_MESSAGES/volto.po +275 -52
  21. package/locales/eu.json +1 -1
  22. package/locales/fi/LC_MESSAGES/volto.po +275 -52
  23. package/locales/fi.json +1 -1
  24. package/locales/fr/LC_MESSAGES/volto.po +276 -53
  25. package/locales/fr.json +1 -1
  26. package/locales/it/LC_MESSAGES/volto.po +469 -246
  27. package/locales/it.json +1 -1
  28. package/locales/ja/LC_MESSAGES/volto.po +275 -52
  29. package/locales/ja.json +1 -1
  30. package/locales/nl/LC_MESSAGES/volto.po +276 -53
  31. package/locales/nl.json +1 -1
  32. package/locales/pt/LC_MESSAGES/volto.po +276 -53
  33. package/locales/pt.json +1 -1
  34. package/locales/pt_BR/LC_MESSAGES/volto.po +309 -86
  35. package/locales/pt_BR.json +1 -1
  36. package/locales/ro/LC_MESSAGES/volto.po +276 -53
  37. package/locales/ro.json +1 -1
  38. package/locales/volto.pot +279 -52
  39. package/locales/zh_CN/LC_MESSAGES/volto.po +276 -53
  40. package/locales/zh_CN.json +1 -1
  41. package/package.json +44 -34
  42. package/packages/volto-slate/package.json +1 -1
  43. package/packages/volto-slate/src/actions/index.js +1 -1
  44. package/packages/volto-slate/src/blocks/Table/TableBlockEdit.jsx +21 -212
  45. package/packages/volto-slate/src/blocks/Table/schema.js +122 -0
  46. package/packages/volto-slate/src/blocks/Text/DefaultTextBlockEditor.jsx +8 -3
  47. package/packages/volto-slate/src/blocks/Text/TextBlockView.jsx +21 -16
  48. package/packages/volto-slate/src/blocks/Text/extensions/withDeserializers.js +3 -1
  49. package/packages/volto-slate/src/blocks/Text/index.js +10 -7
  50. package/packages/volto-slate/src/editor/config.jsx +5 -4
  51. package/packages/volto-slate/src/editor/index.js +4 -4
  52. package/packages/volto-slate/src/editor/less/slate.less +28 -0
  53. package/packages/volto-slate/src/editor/plugins/Link/render.jsx +5 -6
  54. package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
  55. package/packages/volto-slate/src/editor/plugins/StyleMenu/utils.js +14 -5
  56. package/packages/volto-slate/src/editor/render.jsx +77 -8
  57. package/packages/volto-slate/src/editor/ui/SlateContextToolbar.jsx +2 -2
  58. package/packages/volto-slate/src/editor/ui/index.js +15 -15
  59. package/packages/volto-slate/src/index.js +2 -2
  60. package/packages/volto-slate/src/utils/blocks.js +7 -0
  61. package/packages/volto-slate/src/widgets/RichTextWidget.jsx +15 -8
  62. package/razzle.config.js +4 -6
  63. package/src/actions/index.js +4 -0
  64. package/src/actions/navroot/navroot.js +16 -0
  65. package/src/actions/navroot/navroot.test.js +15 -0
  66. package/src/actions/relations/rebuild.js +7 -7
  67. package/src/actions/relations/relations.js +17 -0
  68. package/src/actions/site/site.js +16 -0
  69. package/src/actions/site/site.test.js +15 -0
  70. package/src/actions/userSession/userSession.js +17 -1
  71. package/src/components/index.js +194 -192
  72. package/src/components/manage/Actions/Actions.jsx +133 -243
  73. package/src/components/manage/Add/Add.jsx +7 -8
  74. package/src/components/manage/AnchorPlugin/index.jsx +2 -2
  75. package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +3 -1
  76. package/src/components/manage/Blocks/Block/BlocksForm.jsx +19 -2
  77. package/src/components/manage/Blocks/Block/Edit.jsx +1 -1
  78. package/src/components/manage/Blocks/Block/Settings.jsx +2 -0
  79. package/src/components/manage/Blocks/Block/Settings.test.jsx +92 -0
  80. package/src/components/manage/Blocks/Block/Style.jsx +2 -2
  81. package/src/components/manage/Blocks/Container/Data.jsx +32 -0
  82. package/src/components/manage/Blocks/Container/Edit.jsx +177 -0
  83. package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +121 -0
  84. package/src/components/manage/Blocks/Container/NewBlockAddButton.jsx +84 -0
  85. package/src/components/manage/Blocks/Container/SimpleContainerToolbar.jsx +54 -0
  86. package/src/components/manage/Blocks/Grid/Edit.jsx +47 -0
  87. package/src/components/manage/Blocks/Grid/View.jsx +43 -0
  88. package/src/components/manage/Blocks/Grid/adapter.js +14 -0
  89. package/src/components/manage/Blocks/Grid/grid-1.svg +6 -0
  90. package/src/components/manage/Blocks/Grid/grid-2.svg +9 -0
  91. package/src/components/manage/Blocks/Grid/grid-3.svg +10 -0
  92. package/src/components/manage/Blocks/Grid/grid-4.svg +11 -0
  93. package/src/components/manage/Blocks/Grid/schema.js +35 -0
  94. package/src/components/manage/Blocks/Grid/templates.js +47 -0
  95. package/src/components/manage/Blocks/HTML/Edit.jsx +8 -8
  96. package/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +36 -26
  97. package/src/components/manage/Blocks/Image/Edit.jsx +51 -12
  98. package/src/components/manage/Blocks/Image/Edit.test.jsx +2 -0
  99. package/src/components/manage/Blocks/Image/ImageSidebar.jsx +66 -16
  100. package/src/components/manage/Blocks/Image/View.jsx +26 -5
  101. package/src/components/manage/Blocks/Image/View.test.jsx +20 -0
  102. package/src/components/manage/Blocks/Image/schema.js +17 -10
  103. package/src/components/manage/Blocks/Image/utils.js +14 -0
  104. package/src/components/manage/Blocks/LeadImage/Edit.jsx +32 -10
  105. package/src/components/manage/Blocks/LeadImage/Edit.test.jsx +11 -1
  106. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +28 -9
  107. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -2
  108. package/src/components/manage/Blocks/LeadImage/View.jsx +50 -38
  109. package/src/components/manage/Blocks/LeadImage/View.test.jsx +11 -1
  110. package/src/components/manage/Blocks/Listing/DefaultTemplate.jsx +18 -3
  111. package/src/components/manage/Blocks/Listing/ListingBody.jsx +32 -8
  112. package/src/components/manage/Blocks/Listing/ListingBody.test.jsx +20 -0
  113. package/src/components/manage/Blocks/Listing/SummaryTemplate.jsx +1 -1
  114. package/src/components/manage/Blocks/Listing/getAsyncData.js +3 -5
  115. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +27 -17
  116. package/src/components/manage/Blocks/Maps/Edit.jsx +135 -209
  117. package/src/components/manage/Blocks/Maps/Edit.test.jsx +1 -2
  118. package/src/components/manage/Blocks/Maps/View.test.jsx +1 -2
  119. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +3 -2
  120. package/src/components/manage/Blocks/Search/components/Facets.jsx +66 -7
  121. package/src/components/manage/Blocks/Search/components/FilterList.jsx +4 -6
  122. package/src/components/manage/Blocks/Search/components/SearchInput.jsx +9 -2
  123. package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +2 -9
  124. package/src/components/manage/Blocks/Search/components/index.js +13 -13
  125. package/src/components/manage/Blocks/Search/hocs/index.js +2 -2
  126. package/src/components/manage/Blocks/Search/hocs/withQueryString.jsx +5 -2
  127. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +70 -36
  128. package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
  129. package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
  130. package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
  131. package/src/components/manage/Blocks/Search/schema.js +29 -14
  132. package/src/components/manage/Blocks/Table/Cell.jsx +2 -3
  133. package/src/components/manage/Blocks/Teaser/Body.jsx +0 -1
  134. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +5 -10
  135. package/src/components/manage/Blocks/Teaser/schema.js +5 -0
  136. package/src/components/manage/Blocks/Text/Edit.jsx +2 -3
  137. package/src/components/manage/Blocks/Title/View.jsx +0 -23
  138. package/src/components/manage/Blocks/Title/View.test.jsx +16 -1
  139. package/src/components/manage/Blocks/ToC/Schema.jsx +40 -7
  140. package/src/components/manage/Blocks/ToC/View.jsx +84 -14
  141. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +8 -3
  142. package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +44 -0
  143. package/src/components/manage/Blocks/ToC/variations/HorizontalMenu.jsx +149 -10
  144. package/src/components/manage/Blocks/ToC/variations/index.js +3 -1
  145. package/src/components/manage/Contents/Contents.jsx +285 -114
  146. package/src/components/manage/Contents/ContentsPropertiesModal.jsx +90 -166
  147. package/src/components/manage/Contents/ContentsRenameModal.jsx +88 -139
  148. package/src/components/manage/Contents/ContentsRenameModal.stories.jsx +61 -0
  149. package/src/components/manage/Contents/ContentsTagsModal.jsx +83 -130
  150. package/src/components/manage/Contents/ContentsTagsModal.stories.jsx +68 -0
  151. package/src/components/manage/Contents/ContentsUploadModal.jsx +11 -7
  152. package/src/components/manage/Contents/ContentsWorkflowModal.jsx +87 -154
  153. package/src/components/manage/Controlpanels/Aliases.jsx +4 -12
  154. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +65 -38
  155. package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +2 -2
  156. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +38 -13
  157. package/src/components/manage/Controlpanels/Relations/Relations.jsx +5 -5
  158. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +8 -7
  159. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +68 -68
  160. package/src/components/manage/Controlpanels/Rules/AddRule.jsx +3 -10
  161. package/src/components/manage/Controlpanels/Rules/EditRule.jsx +1 -1
  162. package/src/components/manage/Controlpanels/UndoControlpanel.jsx +6 -9
  163. package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +97 -7
  164. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +127 -99
  165. package/src/components/manage/Delete/Delete.jsx +96 -171
  166. package/src/components/manage/Diff/DiffField.jsx +25 -1
  167. package/src/components/manage/DragDropList/DragDropList.jsx +18 -13
  168. package/src/components/manage/Form/BlockDataForm.jsx +3 -2
  169. package/src/components/manage/Form/BlockDataForm.test.jsx +51 -17
  170. package/src/components/manage/Form/Form.jsx +7 -6
  171. package/src/components/manage/Form/InlineForm.test.jsx +16 -14
  172. package/src/components/manage/History/History.jsx +11 -1
  173. package/src/components/manage/LinksToItem/LinksToItem.jsx +209 -0
  174. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +100 -0
  175. package/src/components/manage/LockingToastsFactory/LockingToastsFactory.jsx +1 -2
  176. package/src/components/manage/Messages/Messages.jsx +32 -99
  177. package/src/components/manage/Messages/Messages.test.jsx +0 -1
  178. package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
  179. package/src/components/manage/Sharing/Sharing.jsx +62 -22
  180. package/src/components/manage/Sidebar/AlignBlock.jsx +1 -1
  181. package/src/components/manage/Sidebar/Sidebar.jsx +139 -220
  182. package/src/components/manage/TemplateChooser/TemplateChooser.jsx +38 -0
  183. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +34 -0
  184. package/src/components/manage/TemplateChooser/template.svg +10 -0
  185. package/src/components/manage/Toast/Toast.jsx +1 -1
  186. package/src/components/manage/Toolbar/More.jsx +17 -2
  187. package/src/components/manage/Toolbar/PersonalTools.jsx +97 -155
  188. package/src/components/manage/Toolbar/Toolbar.jsx +2 -2
  189. package/src/components/manage/UniversalLink/UniversalLink.jsx +6 -12
  190. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +37 -0
  191. package/src/components/manage/Widgets/AlignWidget.jsx +2 -4
  192. package/src/components/manage/Widgets/ArrayWidget.jsx +3 -1
  193. package/src/components/manage/Widgets/ArrayWidget.test.jsx +45 -1
  194. package/src/components/manage/Widgets/ColorPickerWidget.jsx +6 -1
  195. package/src/components/manage/Widgets/ColorPickerWidget.test.jsx +9 -7
  196. package/src/components/manage/Widgets/DatetimeWidget.jsx +2 -8
  197. package/src/components/manage/Widgets/FileWidget.jsx +2 -1
  198. package/src/components/manage/Widgets/FormFieldWrapper.jsx +1 -1
  199. package/src/components/manage/Widgets/IdWidget.jsx +1 -2
  200. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +2 -9
  201. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +3 -10
  202. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx +4 -4
  203. package/src/components/manage/Widgets/RegistryImageWidget.jsx +210 -0
  204. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +91 -0
  205. package/src/components/manage/Widgets/SchemaWidget.jsx +6 -9
  206. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  207. package/src/components/manage/Widgets/SelectWidget.jsx +15 -1
  208. package/src/components/manage/Widgets/SelectWidget.test.jsx +45 -1
  209. package/src/components/manage/Widgets/WysiwygWidget.jsx +2 -9
  210. package/src/components/manage/Workflow/Workflow.jsx +75 -184
  211. package/src/components/theme/Anontools/Anontools.jsx +44 -72
  212. package/src/components/theme/Anontools/Anontools.stories.jsx +16 -6
  213. package/src/components/theme/Anontools/Anontools.test.jsx +16 -2
  214. package/src/components/theme/Breadcrumbs/Breadcrumbs.jsx +52 -99
  215. package/src/components/theme/Breadcrumbs/Breadcrumbs.stories.jsx +14 -13
  216. package/src/components/theme/Comments/Comment.stories.jsx +84 -0
  217. package/src/components/theme/Comments/CommentEditModal.jsx +63 -115
  218. package/src/components/theme/Comments/Comments.jsx +268 -380
  219. package/src/components/theme/Component/Component.jsx +1 -1
  220. package/src/components/theme/ContactForm/ContactForm.jsx +108 -192
  221. package/src/components/theme/ContactForm/ContactForm.stories.jsx +1 -1
  222. package/src/components/theme/ContactForm/ContactForm.test.jsx +2 -3
  223. package/src/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +41 -3
  224. package/src/components/theme/Error/ServerError.jsx +29 -0
  225. package/src/components/theme/Header/Header.jsx +37 -63
  226. package/src/components/theme/Header/Header.test.jsx +18 -0
  227. package/src/components/theme/Image/Image.jsx +96 -0
  228. package/src/components/theme/Image/Image.test.jsx +125 -0
  229. package/src/components/theme/Login/Login.jsx +160 -243
  230. package/src/components/theme/Logo/Logo.Multilingual.test.jsx +131 -1
  231. package/src/components/theme/Logo/Logo.jsx +35 -27
  232. package/src/components/theme/Logo/Logo.test.jsx +135 -1
  233. package/src/components/theme/Logout/Logout.jsx +36 -83
  234. package/src/components/theme/Navigation/Navigation.jsx +86 -171
  235. package/src/components/theme/NotFound/NotFound.jsx +55 -41
  236. package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -5
  237. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +95 -170
  238. package/src/components/theme/PreviewImage/PreviewImage.jsx +31 -15
  239. package/src/components/theme/PreviewImage/PreviewImage.test.js +53 -13
  240. package/src/components/theme/Register/Register.jsx +2 -4
  241. package/src/components/theme/Search/SearchTags.jsx +30 -60
  242. package/src/components/theme/SearchWidget/SearchWidget.jsx +49 -97
  243. package/src/components/theme/SearchWidget/SearchWidget.test.jsx +8 -0
  244. package/src/components/theme/Sitemap/Sitemap.jsx +24 -13
  245. package/src/components/theme/Sitemap/Sitemap.test.jsx +23 -2
  246. package/src/components/theme/TsTest/TsTest.test.tsx +11 -0
  247. package/src/components/theme/TsTest/TsTest.tsx +15 -0
  248. package/src/components/theme/View/AlbumView.jsx +21 -16
  249. package/src/components/theme/View/EventView.jsx +36 -25
  250. package/src/components/theme/View/FileView.jsx +23 -18
  251. package/src/components/theme/View/ImageView.jsx +40 -32
  252. package/src/components/theme/View/ImageView.test.jsx +4 -0
  253. package/src/components/theme/View/LinkView.jsx +53 -78
  254. package/src/components/theme/View/ListingView.jsx +36 -28
  255. package/src/components/theme/View/NewsItemView.jsx +16 -17
  256. package/src/components/theme/View/RenderBlocks.jsx +56 -21
  257. package/src/components/theme/View/RenderEmptyBlock.jsx +5 -0
  258. package/src/components/theme/View/SummaryView.jsx +49 -39
  259. package/src/components/theme/View/TabularView.jsx +59 -53
  260. package/src/components/theme/View/View.jsx +2 -0
  261. package/src/components/theme/Widgets/ImageWidget.stories.jsx +1 -2
  262. package/src/config/Blocks.jsx +46 -0
  263. package/src/config/Components.jsx +3 -1
  264. package/src/config/ControlPanels.js +0 -1
  265. package/src/config/Loadables.jsx +1 -1
  266. package/src/config/NonContentRoutes.jsx +1 -0
  267. package/src/config/RichTextEditor/Blocks.jsx +4 -5
  268. package/src/config/RichTextEditor/FromHTML.jsx +2 -2
  269. package/src/config/RichTextEditor/Plugins.jsx +2 -3
  270. package/src/config/RichTextEditor/Styles.jsx +1 -1
  271. package/src/config/RichTextEditor/ToHTML.jsx +12 -10
  272. package/src/config/RichTextEditor/index.js +2 -3
  273. package/src/config/Views.jsx +6 -4
  274. package/src/config/Widgets.jsx +3 -0
  275. package/src/config/index.js +36 -2
  276. package/src/config/server.js +2 -0
  277. package/src/constants/ActionTypes.js +4 -0
  278. package/src/constants/Indexes.js +3 -1
  279. package/src/express-middleware/devproxy.js +1 -1
  280. package/src/express-middleware/files.js +11 -9
  281. package/src/express-middleware/images.js +12 -5
  282. package/src/express-middleware/ok.js +16 -0
  283. package/src/express-middleware/robotstxt.js +1 -1
  284. package/src/express-middleware/sitemap.js +1 -1
  285. package/src/express-middleware/static.js +3 -3
  286. package/src/helpers/Api/Api.js +1 -1
  287. package/src/helpers/Blocks/Blocks.js +52 -6
  288. package/src/helpers/Blocks/Blocks.test.js +92 -13
  289. package/src/helpers/Extensions/index.js +2 -1
  290. package/src/helpers/Extensions/withBlockSchemaEnhancer.js +63 -61
  291. package/src/helpers/Extensions/withBlockSchemaEnhancer.test.js +145 -0
  292. package/src/helpers/FormValidation/FormValidation.js +37 -7
  293. package/src/helpers/FormValidation/FormValidation.test.js +32 -0
  294. package/src/helpers/Html/Html.jsx +2 -8
  295. package/src/helpers/Loadable/__mocks__/Loadable.js +18 -18
  296. package/src/helpers/MessageLabels/MessageLabels.js +39 -4
  297. package/src/helpers/ScrollToTop/ScrollToTop.jsx +5 -3
  298. package/src/helpers/Site/index.js +21 -0
  299. package/src/helpers/Url/Url.js +22 -1
  300. package/src/helpers/Url/Url.test.js +41 -0
  301. package/src/helpers/Utils/UseDetectClickOutside.stories.jsx +190 -0
  302. package/src/helpers/Utils/Utils.js +35 -0
  303. package/src/helpers/Utils/Utils.test.js +13 -0
  304. package/src/helpers/Utils/usePagination.js +67 -14
  305. package/src/helpers/Utils/usePagination.test.js +115 -0
  306. package/src/helpers/index.js +15 -8
  307. package/src/hooks/client/useClient.js +11 -0
  308. package/src/hooks/clipboard/useClipboard.js +26 -0
  309. package/src/hooks/index.js +2 -0
  310. package/src/icons/grid-block.svg +11 -0
  311. package/src/middleware/api.js +203 -173
  312. package/src/middleware/blacklistRoutes.js +25 -22
  313. package/src/middleware/index.js +2 -2
  314. package/src/middleware/storeProtectLoadUtils.js +61 -62
  315. package/src/middleware/storeProtectLoadUtils.test.js +47 -43
  316. package/src/reducers/actions/actions.js +7 -5
  317. package/src/reducers/actions/actions.test.js +70 -0
  318. package/src/reducers/content/content.test.js +4 -4
  319. package/src/reducers/index.js +4 -0
  320. package/src/reducers/navigation/navigation.js +5 -5
  321. package/src/reducers/navigation/navigation.test.js +30 -0
  322. package/src/reducers/navroot/navroot.js +79 -0
  323. package/src/reducers/navroot/navroot.test.js +110 -0
  324. package/src/reducers/relations/relations.js +74 -46
  325. package/src/reducers/site/site.js +51 -0
  326. package/src/reducers/site/site.test.js +67 -0
  327. package/src/reducers/userSession/userSession.js +15 -1
  328. package/src/registry.js +2 -2
  329. package/src/routes.js +9 -0
  330. package/src/server.jsx +9 -0
  331. package/src/start-server.js +2 -2
  332. package/src/storybook.jsx +24 -38
  333. package/test-setup-config.js +11 -1
  334. package/theme/themes/pastanaga/collections/form.overrides +46 -0
  335. package/theme/themes/pastanaga/collections/menu.overrides +3 -2
  336. package/theme/themes/pastanaga/elements/container.overrides +5 -2
  337. package/theme/themes/pastanaga/elements/input.overrides +11 -1
  338. package/theme/themes/pastanaga/elements/label.overrides +10 -0
  339. package/theme/themes/pastanaga/elements/step.overrides +2 -1
  340. package/theme/themes/pastanaga/extras/blocks.less +25 -15
  341. package/theme/themes/pastanaga/extras/color-picker-widget.less +1 -1
  342. package/theme/themes/pastanaga/extras/contents.less +6 -1
  343. package/theme/themes/pastanaga/extras/draftjs.less +4 -4
  344. package/theme/themes/pastanaga/extras/grid.less +427 -0
  345. package/theme/themes/pastanaga/extras/login.less +3 -0
  346. package/theme/themes/pastanaga/extras/main.less +14 -7
  347. package/theme/themes/pastanaga/extras/react-dates-overrides.less +4 -2
  348. package/theme/themes/pastanaga/extras/search.less +7 -1
  349. package/theme/themes/pastanaga/extras/sidebar.less +5 -4
  350. package/theme/themes/pastanaga/extras/time-picker-overrides.less +5 -3
  351. package/theme/themes/pastanaga/extras/toc.less +29 -0
  352. package/theme/themes/pastanaga/extras/toolbar.less +6 -2
  353. package/theme/themes/pastanaga/extras/userscontrolpanel.less +17 -9
  354. package/theme/themes/pastanaga/extras/widgets.less +1 -1
  355. package/theme/themes/pastanaga/modules/rating.overrides +2 -1
  356. package/theme/themes/pastanaga-cms-ui/elements/container.overrides +2 -1
  357. package/theme/themes/pastanaga-cms-ui/extras/cms-ui.elements.container.less +6 -2
  358. package/theme/themes/pastanaga-cms-ui/extras/cms-ui.site.less +2 -2
  359. package/tsconfig.json +33 -0
  360. package/webpack-plugins/webpack-less-plugin.js +19 -0
  361. package/.yarn/install-state.gz +0 -0
  362. package/.yarn/releases/yarn-3.2.3.cjs +0 -783
  363. package/src/components/manage/Blocks/Teaser/utils.js +0 -44
  364. package/src/components/manage/Blocks/Teaser/utils.test.jsx +0 -229
  365. package/src/components/theme/Header/Header.md +0 -27
@@ -0,0 +1,32 @@
1
+ import { useIntl } from 'react-intl';
2
+ import { BlockDataForm } from '@plone/volto/components';
3
+
4
+ const ContainerData = (props) => {
5
+ const { block, blocksConfig, data, onChangeBlock } = props;
6
+ const intl = useIntl();
7
+
8
+ const schema = blocksConfig[data['@type']].blockSchema({ intl });
9
+ const dataAdapter = blocksConfig[data['@type']].dataAdapter;
10
+
11
+ return (
12
+ <BlockDataForm
13
+ schema={schema}
14
+ title={schema.title}
15
+ onChangeField={(id, value) => {
16
+ dataAdapter({
17
+ block,
18
+ data,
19
+ id,
20
+ onChangeBlock,
21
+ value,
22
+ });
23
+ }}
24
+ formData={data}
25
+ block={block}
26
+ onChangeBlock={onChangeBlock}
27
+ blocksConfig={blocksConfig}
28
+ />
29
+ );
30
+ };
31
+
32
+ export default ContainerData;
@@ -0,0 +1,177 @@
1
+ import { useState } from 'react';
2
+ import { useIntl } from 'react-intl';
3
+ import { pickBy } from 'lodash';
4
+ import { BlocksForm, SidebarPortal } from '@plone/volto/components';
5
+ import PropTypes from 'prop-types';
6
+ import ContainerData from './Data';
7
+ import DefaultEditBlockWrapper from './EditBlockWrapper';
8
+ import SimpleContainerToolbar from './SimpleContainerToolbar';
9
+ import { v4 as uuid } from 'uuid';
10
+ import { blocksFormGenerator } from '@plone/volto/helpers';
11
+
12
+ import DefaultTemplateChooser from '@plone/volto/components/manage/TemplateChooser/TemplateChooser';
13
+
14
+ import config from '@plone/volto/registry';
15
+
16
+ const ContainerBlockEdit = (props) => {
17
+ const {
18
+ block,
19
+ data,
20
+ direction = 'horizontal',
21
+ onChangeBlock,
22
+ onChangeField,
23
+ pathname,
24
+ selected,
25
+ manage,
26
+ } = props;
27
+
28
+ const intl = useIntl();
29
+ const blockType = data['@type'];
30
+ const metadata = props.metadata || props.properties;
31
+ const isInitialized = data?.blocks && data?.blocks_layout;
32
+ const properties = isInitialized ? data : blocksFormGenerator(0, '');
33
+ const blockConfig = config.blocks.blocksConfig[blockType];
34
+ const blocksConfig = blockConfig.blocksConfig || props.blocksConfig;
35
+ const allowedBlocks = blockConfig.allowedBlocks;
36
+ const maxLength = blockConfig.maxLength || 8;
37
+ const templates = blockConfig.templates;
38
+ const ContainerToolbar =
39
+ blockConfig.containerToolbar || SimpleContainerToolbar;
40
+
41
+ // Custom components from config or default ones
42
+ const TemplateChooser = blockConfig.templateChooser || DefaultTemplateChooser;
43
+ const EditBlockWrapper =
44
+ blockConfig.editBlockWrapper || DefaultEditBlockWrapper;
45
+
46
+ let [selectedBlock, setSelectedBlock] = useState(
47
+ properties.blocks_layout.items[0],
48
+ );
49
+ if (props.setSelectedBlock) {
50
+ ({ selectedBlock, setSelectedBlock } = props);
51
+ }
52
+
53
+ const blockState = {};
54
+
55
+ const onAddNewBlock = () => {
56
+ const newuuid = uuid();
57
+ const type = allowedBlocks?.length === 1 ? allowedBlocks[0] : null;
58
+ const blocks = data.blocks || properties.blocks;
59
+ const blocks_layout = data.blocks_layout || properties.blocks_layout;
60
+ const newFormData = {
61
+ ...data,
62
+ blocks: {
63
+ ...blocks,
64
+ [newuuid]: { '@type': type || 'empty' },
65
+ },
66
+ blocks_layout: {
67
+ items: [...blocks_layout.items, newuuid],
68
+ },
69
+ };
70
+ if (blocks_layout.items.length < maxLength) {
71
+ onChangeBlock(block, {
72
+ ...newFormData,
73
+ });
74
+ }
75
+ };
76
+
77
+ const onSelectTemplate = (templateIndex) => {
78
+ const resultantTemplates =
79
+ allowedBlocks?.length === 1 ? templates(allowedBlocks[0]) : templates();
80
+ onChangeBlock(block, {
81
+ ...data,
82
+ ...resultantTemplates(intl)[templateIndex].blocksData,
83
+ });
84
+ };
85
+
86
+ const allowedBlocksConfig = pickBy(blocksConfig, (value, key) =>
87
+ allowedBlocks.includes(key),
88
+ );
89
+
90
+ const containerProps = {
91
+ ...props,
92
+ allowedBlocks,
93
+ allowedBlocksConfig,
94
+ blocksConfig,
95
+ blockType,
96
+ maxLength,
97
+ metadata,
98
+ onAddNewBlock,
99
+ onSelectTemplate,
100
+ selectedBlock,
101
+ setSelectedBlock,
102
+ templates,
103
+ };
104
+
105
+ return (
106
+ <>
107
+ {data.headline && <h2 className="headline">{data.headline}</h2>}
108
+
109
+ {selected && <ContainerToolbar {...containerProps} />}
110
+
111
+ {!isInitialized && templates && (
112
+ <TemplateChooser
113
+ templates={
114
+ allowedBlocks?.length === 1
115
+ ? templates(allowedBlocks[0])
116
+ : templates()
117
+ }
118
+ onSelectTemplate={onSelectTemplate}
119
+ />
120
+ )}
121
+
122
+ <BlocksForm
123
+ metadata={metadata}
124
+ properties={properties}
125
+ direction={direction}
126
+ manage={manage}
127
+ selectedBlock={selected ? selectedBlock : null}
128
+ blocksConfig={allowedBlocksConfig}
129
+ title={data.placeholder}
130
+ isContainer
131
+ stopPropagation={selectedBlock}
132
+ disableAddBlockOnEnterKey
133
+ onSelectBlock={(id) => {
134
+ setSelectedBlock(id);
135
+ }}
136
+ onChangeFormData={(newFormData) => {
137
+ onChangeBlock(block, {
138
+ ...data,
139
+ ...newFormData,
140
+ });
141
+ }}
142
+ onChangeField={(id, value) => {
143
+ if (['blocks', 'blocks_layout'].includes(id)) {
144
+ blockState[id] = value;
145
+ onChangeBlock(block, {
146
+ ...data,
147
+ ...blockState,
148
+ });
149
+ } else {
150
+ onChangeField(id, value);
151
+ }
152
+ }}
153
+ pathname={pathname}
154
+ >
155
+ {({ draginfo }, editBlock, blockProps) => (
156
+ <EditBlockWrapper draginfo={draginfo} blockProps={blockProps}>
157
+ {editBlock}
158
+ </EditBlockWrapper>
159
+ )}
160
+ </BlocksForm>
161
+ <SidebarPortal selected={selected && !selectedBlock}>
162
+ <ContainerData {...props}></ContainerData>
163
+ </SidebarPortal>
164
+ </>
165
+ );
166
+ };
167
+
168
+ ContainerBlockEdit.propTypes = {
169
+ block: PropTypes.string.isRequired,
170
+ onChangeBlock: PropTypes.func.isRequired,
171
+ pathname: PropTypes.string.isRequired,
172
+ selected: PropTypes.bool.isRequired,
173
+ manage: PropTypes.bool.isRequired,
174
+ direction: PropTypes.oneOf(['horizontal', 'vertical']),
175
+ };
176
+
177
+ export default ContainerBlockEdit;
@@ -0,0 +1,121 @@
1
+ import { Icon } from '@plone/volto/components';
2
+ import { Button } from 'semantic-ui-react';
3
+ import { defineMessages, useIntl } from 'react-intl';
4
+ import NewBlockAddButton from './NewBlockAddButton';
5
+ import cx from 'classnames';
6
+ import { isInteractiveElement } from '@plone/volto/helpers';
7
+
8
+ import clearSVG from '@plone/volto/icons/clear.svg';
9
+
10
+ const messages = defineMessages({
11
+ delete: {
12
+ id: 'Remove element {index}',
13
+ defaultMessage: 'Remove element {index}',
14
+ },
15
+ reset: {
16
+ id: 'Reset element {index}',
17
+ defaultMessage: 'Reset element {index}',
18
+ },
19
+ });
20
+
21
+ const EditBlockWrapper = (props) => {
22
+ const intl = useIntl();
23
+
24
+ const { blockProps, draginfo, children } = props;
25
+ const {
26
+ block,
27
+ selected,
28
+ type,
29
+ blocksConfig,
30
+ onChangeBlock,
31
+ onDeleteBlock,
32
+ onSelectBlock,
33
+ data,
34
+ index,
35
+ } = blockProps;
36
+
37
+ function onResetBlock() {
38
+ onChangeBlock(block, { '@type': 'empty' });
39
+ }
40
+
41
+ return (
42
+ <div
43
+ ref={draginfo.innerRef}
44
+ {...draginfo.draggableProps}
45
+ {...draginfo.dragHandleProps}
46
+ className={cx(`block-editor-${data['@type']} contained`, { selected })}
47
+ >
48
+ <div
49
+ role="presentation"
50
+ className="cell-wrapper"
51
+ onClick={(e) => {
52
+ e.block = block;
53
+ onSelectBlock(block);
54
+ }}
55
+ >
56
+ {type !== 'empty' ? (
57
+ <Button
58
+ aria-label={intl.formatMessage(messages.reset, {
59
+ index,
60
+ })}
61
+ basic
62
+ icon
63
+ onClick={(e) => onResetBlock(block, {})}
64
+ className="remove-block-button"
65
+ >
66
+ <Icon name={clearSVG} className="circled" size="24px" />
67
+ </Button>
68
+ ) : (
69
+ <Button
70
+ basic
71
+ icon
72
+ className="remove-block-button"
73
+ onClick={(e) => onDeleteBlock(block, true)}
74
+ aria-label={intl.formatMessage(messages.delete, {
75
+ index,
76
+ })}
77
+ >
78
+ <Icon
79
+ name={clearSVG}
80
+ className="circled"
81
+ size="24px"
82
+ color="#e40166"
83
+ />
84
+ </Button>
85
+ )}
86
+ {type && type !== 'empty' ? (
87
+ <div className={cx('ui drag block inner', type)}>{children}</div>
88
+ ) : (
89
+ <div
90
+ className={cx('gridBlock-empty-placeholder', {
91
+ selected: selected,
92
+ })}
93
+ role="presentation"
94
+ onClick={(e) => {
95
+ onSelectBlock(block);
96
+ // If the click is in the button, then
97
+ if (isInteractiveElement(e.target)) {
98
+ e.stopPropagation();
99
+ }
100
+ }}
101
+ >
102
+ <p>Add a new block</p>
103
+ <NewBlockAddButton
104
+ block={block}
105
+ index={index}
106
+ blocksConfig={blocksConfig}
107
+ onMutateBlock={(block, value) =>
108
+ onChangeBlock(block, {
109
+ ...data,
110
+ ...value,
111
+ })
112
+ }
113
+ />
114
+ </div>
115
+ )}
116
+ </div>
117
+ </div>
118
+ );
119
+ };
120
+
121
+ export default EditBlockWrapper;
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import { Button, Ref } from 'semantic-ui-react';
3
+ import { defineMessages, useIntl } from 'react-intl';
4
+ import { BlockChooser, Icon } from '@plone/volto/components';
5
+ import { useDetectClickOutside } from '@plone/volto/helpers';
6
+ import addSVG from '@plone/volto/icons/add.svg';
7
+ import { usePopper } from 'react-popper';
8
+ import { Portal } from 'react-portal';
9
+
10
+ const messages = defineMessages({
11
+ addBlock: {
12
+ id: 'Add block in position {index}',
13
+ defaultMessage: 'Add block in position {index}',
14
+ },
15
+ });
16
+
17
+ const NewBlockAddButton = (props) => {
18
+ const intl = useIntl();
19
+ const { blocksConfig, block, index, onMutateBlock } = props;
20
+ const [isOpenMenu, setOpenMenu] = React.useState(false);
21
+
22
+ const blockChooserRef = useDetectClickOutside({
23
+ onTriggered: () => setOpenMenu(false),
24
+ triggerKeys: ['Escape'],
25
+ });
26
+
27
+ const [referenceElement, setReferenceElement] = React.useState(null);
28
+ const [popperElement, setPopperElement] = React.useState(null);
29
+ const { styles, attributes } = usePopper(referenceElement, popperElement, {
30
+ placement: 'bottom',
31
+ modifiers: [
32
+ {
33
+ name: 'offset',
34
+ options: {
35
+ offset: [0, -30],
36
+ },
37
+ },
38
+ {
39
+ name: 'flip',
40
+ options: {
41
+ fallbackPlacements: ['right', 'top-start'],
42
+ },
43
+ },
44
+ ],
45
+ });
46
+
47
+ return (
48
+ <>
49
+ <Ref innerRef={setReferenceElement}>
50
+ <Button
51
+ basic
52
+ icon
53
+ onClick={() => setOpenMenu(true)}
54
+ className="add-block-button"
55
+ aria-label={intl.formatMessage(messages.addBlock, {
56
+ index,
57
+ })}
58
+ >
59
+ <Icon name={addSVG} className="circled" size="24px" />
60
+ </Button>
61
+ </Ref>
62
+ {isOpenMenu ? (
63
+ <Portal node={document.getElementById('body')}>
64
+ <div
65
+ ref={setPopperElement}
66
+ style={styles.popper}
67
+ {...attributes.popper}
68
+ className="container-chooser-wrapper"
69
+ >
70
+ <BlockChooser
71
+ onMutateBlock={onMutateBlock}
72
+ currentBlock={block}
73
+ showRestricted
74
+ blocksConfig={blocksConfig}
75
+ ref={blockChooserRef}
76
+ />
77
+ </div>
78
+ </Portal>
79
+ ) : null}
80
+ </>
81
+ );
82
+ };
83
+
84
+ export default NewBlockAddButton;
@@ -0,0 +1,54 @@
1
+ import { defineMessages, useIntl } from 'react-intl';
2
+ import { Button } from 'semantic-ui-react';
3
+ import { Icon } from '@plone/volto/components';
4
+
5
+ import addSVG from '@plone/volto/icons/add.svg';
6
+ import configSVG from '@plone/volto/icons/configuration.svg';
7
+
8
+ const messages = defineMessages({
9
+ addBlock: {
10
+ id: 'Add element to container',
11
+ defaultMessage: 'Add element to container',
12
+ },
13
+ blockSettings: {
14
+ id: 'Container settings',
15
+ defaultMessage: 'Container settings',
16
+ },
17
+ });
18
+
19
+ const SimpleContainerToolbar = (props) => {
20
+ const { data, onAddNewBlock, maxLength, setSelectedBlock } = props;
21
+ const intl = useIntl();
22
+
23
+ return (
24
+ <div className="toolbar">
25
+ <Button.Group>
26
+ <Button
27
+ aria-label={intl.formatMessage(messages.addBlock)}
28
+ icon
29
+ basic
30
+ disabled={data?.blocks_layout?.items?.length >= maxLength}
31
+ onClick={(e) => onAddNewBlock()}
32
+ >
33
+ <Icon name={addSVG} size="24px" />
34
+ </Button>
35
+ </Button.Group>
36
+ <Button.Group>
37
+ <Button
38
+ aria-label={intl.formatMessage(messages.blockSettings)}
39
+ icon
40
+ basic
41
+ onClick={(e) => {
42
+ e.stopPropagation();
43
+ setSelectedBlock();
44
+ props.setSidebarTab(1);
45
+ }}
46
+ >
47
+ <Icon name={configSVG} size="24px" />
48
+ </Button>
49
+ </Button.Group>
50
+ </div>
51
+ );
52
+ };
53
+
54
+ export default SimpleContainerToolbar;
@@ -0,0 +1,47 @@
1
+ import PropTypes from 'prop-types';
2
+ import cx from 'classnames';
3
+ import { useState } from 'react';
4
+ import ContainerEdit from '../Container/Edit';
5
+
6
+ const GridBlockEdit = (props) => {
7
+ const { data } = props;
8
+
9
+ const columnsLength = data?.blocks_layout?.items?.length || 0;
10
+
11
+ const [selectedBlock, setSelectedBlock] = useState(null);
12
+
13
+ return (
14
+ <div
15
+ className={cx({
16
+ one: columnsLength === 1,
17
+ two: columnsLength === 2,
18
+ three: columnsLength === 3,
19
+ four: columnsLength >= 4,
20
+ 'grid-items': true,
21
+ })}
22
+ // This is required to enabling a small "in-between" clickable area
23
+ // for bringing the Grid sidebar alive once you have selected an inner block
24
+ onClick={(e) => {
25
+ if (!e.block) setSelectedBlock(null);
26
+ }}
27
+ role="presentation"
28
+ >
29
+ <ContainerEdit
30
+ {...props}
31
+ selectedBlock={selectedBlock}
32
+ setSelectedBlock={setSelectedBlock}
33
+ direction="horizontal"
34
+ />
35
+ </div>
36
+ );
37
+ };
38
+
39
+ GridBlockEdit.propTypes = {
40
+ block: PropTypes.string.isRequired,
41
+ onChangeBlock: PropTypes.func.isRequired,
42
+ pathname: PropTypes.string.isRequired,
43
+ selected: PropTypes.bool.isRequired,
44
+ manage: PropTypes.bool.isRequired,
45
+ };
46
+
47
+ export default GridBlockEdit;
@@ -0,0 +1,43 @@
1
+ import { Grid } from 'semantic-ui-react';
2
+ import cx from 'classnames';
3
+ import { RenderBlocks } from '@plone/volto/components';
4
+ import { withBlockExtensions } from '@plone/volto/helpers';
5
+ import config from '@plone/volto/registry';
6
+
7
+ const GridBlockView = (props) => {
8
+ const { data, path, className } = props;
9
+ const metadata = props.metadata || props.properties;
10
+ const columns = data.blocks_layout.items;
11
+ const blocksConfig =
12
+ config.blocks.blocksConfig[data['@type']].blocksConfig ||
13
+ props.blocksConfig;
14
+ const location = {
15
+ pathname: path,
16
+ };
17
+ return (
18
+ <div
19
+ className={cx('block', data['@type'], className, {
20
+ one: columns?.length === 1,
21
+ two: columns?.length === 2,
22
+ three: columns?.length === 3,
23
+ four: columns?.length === 4,
24
+ })}
25
+ >
26
+ {data.headline && <h2 className="headline">{data.headline}</h2>}
27
+
28
+ <Grid stackable stretched columns={columns.length}>
29
+ <RenderBlocks
30
+ {...props}
31
+ blockWrapperTag={Grid.Column}
32
+ metadata={metadata}
33
+ content={data}
34
+ location={location}
35
+ blocksConfig={blocksConfig}
36
+ isContainer
37
+ />
38
+ </Grid>
39
+ </div>
40
+ );
41
+ };
42
+
43
+ export default withBlockExtensions(GridBlockView);
@@ -0,0 +1,14 @@
1
+ export const GridBlockDataAdapter = ({
2
+ block,
3
+ data,
4
+ id,
5
+ onChangeBlock,
6
+ value,
7
+ }) => {
8
+ let dataSaved = {
9
+ ...data,
10
+ [id]: value,
11
+ };
12
+
13
+ onChangeBlock(block, dataSaved);
14
+ };
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="96" height="96" fill="#9FD1E5" rx="3"/>
4
+ <rect width="67" height="53" fill="#FFF" opacity=".9" transform="translate(15 22)"/>
5
+ </g>
6
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="96" height="96" fill="#9FD1E5" rx="3"/>
4
+ <g fill="#FFF" opacity=".9" transform="translate(9 22)">
5
+ <rect width="37" height="53"/>
6
+ <rect width="37" height="53" x="42"/>
7
+ </g>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="96" height="96" fill="#9FD1E5" rx="3"/>
4
+ <g fill="#FFF" opacity=".9" transform="translate(6 22)">
5
+ <rect width="25" height="53" x="58"/>
6
+ <rect width="25" height="53"/>
7
+ <rect width="25" height="53" x="29"/>
8
+ </g>
9
+ </g>
10
+ </svg>
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="96" height="96" fill="#9FD1E5" rx="3"/>
4
+ <g fill="#FFF" opacity=".9" transform="translate(8 22)">
5
+ <rect width="18" height="53" x="42"/>
6
+ <rect width="18" height="53" x="63"/>
7
+ <rect width="18" height="53"/>
8
+ <rect width="18" height="53" x="21"/>
9
+ </g>
10
+ </g>
11
+ </svg>
@@ -0,0 +1,35 @@
1
+ import { defineMessages } from 'react-intl';
2
+
3
+ const messages = defineMessages({
4
+ headline: {
5
+ id: 'Headline',
6
+ defaultMessage: 'Headline',
7
+ },
8
+ grid: {
9
+ id: 'Grid',
10
+ defaultMessage: 'Grid',
11
+ },
12
+ });
13
+
14
+ export const GridBlockSchema = (props) => {
15
+ const { intl } = props;
16
+
17
+ return {
18
+ title: intl.formatMessage(messages.grid),
19
+ block: 'grid',
20
+ fieldsets: [
21
+ {
22
+ id: 'default',
23
+ title: 'Default',
24
+ fields: ['headline'],
25
+ },
26
+ ],
27
+
28
+ properties: {
29
+ headline: {
30
+ title: intl.formatMessage(messages.headline),
31
+ },
32
+ },
33
+ required: [],
34
+ };
35
+ };