@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
@@ -16,16 +16,79 @@ import {
16
16
  getBlocksLayoutFieldname,
17
17
  } from '@plone/volto/helpers';
18
18
 
19
+ export const getBlocksTocEntries = (properties, tocData) => {
20
+ const blocksFieldName = getBlocksFieldname(properties);
21
+ const blocksLayoutFieldname = getBlocksLayoutFieldname(properties);
22
+
23
+ const blocks = properties[blocksFieldName];
24
+ const blocks_layout = properties[blocksLayoutFieldname];
25
+
26
+ const levels =
27
+ tocData.levels?.length > 0
28
+ ? tocData.levels.map((l) => parseInt(l.slice(1)))
29
+ : [1, 2, 3, 4, 5, 6];
30
+ let rootLevel = Infinity;
31
+ let blocksFormEntries = [];
32
+ let tocEntries = {};
33
+ let tocEntriesLayout = [];
34
+
35
+ blocks_layout.items.forEach((id) => {
36
+ const block = blocks[id];
37
+ const blockConfig = config.blocks.blocksConfig[block['@type']];
38
+
39
+ if (!block || !blockConfig) {
40
+ return null;
41
+ }
42
+ if (!blockConfig.tocEntries && !blockConfig.tocEntry) {
43
+ return null;
44
+ }
45
+
46
+ const blockTocEntry = blockConfig.tocEntry?.(block, tocData);
47
+
48
+ const blockTocEntries = [
49
+ ...(blockConfig.tocEntries?.(block, tocData) ||
50
+ (blockTocEntry ? [blockTocEntry] : [])),
51
+ ];
52
+
53
+ blocksFormEntries = [...blocksFormEntries, ...blockTocEntries];
54
+
55
+ blockTocEntries.forEach((entry, index) => {
56
+ const i = `${id}-${index}`;
57
+ const level = entry[0];
58
+ const title = entry[1];
59
+ const items = [];
60
+ if (!level || !levels.includes(level)) return;
61
+ tocEntriesLayout.push(i);
62
+ tocEntries[i] = {
63
+ level,
64
+ title: title || block.plaintext,
65
+ items,
66
+ id: i,
67
+ };
68
+ if (level < rootLevel) {
69
+ rootLevel = level;
70
+ }
71
+ });
72
+ });
73
+
74
+ return {
75
+ rootLevel,
76
+ blocksFormEntries,
77
+ tocEntries,
78
+ tocEntriesLayout,
79
+ };
80
+ };
81
+
19
82
  /**
20
83
  * View toc block class.
21
84
  * @class View
22
85
  * @extends Component
23
86
  */
