@kitconcept/volto-light-theme 6.0.0-alpha.8 → 6.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 (101) hide show
  1. package/.changelog.draft +1 -5
  2. package/CHANGELOG.md +226 -0
  3. package/README.md +6 -5
  4. package/locales/de/LC_MESSAGES/volto.po +171 -38
  5. package/locales/en/LC_MESSAGES/volto.po +170 -37
  6. package/locales/es/LC_MESSAGES/volto.po +171 -38
  7. package/locales/eu/LC_MESSAGES/volto.po +171 -38
  8. package/locales/pt_BR/volto.po +171 -38
  9. package/locales/volto.pot +171 -38
  10. package/package.json +15 -6
  11. package/src/components/Blocks/EventMetadata/View.jsx +32 -26
  12. package/src/components/Blocks/Listing/DefaultTemplate.jsx +19 -14
  13. package/src/components/Blocks/Listing/GridTemplate.jsx +9 -12
  14. package/src/components/Blocks/Listing/SummaryTemplate.jsx +9 -7
  15. package/src/components/Blocks/Teaser/DefaultBody.jsx +93 -0
  16. package/src/components/Blocks/Teaser/schema.js +1 -7
  17. package/src/components/Footer/ColumnLinks.tsx +35 -0
  18. package/src/components/Footer/Footer.tsx +32 -0
  19. package/src/components/Footer/slots/Colophon.tsx +24 -0
  20. package/src/components/Footer/slots/Copyright.tsx +65 -0
  21. package/src/components/Footer/slots/CoreFooter.tsx +82 -0
  22. package/src/components/Footer/slots/FollowUsLogoAndLinks.tsx +80 -0
  23. package/src/components/Footer/slots/FooterLogos.tsx +44 -0
  24. package/src/components/Header/Header.tsx +257 -0
  25. package/src/components/Logo/Logo.tsx +85 -0
  26. package/src/components/{Footer/FooterLogos.tsx → LogosContainer/LogosContainer.tsx} +24 -25
  27. package/src/components/MobileNavigation/MobileNavigation.jsx +53 -18
  28. package/src/components/Navigation/Navigation.jsx +14 -3
  29. package/src/components/SearchWidget/IntranetSearchWidget.jsx +32 -5
  30. package/src/components/SearchWidget/SearchWidget.jsx +1 -1
  31. package/src/components/StickyMenu/StickyMenu.tsx +36 -0
  32. package/src/components/Summary/DefaultSummary.jsx +16 -0
  33. package/src/components/Summary/EventSummary.jsx +38 -0
  34. package/src/components/Summary/FileSummary.jsx +24 -0
  35. package/src/components/Summary/NewsItemSummary.jsx +40 -0
  36. package/src/components/Tags/Tags.jsx +46 -0
  37. package/src/components/Theme/EventView.jsx +19 -25
  38. package/src/components/Theme/NewsItemView.jsx +13 -9
  39. package/src/components/Theming/Theming.tsx +20 -17
  40. package/src/components/Widgets/{BlockAlignmentWidget.tsx → BlockAlignment.tsx} +9 -2
  41. package/src/components/Widgets/{BlockWidthWidget.tsx → BlockWidth.tsx} +10 -3
  42. package/src/components/Widgets/BlocksObject.tsx +353 -0
  43. package/src/components/Widgets/Buttons.tsx +117 -0
  44. package/src/components/Widgets/ColorContrastChecker.tsx +117 -0
  45. package/src/components/Widgets/ColorPicker.tsx +59 -0
  46. package/src/components/Widgets/{ColorPickerWidget.tsx → ColorSwatch.tsx} +5 -5
  47. package/src/components/Widgets/ObjectList.tsx +342 -0
  48. package/src/components/Widgets/{ThemingColorPicker.tsx → RACThemingColorPicker.tsx} +4 -0
  49. package/src/components/Widgets/Size.tsx +75 -0
  50. package/src/components/Widgets/ThemeColorSwatch.tsx +17 -0
  51. package/src/components/Widgets/schema/footerLinksSchema.ts +64 -0
  52. package/src/components/Widgets/schema/footerLogosSchema.ts +98 -0
  53. package/src/components/Widgets/schema/headerActionsSchema.ts +64 -0
  54. package/src/components/Widgets/schema/iconLinkListSchema.ts +98 -0
  55. package/src/config/blocks.tsx +39 -20
  56. package/src/config/settings.ts +54 -12
  57. package/src/config/slots.ts +36 -1
  58. package/src/config/summary.ts +24 -0
  59. package/src/config/widgets.ts +57 -20
  60. package/src/customizations/volto/components/manage/Blocks/Teaser/DefaultBody.jsx +8 -0
  61. package/src/customizations/volto/components/theme/Tags/Tags.jsx +11 -0
  62. package/src/customizations/volto/components/theme/View/RenderBlocks.jsx +2 -1
  63. package/src/helpers/DndSortableList.tsx +138 -0
  64. package/src/helpers/dates.js +22 -0
  65. package/src/helpers/doesNodeContainClick.js +64 -0
  66. package/src/helpers/useLiveData.ts +29 -0
  67. package/src/index.ts +33 -2
  68. package/src/primitives/IconLinkList.tsx +69 -0
  69. package/src/primitives/LinkList.tsx +35 -0
  70. package/src/theme/_bgcolor-blocks-layout.scss +50 -12
  71. package/src/theme/_container.scss +4 -0
  72. package/src/theme/_content.scss +6 -0
  73. package/src/theme/_footer.scss +295 -43
  74. package/src/theme/_header.scss +132 -19
  75. package/src/theme/_layout.scss +11 -1
  76. package/src/theme/_sitemap.scss +4 -0
  77. package/src/theme/_utils.scss +14 -1
  78. package/src/theme/_variables.scss +12 -3
  79. package/src/theme/_widgets.scss +102 -10
  80. package/src/theme/blocks/_eventMetadata.scss +5 -2
  81. package/src/theme/blocks/_grid.scss +3 -3
  82. package/src/theme/blocks/_highlight.scss +17 -44
  83. package/src/theme/blocks/_listing.scss +25 -16
  84. package/src/theme/blocks/_maps.scss +3 -3
  85. package/src/theme/blocks/_slider.scss +5 -1
  86. package/src/theme/main.scss +1 -0
  87. package/src/theme/sticky-menu.scss +50 -0
  88. package/src/types.d.ts +102 -0
  89. package/tsconfig.json +1 -1
  90. package/src/components/Footer/Footer.jsx +0 -115
  91. package/src/components/Footer/FooterLinks.tsx +0 -57
  92. package/src/components/Header/Header.jsx +0 -161
  93. package/src/components/Logo/Logo.jsx +0 -51
  94. package/src/components/Widgets/AlignWidget.jsx +0 -80
  95. package/src/components/Widgets/BackgroundColorWidget.tsx +0 -17
  96. package/src/components/Widgets/BlocksObjectWidget.tsx +0 -333
  97. package/src/components/Widgets/ButtonsWidget.tsx +0 -68
  98. package/src/components/Widgets/FooterLinksWidget.tsx +0 -106
  99. package/src/components/Widgets/FooterLogosWidget.tsx +0 -120
  100. package/src/static/container-query-polyfill.modern.js +0 -1
  101. package/src/types/index.d.ts +0 -1
