@kitconcept/volto-light-theme 8.0.0-alpha.28 → 8.0.0-alpha.29
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 +23 -3
- package/CHANGELOG.md +27 -0
- package/locales/af/LC_MESSAGES/volto.po +645 -0
- package/locales/ar/LC_MESSAGES/volto.po +645 -0
- package/locales/bg/LC_MESSAGES/volto.po +645 -0
- package/locales/bn/LC_MESSAGES/volto.po +645 -0
- package/locales/ca/LC_MESSAGES/volto.po +645 -0
- package/locales/cs/LC_MESSAGES/volto.po +645 -0
- package/locales/cy/LC_MESSAGES/volto.po +645 -0
- package/locales/da/LC_MESSAGES/volto.po +645 -0
- package/locales/de/LC_MESSAGES/volto.po +58 -57
- package/locales/el/LC_MESSAGES/volto.po +645 -0
- package/locales/en_AU/LC_MESSAGES/volto.po +645 -0
- package/locales/en_GB/LC_MESSAGES/volto.po +645 -0
- package/locales/eo/LC_MESSAGES/volto.po +645 -0
- package/locales/es/LC_MESSAGES/volto.po +50 -50
- package/locales/et/LC_MESSAGES/volto.po +645 -0
- package/locales/eu/LC_MESSAGES/volto.po +7 -7
- package/locales/fa/LC_MESSAGES/volto.po +645 -0
- package/locales/fi/LC_MESSAGES/volto.po +645 -0
- package/locales/fr/LC_MESSAGES/volto.po +645 -0
- package/locales/fu/LC_MESSAGES/volto.po +645 -0
- package/locales/ga/LC_MESSAGES/volto.po +645 -0
- package/locales/gl/LC_MESSAGES/volto.po +645 -0
- package/locales/he/LC_MESSAGES/volto.po +645 -0
- package/locales/hi/LC_MESSAGES/volto.po +645 -0
- package/locales/hr/LC_MESSAGES/volto.po +645 -0
- package/locales/hu/LC_MESSAGES/volto.po +645 -0
- package/locales/hy/LC_MESSAGES/volto.po +645 -0
- package/locales/id/LC_MESSAGES/volto.po +645 -0
- package/locales/it/LC_MESSAGES/volto.po +645 -0
- package/locales/ja/LC_MESSAGES/volto.po +645 -0
- package/locales/ka/LC_MESSAGES/volto.po +645 -0
- package/locales/kn/LC_MESSAGES/volto.po +645 -0
- package/locales/ko/LC_MESSAGES/volto.po +645 -0
- package/locales/lt/LC_MESSAGES/volto.po +645 -0
- package/locales/lv/LC_MESSAGES/volto.po +645 -0
- package/locales/mi/LC_MESSAGES/volto.po +645 -0
- package/locales/mk_MK/LC_MESSAGES/volto.po +645 -0
- package/locales/ms/LC_MESSAGES/volto.po +645 -0
- package/locales/mt/LC_MESSAGES/volto.po +645 -0
- package/locales/my/LC_MESSAGES/volto.po +645 -0
- package/locales/nl/LC_MESSAGES/volto.po +645 -0
- package/locales/nl_BE/LC_MESSAGES/volto.po +645 -0
- package/locales/nn/LC_MESSAGES/volto.po +645 -0
- package/locales/no/LC_MESSAGES/volto.po +645 -0
- package/locales/pl/LC_MESSAGES/volto.po +645 -0
- package/locales/pt/LC_MESSAGES/volto.po +645 -0
- package/locales/rm/LC_MESSAGES/volto.po +645 -0
- package/locales/ro/LC_MESSAGES/volto.po +645 -0
- package/locales/ru/LC_MESSAGES/volto.po +645 -0
- package/locales/sk/LC_MESSAGES/volto.po +645 -0
- package/locales/sl/LC_MESSAGES/volto.po +645 -0
- package/locales/sm/LC_MESSAGES/volto.po +645 -0
- package/locales/sq/LC_MESSAGES/volto.po +645 -0
- package/locales/sr/LC_MESSAGES/volto.po +645 -0
- package/locales/sr_Cyrl/LC_MESSAGES/volto.po +645 -0
- package/locales/sr_Latn/LC_MESSAGES/volto.po +645 -0
- package/locales/sv/LC_MESSAGES/volto.po +645 -0
- package/locales/sw/LC_MESSAGES/volto.po +645 -0
- package/locales/ta/LC_MESSAGES/volto.po +645 -0
- package/locales/te/LC_MESSAGES/volto.po +645 -0
- package/locales/th/LC_MESSAGES/volto.po +645 -0
- package/locales/tl/LC_MESSAGES/volto.po +645 -0
- package/locales/to/LC_MESSAGES/volto.po +645 -0
- package/locales/tr/LC_MESSAGES/volto.po +645 -0
- package/locales/uk/LC_MESSAGES/volto.po +645 -0
- package/locales/vi/LC_MESSAGES/volto.po +645 -0
- package/locales/zh_CN/LC_MESSAGES/volto.po +645 -0
- package/locales/zh_HK/LC_MESSAGES/volto.po +645 -0
- package/locales/zh_TW/LC_MESSAGES/volto.po +645 -0
- package/package.json +6 -6
- package/src/components/Blocks/Button/schema.js +12 -0
- package/src/components/Blocks/Image/Edit.jsx +8 -32
- package/src/components/Blocks/Image/View.jsx +9 -26
- package/src/components/Blocks/Image/adapter.js +28 -14
- package/src/components/Blocks/Image/adapter.test.js +156 -0
- package/src/components/Blocks/Image/schema.js +21 -7
- package/src/components/Blocks/Listing/GridTemplate.jsx +1 -0
- package/src/components/Blocks/Listing/SummaryTemplate.jsx +1 -0
- package/src/components/Blocks/Maps/MapsSidebar.jsx +68 -0
- package/src/components/Blocks/Maps/View.jsx +37 -0
- package/src/components/Blocks/Maps/adapter.js +27 -0
- package/src/components/Blocks/Maps/adapter.test.js +63 -0
- package/src/components/Blocks/Maps/schema.js +42 -2
- package/src/components/Blocks/Separator/schema.js +12 -0
- package/src/components/Blocks/Teaser/DefaultBody.tsx +10 -1
- package/src/components/Blocks/Video/VideoSidebar.jsx +68 -0
- package/src/components/Blocks/Video/View.jsx +38 -0
- package/src/components/Blocks/Video/adapter.js +28 -0
- package/src/components/Blocks/Video/adapter.test.js +63 -0
- package/src/components/Blocks/Video/schema.js +42 -2
- package/src/components/Footer/Footer.tsx +2 -2
- package/src/components/Footer/slots/FollowUsLogoAndLinks.tsx +12 -23
- package/src/components/Theme/ImageView.jsx +8 -1
- package/src/config/blocks.tsx +63 -0
- package/src/config/classExtenders.ts +11 -10
- package/src/config/settings.ts +6 -0
- package/src/customizations/volto/components/manage/Blocks/Maps/MapsSidebar.jsx +10 -0
- package/src/customizations/volto/components/manage/Blocks/Maps/View.jsx +10 -0
- package/src/customizations/volto/components/manage/Blocks/Video/VideoSidebar.jsx +10 -0
- package/src/customizations/volto/components/manage/Blocks/Video/View.jsx +10 -0
- package/src/index.ts +8 -0
- package/src/primitives/Card/Card.tsx +4 -1
- package/src/theme/_footer.scss +61 -51
- package/src/theme/_layout.scss +7 -62
- package/src/theme/_typo-custom.scss +1 -1
- package/src/theme/_variables.scss +21 -0
- package/src/theme/blocks/_grid.scss +1 -0
- package/src/theme/blocks/_highlight.scss +10 -7
- package/src/theme/blocks/_image.scss +96 -186
- package/src/theme/blocks/_listing.scss +5 -1
- package/src/theme/blocks/_maps.scss +60 -34
- package/src/transforms/to6.ts +5 -49
- package/src/transforms/to8.test.js +201 -0
- package/src/transforms/to8.ts +109 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
1
2
|
import { useSelector } from 'react-redux';
|
|
2
3
|
import type { GetSiteResponse } from '@plone/types';
|
|
3
4
|
import { isInternalURL } from '@plone/volto/helpers/Url/Url';
|
|
@@ -5,6 +6,7 @@ import DefaultSummary from '@kitconcept/volto-light-theme/components/Summary/Def
|
|
|
5
6
|
import type { SummaryComponentType } from '@kitconcept/volto-light-theme/components/Summary/DefaultSummary';
|
|
6
7
|
import Card from '../../../primitives/Card/Card';
|
|
7
8
|
import config from '@plone/volto/registry';
|
|
9
|
+
import { GridContext } from '@plone/volto/components/manage/Blocks/Grid/context';
|
|
8
10
|
|
|
9
11
|
type FormState = {
|
|
10
12
|
site: { data: GetSiteResponse };
|
|
@@ -15,7 +17,13 @@ const TeaserDefaultTemplate = (props) => {
|
|
|
15
17
|
(state) => state.site?.data,
|
|
16
18
|
);
|
|
17
19
|
const hideProfileLinks = site?.['kitconcept.disable_profile_links'];
|
|
18
|
-
const { data, isEditMode } = props;
|
|
20
|
+
const { data, isEditMode, isContainer } = props;
|
|
21
|
+
const columns = useContext(GridContext);
|
|
22
|
+
const sizes = config.blocks.blocksConfig.teaser?.getSizes?.({
|
|
23
|
+
data,
|
|
24
|
+
inGrid: isContainer,
|
|
25
|
+
columns,
|
|
26
|
+
});
|
|
19
27
|
const href = data.href?.[0] || {};
|
|
20
28
|
const image = data.preview_image?.[0];
|
|
21
29
|
const url = data.preview_image?.[0]?.['@id'];
|
|
@@ -50,6 +58,7 @@ const TeaserDefaultTemplate = (props) => {
|
|
|
50
58
|
item={!data.overwrite ? href : { ...href, ...localOverrides }}
|
|
51
59
|
image={data.overwrite ? image : undefined}
|
|
52
60
|
imageComponent={Image}
|
|
61
|
+
sizes={sizes}
|
|
53
62
|
/>
|
|
54
63
|
<Card.Summary>
|
|
55
64
|
<Summary
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { VideoBlockSchema } from '@plone/volto/components/manage/Blocks/Video/schema';
|
|
3
|
+
import { Segment } from 'semantic-ui-react';
|
|
4
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
5
|
+
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
6
|
+
import { BlockDataForm } from '@plone/volto/components/manage/Form';
|
|
7
|
+
import videoSVG from '@plone/volto/icons/videocamera.svg';
|
|
8
|
+
|
|
9
|
+
const messages = defineMessages({
|
|
10
|
+
Video: {
|
|
11
|
+
id: 'Video',
|
|
12
|
+
defaultMessage: 'Video',
|
|
13
|
+
},
|
|
14
|
+
NoVideo: {
|
|
15
|
+
id: 'No Video selected',
|
|
16
|
+
defaultMessage: 'No Video selected',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const VideoSidebar = (props) => {
|
|
21
|
+
const {
|
|
22
|
+
blocksConfig,
|
|
23
|
+
blocksErrors,
|
|
24
|
+
data,
|
|
25
|
+
block,
|
|
26
|
+
onChangeBlock,
|
|
27
|
+
navRoot,
|
|
28
|
+
contentType,
|
|
29
|
+
} = props;
|
|
30
|
+
const intl = useIntl();
|
|
31
|
+
const schema = VideoBlockSchema({ ...props, intl });
|
|
32
|
+
const dataAdapter = blocksConfig[data['@type']].dataAdapter;
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
{!data.url ? (
|
|
37
|
+
<Segment className="sidebar-metadata-container" secondary>
|
|
38
|
+
{intl.formatMessage(messages.NoVideo)}
|
|
39
|
+
<Icon name={videoSVG} size="100px" color="#b8c6c8" />
|
|
40
|
+
</Segment>
|
|
41
|
+
) : (
|
|
42
|
+
<BlockDataForm
|
|
43
|
+
schema={schema}
|
|
44
|
+
title={intl.formatMessage(messages.Video)}
|
|
45
|
+
// START CUSTOMIZATION
|
|
46
|
+
onChangeField={(id, value) => {
|
|
47
|
+
dataAdapter({
|
|
48
|
+
block,
|
|
49
|
+
data,
|
|
50
|
+
id,
|
|
51
|
+
onChangeBlock,
|
|
52
|
+
value,
|
|
53
|
+
});
|
|
54
|
+
}}
|
|
55
|
+
// END CUSTOMIZATION
|
|
56
|
+
onChangeBlock={onChangeBlock}
|
|
57
|
+
formData={data}
|
|
58
|
+
block={block}
|
|
59
|
+
navRoot={navRoot}
|
|
60
|
+
contentType={contentType}
|
|
61
|
+
errors={blocksErrors}
|
|
62
|
+
/>
|
|
63
|
+
)}
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default VideoSidebar;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View video block.
|
|
3
|
+
* @module components/manage/Blocks/Video/View
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
import Body from '@plone/volto/components/manage/Blocks/Video/Body';
|
|
9
|
+
import { withBlockExtensions } from '@plone/volto/helpers/Extensions';
|
|
10
|
+
import cx from 'classnames';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* View video block class.
|
|
14
|
+
* @class View
|
|
15
|
+
* @extends Component
|
|
16
|
+
*/
|
|
17
|
+
const View = (props) => {
|
|
18
|
+
const { data, className, style } = props;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
// START CUSTOMIZATION
|
|
22
|
+
<div className={cx('block video', className)} style={style}>
|
|
23
|
+
{/* // END CUSTOMIZATION */}
|
|
24
|
+
<Body data={data} />
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Property types.
|
|
31
|
+
* @property {Object} propTypes Property types.
|
|
32
|
+
* @static
|
|
33
|
+
*/
|
|
34
|
+
View.propTypes = {
|
|
35
|
+
data: PropTypes.objectOf(PropTypes.any).isRequired,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default withBlockExtensions(View);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const VideoBlockDataAdapter = ({
|
|
2
|
+
block,
|
|
3
|
+
data,
|
|
4
|
+
id,
|
|
5
|
+
item,
|
|
6
|
+
onChangeBlock,
|
|
7
|
+
value,
|
|
8
|
+
}) => {
|
|
9
|
+
let dataSaved = {
|
|
10
|
+
...data,
|
|
11
|
+
[id]: value,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const align = dataSaved.styles?.['align:noprefix'];
|
|
15
|
+
const isFloating = align === 'left' || align === 'right';
|
|
16
|
+
|
|
17
|
+
if (isFloating) {
|
|
18
|
+
dataSaved = {
|
|
19
|
+
...dataSaved,
|
|
20
|
+
styles: {
|
|
21
|
+
...dataSaved.styles,
|
|
22
|
+
'blockWidth:noprefix': 'default',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
onChangeBlock(block, dataSaved);
|
|
28
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { VideoBlockDataAdapter } from './adapter';
|
|
3
|
+
|
|
4
|
+
const alignLeft = { 'align:noprefix': 'left' };
|
|
5
|
+
const alignCenter = { 'align:noprefix': 'center' };
|
|
6
|
+
|
|
7
|
+
describe('VideoBlockDataAdapter', () => {
|
|
8
|
+
it('applies the default width for a floating video', () => {
|
|
9
|
+
const onChangeBlock = vi.fn();
|
|
10
|
+
|
|
11
|
+
VideoBlockDataAdapter({
|
|
12
|
+
block: 'block-1',
|
|
13
|
+
data: { '@type': 'video', styles: { ...alignLeft } },
|
|
14
|
+
id: 'url',
|
|
15
|
+
onChangeBlock,
|
|
16
|
+
value: 'https://example.com/video',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(onChangeBlock).toHaveBeenCalledWith('block-1', {
|
|
20
|
+
'@type': 'video',
|
|
21
|
+
url: 'https://example.com/video',
|
|
22
|
+
styles: {
|
|
23
|
+
...alignLeft,
|
|
24
|
+
'blockWidth:noprefix': 'default',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('leaves the styles untouched for a non-floating video', () => {
|
|
30
|
+
const onChangeBlock = vi.fn();
|
|
31
|
+
|
|
32
|
+
VideoBlockDataAdapter({
|
|
33
|
+
block: 'block-1',
|
|
34
|
+
data: { '@type': 'video', styles: { ...alignCenter } },
|
|
35
|
+
id: 'url',
|
|
36
|
+
onChangeBlock,
|
|
37
|
+
value: 'https://example.com/video',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(onChangeBlock).toHaveBeenCalledWith('block-1', {
|
|
41
|
+
'@type': 'video',
|
|
42
|
+
url: 'https://example.com/video',
|
|
43
|
+
styles: { ...alignCenter },
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('leaves the styles untouched when no alignment is set', () => {
|
|
48
|
+
const onChangeBlock = vi.fn();
|
|
49
|
+
|
|
50
|
+
VideoBlockDataAdapter({
|
|
51
|
+
block: 'block-1',
|
|
52
|
+
data: { '@type': 'video' },
|
|
53
|
+
id: 'url',
|
|
54
|
+
onChangeBlock,
|
|
55
|
+
value: 'https://example.com/video',
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
expect(onChangeBlock).toHaveBeenCalledWith('block-1', {
|
|
59
|
+
'@type': 'video',
|
|
60
|
+
url: 'https://example.com/video',
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -1,5 +1,45 @@
|
|
|
1
|
+
import config from '@plone/volto/registry';
|
|
2
|
+
import { defineMessages } from 'react-intl';
|
|
3
|
+
import { addStyling } from '@plone/volto/helpers/Extensions/withBlockSchemaEnhancer';
|
|
4
|
+
|
|
5
|
+
const messages = defineMessages({
|
|
6
|
+
BlockWidth: {
|
|
7
|
+
id: 'Block Width',
|
|
8
|
+
defaultMessage: 'Block Width',
|
|
9
|
+
},
|
|
10
|
+
Alignment: {
|
|
11
|
+
id: 'Alignment',
|
|
12
|
+
defaultMessage: 'Alignment',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
1
15
|
export const videoBlockSchemaEnhancer = ({ formData, schema, intl }) => {
|
|
2
|
-
schema
|
|
3
|
-
|
|
16
|
+
addStyling({ schema, intl });
|
|
17
|
+
|
|
18
|
+
schema.fieldsets[0].fields = schema.fieldsets[0].fields.filter(
|
|
19
|
+
(f) => f !== 'align',
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const align = formData.styles?.['align:noprefix'];
|
|
23
|
+
const isFloating = align === 'left' || align === 'right';
|
|
24
|
+
|
|
25
|
+
schema.properties.styles.schema.fieldsets[0].fields = [
|
|
26
|
+
'align:noprefix',
|
|
27
|
+
'blockWidth:noprefix',
|
|
28
|
+
...schema.properties.styles.schema.fieldsets[0].fields,
|
|
29
|
+
];
|
|
30
|
+
schema.properties.styles.schema.properties['align:noprefix'] = {
|
|
31
|
+
widget: 'blockAlignment',
|
|
32
|
+
title: intl.formatMessage(messages.Alignment),
|
|
33
|
+
default: 'center',
|
|
34
|
+
actions: config.blocks.alignments.map((alignment) => alignment.name),
|
|
35
|
+
};
|
|
36
|
+
schema.properties.styles.schema.properties['blockWidth:noprefix'] = {
|
|
37
|
+
widget: 'blockWidth',
|
|
38
|
+
title: intl.formatMessage(messages.BlockWidth),
|
|
39
|
+
default: 'default',
|
|
40
|
+
actions: config.blocks.widths.map((width) => width.name),
|
|
41
|
+
};
|
|
42
|
+
schema.properties.styles.schema.properties['blockWidth:noprefix'].disabled =
|
|
43
|
+
isFloating;
|
|
4
44
|
return schema;
|
|
5
45
|
};
|
|
@@ -20,9 +20,9 @@ const Footer = () => {
|
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
22
|
<footer id="footer">
|
|
23
|
-
<
|
|
23
|
+
<Container className="pre-footer">
|
|
24
24
|
<SlotRenderer name="preFooter" content={content} />
|
|
25
|
-
</
|
|
25
|
+
</Container>
|
|
26
26
|
<SlotRenderer name="footer" content={content} />
|
|
27
27
|
<Container className="post-footer">
|
|
28
28
|
<SlotRenderer name="postFooter" content={content} />
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FormattedMessage } from 'react-intl';
|
|
2
|
-
import cx from 'classnames';
|
|
3
2
|
import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
|
|
4
3
|
import ConditionalLink from '@plone/volto/components/manage/ConditionalLink/ConditionalLink';
|
|
5
4
|
import { Container } from '@plone/components';
|
|
@@ -34,27 +33,12 @@ const FollowUsPostFooterLogoAndLinks = ({ content }: { content: Content }) => {
|
|
|
34
33
|
: flattenToAppURL(post_footer_logo?.download);
|
|
35
34
|
|
|
36
35
|
return content ? (
|
|
37
|
-
<Container
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
{social_links?.length > 0 && (
|
|
44
|
-
<div className="follow-us">
|
|
45
|
-
<span>
|
|
46
|
-
<FormattedMessage id="Follow us:" defaultMessage="Follow us:" />
|
|
47
|
-
</span>
|
|
48
|
-
<SlotRenderer name="followUs" content={content} />
|
|
49
|
-
</div>
|
|
50
|
-
)}
|
|
51
|
-
{footer_links?.length > 0 && (
|
|
52
|
-
<div className="footer-links">
|
|
53
|
-
<SlotRenderer name="footerLinks" content={content} />
|
|
54
|
-
<LinkList links={footer_links} />
|
|
55
|
-
</div>
|
|
56
|
-
)}
|
|
57
|
-
</div>
|
|
36
|
+
<Container className="default follow-us-links-and-logo">
|
|
37
|
+
{social_links?.length > 0 && (
|
|
38
|
+
<div className="follow-us">
|
|
39
|
+
<SlotRenderer name="followUs" content={content} />
|
|
40
|
+
</div>
|
|
41
|
+
)}
|
|
58
42
|
{post_footer_logo?.data || post_footer_logo?.download ? (
|
|
59
43
|
<div className="footer-logo">
|
|
60
44
|
<span>
|
|
@@ -63,7 +47,6 @@ const FollowUsPostFooterLogoAndLinks = ({ content }: { content: Content }) => {
|
|
|
63
47
|
defaultMessage="Sponsored by:"
|
|
64
48
|
/>
|
|
65
49
|
</span>
|
|
66
|
-
{/* @ts-ignore */}
|
|
67
50
|
<ConditionalLink
|
|
68
51
|
condition={content?.post_footer_logo_link}
|
|
69
52
|
to={content?.post_footer_logo_link}
|
|
@@ -73,6 +56,12 @@ const FollowUsPostFooterLogoAndLinks = ({ content }: { content: Content }) => {
|
|
|
73
56
|
</ConditionalLink>
|
|
74
57
|
</div>
|
|
75
58
|
) : null}
|
|
59
|
+
{footer_links?.length > 0 && (
|
|
60
|
+
<div className="footer-links">
|
|
61
|
+
<SlotRenderer name="footerLinks" content={content} />
|
|
62
|
+
<LinkList links={footer_links} />
|
|
63
|
+
</div>
|
|
64
|
+
)}
|
|
76
65
|
</Container>
|
|
77
66
|
) : null;
|
|
78
67
|
};
|
|
@@ -23,6 +23,7 @@ const ImageView = ({ content }) => {
|
|
|
23
23
|
const Image = config.getComponent('Image').component;
|
|
24
24
|
const Container =
|
|
25
25
|
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
26
|
+
const width = config.settings.layout.defaultContainerWidth;
|
|
26
27
|
|
|
27
28
|
return (
|
|
28
29
|
<Container id="page-document" className="view-wrapper image-view">
|
|
@@ -30,7 +31,13 @@ const ImageView = ({ content }) => {
|
|
|
30
31
|
<h1 className="documentFirstHeading">{content.title}</h1>
|
|
31
32
|
{content?.image?.download && (
|
|
32
33
|
<figure>
|
|
33
|
-
<Image
|
|
34
|
+
<Image
|
|
35
|
+
item={content}
|
|
36
|
+
imageField="image"
|
|
37
|
+
alt=""
|
|
38
|
+
responsive={true}
|
|
39
|
+
sizes={`(max-width: ${width}px) 100vw, ${width}px`}
|
|
40
|
+
/>
|
|
34
41
|
<Caption
|
|
35
42
|
title={content.title}
|
|
36
43
|
description={content.description}
|
package/src/config/blocks.tsx
CHANGED
|
@@ -30,6 +30,8 @@ import {
|
|
|
30
30
|
standAloneImageBlockSchemaEnhancer,
|
|
31
31
|
} from '../components/Blocks/Image/schema';
|
|
32
32
|
import { ImageBlockDataAdapter } from '../components/Blocks/Image/adapter';
|
|
33
|
+
import { VideoBlockDataAdapter } from '../components/Blocks/Video/adapter';
|
|
34
|
+
import { MapsBlockDataAdapter } from '../components/Blocks/Maps/adapter';
|
|
33
35
|
|
|
34
36
|
import { AccordionSchemaEnhancer } from '../components/Blocks/Accordion/schema';
|
|
35
37
|
|
|
@@ -66,6 +68,7 @@ declare module '@plone/types' {
|
|
|
66
68
|
}
|
|
67
69
|
export interface BlockConfigBase {
|
|
68
70
|
themes?: StyleDefinition[];
|
|
71
|
+
alignments?: StyleDefinition[];
|
|
69
72
|
defaultTheme: string;
|
|
70
73
|
allowedBlocks?: string[];
|
|
71
74
|
allowed_headline_tags?: string[][];
|
|
@@ -81,6 +84,10 @@ declare module '@plone/types' {
|
|
|
81
84
|
export interface SettingsConfig {
|
|
82
85
|
blockModel?: number;
|
|
83
86
|
}
|
|
87
|
+
|
|
88
|
+
export interface BlocksConfig {
|
|
89
|
+
alignments: StyleDefinition[];
|
|
90
|
+
}
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
export default function install(config: ConfigType) {
|
|
@@ -147,6 +154,31 @@ export default function install(config: ConfigType) {
|
|
|
147
154
|
},
|
|
148
155
|
];
|
|
149
156
|
|
|
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
|
+
];
|
|
181
|
+
|
|
150
182
|
config.registerUtility({
|
|
151
183
|
name: 'blockThemesEnhancer',
|
|
152
184
|
type: 'styleWrapperStyleObjectEnhancer',
|
|
@@ -159,6 +191,20 @@ export default function install(config: ConfigType) {
|
|
|
159
191
|
method: styleDefinitionsEnhancer,
|
|
160
192
|
});
|
|
161
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
|
+
|
|
162
208
|
// No required blocks except eventMetadata
|
|
163
209
|
config.blocks.requiredBlocks = [
|
|
164
210
|
...config.blocks.requiredBlocks,
|
|
@@ -323,15 +369,25 @@ export default function install(config: ConfigType) {
|
|
|
323
369
|
category: 'title',
|
|
324
370
|
};
|
|
325
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
|
+
|
|
326
380
|
config.blocks.blocksConfig.teaser = {
|
|
327
381
|
...config.blocks.blocksConfig.teaser,
|
|
328
382
|
group: 'teasers',
|
|
329
383
|
imageScale: 'larger',
|
|
384
|
+
getSizes: getTeaserSizes,
|
|
330
385
|
schemaEnhancer: composeSchema(defaultStylingSchema, teaserSchemaEnhancer),
|
|
331
386
|
};
|
|
332
387
|
|
|
333
388
|
config.blocks.blocksConfig.video = {
|
|
334
389
|
...config.blocks.blocksConfig.video,
|
|
390
|
+
dataAdapter: VideoBlockDataAdapter,
|
|
335
391
|
schemaEnhancer: composeSchema(
|
|
336
392
|
defaultStylingSchema,
|
|
337
393
|
videoBlockSchemaEnhancer,
|
|
@@ -339,6 +395,7 @@ export default function install(config: ConfigType) {
|
|
|
339
395
|
};
|
|
340
396
|
config.blocks.blocksConfig.maps = {
|
|
341
397
|
...config.blocks.blocksConfig.maps,
|
|
398
|
+
dataAdapter: MapsBlockDataAdapter,
|
|
342
399
|
schemaEnhancer: composeSchema(
|
|
343
400
|
defaultStylingSchema,
|
|
344
401
|
mapsBlockSchemaEnhancer,
|
|
@@ -410,5 +467,11 @@ export default function install(config: ConfigType) {
|
|
|
410
467
|
schemaEnhancer: sliderBlockSchemaEnhancer,
|
|
411
468
|
};
|
|
412
469
|
|
|
470
|
+
// Highlight Block
|
|
471
|
+
config.blocks.blocksConfig.highlight = {
|
|
472
|
+
...config.blocks.blocksConfig.highlight,
|
|
473
|
+
schemaEnhancer: defaultStylingSchema,
|
|
474
|
+
};
|
|
475
|
+
|
|
413
476
|
return config;
|
|
414
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
package/src/config/settings.ts
CHANGED
|
@@ -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
|
|
|
@@ -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;
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { Container } from '@plone/components';
|
|
|
6
6
|
import EventView from './components/Theme/EventView';
|
|
7
7
|
|
|
8
8
|
import { migrateToVLT6ColorAndWidthModel } from './transforms/to6';
|
|
9
|
+
import { migrateToVLT8FloatingBlocks } from './transforms/to8';
|
|
9
10
|
|
|
10
11
|
import installSettings from './config/settings';
|
|
11
12
|
import installBlocks from './config/blocks';
|
|
@@ -98,6 +99,13 @@ const applyConfig = (config: ConfigType) => {
|
|
|
98
99
|
method: migrateToVLT6ColorAndWidthModel,
|
|
99
100
|
});
|
|
100
101
|
|
|
102
|
+
config.registerUtility({
|
|
103
|
+
name: 'migrateToVLT8FloatingBlocks',
|
|
104
|
+
type: 'transform',
|
|
105
|
+
dependencies: { reducer: 'content' },
|
|
106
|
+
method: migrateToVLT8FloatingBlocks,
|
|
107
|
+
});
|
|
108
|
+
|
|
101
109
|
config.views.contentTypesViews.Event = EventView;
|
|
102
110
|
|
|
103
111
|
config.addonReducers = {
|
|
@@ -94,10 +94,12 @@ type CardImageProps = {
|
|
|
94
94
|
imageComponent?: React.ComponentType<any>;
|
|
95
95
|
children?: React.ReactNode;
|
|
96
96
|
showPlaceholderImage?: boolean;
|
|
97
|
+
sizes?: string;
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
const CardImage = (props: CardImageProps) => {
|
|
100
|
-
const { src, item, image, imageComponent, showPlaceholderImage } =
|
|
101
|
+
const { src, item, image, imageComponent, showPlaceholderImage, sizes } =
|
|
102
|
+
props;
|
|
101
103
|
const Image = imageComponent || DefaultImage;
|
|
102
104
|
|
|
103
105
|
return (
|
|
@@ -115,6 +117,7 @@ const CardImage = (props: CardImageProps) => {
|
|
|
115
117
|
alt=""
|
|
116
118
|
loading="lazy"
|
|
117
119
|
responsive={true}
|
|
120
|
+
sizes={sizes}
|
|
118
121
|
/>
|
|
119
122
|
)
|
|
120
123
|
) : (
|