24
87
  const View = (props) => {
25
- const { properties, data } = props;
88
+ const { data } = props;
26
89
  const { variation } = props;
27
- const blocksFieldname = getBlocksFieldname(properties);
28
- const blocksLayoutFieldname = getBlocksLayoutFieldname(properties);
90
+ const metadata = props.metadata || props.properties;
91
+ const blocksFieldname = getBlocksFieldname(metadata);
29
92
  const levels = React.useMemo(
30
93
  () =>
31
94
  data.levels?.length > 0
@@ -34,14 +97,15 @@ const View = (props) => {
34
97
  [data],
35
98
  );
36
99
  const tocEntries = React.useMemo(() => {
37
- let rootLevel = Infinity;
38
100
  let entries = [];
39
101
  let prevEntry = {};
40
- let tocEntries = {};
41
- let tocEntriesLayout = [];
102
+ const { rootLevel, tocEntries, tocEntriesLayout } = getBlocksTocEntries(
103
+ metadata,
104
+ data,
105
+ );
42
106
 
43
- properties[blocksLayoutFieldname].items.forEach((id) => {
44
- const block = properties[blocksFieldname][id];
107
+ tocEntriesLayout.forEach((id) => {
108
+ const block = metadata[blocksFieldname][id];
45
109
  if (typeof block === 'undefined') {
46
110
  return null;
47
111
  }
@@ -50,16 +114,22 @@ const View = (props) => {
50
114
  block,
51
115
  data,
52
116
  );
117
+
53
118
  if (entry) {
54
119
  const level = entry[0];
55
120
  const title = entry[1];
56
121
  const items = [];
122
+ if (!title?.trim() && !block.plaintext?.trim()) return;
57
123
  if (!level || !levels.includes(level)) return;
58
124
  tocEntriesLayout.push(id);
59
- tocEntries[id] = { level, title: title || block.plaintext, items, id };
60
- if (level < rootLevel) {
61
- rootLevel = level;
62
- }
125
+ tocEntries[id] = {
126
+ level,
127
+ title: title || block.plaintext,
128
+ items,
129
+ id,
130
+ override_toc: block.override_toc,
131
+ plaintext: block.plaintext,
132
+ };
63
133
  }
64
134
  });
65
135
 
@@ -91,7 +161,7 @@ const View = (props) => {
91
161
  });
92
162
 
93
163
  return entries;
94
- }, [data, levels, properties, blocksFieldname, blocksLayoutFieldname]);
164
+ }, [data, levels, metadata, blocksFieldname]);
95
165
 
96
166
  const Renderer = variation?.view;
97
167
  return (
@@ -101,7 +171,7 @@ const View = (props) => {
101
171
  )}
102
172
 
103
173
  {Renderer ? (
104
- <Renderer {...props} tocEntries={tocEntries} properties={properties} />
174
+ <Renderer {...props} tocEntries={tocEntries} metadata={metadata} />
105
175
  ) : (
106
176
  <div>View extension not found</div>
107
177
  )}
@@ -8,15 +8,20 @@ import PropTypes from 'prop-types';
8
8
  import { map } from 'lodash';
9
9
  import { List } from 'semantic-ui-react';
10
10
  import { FormattedMessage, injectIntl } from 'react-intl';
11
- import AnchorLink from 'react-anchor-link-smooth-scroll';
11
+ import Slugger from 'github-slugger';
12
+ import { UniversalLink } from '@plone/volto/components';
13
+ import { normalizeString } from '@plone/volto/helpers';
12
14
 
13
15
  const RenderListItems = ({ items, data }) => {
14
16
  return map(items, (item) => {
15
- const { id, level, title } = item;
17
+ const { id, level, title, override_toc, plaintext } = item;
18
+ const slug = override_toc
19
+ ? Slugger.slug(normalizeString(plaintext))
20
+ : Slugger.slug(normalizeString(title)) || id;
16
21
  return (
17
22
  item && (
18
23
  <List.Item key={id} className={`item headline-${level}`} as="li">
19
- <AnchorLink href={`#${id}`}>{title}</AnchorLink>
24
+ <UniversalLink href={`#${slug}`}>{title}</UniversalLink>
20
25
  {item.items?.length > 0 && (
21
26
  <List
22
27
  ordered={data.ordered}
@@ -0,0 +1,44 @@
1
+ import renderer from 'react-test-renderer';
2
+ import configureStore from 'redux-mock-store';
3
+ import { Provider } from 'react-intl-redux';
4
+ import { MemoryRouter } from 'react-router-dom';
5
+ import DefaultTocRenderer from './DefaultTocRenderer';
6
+
7
+ const mockStore = configureStore();
8
+
9
+ const data = { '@type': 'toc', variation: 'default' };
10
+
11
+ const tocEntries = [
12
+ {
13
+ level: 2,
14
+ title: 'Hello this is a sample page',
15
+ items: [
16
+ {
17
+ level: 3,
18
+ title: 'Test level 3',
19
+ items: [],
20
+ id: 'be612682-6df9-4a5e-b3a1-9dec5d82ae14',
21
+ parentId: '3a8bff13-3245-44f6-8a35-e0defef5898e',
22
+ },
23
+ ],
24
+ id: '3a8bff13-3245-44f6-8a35-e0defef5898e',
25
+ },
26
+ ];
27
+
28
+ test('renders a default toc renderer component', () => {
29
+ const store = mockStore({
30
+ intl: {
31
+ locale: 'en',
32
+ messages: {},
33
+ },
34
+ });
35
+ const component = renderer.create(
36
+ <Provider store={store}>
37
+ <MemoryRouter>
38
+ <DefaultTocRenderer data={data} tocEntries={tocEntries} />
39
+ </MemoryRouter>
40
+ </Provider>,
41
+ );
42
+ const json = component.toJSON();
43
+ expect(json).toMatchSnapshot();
44
+ });
@@ -1,23 +1,23 @@
1
- /**
2
- * View toc block.
3
- * @module components/manage/Blocks/ToC/View
4
- */
5
-
6
- import React from 'react';
1
+ import React, { useEffect, useState } from 'react';
7
2
  import PropTypes from 'prop-types';
8
3
  import { map } from 'lodash';
9
- import { Menu } from 'semantic-ui-react';
4
+ import { Menu, Dropdown } from 'semantic-ui-react';
10
5
  import { FormattedMessage, injectIntl } from 'react-intl';
11
6
  import AnchorLink from 'react-anchor-link-smooth-scroll';
7
+ import Slugger from 'github-slugger';
8
+ import { normalizeString } from '@plone/volto/helpers';
12
9
 
13
10
  const RenderMenuItems = ({ items }) => {
14
11
  return map(items, (item) => {
15
- const { id, level, title } = item;
12
+ const { id, level, title, override_toc, plaintext } = item;
13
+ const slug = override_toc
14
+ ? Slugger.slug(normalizeString(plaintext))
15
+ : Slugger.slug(normalizeString(title)) || id;
16
16
  return (
17
17
  item && (
18
18
  <React.Fragment key={id}>
19
19
  <Menu.Item className={`headline-${level}`}>
20
- <AnchorLink href={`#${id}`}>{title}</AnchorLink>
20
+ <AnchorLink href={`#${slug}`}>{title}</AnchorLink>
21
21
  </Menu.Item>
22
22
  {item.items?.length > 0 && <RenderMenuItems items={item.items} />}
23
23
  </React.Fragment>
@@ -32,6 +32,131 @@ const RenderMenuItems = ({ items }) => {
32
32
  * @extends Component
33
33
  */
34
34
  const View = ({ data, tocEntries }) => {
35
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
36
+ // When the page is resized to prevent items from the TOC from going out of the viewport,
37
+ // a dropdown menu is added containing all the items that don't fit.
38
+ const handleResize = () => {
39
+ const menuElement = document.querySelector('.responsive-menu');
40
+ const containerWidth = menuElement.offsetWidth;
41
+
42
+ // Get all divs that contain the items from the TOC, except the dropdown button
43
+ const nested = document.querySelectorAll(
44
+ '.responsive-menu .item:not(.dropdown)',
45
+ );
46
+ const nestedArray = Object.values(nested);
47
+ const middle = Math.ceil(nestedArray.length / 2);
48
+ const firstHalfNested = nestedArray.slice(0, middle);
49
+ const secondHalfNested = nestedArray.slice(middle);
50
+
51
+ const dropdown = document.querySelector('.dropdown');
52
+ const dropdownWidth = dropdown.offsetWidth;
53
+
54
+ const firstHalfNestedHiddenItems = [];
55
+
56
+ // Add a 'hidden' class for the items that should be in the dropdown
57
+ firstHalfNested.forEach((item) => {
58
+ const itemOffsetLeft = item.offsetLeft;
59
+ const itemOffsetWidth = item.offsetWidth;
60
+ if (itemOffsetLeft + itemOffsetWidth > containerWidth - dropdownWidth) {
61
+ item.classList.add('hidden');
62
+ firstHalfNestedHiddenItems.push(item);
63
+ } else {
64
+ item.classList.remove('hidden');
65
+ }
66
+ });
67
+
68
+ secondHalfNested.forEach((item) => item.classList.add('hidden-dropdown'));
69
+
70
+ const diff = firstHalfNested.length - firstHalfNestedHiddenItems.length;
71
+ const secondHalfNestedShownItems = secondHalfNested.slice(diff);
72
+ secondHalfNestedShownItems.forEach((item) =>
73
+ item.classList.remove('hidden-dropdown'),
74
+ );
75
+
76
+ // If there are elements that should be displayed in the dropdown, show the dropdown button
77
+ if (secondHalfNestedShownItems.length > 0)
78
+ dropdown.classList.remove('hidden-dropdown');
79
+ else {
80
+ dropdown.classList.add('hidden-dropdown');
81
+ }
82
+ };
83
+
84
+ const handleDropdownKeyDown = (event) => {
85
+ const dropdownMenu = document.querySelector('.menu.transition');
86
+ if (event.key === 'ArrowDown' && isDropdownOpen) {
87
+ event.preventDefault();
88
+ const menuItems = dropdownMenu.querySelectorAll(
89
+ '.item:not(.hidden-dropdown)',
90
+ );
91
+ const focusedItem = dropdownMenu.querySelector('.item.focused');
92
+ const focusedIndex = Array.from(menuItems).indexOf(focusedItem);
93
+
94
+ if (focusedIndex === -1) {
95
+ // No item is currently focused, so focus the first item
96
+ menuItems[0].classList.add('focused');
97
+ } else if (focusedIndex === menuItems.length - 1) {
98
+ // Remove focus from the currently focused item and close the dropdown
99
+ focusedItem.classList.remove('focused');
100
+ setIsDropdownOpen(false);
101
+
102
+ // Focus the next element on the page
103
+ const nextElement = dropdownMenu.nextElementSibling;
104
+ if (nextElement) {
105
+ nextElement.focus();
106
+ }
107
+ } else {
108
+ // Remove focus from the currently focused item
109
+ focusedItem.classList.remove('focused');
110
+
111
+ // Focus the next item or wrap around to the first item
112
+ const nextIndex = (focusedIndex + 1) % menuItems.length;
113
+ menuItems[nextIndex].classList.add('focused');
114
+ }
115
+ } else if (event.key === 'Enter' && isDropdownOpen) {
116
+ const focusedItem = dropdownMenu.querySelector('.item.focused');
117
+ if (focusedItem) {
118
+ focusedItem.querySelector('a').click();
119
+ focusedItem.classList.remove('focused');
120
+ }
121
+ } else if (event.key === 'Tab') {
122
+ const focusedItem = dropdownMenu.querySelector('.item.focused');
123
+ if (focusedItem) {
124
+ focusedItem.classList.remove('focused');
125
+ }
126
+ }
127
+ };
128
+
129
+ useEffect(() => {
130
+ if (data.sticky) {
131
+ const toc = document.querySelector('.horizontalMenu');
132
+ const tocPos = toc ? toc.offsetTop : 0;
133
+
134
+ const handleScroll = () => {
135
+ let scrollPos = window.scrollY;
136
+ if (scrollPos > tocPos && toc) {
137
+ toc.classList.add('sticky-toc');
138
+ } else if (scrollPos <= tocPos && toc) {
139
+ toc.classList.remove('sticky-toc');
140
+ }
141
+ };
142
+
143
+ window.addEventListener('scroll', handleScroll);
144
+
145
+ return () => {
146
+ window.removeEventListener('scroll', handleScroll);
147
+ };
148
+ }
149
+ }, [data.sticky]);
150
+
151
+ useEffect(() => {
152
+ handleResize();
153
+ window.addEventListener('resize', handleResize);
154
+
155
+ return () => {
156
+ window.removeEventListener('resize', handleResize);
157
+ };
158
+ });
159
+
35
160
  return (
36
161
  <>
37
162
  {data.title && !data.hide_title ? (
@@ -46,8 +171,22 @@ const View = ({ data, tocEntries }) => {
46
171
  ) : (
47
172
  ''
48
173
  )}
49
- <Menu>
174
+ <Menu className="responsive-menu">
50
175
  <RenderMenuItems items={tocEntries} />
176
+ <Dropdown
177
+ item
178
+ text="More"
179
+ className="hidden-dropdown"
180
+ open={isDropdownOpen}
181
+ onOpen={() => setIsDropdownOpen(true)}
182
+ onClose={() => setIsDropdownOpen(false)}
183
+ tabIndex={0}
184
+ onKeyDown={handleDropdownKeyDown}
185
+ >
186
+ <Dropdown.Menu>
187
+ <RenderMenuItems items={tocEntries} />
188
+ </Dropdown.Menu>
189
+ </Dropdown>
51
190
  </Menu>
52
191
  </>
53
192
  );
@@ -1,7 +1,7 @@
1
1
  import DefaultTocRenderer from './DefaultTocRenderer';
2
2
  import HorizontalMenu from './HorizontalMenu';
3
3
 
4
- export default [
4
+ const ToCVariations = [
5
5
  {
6
6
  id: 'default',
7
7
  title: 'Listing (default)',
@@ -14,3 +14,5 @@ export default [
14
14
  view: HorizontalMenu,
15
15
  },
16
16
  ];
17
+
18
+ export default ToCVariations;