@@ -0,0 +1,342 @@
1
+ import { useState } from 'react';
2
+ import { defineMessages, useIntl } from 'react-intl';
3
+ import { Button } from '@plone/components';
4
+ import { Text } from 'react-aria-components';
5
+ import Icon from '@plone/volto/components/theme/Icon/Icon';
6
+ import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
7
+ import { applySchemaDefaults } from '@plone/volto/helpers/Blocks/Blocks';
8
+ import { reorderArray } from '@plone/volto/helpers/Utils/Utils';
9
+ import AnimateHeight from 'react-animate-height';
10
+ import ObjectWidget from '@plone/volto/components/manage/Widgets/ObjectWidget';
11
+ import DndSortableList from '../../helpers/DndSortableList';
12
+ import cx from 'classnames';
13
+ import upSVG from '@plone/volto/icons/up-key.svg';
14
+ import downSVG from '@plone/volto/icons/down-key.svg';
15
+ import deleteSVG from '@plone/volto/icons/delete.svg';
16
+ import addSVG from '@plone/volto/icons/add.svg';
17
+ import dragSVG from '@plone/volto/icons/drag.svg';
18
+ import { v4 as uuid } from 'uuid';
19
+ import type { BlockConfigBase, Content, JSONSchema } from '@plone/types';
20
+ import type { IntlShape } from 'react-intl';
21
+ import config from '@plone/volto/registry';
22
+ import isEmpty from 'lodash/isEmpty';
23
+
24
+ const messages = defineMessages({
25
+ labelRemoveItem: {
26
+ id: 'Remove item',
27
+ defaultMessage: 'Remove item',
28
+ },
29
+ labelCollapseItem: {
30
+ id: 'Collapse item',
31
+ defaultMessage: 'Collapse item',
32
+ },
33
+ labelShowItem: {
34
+ id: 'Show item',
35
+ defaultMessage: 'Show item',
36
+ },
37
+ emptyObjectList: {
38
+ id: 'Empty object list',
39
+ defaultMessage: 'Empty object list',
40
+ },
41
+ add: {
42
+ id: 'Add (object list)',
43
+ defaultMessage: 'Add',
44
+ },
45
+ });
46
+
47
+ export type ObjectListWidgetSchema =
48
+ | (JSONSchema & { addMessage: string })
49
+ | ((props: ObjectListWidgetProps) => JSONSchema & { addMessage: string });
50
+
51
+ export type ObjectListWidgetProps = {
52
+ /**
53
+ * The ID of the widget.
54
+ */
55
+ id: string;
56
+ /**
57
+ * The ID of the block this widget belongs to.
58
+ */
59
+ block: string;
60
+ /**
61
+ * The fieldset this widget belongs to.
62
+ */
63
+ fieldSet: string;
64
+ /**
65
+ * The title of the widget.
66
+ */
67
+ title: string;
68
+ /**
69
+ * The current value of the widget, which is BlocksData.
70
+ */
71
+ value?: Array<Record<string, any>>;
72
+ /**
73
+ * The default value for the widget. Can be a string or an object.
74
+ */
75
+ default?: string | object;
76
+ /**
77
+ * Whether the widget is required.
78
+ */
79
+ required?: boolean;
80
+ /**
81
+ * The value to use when the widget is missing a value.
82
+ */
83
+ missing_value?: unknown;
84
+ /**
85
+ * The CSS class name for the widget.
86
+ */
87
+ className?: string;
88
+ /**
89
+ * A callback function that is called when the value of the widget changes.
90
+ * @param id The ID of the widget.
91
+ * @param value The new value of the widget.
92
+ */
93
+ onChange: (id: string, value: any) => void;
94
+ /**
95
+ * The index of the currently active object.
96
+ */
97
+ activeObject: number;
98
+ /**
99
+ * A callback function that is called to set the active object.
100
+ * @param index The index of the object to set as active.
101
+ */
102
+ setActiveObject: (index: number) => void;
103
+ /**
104
+ * The schema for the ObjectListWidget.
105
+ */
106
+ schema?: ObjectListWidgetSchema;
107
+ /**
108
+ * The name of the schema.
109
+ */
110
+ schemaName?: string | undefined;
111
+ /**
112
+ * An optional function to enhance the schema.
113
+ * @param args An object containing the schema, form data, intl, navRoot, and contentType.
114
+ */
115
+ schemaEnhancer?: (args: {
116
+ schema: JSONSchema & { addMessage: string };
117
+ formData: BlockConfigBase;
118
+ intl: IntlShape;
119
+ navRoot: Content;
120
+ contentType: string;
121
+ }) => JSONSchema;
122
+ };
123
+
124
+ const EMPTY_SCHEMA = {
125
+ fieldsets: [
126
+ {
127
+ id: 'default',
128
+ title: 'Default',
129
+ fields: [],
130
+ },
131
+ ],
132
+ properties: {},
133
+ required: [],
134
+ };
135
+
136
+ const ObjectListWidget = (props: ObjectListWidgetProps) => {
137
+ const {
138
+ block,
139
+ fieldSet,
140
+ id,
141
+ value = [],
142
+ onChange,
143
+ schemaEnhancer,
144
+ schemaName,
145
+ } = props;
146
+
147
+ const schema =
148
+ config.getUtility({
149
+ type: 'schema',
150
+ name: schemaName,
151
+ }).method ||
152
+ props.schema ||
153
+ EMPTY_SCHEMA;
154
+
155
+ const [localActiveObject, setLocalActiveObject] = useState(
156
+ props.activeObject ?? value?.length - 1,
157
+ );
158
+
159
+ let activeObject: number, setActiveObject: (index: number) => void;
160
+ if (
161
+ (props.activeObject || props.activeObject === 0) &&
162
+ props.setActiveObject
163
+ ) {
164
+ activeObject = props.activeObject;
165
+ setActiveObject = props.setActiveObject;
166
+ } else {
167
+ activeObject = localActiveObject;
168
+ setActiveObject = setLocalActiveObject;
169
+ }
170
+
171
+ const intl = useIntl();
172
+
173
+ function handleChangeActiveObject(index) {
174
+ const newIndex = activeObject === index ? -1 : index;
175
+
176
+ setActiveObject(newIndex);
177
+ }
178
+
179
+ const objectSchema = typeof schema === 'function' ? schema(props) : schema;
180
+
181
+ function handleDragEnd(event) {
182
+ const { active, over } = event;
183
+
184
+ if (active.id !== over.id) {
185
+ const source = value.findIndex((item) => item['@id'] === active.id);
186
+ const destination = value.findIndex((item) => item['@id'] === over.id);
187
+
188
+ const newValue = reorderArray(value, source, destination);
189
+ onChange(id, newValue);
190
+ }
191
+ }
192
+
193
+ return (
194
+ <div className="object-list-widget">
195
+ <FormFieldWrapper {...props} noForInFieldLabel className="objectlist">
196
+ <div className="add-item-button-wrapper">
197
+ <Button
198
+ aria-label={
199
+ objectSchema.addMessage ||
200
+ `${intl.formatMessage(messages.add)} ${objectSchema.title}`
201
+ }
202
+ onPress={() => {
203
+ const data = {
204
+ '@id': uuid(),
205
+ };
206
+
207
+ const objSchema = schemaEnhancer
208
+ ? // @ts-ignore - TODO Make sure this continues to have sense
209
+ schemaEnhancer({ schema: objectSchema, formData: data, intl })
210
+ : objectSchema;
211
+ const dataWithDefaults = applySchemaDefaults({
212
+ data,
213
+ schema: objSchema,
214
+ intl,
215
+ });
216
+
217
+ onChange(id, [...(value || []), dataWithDefaults]);
218
+ setActiveObject(value?.length || 0);
219
+ }}
220
+ >
221
+ <Icon name={addSVG} size="18px" />
222
+ {/* Custom addMessage in schema, else default to English */}
223
+ <Text>
224
+ {objectSchema.addMessage ||
225
+ `${intl.formatMessage(messages.add)} ${objectSchema.title}`}
226
+ </Text>
227
+ </Button>
228
+ </div>
229
+ {value?.length === 0 && (
230
+ <input
231
+ aria-labelledby={`fieldset-${
232
+ fieldSet || 'default'
233
+ }-field-label-${id}`}
234
+ type="hidden"
235
+ value={intl.formatMessage(messages.emptyObjectList)}
236
+ />
237
+ )}
238
+ </FormFieldWrapper>
239
+ {!isEmpty(value) && (
240
+ <DndSortableList
241
+ items={value || []}
242
+ handleDragEnd={handleDragEnd}
243
+ activeObject={activeObject}
244
+ setActiveObject={setActiveObject}
245
+ >
246
+ {({ item, uid, index, attributes, listeners }) => {
247
+ return (
248
+ <div
249
+ className={cx('olw-item-wrapper', {
250
+ active: activeObject === index,
251
+ })}
252
+ key={uid}
253
+ >
254
+ <div
255
+ className="olw-item-title-bar"
256
+ onClick={() => handleChangeActiveObject(index)}
257
+ role="presentation"
258
+ aria-label={`${
259
+ activeObject === index
260
+ ? intl.formatMessage(messages.labelCollapseItem)
261
+ : intl.formatMessage(messages.labelShowItem)
262
+ } #${index ? index + 1 : ''}`}
263
+ >
264
+ <div className="drag handle" {...listeners} {...attributes}>
265
+ <Icon name={dragSVG} size="18px" />
266
+ </div>
267
+
268
+ <div className="olw-item-title">
269
+ {item.title ||
270
+ `${objectSchema.title} #${index !== undefined ? index + 1 : ''}`}
271
+ </div>
272
+ <div className="olw-tools">
273
+ <div
274
+ role="presentation"
275
+ onClick={(e) => {
276
+ e.stopPropagation();
277
+ }}
278
+ >
279
+ <Button
280
+ aria-label={`${intl.formatMessage(
281
+ messages.labelRemoveItem,
282
+ )} #${index + 1}`}
283
+ onPress={() => {
284
+ onChange(
285
+ id,
286
+ value.filter((v, i) => i !== index),
287
+ );
288
+ }}
289
+ >
290
+ <Icon name={deleteSVG} size="20px" color="#e40166" />
291
+ </Button>
292
+ </div>
293
+ {activeObject === index ? (
294
+ <Icon name={upSVG} size="20px" />
295
+ ) : (
296
+ <Icon name={downSVG} size="20px" />
297
+ )}
298
+ </div>
299
+ </div>
300
+ <AnimateHeight
301
+ animateOpacity
302
+ duration={300}
303
+ height={activeObject === index ? 'auto' : 0}
304
+ >
305
+ <div
306
+ className={cx('olw-item-content', {
307
+ active: activeObject === index,
308
+ })}
309
+ >
310
+ <ObjectWidget
311
+ id={`${uid}`}
312
+ key={`olw-${uid}`}
313
+ block={block}
314
+ schema={
315
+ schemaEnhancer
316
+ ? // @ts-ignore - TODO Make sure this continues to have sense
317
+ schemaEnhancer({
318
+ schema: objectSchema,
319
+ formData: item,
320
+ intl,
321
+ })
322
+ : objectSchema
323
+ }
324
+ value={item}
325
+ onChange={(fieldId: string, fieldValue: any) => {
326
+ const newvalue = value.map((v, i) =>
327
+ i !== index ? v : fieldValue,
328
+ );
329
+ onChange(id, newvalue);
330
+ }}
331
+ />
332
+ </div>
333
+ </AnimateHeight>
334
+ </div>
335
+ );
336
+ }}
337
+ </DndSortableList>
338
+ )}
339
+ </div>
340
+ );
341
+ };
342
+ export default ObjectListWidget;
@@ -1,3 +1,7 @@
1
+ // Description: A color picker widget using react-aria-components
2
+ // color picker component. Put in the fridge for now because
3
+ // it had performance problems with Volto sidebar.
4
+ // For now, using `ColorPicker` widget instead.
1
5
  import { ColorField, ColorPicker } from '@plone/components';
