@kitconcept/volto-light-theme 8.0.0-alpha.3 → 8.0.0-alpha.30

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 (200) hide show
  1. package/.changelog.draft +6 -9
  2. package/CHANGELOG.md +310 -0
  3. package/locales/af/LC_MESSAGES/volto.po +645 -0
  4. package/locales/ar/LC_MESSAGES/volto.po +645 -0
  5. package/locales/bg/LC_MESSAGES/volto.po +645 -0
  6. package/locales/bn/LC_MESSAGES/volto.po +645 -0
  7. package/locales/ca/LC_MESSAGES/volto.po +645 -0
  8. package/locales/cs/LC_MESSAGES/volto.po +645 -0
  9. package/locales/cy/LC_MESSAGES/volto.po +645 -0
  10. package/locales/da/LC_MESSAGES/volto.po +645 -0
  11. package/locales/de/LC_MESSAGES/volto.po +83 -167
  12. package/locales/el/LC_MESSAGES/volto.po +645 -0
  13. package/locales/en/LC_MESSAGES/volto.po +30 -115
  14. package/locales/en_AU/LC_MESSAGES/volto.po +645 -0
  15. package/locales/en_GB/LC_MESSAGES/volto.po +645 -0
  16. package/locales/eo/LC_MESSAGES/volto.po +645 -0
  17. package/locales/es/LC_MESSAGES/volto.po +75 -160
  18. package/locales/et/LC_MESSAGES/volto.po +645 -0
  19. package/locales/eu/LC_MESSAGES/volto.po +59 -125
  20. package/locales/fa/LC_MESSAGES/volto.po +645 -0
  21. package/locales/fi/LC_MESSAGES/volto.po +645 -0
  22. package/locales/fr/LC_MESSAGES/volto.po +645 -0
  23. package/locales/fu/LC_MESSAGES/volto.po +645 -0
  24. package/locales/ga/LC_MESSAGES/volto.po +645 -0
  25. package/locales/gl/LC_MESSAGES/volto.po +645 -0
  26. package/locales/he/LC_MESSAGES/volto.po +645 -0
  27. package/locales/hi/LC_MESSAGES/volto.po +645 -0
  28. package/locales/hr/LC_MESSAGES/volto.po +645 -0
  29. package/locales/hu/LC_MESSAGES/volto.po +645 -0
  30. package/locales/hy/LC_MESSAGES/volto.po +645 -0
  31. package/locales/id/LC_MESSAGES/volto.po +645 -0
  32. package/locales/it/LC_MESSAGES/volto.po +645 -0
  33. package/locales/ja/LC_MESSAGES/volto.po +645 -0
  34. package/locales/ka/LC_MESSAGES/volto.po +645 -0
  35. package/locales/kn/LC_MESSAGES/volto.po +645 -0
  36. package/locales/ko/LC_MESSAGES/volto.po +645 -0
  37. package/locales/lt/LC_MESSAGES/volto.po +645 -0
  38. package/locales/lv/LC_MESSAGES/volto.po +645 -0
  39. package/locales/mi/LC_MESSAGES/volto.po +645 -0
  40. package/locales/mk_MK/LC_MESSAGES/volto.po +645 -0
  41. package/locales/ms/LC_MESSAGES/volto.po +645 -0
  42. package/locales/mt/LC_MESSAGES/volto.po +645 -0
  43. package/locales/my/LC_MESSAGES/volto.po +645 -0
  44. package/locales/nl/LC_MESSAGES/volto.po +645 -0
  45. package/locales/nl_BE/LC_MESSAGES/volto.po +645 -0
  46. package/locales/nn/LC_MESSAGES/volto.po +645 -0
  47. package/locales/no/LC_MESSAGES/volto.po +645 -0
  48. package/locales/pl/LC_MESSAGES/volto.po +645 -0
  49. package/locales/pt/LC_MESSAGES/volto.po +645 -0
  50. package/locales/pt_BR/LC_MESSAGES/volto.po +38 -123
  51. package/locales/rm/LC_MESSAGES/volto.po +645 -0
  52. package/locales/ro/LC_MESSAGES/volto.po +645 -0
  53. package/locales/ru/LC_MESSAGES/volto.po +645 -0
  54. package/locales/sk/LC_MESSAGES/volto.po +645 -0
  55. package/locales/sl/LC_MESSAGES/volto.po +645 -0
  56. package/locales/sm/LC_MESSAGES/volto.po +645 -0
  57. package/locales/sq/LC_MESSAGES/volto.po +645 -0
  58. package/locales/sr/LC_MESSAGES/volto.po +645 -0
  59. package/locales/sr_Cyrl/LC_MESSAGES/volto.po +645 -0
  60. package/locales/sr_Latn/LC_MESSAGES/volto.po +645 -0
  61. package/locales/sv/LC_MESSAGES/volto.po +645 -0
  62. package/locales/sw/LC_MESSAGES/volto.po +645 -0
  63. package/locales/ta/LC_MESSAGES/volto.po +645 -0
  64. package/locales/te/LC_MESSAGES/volto.po +645 -0
  65. package/locales/th/LC_MESSAGES/volto.po +645 -0
  66. package/locales/tl/LC_MESSAGES/volto.po +645 -0
  67. package/locales/to/LC_MESSAGES/volto.po +645 -0
  68. package/locales/tr/LC_MESSAGES/volto.po +645 -0
  69. package/locales/uk/LC_MESSAGES/volto.po +645 -0
  70. package/locales/vi/LC_MESSAGES/volto.po +645 -0
  71. package/locales/volto.pot +31 -116
  72. package/locales/zh_CN/LC_MESSAGES/volto.po +645 -0
  73. package/locales/zh_HK/LC_MESSAGES/volto.po +645 -0
  74. package/locales/zh_TW/LC_MESSAGES/volto.po +645 -0
  75. package/package.json +7 -4
  76. package/src/__mocks__/semantic-ui-react.ts +31 -0
  77. package/src/components/Blocks/Block/EditBlockWrapper.jsx +9 -3
  78. package/src/components/Blocks/Button/schema.js +12 -0
  79. package/src/components/Blocks/EventCalendar/Search/components/EventTemplate.tsx +1 -1
  80. package/src/components/Blocks/Image/Edit.jsx +9 -32
  81. package/src/components/Blocks/Image/View.jsx +9 -26
  82. package/src/components/Blocks/Image/adapter.js +28 -14
  83. package/src/components/Blocks/Image/adapter.test.js +156 -0
  84. package/src/components/Blocks/Image/schema.js +21 -7
  85. package/src/components/Blocks/Listing/DefaultTemplate.jsx +12 -6
  86. package/src/components/Blocks/Listing/GridTemplate.jsx +17 -7
  87. package/src/components/Blocks/Listing/ListingBody.jsx +4 -1
  88. package/src/components/Blocks/Listing/SummaryTemplate.jsx +17 -7
  89. package/src/components/Blocks/Maps/MapsSidebar.jsx +68 -0
  90. package/src/components/Blocks/Maps/View.jsx +37 -0
  91. package/src/components/Blocks/Maps/adapter.js +27 -0
  92. package/src/components/Blocks/Maps/adapter.test.js +63 -0
  93. package/src/components/Blocks/Maps/schema.js +42 -2
  94. package/src/components/Blocks/Separator/schema.js +12 -0
  95. package/src/components/Blocks/Teaser/DefaultBody.tsx +35 -6
  96. package/src/components/Blocks/Video/VideoSidebar.jsx +68 -0
  97. package/src/components/Blocks/Video/View.jsx +38 -0
  98. package/src/components/Blocks/Video/adapter.js +28 -0
  99. package/src/components/Blocks/Video/adapter.test.js +63 -0
  100. package/src/components/Blocks/Video/schema.js +42 -2
  101. package/src/components/Blocks/schema.ts +69 -0
  102. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +128 -0
  103. package/src/components/Breadcrumbs/Breadcrumbs.tsx +117 -0
  104. package/src/components/Caption/Caption.test.tsx +31 -0
  105. package/src/components/Caption/{Caption.jsx → Caption.tsx} +14 -21
  106. package/src/components/Footer/ColumnLinks.tsx +2 -2
  107. package/src/components/Footer/Footer.tsx +2 -2
  108. package/src/components/Footer/slots/Colophon.tsx +13 -1
  109. package/src/components/Footer/slots/CoreFooter.tsx +4 -2
  110. package/src/components/Footer/slots/FollowUsLogoAndLinks.tsx +12 -23
  111. package/src/components/Header/Header.tsx +3 -3
  112. package/src/components/LanguageSelector/LanguageSelector.tsx +91 -0
  113. package/src/components/MobileNavigation/MobileNavigation.jsx +11 -9
  114. package/src/components/Navigation/Navigation.test.tsx +176 -0
  115. package/src/components/Navigation/{Navigation.jsx → Navigation.tsx} +89 -42
  116. package/src/components/StickyMenu/MobileCarouselArrowButton.tsx +81 -0
  117. package/src/components/StickyMenu/MobileStickyMenu.tsx +76 -0
  118. package/src/components/Summary/DefaultSummary.tsx +10 -3
  119. package/src/components/Summary/EventSummary.tsx +10 -3
  120. package/src/components/Summary/FileSummary.tsx +10 -3
  121. package/src/components/Summary/NewsItemSummary.tsx +10 -3
  122. package/src/components/Summary/PersonSummary.tsx +10 -3
  123. package/src/components/Summary/Summary.stories.tsx +46 -30
  124. package/src/components/Tags/Tags.test.tsx +71 -0
  125. package/src/components/Tags/{Tags.jsx → Tags.tsx} +9 -25
  126. package/src/components/Theme/EventView.jsx +4 -4
  127. package/src/components/Theme/ImageView.jsx +8 -1
  128. package/src/components/Theme/NewsItemView.jsx +4 -4
  129. package/src/components/Theme/RenderBlocksV2.jsx +38 -15
  130. package/src/components/Widgets/ColorSwatch.stories.tsx +197 -0
  131. package/src/components/Widgets/ColorSwatch.test.tsx +188 -0
  132. package/src/components/Widgets/ColorSwatch.tsx +77 -39
  133. package/src/components/Widgets/ObjectList.tsx +37 -27
  134. package/src/components/Widgets/SoftTextWidget.tsx +129 -0
  135. package/src/components/Widgets/SoftTextareaWidget.tsx +118 -0
  136. package/src/components/Widgets/ThemeColorSwatch.tsx +5 -9
  137. package/src/config/blocks.tsx +83 -28
  138. package/src/config/classExtenders.ts +11 -10
  139. package/src/config/settings.ts +6 -0
  140. package/src/config/slots.ts +7 -0
  141. package/src/config/widgets.ts +5 -9
  142. package/src/customizations/volto/components/manage/Blocks/Maps/MapsSidebar.jsx +10 -0
  143. package/src/customizations/volto/components/manage/Blocks/Maps/View.jsx +10 -0
  144. package/src/customizations/volto/components/manage/Blocks/Video/VideoSidebar.jsx +10 -0
  145. package/src/customizations/volto/components/manage/Blocks/Video/View.jsx +10 -0
  146. package/src/customizations/volto/components/manage/DragDropList/DragDropList.jsx +263 -0
  147. package/src/customizations/volto/components/theme/LanguageSelector/LanguageSelector.tsx +10 -0
  148. package/src/helpers/styleDefinitions.test.tsx +30 -0
  149. package/src/helpers/styleDefinitions.ts +49 -0
  150. package/src/helpers/useLiveData.ts +7 -2
  151. package/src/index.ts +15 -0
  152. package/src/internalChecks.test.ts +94 -0
  153. package/src/primitives/Card/Card.stories.tsx +4 -1
  154. package/src/primitives/Card/Card.test.tsx +11 -33
  155. package/src/primitives/Card/Card.tsx +37 -44
  156. package/src/primitives/IconLinkList.tsx +53 -52
  157. package/src/primitives/LinkIconButton.tsx +52 -0
  158. package/src/reducers/errorContext.ts +14 -0
  159. package/src/reducers/index.ts +7 -0
  160. package/src/theme/_bgcolor-blocks-layout.scss +48 -46
  161. package/src/theme/_content.scss +12 -13
  162. package/src/theme/_export_import.scss +94 -0
  163. package/src/theme/_footer.scss +131 -64
  164. package/src/theme/_header.scss +25 -5
  165. package/src/theme/_insets.scss +1 -1
  166. package/src/theme/_layout.scss +41 -77
  167. package/src/theme/_mobile-sticky-menu.scss +92 -0
  168. package/src/theme/_search-page.scss +250 -0
  169. package/src/theme/_typo-custom.scss +24 -8
  170. package/src/theme/_variables.scss +40 -4
  171. package/src/theme/_widgets.scss +6 -17
  172. package/src/theme/blocks/_accordion.scss +11 -4
  173. package/src/theme/blocks/_form.scss +350 -0
  174. package/src/theme/blocks/_grid.scss +10 -77
  175. package/src/theme/blocks/_highlight.scss +10 -7
  176. package/src/theme/blocks/_image.scss +99 -184
  177. package/src/theme/blocks/_listing.scss +61 -128
  178. package/src/theme/blocks/_maps.scss +60 -34
  179. package/src/theme/blocks/_search.scss +3 -4
  180. package/src/theme/blocks/_table.scss +1 -0
  181. package/src/theme/blocks/_teaser.scss +7 -117
  182. package/src/theme/blocks/_toc.scss +2 -1
  183. package/src/theme/card.scss +136 -69
  184. package/src/theme/main.scss +4 -0
  185. package/src/theme/notfound.scss +2 -0
  186. package/src/theme/person.scss +7 -1
  187. package/src/theme/sticky-menu.scss +7 -5
  188. package/src/transforms/to6.ts +5 -49
  189. package/src/transforms/to8.test.js +201 -0
  190. package/src/transforms/to8.ts +109 -0
  191. package/src/types.d.ts +1 -0
  192. package/vitest.config.mjs +28 -3
  193. package/razzle.extend.js +0 -38
  194. package/src/components/Blocks/schema.js +0 -44
  195. package/src/components/Breadcrumbs/Breadcrumbs.jsx +0 -118
  196. package/src/components/Widgets/AlignWidget.tsx +0 -84
  197. package/src/components/Widgets/BlockAlignment.tsx +0 -88
  198. package/src/components/Widgets/BlockWidth.tsx +0 -101
  199. package/src/components/Widgets/Buttons.tsx +0 -167
  200. package/src/components/Widgets/Size.tsx +0 -78
