@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,47 @@
1
+ import { defineMessages } from 'react-intl';
2
+ import { blocksFormGenerator } from '@plone/volto/helpers';
3
+
4
+ import gridTemplate1 from './grid-1.svg';
5
+ import gridTemplate2 from './grid-2.svg';
6
+ import gridTemplate3 from './grid-3.svg';
7
+ import gridTemplate4 from './grid-4.svg';
8
+
9
+ const messages = defineMessages({
10
+ column: {
11
+ id: 'column',
12
+ defaultMessage: 'column',
13
+ },
14
+ columns: {
15
+ id: 'columns',
16
+ defaultMessage: 'columns',
17
+ },
18
+ });
19
+
20
+ const templates = (type) => (intl) => [
21
+ {
22
+ image: gridTemplate1,
23
+ id: 'gridtemplateone',
24
+ title: `1 ${intl.formatMessage(messages.column)}`,
25
+ blocksData: blocksFormGenerator(1, type),
26
+ },
27
+ {
28
+ image: gridTemplate2,
29
+ id: 'gridtemplatetwo',
30
+ title: `2 ${intl.formatMessage(messages.columns)}`,
31
+ blocksData: blocksFormGenerator(2, type),
32
+ },
33
+ {
34
+ image: gridTemplate3,
35
+ id: 'gridtemplatethree',
36
+ title: `3 ${intl.formatMessage(messages.columns)}`,
37
+ blocksData: blocksFormGenerator(3, type),
38
+ },
39
+ {
40
+ image: gridTemplate4,
41
+ id: 'gridtemplatefour',
42
+ title: `4 ${intl.formatMessage(messages.columns)}`,
43
+ blocksData: blocksFormGenerator(4, type),
44
+ },
45
+ ];
46
+
47
+ export default templates;
@@ -149,14 +149,14 @@ class Edit extends Component {
149
149
  * @method onPreview
150
150
  * @returns {undefined}
151
151
  */
152
- onPreview() {
152
+ async onPreview() {
153
153
  try {
154
- const code = this.props.prettierStandalone
155
- .format(this.getValue(), {
154
+ const code = (
155
+ await this.props.prettierStandalone.format(this.getValue(), {
156
156
  parser: 'html',
157
157
  plugins: [this.props.prettierParserHtml],
158
158
  })
159
- .trim();
159
+ ).trim();
160
160
  this.setState(
161
161
  {
162
162
  isPreview: !this.state.isPreview,
@@ -174,14 +174,14 @@ class Edit extends Component {
174
174
  * @method onPrettify
175
175
  * @returns {undefined}
176
176
  */
177
- onPrettify = () => {
177
+ onPrettify = async () => {
178
178
  try {
179
- const code = this.props.prettierStandalone
180
- .format(this.getValue(), {
179
+ const code = (
180
+ await this.props.prettierStandalone.format(this.getValue(), {
181
181
  parser: 'html',
182
182
  plugins: [this.props.prettierParserHtml],
183
183
  })
184
- .trim();
184
+ ).trim();
185
185
  this.onChangeCode(code);
186
186
  } catch (ex) {
187
187
  // error while parsing the user-typed HTML
@@ -14,7 +14,11 @@ import { defineMessages, injectIntl } from 'react-intl';
14
14
  import cx from 'classnames';
15
15
 
16
16
  import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
17
- import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers';
17
+ import {
18
+ flattenToAppURL,
19
+ getBaseUrl,
20
+ validateFileUploadSize,
21
+ } from '@plone/volto/helpers';
18
22
  import { createContent } from '@plone/volto/actions';
19
23
  import { Icon, SidebarPortal, LinkMore } from '@plone/volto/components';
20
24
 
@@ -122,9 +126,8 @@ class EditComponent extends Component {
122
126
  },
123
127
  });
124
128
 
125
- this.extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(
126
- blockTitleRenderMap,
127
- );
129
+ this.extendedBlockRenderMap =
130
+ DefaultDraftBlockRenderMap.merge(blockTitleRenderMap);
128
131
 
129
132
  this.extendedDescripBlockRenderMap = DefaultDraftBlockRenderMap.merge(
130
133
  blockDescriptionRenderMap,
@@ -275,6 +278,7 @@ class EditComponent extends Component {
275
278
  */
276
279
  onUploadImage({ target }) {
277
280
  const file = target.files[0];
281
+ if (!validateFileUploadSize(file, this.props.intl.formatMessage)) return;
278
282
  this.setState({
279
283
  uploading: true,
280
284
  });
@@ -316,24 +320,26 @@ class EditComponent extends Component {
316
320
  selected: this.props.selected,
317
321
  })}
318
322
  >
319
- {this.props.selected && this.props.editable && !!this.props.data.url && (
320
- <div className="toolbar">
321
- <Button.Group>
322
- <Button
323
- icon
324
- basic
325
- onClick={() =>
326
- this.props.onChangeBlock(this.props.block, {
327
- ...this.props.data,
328
- url: '',
329
- })
330
- }
331
- >
332
- <Icon name={clearSVG} size="24px" color="#e40166" />
333
- </Button>
334
- </Button.Group>
335
- </div>
336
- )}
323
+ {this.props.selected &&
324
+ this.props.editable &&
325
+ !!this.props.data.url && (
326
+ <div className="toolbar">
327
+ <Button.Group>
328
+ <Button
329
+ icon
330
+ basic
331
+ onClick={() =>
332
+ this.props.onChangeBlock(this.props.block, {
333
+ ...this.props.data,
334
+ url: '',
335
+ })
336
+ }
337
+ >
338
+ <Icon name={clearSVG} size="24px" color="#e40166" />
339
+ </Button>
340
+ </Button.Group>
341
+ </div>
342
+ )}
337
343
  <div className="block-inner-wrapper">
338
344
  {this.props.data.url ? (
339
345
  <img
@@ -386,7 +392,8 @@ class EditComponent extends Component {
386
392
  placeholder={this.props.intl.formatMessage(messages.title)}
387
393
  blockStyleFn={() => 'title-editor'}
388
394
  onUpArrow={() => {
389
- const selectionState = this.state.titleEditorState.getSelection();
395
+ const selectionState =
396
+ this.state.titleEditorState.getSelection();
390
397
  const { titleEditorState } = this.state;
391
398
  if (
392
399
  titleEditorState
@@ -402,7 +409,8 @@ class EditComponent extends Component {
402
409
  }
403
410
  }}
404
411
  onDownArrow={() => {
405
- const selectionState = this.state.titleEditorState.getSelection();
412
+ const selectionState =
413
+ this.state.titleEditorState.getSelection();
406
414
  const { titleEditorState } = this.state;
407
415
  if (
408
416
  titleEditorState
@@ -430,7 +438,8 @@ class EditComponent extends Component {
430
438
  )}
431
439
  blockStyleFn={() => 'description-editor'}
432
440
  onUpArrow={() => {
433
- const selectionState = this.state.descriptionEditorState.getSelection();
441
+ const selectionState =
442
+ this.state.descriptionEditorState.getSelection();
434
443
  const currentCursorPosition = selectionState.getStartOffset();
435
444
 
436
445
  if (currentCursorPosition === 0) {
@@ -439,7 +448,8 @@ class EditComponent extends Component {
439
448
  }
440
449
  }}
441
450
  onDownArrow={() => {
442
- const selectionState = this.state.descriptionEditorState.getSelection();
451
+ const selectionState =
452
+ this.state.descriptionEditorState.getSelection();
443
453
  const { descriptionEditorState } = this.state;
444
454
  const currentCursorPosition = selectionState.getStartOffset();
445
455
  const blockLength = descriptionEditorState
@@ -15,13 +15,15 @@ import cx from 'classnames';
15
15
  import { isEqual } from 'lodash';
16
16
 
17
17
  import { Icon, ImageSidebar, SidebarPortal } from '@plone/volto/components';
18
- import { withBlockExtensions } from '@plone/volto/helpers';
19
18
  import { createContent } from '@plone/volto/actions';
20
19
  import {
21
20
  flattenToAppURL,
22
21
  getBaseUrl,
23
22
  isInternalURL,
23
+ withBlockExtensions,
24
+ validateFileUploadSize,
24
25
  } from '@plone/volto/helpers';
26
+ import config from '@plone/volto/registry';
25
27
 
26
28
  import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';
27
29
  import clearSVG from '@plone/volto/icons/clear.svg';
@@ -58,7 +60,7 @@ class Edit extends Component {
58
60
  block: PropTypes.string.isRequired,
59
61
  index: PropTypes.number.isRequired,
60
62
  data: PropTypes.objectOf(PropTypes.any).isRequired,
61
- content: PropTypes.objectOf(PropTypes.any).isRequired,
63
+ content: PropTypes.objectOf(PropTypes.any),
62
64
  request: PropTypes.shape({
63
65
  loading: PropTypes.bool,
64
66
  loaded: PropTypes.bool,
@@ -87,6 +89,7 @@ class Edit extends Component {
87
89
  * @returns {undefined}
88
90
  */
89
91
  UNSAFE_componentWillReceiveProps(nextProps) {
92
+ // Update block data after upload finished
90
93
  if (
91
94
  this.props.request.loading &&
92
95
  nextProps.request.loaded &&
@@ -98,6 +101,8 @@ class Edit extends Component {
98
101
  this.props.onChangeBlock(this.props.block, {
99
102
  ...this.props.data,
100
103
  url: nextProps.content['@id'],
104
+ image_field: 'image',
105
+ image_scales: { image: [nextProps.content.image] },
101
106
  alt: '',
102
107
  });
103
108
  }
@@ -125,6 +130,7 @@ class Edit extends Component {
125
130
  onUploadImage = (e) => {
126
131
  e.stopPropagation();
127
132
  const file = e.target.files[0];
133
+ if (!validateFileUploadSize(file, this.props.intl.formatMessage)) return;
128
134
  this.setState({
129
135
  uploading: true,
130
136
  });
@@ -169,6 +175,8 @@ class Edit extends Component {
169
175
  this.props.onChangeBlock(this.props.block, {
170
176
  ...this.props.data,
171
177
  url: flattenToAppURL(this.state.url),
178
+ image_field: undefined,
179
+ image_scales: undefined,
172
180
  });
173
181
  };
174
182
 
@@ -178,23 +186,25 @@ class Edit extends Component {
178
186
  * @param {array} files File objects
179
187
  * @returns {undefined}
180
188
  */
181
- onDrop = (file) => {
182
- this.setState({
183
- uploading: true,
184
- });
189
+ onDrop = (files) => {
190
+ if (!validateFileUploadSize(files[0], this.props.intl.formatMessage)) {
191
+ this.setState({ dragging: false });
192
+ return;
193
+ }
194
+ this.setState({ uploading: true });
185
195
 
186
- readAsDataURL(file[0]).then((data) => {
196
+ readAsDataURL(files[0]).then((data) => {
187
197
  const fields = data.match(/^data:(.*);(.*),(.*)$/);
188
198
  this.props.createContent(
189
199
  getBaseUrl(this.props.pathname),
190
200
  {
191
201
  '@type': 'Image',
192
- title: file[0].name,
202
+ title: files[0].name,
193
203
  image: {
194
204
  data: fields[3],
195
205
  encoding: fields[2],
196
206
  'content-type': fields[1],
197
- filename: file[0].name,
207
+ filename: files[0].name,
198
208
  },
199
209
  },
200
210
  this.props.block,
@@ -236,10 +246,12 @@ class Edit extends Component {
236
246
  * @returns {string} Markup for the component.
237
247
  */
238
248
  render() {
249
+ const Image = config.getComponent({ name: 'Image' }).component;
239
250
  const { data } = this.props;
240
251
  const placeholder =
241
252
  this.props.data.placeholder ||
242
253
  this.props.intl.formatMessage(messages.ImageBlockInputPlaceholder);
254
+
243
255
  return (
244
256
  <div
245
257
  className={cx(
@@ -251,15 +263,26 @@ class Edit extends Component {
251
263
  )}
252
264
  >
253
265
  {data.url ? (
254
- <img
266
+ <Image
255
267
  className={cx({
256
268
  'full-width': data.align === 'full',
257
269
  large: data.size === 'l',
258
270
  medium: data.size === 'm',
259
271
  small: data.size === 's',
260
272
  })}
273
+ item={
274
+ data.image_scales
275
+ ? {
276
+ '@id': data.url,
277
+ image_field: data.image_field,
278
+ image_scales: data.image_scales,
279
+ }
280
+ : undefined
281
+ }
261
282
  src={
262
- isInternalURL(data.url)
283
+ data.image_scales
284
+ ? undefined
285
+ : isInternalURL(data.url)
263
286
  ? // Backwards compat in the case that the block is storing the full server URL
264
287
  (() => {
265
288
  if (data.size === 'l')
@@ -274,7 +297,10 @@ class Edit extends Component {
274
297
  })()
275
298
  : data.url
276
299
  }
300
+ sizes={config.blocks.blocksConfig.image.getSizes(data)}
277
301
  alt={data.alt || ''}
302
+ loading="lazy"
303
+ responsive={true}
278
304
  />
279
305
  ) : (
280
306
  <div>
@@ -309,7 +335,20 @@ class Edit extends Component {
309
335
  onClick={(e) => {
310
336
  e.stopPropagation();
311
337
  e.preventDefault();
312
- this.props.openObjectBrowser();
338
+ this.props.openObjectBrowser({
339
+ onSelectItem: (
340
+ url,
341
+ { title, image_field, image_scales },
342
+ ) => {
343
+ this.props.onChangeBlock(this.props.block, {
344
+ ...this.props.data,
345
+ url,
346
+ image_field,
347
+ image_scales,
348
+ alt: this.props.data.alt || title || '',
349
+ });
350
+ },
351
+ });
313
352
  }}
314
353
  >
315
354
  <Icon name={navTreeSVG} size="24px" />
@@ -3,6 +3,7 @@ import renderer from 'react-test-renderer';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import { waitFor } from '@testing-library/react';
6
+ import { getImageBlockSizes } from './utils';
6
7
  import config from '@plone/volto/registry';
7
8
 
8
9
  import Edit from './Edit';
@@ -25,6 +26,7 @@ config.blocks.blocksConfig = {
25
26
  addPermission: [],
26
27
  view: [],
27
28
  },
29
+ getSizes: getImageBlockSizes,
28
30
  },
29
31
  };
30
32
 
@@ -1,14 +1,15 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { Segment } from 'semantic-ui-react';
4
- import { useIntl, FormattedMessage } from 'react-intl';
5
- import { BlockDataForm, Icon } from '@plone/volto/components';
6
- import { isInternalURL, flattenToAppURL } from '@plone/volto/helpers';
3
+ import { Segment, Button } from 'semantic-ui-react';
4
+ import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
5
+ import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers';
6
+ import { BlockDataForm, Icon, Image } from '@plone/volto/components';
7
7
  import { ImageSchema } from './schema';
8
8
  import imageSVG from '@plone/volto/icons/image.svg';
9
+ import trashSVG from '@plone/volto/icons/delete.svg';
9
10
 
10
11
  const ImageSidebar = (props) => {
11
- const { data, block, onChangeBlock } = props;
12
+ const { blocksConfig, data, block, onChangeBlock } = props;
12
13
  const intl = useIntl();
13
14
  const schema = ImageSchema({ formData: data, intl });
14
15
  return (
@@ -17,21 +18,58 @@ const ImageSidebar = (props) => {
17
18
  <h2>
18
19
  <FormattedMessage id="Image" defaultMessage="Image" />
19
20
  </h2>
21
+ <Button.Group>
22
+ <Button
23
+ title={intl.formatMessage(messages.clear)}
24
+ basic
25
+ disabled={!data.url}
26
+ onClick={() => {
27
+ onChangeBlock(block, {
28
+ ...data,
29
+ url: undefined,
30
+ image_scales: undefined,
31
+ image_field: undefined,
32
+ alt: data.url.title === data.alt ? undefined : data.alt,
33
+ });
34
+ }}
35
+ >
36
+ <Icon name={trashSVG} size="24px" color="red" />
37
+ </Button>
38
+ </Button.Group>
20
39
  </header>
21
40
 
22
- <Segment className="sidebar-metadata-container" secondary attached>
41
+ <Segment
42
+ className="sidebar-metadata-container image-sidebar"
43
+ secondary
44
+ attached
45
+ >
23
46
  {data.url ? (
24
47
  <>
25
- {data.url.split('/').slice(-1)[0]}
26
- {isInternalURL(data.url) && (
27
- <img
28
- src={`${flattenToAppURL(data.url)}/@@images/image/mini`}
29
- alt={data.alt}
30
- />
31
- )}
32
- {!isInternalURL(data.url) && (
33
- <img src={data.url} alt={data.alt} style={{ width: '50%' }} />
34
- )}
48
+ <div>{(data.url?.['@id'] ?? data.url).split('/').slice(-1)[0]}</div>
49
+ <Image
50
+ item={
51
+ data.image_scales
52
+ ? {
53
+ '@id': data.url,
54
+ image_field: data.image_field,
55
+ image_scales: data.image_scales,
56
+ }
57
+ : undefined
58
+ }
59
+ src={
60
+ data.image_scales
61
+ ? undefined
62
+ : isInternalURL(data.url)
63
+ ? // Backwards compat in the case that the block is storing the full server URL
64
+ `${flattenToAppURL(data.url)}/@@images/image/preview`
65
+ : data.url
66
+ }
67
+ sizes="188px"
68
+ alt={intl.formatMessage(messages.preview)}
69
+ loading="lazy"
70
+ responsive={true}
71
+ style={{ width: '50%' }}
72
+ />
35
73
  </>
36
74
  ) : (
37
75
  <>
@@ -55,6 +93,7 @@ const ImageSidebar = (props) => {
55
93
  onChangeBlock={onChangeBlock}
56
94
  formData={data}
57
95
  block={block}
96
+ blocksConfig={blocksConfig}
58
97
  />
59
98
  </>
60
99
  );
@@ -67,3 +106,14 @@ ImageSidebar.propTypes = {
67
106
  };
68
107
 
69
108
  export default ImageSidebar;
109
+
110
+ const messages = defineMessages({
111
+ preview: {
112
+ id: 'image_block_preview',
113
+ defaultMessage: 'Image preview',
114
+ },
115
+ clear: {
116
+ id: 'image_block_clear',
117
+ defaultMessage: 'Clear image',
118
+ },
119
+ });
@@ -7,16 +7,23 @@ import React from 'react';
7
7
  import PropTypes from 'prop-types';
8
8
  import { UniversalLink } from '@plone/volto/components';
9
9
  import cx from 'classnames';
10
- import { withBlockExtensions } from '@plone/volto/helpers';
11
- import { flattenToAppURL, isInternalURL } from '@plone/volto/helpers';
10
+ import {
11
+ flattenToAppURL,
12
+ isInternalURL,
13
+ withBlockExtensions,
14
+ } from '@plone/volto/helpers';
15
+ import config from '@plone/volto/registry';
12
16
 
13
17
  /**
14
18
  * View image block class.
15
19
  * @class View
16
20
  * @extends Component
17
21
  */
18
- export const View = ({ data, detached }) => {
22
+ export const View = ({ className, data, detached, properties }) => {
19
23
  const href = data?.href?.[0]?.['@id'] || '';
24
+
25
+ const Image = config.getComponent({ name: 'Image' }).component;
26
+
20
27
  return (
21
28
  <p
22
29
  className={cx(
@@ -26,21 +33,33 @@ export const View = ({ data, detached }) => {
26
33
  detached,
27
34
  },
28
35
  data.align,
36
+ className,
29
37
  )}
30
38
  >
31
39
  {data.url && (
32
40
  <>
33
41
  {(() => {
34
42
  const image = (
35
- <img
43
+ <Image
36
44
  className={cx({
37
45
  'full-width': data.align === 'full',
38
46
  large: data.size === 'l',
39
47
  medium: data.size === 'm',
40
48
  small: data.size === 's',
41
49
  })}
50
+ item={
51
+ data.image_scales
52
+ ? {
53
+ '@id': data.url,
54
+ image_field: data.image_field,
55
+ image_scales: data.image_scales,
56
+ }
57
+ : undefined
58
+ }
42
59
  src={
43
- isInternalURL(data.url)
60
+ data.image_scales
61
+ ? undefined
62
+ : isInternalURL(data.url)
44
63
  ? // Backwards compat in the case that the block is storing the full server URL
45
64
  (() => {
46
65
  if (data.size === 'l')
@@ -57,8 +76,10 @@ export const View = ({ data, detached }) => {
57
76
  })()
58
77
  : data.url
59
78
  }
79
+ sizes={config.blocks.blocksConfig.image.getSizes(data)}
60
80
  alt={data.alt || ''}
61
81
  loading="lazy"
82
+ responsive={true}
62
83
  />
63
84
  );
64
85
  if (href) {
@@ -4,6 +4,8 @@ import { render } from '@testing-library/react';
4
4
  import { MemoryRouter } from 'react-router-dom';
5
5
  import { Provider } from 'react-intl-redux';
6
6
  import configureStore from 'redux-mock-store';
7
+ import { getImageBlockSizes } from './utils';
8
+ import config from '@plone/volto/registry';
7
9
  import { View } from './View';
8
10
 
9
11
  const mockStore = configureStore();
@@ -15,6 +17,24 @@ const store = mockStore({
15
17
  },
16
18
  });
17
19
 
20
+ config.blocks.blocksConfig = {
21
+ image: {
22
+ id: 'image',
23
+ title: 'Image',
24
+ group: 'media',
25
+ extensions: {},
26
+ variations: [],
27
+ restricted: false,
28
+ mostUsed: true,
29
+ sidebarTab: 1,
30
+ security: {
31
+ addPermission: [],
32
+ view: [],
33
+ },
34
+ getSizes: getImageBlockSizes,
35
+ },
36
+ };
37
+
18
38
  describe('Image View Component', () => {
19
39
  test('renders a view image component with a local image', () => {
20
40
  const { getByRole } = render(<View data={{ url: '/image.jpg' }} />);
@@ -1,10 +1,6 @@
1
1
  import { defineMessages } from 'react-intl';
2
2
 
3
3
  const messages = defineMessages({
4
- Source: {
5
- id: 'Source',
6
- defaultMessage: 'Source',
7
- },
8
4
  Image: {
9
5
  id: 'Image',
10
6
  defaultMessage: 'Image',
@@ -37,6 +33,10 @@ const messages = defineMessages({
37
33
  id: 'Alt text hint link text',
38
34
  defaultMessage: 'Describe the purpose of the image.',
39
35
  },
36
+ linkSettings: {
37
+ id: 'Link settings',
38
+ defaultMessage: 'Link settings',
39
+ },
40
40
  });
41
41
 
42
42
  export function ImageSchema({ formData, intl }) {
@@ -45,23 +45,19 @@ export function ImageSchema({ formData, intl }) {
45
45
  {
46
46
  id: 'default',
47
47
  title: 'Default',
48
- fields: [...(formData.url ? ['url', 'alt', 'align', 'size'] : [])],
48
+ fields: [...(formData.url ? ['alt', 'align', 'size'] : [])],
49
49
  },
50
50
  ...(formData.url
51
51
  ? [
52
52
  {
53
53
  id: 'link_settings',
54
- title: 'Link settings',
54
+ title: intl.formatMessage(messages.linkSettings),
55
55
  fields: ['href', 'openLinkInNewTab'],
56
56
  },
57
57
  ]
58
58
  : []),
59
59
  ],
60
60
  properties: {
61
- url: {
62
- title: intl.formatMessage(messages.Source),
63
- widget: 'url',
64
- },
65
61
  alt: {
66
62
  title: intl.formatMessage(messages.AltText),
67
63
  description: (
@@ -101,3 +97,14 @@ export function ImageSchema({ formData, intl }) {
101
97
  required: [],
102
98
  };
103
99
  }
100
+
101
+ export const gridImageDisableSizeAndPositionHandlersSchema = ({
102
+ schema,
103
+ formData,
104
+ intl,
105
+ }) => {
106
+ schema.fieldsets[0].fields = schema.fieldsets[0].fields.filter(
107
+ (item) => !['align', 'size'].includes(item),
108
+ );
109
+ return schema;
110
+ };
@@ -0,0 +1,14 @@
1
+ export function getImageBlockSizes(data) {
2
+ if (data.align === 'full') return '100vw';
3
+ if (data.align === 'center') {
4
+ if (data.size === 'l') return '100vw';
5
+ if (data.size === 'm') return '50vw';
6
+ if (data.size === 's') return '25vw';
7
+ }
8
+ if (data.align === 'left' || data.align === 'right') {
9
+ if (data.size === 'l') return '50vw';
10
+ if (data.size === 'm') return '25vw';
11
+ if (data.size === 's') return '15vw';
12
+ }
13
+ return undefined;
14
+ }