2
6
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
3
7
 
@@ -0,0 +1,75 @@
1
+ import { defineMessages, useIntl } from 'react-intl';
2
+ import ButtonsWidget, {
3
+ type ActionInfo,
4
+ type ButtonsWidgetProps,
5
+ } from './Buttons';
6
+ import type { IntlShape } from 'react-intl';
7
+
8
+ const messages = defineMessages({
9
+ s: {
10
+ id: 'Small',
11
+ defaultMessage: 'Small',
12
+ },
13
+ m: {
14
+ id: 'Medium',
15
+ defaultMessage: 'Medium',
16
+ },
17
+ l: {
18
+ id: 'Large',
19
+ defaultMessage: 'Large',
20
+ },
21
+ });
22
+
23
+ export const defaultActionsInfo = ({
24
+ intl,
25
+ }: {
26
+ intl: IntlShape;
27
+ }): Record<string, ActionInfo> => ({
28
+ s: ['S', intl.formatMessage(messages.s)],
29
+ m: ['M', intl.formatMessage(messages.m)],
30
+ l: ['L', intl.formatMessage(messages.l)],
31
+ });
32
+
33
+ const DEFAULT_ACTIONS = [
34
+ {
35
+ name: 's',
36
+ label: 'Small',
37
+ },
38
+ {
39
+ name: 'm',
40
+ label: 'Medium',
41
+ },
42
+ {
43
+ name: 'l',
44
+ label: 'Large',
45
+ },
46
+ ];
47
+
48
+ const SizeWidget = (props: ButtonsWidgetProps) => {
49
+ const intl = useIntl();
50
+
51
+ const { actions = DEFAULT_ACTIONS, actionsInfoMap, filterActions } = props;
52
+ let filteredActions;
53
+ if (filterActions) {
54
+ filteredActions = actions.filter((action) =>
55
+ filterActions.includes(action.name),
56
+ );
57
+ } else {
58
+ filteredActions = actions;
59
+ }
60
+
61
+ const actionsInfo = {
62
+ ...defaultActionsInfo({ intl }),
63
+ ...actionsInfoMap,
64
+ };
65
+
66
+ return (
67
+ <ButtonsWidget
68
+ {...props}
69
+ actions={filteredActions}
70
+ actionsInfoMap={actionsInfo}
71
+ />
72
+ );
73
+ };
74
+
75
+ export default SizeWidget;
@@ -0,0 +1,17 @@
1
+ import ColorSwatchWidget from './ColorSwatch';
2
+ import config from '@plone/volto/registry';
3
+ import type { ColorSwatchProps } from './ColorSwatch';
4
+
5
+ const ThemeColorSwatch = (props: ColorSwatchProps) => {
6
+ const colors: ColorSwatchProps['colors'] = config.blocks.themes;
7
+
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
+ );
15
+ };
16
+
17
+ export default ThemeColorSwatch;
@@ -0,0 +1,64 @@
1
+ import type { BlockEditProps } from '@plone/types';
2
+ import { defineMessages } from 'react-intl';
3
+ import type { IntlShape } from 'react-intl';
4
+
5
+ const messages = defineMessages({
6
+ title: {
7
+ id: 'Title',
8
+ defaultMessage: 'Title',
9
+ },
10
+ item: {
11
+ id: 'Link',
12
+ defaultMessage: 'Link',
13
+ },
14
+ addLink: {
15
+ id: 'Add link',
16
+ defaultMessage: 'Add link',
17
+ },
18
+ Target: {
19
+ id: 'Target',
20
+ defaultMessage: 'Target',
21
+ },
22
+ openLinkInNewTab: {
23
+ id: 'Open in a new tab',
24
+ defaultMessage: 'Open in a new tab',
25
+ },
26
+ });
27
+
28
+ export function footerLinksSchema({
29
+ props,
30
+ intl,
31
+ }: {
32
+ props: BlockEditProps;
33
+ intl: IntlShape;
34
+ }) {
35
+ return {
36
+ title: intl.formatMessage(messages.item),
37
+ addMessage: intl.formatMessage(messages.addLink),
38
+ fieldsets: [
39
+ {
40
+ id: 'default',
41
+ title: 'Default',
42
+ fields: ['title', 'href', 'openLinkInNewTab'],
43
+ },
44
+ ],
45
+
46
+ properties: {
47
+ title: {
48
+ title: intl.formatMessage(messages.title),
49
+ },
50
+ href: {
51
+ title: intl.formatMessage(messages.Target),
52
+ widget: 'object_browser',
53
+ mode: 'link',
54
+ selectedItemAttrs: ['Title', 'Description', '@type'],
55
+ allowExternals: true,
56
+ },
57
+ openLinkInNewTab: {
58
+ title: intl.formatMessage(messages.openLinkInNewTab),
59
+ type: 'boolean',
60
+ },
61
+ },
62
+ required: [],
63
+ };
64
+ }
@@ -0,0 +1,98 @@
1
+ import type { BlockEditProps } from '@plone/types';
2
+ import { defineMessages } from 'react-intl';
3
+ import type { IntlShape } from 'react-intl';
4
+
5
+ const messages = defineMessages({
6
+ Target: {
7
+ id: 'Target',
8
+ defaultMessage: 'Target',
9
+ },
10
+ title: {
11
+ id: 'Title',
12
+ defaultMessage: 'Title',
13
+ },
14
+ AltText: {
15
+ id: 'Alt text',
16
+ defaultMessage: 'Alt text',
17
+ },
18
+ description: {
19
+ id: 'Description',
20
+ defaultMessage: 'Description',
21
+ },
22
+ logo: {
23
+ id: 'Logo image',
24
+ defaultMessage: 'Logo image',
25
+ },
26
+ item: {
27
+ id: 'Logo',
28
+ defaultMessage: 'Logo',
29
+ },
30
+ addLogo: {
31
+ id: 'Add logo',
32
+ defaultMessage: 'Add logo',
33
+ },
34
+ headline: {
35
+ id: 'Headline',
36
+ defaultMessage: 'Headline',
37
+ },
38
+ hideDescription: {
39
+ id: 'Hide description',
40
+ defaultMessage: 'Hide description',
41
+ },
42
+ settings: {
43
+ id: 'Settings',
44
+ defaultMessage: 'Settings',
45
+ },
46
+ openLinkInNewTab: {
47
+ id: 'Open in a new tab',
48
+ defaultMessage: 'Open in a new tab',
49
+ },
50
+ });
51
+
52
+ export function footerLogosSchema({
53
+ props,
54
+ intl,
55
+ }: {
56
+ props: BlockEditProps;
57
+ intl: IntlShape;
58
+ }) {
59
+ return {
60
+ title: intl.formatMessage(messages.item),
61
+ addMessage: intl.formatMessage(messages.addLogo),
62
+ fieldsets: [
63
+ {
64
+ id: 'default',
65
+ title: 'Default',
66
+ fields: ['logo', 'alt', 'href', 'openLinkInNewTab'],
67
+ },
68
+ ],
69
+
70
+ properties: {
71
+ title: {
72
+ title: intl.formatMessage(messages.title),
73
+ },
74
+ logo: {
75
+ title: intl.formatMessage(messages.logo),
76
+ widget: 'object_browser',
77
+ selectedItemAttrs: ['Title', 'Description', 'image_field', '@type'],
78
+ mode: 'image',
79
+ allowExternals: true,
80
+ },
81
+ alt: {
82
+ title: intl.formatMessage(messages.AltText),
83
+ },
84
+ href: {
85
+ title: intl.formatMessage(messages.Target),
86
+ widget: 'object_browser',
87
+ mode: 'link',
88
+ selectedItemAttrs: ['Title', 'Description'],
89
+ allowExternals: true,
90
+ },
91
+ openLinkInNewTab: {
92
+ title: intl.formatMessage(messages.openLinkInNewTab),
93
+ type: 'boolean',
94
+ },
95
+ },
96
+ required: [],
97
+ };
98
+ }
@@ -0,0 +1,64 @@
1
+ import type { BlockEditProps } from '@plone/types';
2
+ import { defineMessages } from 'react-intl';
3
+ import type { IntlShape } from 'react-intl';
4
+
5
+ const messages = defineMessages({
6
+ title: {
7
+ id: 'Title',
8
+ defaultMessage: 'Title',
9
+ },
10
+ item: {
11
+ id: 'Action',
12
+ defaultMessage: 'Action',
13
+ },
14
+ addAction: {
15
+ id: 'Add action',
16
+ defaultMessage: 'Add action',
17
+ },
18
+ Target: {
19
+ id: 'Target',
20
+ defaultMessage: 'Target',
21
+ },
22
+ openLinkInNewTab: {
23
+ id: 'Open in a new tab',
24
+ defaultMessage: 'Open in a new tab',
25
+ },
26
+ });
27
+
28
+ export function headerActionsSchema({
29
+ props,
30
+ intl,
31
+ }: {
32
+ props: BlockEditProps;
33
+ intl: IntlShape;
34
+ }) {
35
+ return {
36
+ title: intl.formatMessage(messages.item),
37
+ addMessage: intl.formatMessage(messages.addAction),
38
+ fieldsets: [
39
+ {
40
+ id: 'default',
41
+ title: 'Default',
42
+ fields: ['title', 'href', 'openLinkInNewTab'],
43
+ },
44
+ ],
45
+
46
+ properties: {
47
+ title: {
48
+ title: intl.formatMessage(messages.title),
49
+ },
50
+ href: {
51
+ title: intl.formatMessage(messages.Target),
52
+ widget: 'object_browser',
53
+ mode: 'link',
54
+ selectedItemAttrs: ['Title', 'Description', '@type'],
55
+ allowExternals: true,
56
+ },
57
+ openLinkInNewTab: {
58
+ title: intl.formatMessage(messages.openLinkInNewTab),
59
+ type: 'boolean',
60
+ },
61
+ },
62
+ required: [],
63
+ };
64
+ }