@@ -2,16 +2,12 @@ import ColorSwatchWidget from './ColorSwatch';
2
2
  import config from '@plone/volto/registry';
3
3
  import type { ColorSwatchProps } from './ColorSwatch';
4
4
 
5
- const ThemeColorSwatch = (props: ColorSwatchProps) => {
6
- const colors: ColorSwatchProps['colors'] = config.blocks.themes;
5
+ const ThemeColorSwatch = (
6
+ props: Omit<ColorSwatchProps, 'themes' | 'colors'>,
7
+ ) => {
8
+ const themes: ColorSwatchProps['themes'] = config.blocks.themes;
7
9
 
8
- const defaultValue = colors.find(
9
- (color) => color.name === config.settings.defaultBackgroundColor,
10
- )?.style;
11
-
12
- return (
13
- <ColorSwatchWidget {...props} default={defaultValue} colors={colors} />
14
- );
10
+ return <ColorSwatchWidget {...props} themes={themes} />;
15
11
  };
16
12
 
17
13
  export default ThemeColorSwatch;
@@ -4,8 +4,12 @@ import type { StyleDefinition } from '@plone/types';
4
4
  import cloneDeep from 'lodash/cloneDeep';
5
5
 
6
6
  import { composeSchema } from '@plone/volto/helpers/Extensions';
7
- import { findStyleByName } from '@plone/volto/helpers/Blocks/Blocks';
8
7
  import { defaultStylingSchema } from '../components/Blocks/schema';
8
+ import {
9
+ blockThemesEnhancer,
10
+ styleDefinitionsEnhancer,
11
+ } from '../helpers/styleDefinitions';
12
+
9
13
  import {
10
14
  gridTeaserDisableStylingSchema,
11
15
  teaserSchemaEnhancer,
@@ -26,6 +30,8 @@ import {
26
30
  standAloneImageBlockSchemaEnhancer,
27
31
  } from '../components/Blocks/Image/schema';
28
32
  import { ImageBlockDataAdapter } from '../components/Blocks/Image/adapter';
33
+ import { VideoBlockDataAdapter } from '../components/Blocks/Video/adapter';
34
+ import { MapsBlockDataAdapter } from '../components/Blocks/Maps/adapter';
29
35
 
30
36
  import { AccordionSchemaEnhancer } from '../components/Blocks/Accordion/schema';
31
37
 
@@ -40,7 +46,6 @@ import { tocBlockSchemaEnhancer } from '../components/Blocks/Toc/schema';
40
46
  import { mapsBlockSchemaEnhancer } from '../components/Blocks/Maps/schema';
41
47
  import { sliderBlockSchemaEnhancer } from '../components/Blocks/Slider/schema';
42
48
  import EventMetadataView from '../components/Blocks/EventMetadata/View';
43
- import isEmpty from 'lodash/isEmpty';
44
49
 
45
50
  import SearchBlockViewEvent from '../components/Blocks/EventCalendar/Search/SearchBlockView';
46
51
  import SearchBlockEditEvent from '../components/Blocks/EventCalendar/Search/SearchBlockEdit';
@@ -51,6 +56,7 @@ declare module '@plone/types' {
51
56
  export interface BlocksConfigData {
52
57
  introduction: BlockConfigBase;
53
58
  heading: BlockConfigBase;
59
+ banner: BlockConfigBase;
54
60
  __button: BlockConfigBase;
55
61
  separator: BlockConfigBase;
56
62
  slider: BlockConfigBase;
@@ -62,6 +68,8 @@ declare module '@plone/types' {
62
68
  }
63
69
  export interface BlockConfigBase {
64
70
  themes?: StyleDefinition[];
71
+ alignments?: StyleDefinition[];
72
+ defaultTheme: string;
65
73
  allowedBlocks?: string[];
66
74
  allowed_headline_tags?: string[][];
67
75
  unwantedButtons?: string[];
@@ -76,6 +84,10 @@ declare module '@plone/types' {
76
84
  export interface SettingsConfig {
77
85
  blockModel?: number;
78
86
  }
87
+
88
+ export interface BlocksConfig {
89
+ alignments: StyleDefinition[];
90
+ }
79
91
  }
80
92
 
81
93
  export default function install(config: ConfigType) {
@@ -142,31 +154,30 @@ export default function install(config: ConfigType) {
142
154
  },
143
155
  ];
144
156
 
145
- function blockThemesEnhancer({ data, container }) {
146
- if (!data['@type']) return {};
147
- const blockConfig = config.blocks.blocksConfig[data['@type']];
148
- if (!blockConfig) return {};
149
- const blockStyleDefinitions =
150
- // We look up for the blockThemes in the block's config, then in the global config
151
- // We keep `colors` for BBB, but `themes` should be used
152
- blockConfig.themes || blockConfig.colors || config.blocks.themes || [];
153
-
154
- if (
155
- !isEmpty(container) &&
156
- container.theme &&
157
- (!data.theme || data.theme === 'default')
158
- ) {
159
- return findStyleByName(blockStyleDefinitions, container.theme);
160
- }
161
- if (data.theme) {
162
- return data.theme
163
- ? findStyleByName(blockStyleDefinitions, data.theme)
164
- : {};
165
- } else {
166
- // No theme, return default color
167
- return findStyleByName(config.blocks.themes, 'default');
168
- }
169
- }
157
+ // Default block alignments
158
+ config.blocks.alignments = [
159
+ {
160
+ style: {
161
+ '--block-alignment': 'var(--align-left)',
162
+ },
163
+ name: 'left',
164
+ label: 'Left',
165
+ },
166
+ {
167
+ style: {
168
+ '--block-alignment': 'var(--align-center)',
169
+ },
170
+ name: 'center',
171
+ label: 'Center',
172
+ },
173
+ {
174
+ style: {
175
+ '--block-alignment': 'var(--align-right)',
176
+ },
177
+ name: 'right',
178
+ label: 'Right',
179
+ },
180
+ ];
170
181
 
171
182
  config.registerUtility({
172
183
  name: 'blockThemesEnhancer',
@@ -174,6 +185,26 @@ export default function install(config: ConfigType) {
174
185
  method: blockThemesEnhancer,
175
186
  });
176
187
 
188
+ config.registerUtility({
189
+ name: 'styleDefinitionsEnhancer',
190
+ type: 'styleWrapperStyleObjectEnhancer',
191
+ method: styleDefinitionsEnhancer,
192
+ });
193
+
194
+ config.registerUtility({
195
+ name: 'align:noprefix',
196
+ type: 'styleFieldDefinition',
197
+ method: ({ data }: { data: { '@type'?: string } }) =>
198
+ config.blocks.blocksConfig?.[data?.['@type'] ?? '']?.alignments ||
199
+ config.blocks.alignments,
200
+ });
201
+
202
+ config.registerUtility({
203
+ name: 'blockWidth:noprefix',
204
+ type: 'styleFieldDefinition',
205
+ method: () => config.blocks.widths,
206
+ });
207
+
177
208
  // No required blocks except eventMetadata
178
209
  config.blocks.requiredBlocks = [
179
210
  ...config.blocks.requiredBlocks,
@@ -314,6 +345,10 @@ export default function install(config: ConfigType) {
314
345
  ),
315
346
  );
316
347
 
348
+ config.blocks.blocksConfig.banner = {
349
+ ...config.blocks.blocksConfig.banner,
350
+ schemaEnhancer: defaultStylingSchema,
351
+ };
317
352
  config.blocks.blocksConfig.introduction = {
318
353
  ...config.blocks.blocksConfig.introduction,
319
354
  unwantedButtons: ['heading-three', 'blockquote'],
@@ -334,15 +369,25 @@ export default function install(config: ConfigType) {
334
369
  category: 'title',
335
370
  };
336
371
 
372
+ const getTeaserSizes = ({ inGrid = false, columns = 1 } = {}) => {
373
+ const { defaultContainerWidth, tabletBreakpoint } = config.settings.layout;
374
+ const desktopWidth = Math.floor(
375
+ defaultContainerWidth / (inGrid ? columns : 2),
376
+ );
377
+ return `(max-width: ${tabletBreakpoint}px) 100vw, ${desktopWidth}px`;
378
+ };
379
+
337
380
  config.blocks.blocksConfig.teaser = {
338
381
  ...config.blocks.blocksConfig.teaser,
339
382
  group: 'teasers',
340
383
  imageScale: 'larger',
384
+ getSizes: getTeaserSizes,
341
385
  schemaEnhancer: composeSchema(defaultStylingSchema, teaserSchemaEnhancer),
342
386
  };
343
387
 
344
388
  config.blocks.blocksConfig.video = {
345
389
  ...config.blocks.blocksConfig.video,
390
+ dataAdapter: VideoBlockDataAdapter,
346
391
  schemaEnhancer: composeSchema(
347
392
  defaultStylingSchema,
348
393
  videoBlockSchemaEnhancer,
@@ -350,6 +395,7 @@ export default function install(config: ConfigType) {
350
395
  };
351
396
  config.blocks.blocksConfig.maps = {
352
397
  ...config.blocks.blocksConfig.maps,
398
+ dataAdapter: MapsBlockDataAdapter,
353
399
  schemaEnhancer: composeSchema(
354
400
  defaultStylingSchema,
355
401
  mapsBlockSchemaEnhancer,
@@ -416,7 +462,16 @@ export default function install(config: ConfigType) {
416
462
  };
417
463
 
418
464
  // Slider Block
419
- config.blocks.blocksConfig.slider.schemaEnhancer = sliderBlockSchemaEnhancer;
465
+ config.blocks.blocksConfig.slider = {
466
+ ...config.blocks.blocksConfig.slider,
467
+ schemaEnhancer: sliderBlockSchemaEnhancer,
468
+ };
469
+
470
+ // Highlight Block
471
+ config.blocks.blocksConfig.highlight = {
472
+ ...config.blocks.blocksConfig.highlight,
473
+ schemaEnhancer: defaultStylingSchema,
474
+ };
420
475
 
421
476
  return config;
422
477
  }
@@ -1,6 +1,5 @@
1
1
  import type { ConfigType } from '@plone/registry';
2
2
  import { getPreviousNextBlock } from '@plone/volto/helpers/Blocks/Blocks';
3
- import { getCurrentStyleByName } from '../helpers/helpers';
4
3
 
5
4
  export default function install(config: ConfigType) {
6
5
  // Register custom StyleWrapper ClassNames
@@ -71,15 +70,17 @@ export default function install(config: ConfigType) {
71
70
  config.settings.styleClassNameExtenders.push(
72
71
  ({ data, classNames }: { data: any; classNames: Array<string> }) => {
73
72
  const currentBlockWidth =
74
- getCurrentStyleByName(
75
- config.blocks.widths,
76
- 'blockWidth:noprefix',
77
- data,
78
- ) || 'default';
79
- if (currentBlockWidth) {
80
- return [...classNames, `has--block-width--${currentBlockWidth}`];
81
- }
82
- return classNames;
73
+ data?.styles?.['blockWidth:noprefix'] || 'default';
74
+ return [...classNames, `has--block-width--${currentBlockWidth}`];
75
+ },
76
+ );
77
+
78
+ // Blocks alignment convenience classes injection
79
+ config.settings.styleClassNameExtenders.push(
80
+ ({ data, classNames }: { data: any; classNames: Array<string> }) => {
81
+ const currentBlockAlignment =
82
+ data?.styles?.['align:noprefix'] || 'center';
83
+ return [...classNames, `has--block-alignment--${currentBlockAlignment}`];
83
84
  },
84
85
  );
85
86
 
@@ -28,6 +28,12 @@ export default function install(config: ConfigType) {
28
28
  config.settings.contentMetadataTagsImageField = 'preview_image';
29
29
  config.settings.querystringSearchGet = true;
30
30
 
31
+ config.settings.layout = {
32
+ ...config.settings.layout,
33
+ defaultContainerWidth: 940,
34
+ tabletBreakpoint: 768,
35
+ };
36
+
31
37
  config.settings.slidingSearchAnimation = true;
32
38
  config.settings.openExternalLinkInNewTab = true;
33
39
 
@@ -5,6 +5,7 @@ import FollowUsLogoAndLinks from '../components/Footer/slots/FollowUsLogoAndLink
5
5
  import Colophon from '../components/Footer/slots/Colophon';
6
6
  import CoreFooter from '../components/Footer/slots/CoreFooter';
7
7
  import StickyMenu from '../components/StickyMenu/StickyMenu';
8
+ import MobileStickyMenu from '../components/StickyMenu/MobileStickyMenu';
8
9
  import Anontools from '../components/Anontools/Anontools';
9
10
  import type { Content } from '@plone/types';
10
11
 
@@ -57,5 +58,11 @@ export default function install(config: ConfigType) {
57
58
  component: Colophon,
58
59
  });
59
60
 
61
+ config.registerSlotComponent({
62
+ name: 'MobileStickyMenu',
63
+ slot: 'preFooter',
64
+ component: MobileStickyMenu,
65
+ });
66
+
60
67
  return config;
61
68
  }
@@ -1,8 +1,5 @@
1
1
  import type { ConfigType } from '@plone/registry';
2
- import BlockWidth from '../components/Widgets/BlockWidth';
3
- import BlockAlignment from '../components/Widgets/BlockAlignment';
4
2
  import ColorSwatch from '../components/Widgets/ColorSwatch';
5
- import Size from '../components/Widgets/Size';
6
3
  import ColorPicker from '../components/Widgets/ColorPicker';
7
4
  import ThemeColorSwatch from '../components/Widgets/ThemeColorSwatch';
8
5
  // import BlocksObject from '../components/Widgets/BlocksObject';
@@ -12,7 +9,8 @@ import { footerLogosSchema } from '../components/Widgets/schema/footerLogosSchem
12
9
  import { footerLinksSchema } from '../components/Widgets/schema/footerLinksSchema';
13
10
  import { iconLinkListSchema } from '../components/Widgets/schema/iconLinkListSchema';
14
11
  import ModalJSONEditor from '../components/Widgets/ModalJSONEditor';
15
- import AlignWidget from '../components/Widgets/AlignWidget';
12
+ import SoftTextWidget from '../components/Widgets/SoftTextWidget';
13
+ import SoftTextareaWidget from '../components/Widgets/SoftTextareaWidget';
16
14
 
17
15
  export default function install(config: ConfigType) {
18
16
  // Color picker widget override - use our own non-semanticUI widget
@@ -20,21 +18,19 @@ export default function install(config: ConfigType) {
20
18
  // `color_picker` is a terrible name for this widget, it should be `colorSwatch`
21
19
  // ToDo: Rename it in Volto 19
22
20
  config.widgets.widget.color_picker = ColorSwatch;
21
+ config.widgets.widget.colorSwatch = ColorSwatch;
23
22
 
24
23
  // ObjectList widget override - use our own non-semanticUI widget
25
24
  // it uses also dnd-kit for drag and drop
26
25
  config.widgets.widget.object_list = ObjectList;
27
26
 
28
- config.widgets.widget.align = AlignWidget;
29
-
30
27
  // Force Preview image link widget to the image widget
31
28
  config.widgets.id.preview_image_link = config.widgets.widget.image;
32
29
 
33
- config.widgets.widget.blockWidth = BlockWidth;
34
- config.widgets.widget.blockAlignment = BlockAlignment;
35
30
  config.widgets.widget.colorPicker = ColorPicker;
36
- config.widgets.widget.size = Size;
37
31
  config.widgets.widget.themeColorSwatch = ThemeColorSwatch;
32
+ config.widgets.widget.softTextWidget = SoftTextWidget;
33
+ config.widgets.widget.softTextareaWidget = SoftTextareaWidget;
38
34
 
39
35
  config.widgets.widget.modalJSONEditor = ModalJSONEditor;
40
36
 
@@ -0,0 +1,10 @@
1
+ /**
2
+ * OVERRIDE MapsSidebar.jsx
3
+ * REASON: Route field changes through dataAdapter to enforce default block width when floating.
4
+ * DATE: 2026-04-16
5
+ * DEVELOPER: @danalvrz
6
+ */
7
+
8
+ import MapsSidebar from '../../../../../../components/Blocks/Maps/MapsSidebar';
9
+
10
+ export default MapsSidebar;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * OVERRIDE View.jsx
3
+ * REASON: Use align:noprefix and blockWidth:noprefix CSS custom properties instead of align class.
4
+ * DATE: 2026-04-16
5
+ * DEVELOPER: @danalvrz
6
+ */
7
+
8
+ import MapsView from '../../../../../../components/Blocks/Maps/View';
9
+
10
+ export default MapsView;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * OVERRIDE VideoSidebar.jsx
3
+ * REASON: Route field changes through dataAdapter to enforce default block width when floating.
4
+ * DATE: 2026-04-16
5
+ * DEVELOPER: @danalvrz
6
+ */
7
+
8
+ import VideoSidebar from '../../../../../../components/Blocks/Video/VideoSidebar';
9
+
10
+ export default VideoSidebar;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * OVERRIDE View.jsx
3
+ * REASON: Use align:noprefix and blockWidth:noprefix CSS custom properties instead of align class.
4
+ * DATE: 2026-04-16
5
+ * DEVELOPER: @danalvrz
6
+ */
7
+
8
+ import VideoView from '../../../../../../components/Blocks/Video/View';
9
+
10
+ export default VideoView;
@@ -0,0 +1,263 @@
1
+ /**
2
+ * OVERRIDE: DragDropList.jsx
3
+ * REASON: Adding BlockModelv3 guards and customizations.
4
+ * Not moved to core yet, and as it's temporary, we keep it here.
5
+ * DATE: 2025-12-01
6
+ * DEVELOPER: @sneridagh
7
+ */
8
+
9
+ import React, { useRef } from 'react';
10
+ import isEmpty from 'lodash/isEmpty';
11
+ import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
12
+ import { v4 as uuid } from 'uuid';
13
+ import config from '@plone/volto/registry';
14
+
15
+ const getVerticalPlaceholder = (
16
+ draggedDOM,
17
+ sourceIndex,
18
+ destinationIndex,
19
+ parentDOM,
20
+ ) => {
21
+ // Because of the margin rendering rules, there is no easy
22
+ // way to calculate the offset of the placeholder.
23
+ //
24
+ // (Note that this is the reason we cannot use the solutions
25
+ // published on the net, because they assume that we are in control
26
+ // of the content and there are no additional margins involved.)
27
+ //
28
+ // To get a placeholder that looks good in all cases, we
29
+ // fill up the space between the previous and the next element.
30
+ const childrenArray = [...parentDOM.children];
31
+ // Remove the source element
32
+ childrenArray.splice(sourceIndex, 1);
33
+ // Also remove the placeholder that the library always inserts at the end
34
+ childrenArray.splice(-1, 1);
35
+ const parentRect = parentDOM.getBoundingClientRect();
36
+ const prevNode = childrenArray[destinationIndex - 1];
37
+ const nextNode = childrenArray[destinationIndex];
38
+ let top, bottom;
39
+ if (prevNode) {
40
+ const prevRect = prevNode.getBoundingClientRect();
41
+ top = prevRect.top + prevRect.height - parentRect.top;
42
+ } else {
43
+ top = 0;
44
+ }
45
+ if (nextNode) {
46
+ const nextRect = nextNode.getBoundingClientRect();
47
+ bottom = nextRect.top - parentRect.top;
48
+ } else {
49
+ bottom =
50
+ parentRect.bottom +
51
+ draggedDOM.getBoundingClientRect().height -
52
+ parentRect.top;
53
+ }
54
+ return {
55
+ clientY: top,
56
+ clientHeight: bottom - top,
57
+ clientX: parseFloat(window.getComputedStyle(parentDOM).paddingLeft),
58
+ clientWidth: draggedDOM.clientWidth,
59
+ };
60
+ };
61
+
62
+ const getHorizontalPlaceholder = (draggedDOM, destinationIndex, parentDOM) => {
63
+ // The next element will be the one with a gray placeholder behind it.
64
+ //
65
+ // If the element is the last (doesn't have a next element), the whole draggable
66
+ // area will be highlighted
67
+
68
+ const parentRect = parentDOM.getBoundingClientRect();
69
+ let height;
70
+
71
+ height = parentRect.bottom - parentRect.top;
72
+
73
+ let clientWidth = draggedDOM.clientWidth;
74
+
75
+ let innerDroppablePlaceholderMarginLeft =
76
+ parentDOM.children[destinationIndex].getBoundingClientRect().x;
77
+ if (parentDOM.children.length - 1 === destinationIndex) {
78
+ innerDroppablePlaceholderMarginLeft = parentRect.x;
79
+ clientWidth = parentDOM.getBoundingClientRect().width;
80
+ }
81
+ return {
82
+ clientY: 0,
83
+ clientHeight: height,
84
+ clientX: parseFloat(innerDroppablePlaceholderMarginLeft - parentRect.x),
85
+ clientWidth: clientWidth,
86
+ };
87
+ };
88
+
89
+ const DragDropList = (props) => {
90
+ const {
91
+ childList,
92
+ children,
93
+ direction = 'vertical',
94
+ onMoveItem,
95
+ as = 'div',
96
+ style,
97
+ forwardedAriaLabelledBy,
98
+ reactBeautifulDnd,
99
+ } = props; //renderChild
100
+ const { DragDropContext, Draggable, Droppable } = reactBeautifulDnd;
101
+ const [placeholderProps, setPlaceholderProps] = React.useState({});
102
+ const [uid] = React.useState(uuid());
103
+ // queueing timed action
104
+ const timer = useRef(null);
105
+ const parentRef = useRef(null);
106
+ const onDragStart = React.useCallback(
107
+ (event) => {
108
+ clearTimeout(timer.current);
109
+ const queryAttr = 'data-rbd-draggable-id';
110
+ const domQuery = `[${queryAttr}='${event.draggableId}']`;
111
+ const draggedDOM = document.querySelector(domQuery);
112
+ if (!draggedDOM) {
113
+ return;
114
+ }
115
+ const sourceIndex = event.source.index;
116
+ setPlaceholderProps(
117
+ direction === 'horizontal'
118
+ ? getHorizontalPlaceholder(draggedDOM, sourceIndex, parentRef.current)
119
+ : getVerticalPlaceholder(
120
+ draggedDOM,
121
+ sourceIndex,
122
+ sourceIndex,
123
+ parentRef.current,
124
+ ),
125
+ );
126
+ },
127
+ [direction],
128
+ );
129
+
130
+ const onDragEnd = React.useCallback(
131
+ (result) => {
132
+ clearTimeout(timer.current);
133
+ onMoveItem(result);
134
+ setPlaceholderProps({});
135
+ },
136
+ [onMoveItem],
137
+ );
138
+
139
+ const onDragUpdate = React.useCallback(
140
+ (update) => {
141
+ clearTimeout(timer.current);
142
+ setPlaceholderProps({});
143
+ if (!update.destination) {
144
+ return;
145
+ }
146
+ const draggableId = update.draggableId;
147
+ const queryAttr = 'data-rbd-draggable-id';
148
+ const domQuery = `[${queryAttr}='${draggableId}']`;
149
+ const draggedDOM = document.querySelector(domQuery);
150
+ if (!draggedDOM) {
151
+ return;
152
+ }
153
+ const sourceIndex = update.source.index;
154
+ const destinationIndex = update.destination.index;
155
+ // Wait until the animations have finished, to make it look good.
156
+ timer.current = setTimeout(() => {
157
+ setPlaceholderProps(
158
+ direction === 'horizontal'
159
+ ? getHorizontalPlaceholder(
160
+ draggedDOM,
161
+ destinationIndex,
162
+ parentRef.current,
163
+ )
164
+ : getVerticalPlaceholder(
165
+ draggedDOM,
166
+ sourceIndex,
167
+ destinationIndex,
168
+ parentRef.current,
169
+ ),
170
+ );
171
+ }, 250);
172
+ },
173
+ [direction],
174
+ );
175
+
176
+ const AsDomComponent = as;
177
+ return (
178
+ <DragDropContext
179
+ onDragStart={onDragStart}
180
+ onDragUpdate={onDragUpdate}
181
+ onDragEnd={onDragEnd}
182
+ >
183
+ <Droppable
184
+ droppableId={uid}
185
+ direction={direction}
186
+ renderClone={(provided, snapshot, rubric) => {
187
+ const index = rubric.source.index;
188
+ return children({
189
+ child: childList[index][1],
190
+ childId: childList[index][0],
191
+ index,
192
+ draginfo: provided,
193
+ });
194
+ }}
195
+ >
196
+ {(provided, snapshot) => (
197
+ <AsDomComponent
198
+ ref={(el) => {
199
+ provided.innerRef(el);
200
+ parentRef.current = el;
201
+ }}
202
+ {...provided.droppableProps}
203
+ style={{ ...style, position: 'relative' }}
204
+ aria-labelledby={forwardedAriaLabelledBy}
205
+ >
206
+ {childList
207
+ .filter(([id, child]) => id && child) // beware numbers!
208
+ .map(([childId, child], index) => {
209
+ const dragDisabled =
210
+ config.blocks.blocksConfig?.[child?.['@type']]?.blockModel ===
211
+ 3;
212
+ if (!dragDisabled) {
213
+ return (
214
+ <Draggable
215
+ draggableId={childId.toString()}
216
+ index={index}
217
+ key={childId}
218
+ isDragDisabled={!!dragDisabled}
219
+ style={{
220
+ userSelect: 'none',
221
+ }}
222
+ >
223
+ {(draginfo) =>
224
+ children({ child, childId, index, draginfo })
225
+ }
226
+ </Draggable>
227
+ );
228
+ } else {
229
+ return (
230
+ <React.Fragment key={childId}>
231
+ {children({
232
+ child,
233
+ childId,
234
+ index,
235
+ draginfo: { draggableProps: {} },
236
+ })}
237
+ </React.Fragment>
238
+ );
239
+ }
240
+ })}
241
+ {provided.placeholder}
242
+ {!isEmpty(placeholderProps) && snapshot.isDraggingOver && (
243
+ <div
244
+ style={{
245
+ position: 'absolute',
246
+ top: placeholderProps.clientY,
247
+ left: placeholderProps.clientX,
248
+ height: placeholderProps.clientHeight,
249
+ background: '#eee',
250
+ width: placeholderProps.clientWidth,
251
+ borderRadius: '3px',
252
+ ...(direction === 'horizontal' && { zIndex: -1 }),
253
+ }}
254
+ />
255
+ )}
256
+ </AsDomComponent>
257
+ )}
258
+ </Droppable>
259
+ </DragDropContext>
260
+ );
261
+ };
262
+
263
+ export default injectLazyLibs(['reactBeautifulDnd'])(DragDropList);
@@ -0,0 +1,10 @@
1
+ /**
2
+ * OVERRIDE LanguageSelector.tsx
3
+ * REASON: Show only two letters of the native language name.
4
+ * SemanticUI-free located at the components folder.
5
+ * To override it, override the @kitconcept/volto-light-theme one instead of
6
+ * this one.
7
+ */
8
+ import LanguageSelector from '../../../../../components/LanguageSelector/LanguageSelector';
9
+
10
+ export default LanguageSelector;