@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.
- package/.changelog.draft +1 -5
- package/CHANGELOG.md +226 -0
- package/README.md +6 -5
- package/locales/de/LC_MESSAGES/volto.po +171 -38
- package/locales/en/LC_MESSAGES/volto.po +170 -37
- package/locales/es/LC_MESSAGES/volto.po +171 -38
- package/locales/eu/LC_MESSAGES/volto.po +171 -38
- package/locales/pt_BR/volto.po +171 -38
- package/locales/volto.pot +171 -38
- package/package.json +15 -6
- package/src/components/Blocks/EventMetadata/View.jsx +32 -26
- package/src/components/Blocks/Listing/DefaultTemplate.jsx +19 -14
- package/src/components/Blocks/Listing/GridTemplate.jsx +9 -12
- package/src/components/Blocks/Listing/SummaryTemplate.jsx +9 -7
- package/src/components/Blocks/Teaser/DefaultBody.jsx +93 -0
- package/src/components/Blocks/Teaser/schema.js +1 -7
- package/src/components/Footer/ColumnLinks.tsx +35 -0
- package/src/components/Footer/Footer.tsx +32 -0
- package/src/components/Footer/slots/Colophon.tsx +24 -0
- package/src/components/Footer/slots/Copyright.tsx +65 -0
- package/src/components/Footer/slots/CoreFooter.tsx +82 -0
- package/src/components/Footer/slots/FollowUsLogoAndLinks.tsx +80 -0
- package/src/components/Footer/slots/FooterLogos.tsx +44 -0
- package/src/components/Header/Header.tsx +257 -0
- package/src/components/Logo/Logo.tsx +85 -0
- package/src/components/{Footer/FooterLogos.tsx → LogosContainer/LogosContainer.tsx} +24 -25
- package/src/components/MobileNavigation/MobileNavigation.jsx +53 -18
- package/src/components/Navigation/Navigation.jsx +14 -3
- package/src/components/SearchWidget/IntranetSearchWidget.jsx +32 -5
- package/src/components/SearchWidget/SearchWidget.jsx +1 -1
- package/src/components/StickyMenu/StickyMenu.tsx +36 -0
- package/src/components/Summary/DefaultSummary.jsx +16 -0
- package/src/components/Summary/EventSummary.jsx +38 -0
- package/src/components/Summary/FileSummary.jsx +24 -0
- package/src/components/Summary/NewsItemSummary.jsx +40 -0
- package/src/components/Tags/Tags.jsx +46 -0
- package/src/components/Theme/EventView.jsx +19 -25
- package/src/components/Theme/NewsItemView.jsx +13 -9
- package/src/components/Theming/Theming.tsx +20 -17
- package/src/components/Widgets/{BlockAlignmentWidget.tsx → BlockAlignment.tsx} +9 -2
- package/src/components/Widgets/{BlockWidthWidget.tsx → BlockWidth.tsx} +10 -3
- package/src/components/Widgets/BlocksObject.tsx +353 -0
- package/src/components/Widgets/Buttons.tsx +117 -0
- package/src/components/Widgets/ColorContrastChecker.tsx +117 -0
- package/src/components/Widgets/ColorPicker.tsx +59 -0
- package/src/components/Widgets/{ColorPickerWidget.tsx → ColorSwatch.tsx} +5 -5
- package/src/components/Widgets/ObjectList.tsx +342 -0
- package/src/components/Widgets/{ThemingColorPicker.tsx → RACThemingColorPicker.tsx} +4 -0
- package/src/components/Widgets/Size.tsx +75 -0
- package/src/components/Widgets/ThemeColorSwatch.tsx +17 -0
- package/src/components/Widgets/schema/footerLinksSchema.ts +64 -0
- package/src/components/Widgets/schema/footerLogosSchema.ts +98 -0
- package/src/components/Widgets/schema/headerActionsSchema.ts +64 -0
- package/src/components/Widgets/schema/iconLinkListSchema.ts +98 -0
- package/src/config/blocks.tsx +39 -20
- package/src/config/settings.ts +54 -12
- package/src/config/slots.ts +36 -1
- package/src/config/summary.ts +24 -0
- package/src/config/widgets.ts +57 -20
- package/src/customizations/volto/components/manage/Blocks/Teaser/DefaultBody.jsx +8 -0
- package/src/customizations/volto/components/theme/Tags/Tags.jsx +11 -0
- package/src/customizations/volto/components/theme/View/RenderBlocks.jsx +2 -1
- package/src/helpers/DndSortableList.tsx +138 -0
- package/src/helpers/dates.js +22 -0
- package/src/helpers/doesNodeContainClick.js +64 -0
- package/src/helpers/useLiveData.ts +29 -0
- package/src/index.ts +33 -2
- package/src/primitives/IconLinkList.tsx +69 -0
- package/src/primitives/LinkList.tsx +35 -0
- package/src/theme/_bgcolor-blocks-layout.scss +50 -12
- package/src/theme/_container.scss +4 -0
- package/src/theme/_content.scss +6 -0
- package/src/theme/_footer.scss +295 -43
- package/src/theme/_header.scss +132 -19
- package/src/theme/_layout.scss +11 -1
- package/src/theme/_sitemap.scss +4 -0
- package/src/theme/_utils.scss +14 -1
- package/src/theme/_variables.scss +12 -3
- package/src/theme/_widgets.scss +102 -10
- package/src/theme/blocks/_eventMetadata.scss +5 -2
- package/src/theme/blocks/_grid.scss +3 -3
- package/src/theme/blocks/_highlight.scss +17 -44
- package/src/theme/blocks/_listing.scss +25 -16
- package/src/theme/blocks/_maps.scss +3 -3
- package/src/theme/blocks/_slider.scss +5 -1
- package/src/theme/main.scss +1 -0
- package/src/theme/sticky-menu.scss +50 -0
- package/src/types.d.ts +102 -0
- package/tsconfig.json +1 -1
- package/src/components/Footer/Footer.jsx +0 -115
- package/src/components/Footer/FooterLinks.tsx +0 -57
- package/src/components/Header/Header.jsx +0 -161
- package/src/components/Logo/Logo.jsx +0 -51
- package/src/components/Widgets/AlignWidget.jsx +0 -80
- package/src/components/Widgets/BackgroundColorWidget.tsx +0 -17
- package/src/components/Widgets/BlocksObjectWidget.tsx +0 -333
- package/src/components/Widgets/ButtonsWidget.tsx +0 -68
- package/src/components/Widgets/FooterLinksWidget.tsx +0 -106
- package/src/components/Widgets/FooterLogosWidget.tsx +0 -120
- package/src/static/container-query-polyfill.modern.js +0 -1
- 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
|
+
}
|