@kitconcept/volto-light-theme 6.0.0-alpha.2 → 6.0.0-alpha.4
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 +2 -2
- package/CHANGELOG.md +18 -0
- package/package.json +2 -2
- package/src/components/Footer/Footer.jsx +23 -97
- package/src/components/Footer/FooterLinks.tsx +54 -0
- package/src/components/Footer/FooterLogos.tsx +75 -0
- package/src/config/blocks.tsx +5 -7
- package/src/config/slots.ts +7 -0
- package/src/index.ts +7 -0
- package/src/theme/_footer.scss +27 -1
- package/src/theme/_layout.scss +12 -0
- package/src/theme/_variables.scss +1 -0
package/.changelog.draft
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
## 6.0.0-alpha.
|
|
1
|
+
## 6.0.0-alpha.4 (2024-12-08)
|
|
2
2
|
|
|
3
3
|
### Bugfix
|
|
4
4
|
|
|
5
|
-
- Fix
|
|
5
|
+
- Fix initialBlocks config, do not override the whole thing. @sneridagh [#441](https://github.com/kitconcept/volto-light-theme/pull/441)
|
|
6
6
|
|
|
7
7
|
|
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,24 @@
|
|
|
8
8
|
|
|
9
9
|
<!-- towncrier release notes start -->
|
|
10
10
|
|
|
11
|
+
## 6.0.0-alpha.4 (2024-12-08)
|
|
12
|
+
|
|
13
|
+
### Bugfix
|
|
14
|
+
|
|
15
|
+
- Fix initialBlocks config, do not override the whole thing. @sneridagh [#441](https://github.com/kitconcept/volto-light-theme/pull/441)
|
|
16
|
+
|
|
17
|
+
## 6.0.0-alpha.3 (2024-12-05)
|
|
18
|
+
|
|
19
|
+
### Feature
|
|
20
|
+
|
|
21
|
+
- New look and feel specs for footer logos. @sneridagh
|
|
22
|
+
Added two slots: `preFooter` and `postFooter`. [#437](https://github.com/kitconcept/volto-light-theme/pull/437)
|
|
23
|
+
|
|
24
|
+
### Bugfix
|
|
25
|
+
|
|
26
|
+
- Fixed edge case when you delete the image content type from the site. @sneridagh [#437](https://github.com/kitconcept/volto-light-theme/pull/437)
|
|
27
|
+
- Fixed layout shift jumps on RAC Popovers. @sneridagh [#440](https://github.com/kitconcept/volto-light-theme/pull/440)
|
|
28
|
+
|
|
11
29
|
## 6.0.0-alpha.2 (2024-11-25)
|
|
12
30
|
|
|
13
31
|
### Bugfix
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitconcept/volto-light-theme",
|
|
3
|
-
"version": "6.0.0-alpha.
|
|
3
|
+
"version": "6.0.0-alpha.4",
|
|
4
4
|
"description": "Volto Light Theme by kitconcept",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/types/index.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"uuid": "^11.0.0",
|
|
40
|
-
"@plone/components": "^2.
|
|
40
|
+
"@plone/components": "^2.2.1"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@eeacms/volto-accordion-block": "^10.4.6",
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
// SemanticUI-free pre-@plone/components
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import
|
|
4
|
-
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|
3
|
+
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
|
5
4
|
import { useSelector, shallowEqual } from 'react-redux';
|
|
6
|
-
import
|
|
7
|
-
import ConditionalLink from '@plone/volto/components/manage/ConditionalLink/ConditionalLink';
|
|
5
|
+
import { useLocation } from 'react-router-dom';
|
|
8
6
|
import Logo from '@plone/volto/components/theme/Logo/Logo';
|
|
9
7
|
import { Container } from '@plone/components';
|
|
10
|
-
import
|
|
11
|
-
import
|
|
8
|
+
import SlotRenderer from '@plone/volto/components/theme/SlotRenderer/SlotRenderer';
|
|
9
|
+
import FooterLinks from './FooterLinks';
|
|
12
10
|
|
|
13
11
|
const messages = defineMessages({
|
|
14
12
|
copyright: {
|
|
@@ -17,27 +15,28 @@ const messages = defineMessages({
|
|
|
17
15
|
},
|
|
18
16
|
});
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const { settings } = config;
|
|
28
|
-
const { lang, siteActions = [] } = useSelector(
|
|
18
|
+
const Footer = () => {
|
|
19
|
+
const intl = useIntl();
|
|
20
|
+
const {
|
|
21
|
+
content,
|
|
22
|
+
lang,
|
|
23
|
+
siteActions = [],
|
|
24
|
+
} = useSelector(
|
|
29
25
|
(state) => ({
|
|
30
26
|
lang: state.intl.locale,
|
|
31
27
|
siteActions: state.actions?.actions?.site_actions,
|
|
28
|
+
content: state.content.data,
|
|
32
29
|
}),
|
|
33
30
|
shallowEqual,
|
|
34
31
|
);
|
|
32
|
+
const location = useLocation();
|
|
35
33
|
const navroot = useSelector((state) => state.navroot.data.navroot);
|
|
36
34
|
const footerLinks = navroot?.footer_links;
|
|
37
|
-
const footerLogos = navroot?.footer_logos;
|
|
38
35
|
|
|
39
36
|
return (
|
|
40
37
|
<footer id="footer">
|
|
38
|
+
<SlotRenderer name="preFooter" content={content} location={location} />
|
|
39
|
+
|
|
41
40
|
<Container className="footer">
|
|
42
41
|
<div className="footer-message">
|
|
43
42
|
<FormattedMessage
|
|
@@ -84,75 +83,11 @@ const Footer = ({ intl }) => {
|
|
|
84
83
|
}}
|
|
85
84
|
/>
|
|
86
85
|
</div>
|
|
87
|
-
<
|
|
88
|
-
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const href = flattenToAppURL(link.href[0]['@id']);
|
|
93
|
-
|
|
94
|
-
if (!href) return null;
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<li className="item" key={href}>
|
|
98
|
-
<UniversalLink href={href}>{title}</UniversalLink>
|
|
99
|
-
</li>
|
|
100
|
-
);
|
|
101
|
-
})
|
|
102
|
-
: siteActions?.length
|
|
103
|
-
? siteActions.map((item) => (
|
|
104
|
-
<li className="item" key={item.id}>
|
|
105
|
-
<UniversalLink
|
|
106
|
-
className="item"
|
|
107
|
-
href={
|
|
108
|
-
settings.isMultilingual
|
|
109
|
-
? `/${lang}/${
|
|
110
|
-
item.url
|
|
111
|
-
? flattenToAppURL(item.url)
|
|
112
|
-
: addAppURL(item.id)
|
|
113
|
-
}`
|
|
114
|
-
: item.url
|
|
115
|
-
? flattenToAppURL(item.url)
|
|
116
|
-
: addAppURL(item.id)
|
|
117
|
-
}
|
|
118
|
-
>
|
|
119
|
-
{item?.title}
|
|
120
|
-
</UniversalLink>
|
|
121
|
-
</li>
|
|
122
|
-
))
|
|
123
|
-
: null}
|
|
124
|
-
</ul>
|
|
125
|
-
<ul className="footer-logos">
|
|
126
|
-
{!isEmpty(footerLogos?.blocks)
|
|
127
|
-
? footerLogos.blocks_layout.items.map((itemId) => {
|
|
128
|
-
const logo = footerLogos.blocks[itemId];
|
|
129
|
-
let logoHref, hrefTitle, href, srcAlt, src;
|
|
130
|
-
if (logo?.href) {
|
|
131
|
-
hrefTitle = logo.href[0]['title'];
|
|
132
|
-
href = flattenToAppURL(logo.href[0]['@id']);
|
|
133
|
-
}
|
|
134
|
-
if (logo?.logo) {
|
|
135
|
-
logoHref = logo.logo[0]['@id'];
|
|
136
|
-
srcAlt = logo['alt'];
|
|
137
|
-
src = `${flattenToAppURL(logoHref)}/${logo.logo[0].image_scales[logo.logo[0].image_field][0].download}`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (!src) return null;
|
|
141
|
-
|
|
142
|
-
return (
|
|
143
|
-
<li className="item" key={href}>
|
|
144
|
-
<ConditionalLink
|
|
145
|
-
condition={href}
|
|
146
|
-
to={href}
|
|
147
|
-
title={hrefTitle || srcAlt}
|
|
148
|
-
>
|
|
149
|
-
<img src={src} alt={srcAlt} />
|
|
150
|
-
</ConditionalLink>
|
|
151
|
-
</li>
|
|
152
|
-
);
|
|
153
|
-
})
|
|
154
|
-
: null}
|
|
155
|
-
</ul>
|
|
86
|
+
<FooterLinks
|
|
87
|
+
links={footerLinks}
|
|
88
|
+
siteActions={siteActions}
|
|
89
|
+
lang={lang}
|
|
90
|
+
/>
|
|
156
91
|
<div className="logo">
|
|
157
92
|
<Logo />
|
|
158
93
|
</div>
|
|
@@ -171,19 +106,10 @@ const Footer = ({ intl }) => {
|
|
|
171
106
|
by kitconcept
|
|
172
107
|
</div>
|
|
173
108
|
</Container>
|
|
109
|
+
|
|
110
|
+
<SlotRenderer name="postFooter" content={content} location={location} />
|
|
174
111
|
</footer>
|
|
175
112
|
);
|
|
176
113
|
};
|
|
177
114
|
|
|
178
|
-
|
|
179
|
-
* Property types.
|
|
180
|
-
* @property {Object} propTypes Property types.
|
|
181
|
-
* @static
|
|
182
|
-
*/
|
|
183
|
-
Footer.propTypes = {
|
|
184
|
-
/**
|
|
185
|
-
* i18n object
|
|
186
|
-
*/
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
export default injectIntl(Footer);
|
|
115
|
+
export default Footer;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import isEmpty from 'lodash/isEmpty';
|
|
2
|
+
import { addAppURL, flattenToAppURL } from '@plone/volto/helpers/Url/Url';
|
|
3
|
+
import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
|
|
4
|
+
import type { BlocksData } from '@plone/types';
|
|
5
|
+
import config from '@plone/volto/registry';
|
|
6
|
+
|
|
7
|
+
type FooterLinksProps = { links: BlocksData; siteActions: any; lang: string };
|
|
8
|
+
|
|
9
|
+
const FooterLinks = (props: FooterLinksProps) => {
|
|
10
|
+
const { lang, links, siteActions } = props;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<ul className="footer-links">
|
|
14
|
+
{!isEmpty(links?.blocks)
|
|
15
|
+
? links.blocks_layout.items.map((itemId) => {
|
|
16
|
+
const link = links.blocks[itemId];
|
|
17
|
+
const title = link.title || link.href[0]['title'];
|
|
18
|
+
const href = flattenToAppURL(link.href[0]['@id']);
|
|
19
|
+
|
|
20
|
+
if (!href) return null;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<li className="item" key={href}>
|
|
24
|
+
<UniversalLink href={href}>{title}</UniversalLink>
|
|
25
|
+
</li>
|
|
26
|
+
);
|
|
27
|
+
})
|
|
28
|
+
: siteActions?.length
|
|
29
|
+
? siteActions.map((item) => (
|
|
30
|
+
<li className="item" key={item.id}>
|
|
31
|
+
<UniversalLink
|
|
32
|
+
className="item"
|
|
33
|
+
href={
|
|
34
|
+
config.settings.isMultilingual
|
|
35
|
+
? `/${lang}/${
|
|
36
|
+
item.url
|
|
37
|
+
? flattenToAppURL(item.url)
|
|
38
|
+
: addAppURL(item.id)
|
|
39
|
+
}`
|
|
40
|
+
: item.url
|
|
41
|
+
? flattenToAppURL(item.url)
|
|
42
|
+
: addAppURL(item.id)
|
|
43
|
+
}
|
|
44
|
+
>
|
|
45
|
+
{item?.title}
|
|
46
|
+
</UniversalLink>
|
|
47
|
+
</li>
|
|
48
|
+
))
|
|
49
|
+
: null}
|
|
50
|
+
</ul>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default FooterLinks;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { Content } from '@plone/types';
|
|
2
|
+
import isEmpty from 'lodash/isEmpty';
|
|
3
|
+
import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
|
|
4
|
+
import ConditionalLink from '@plone/volto/components/manage/ConditionalLink/ConditionalLink';
|
|
5
|
+
import { useSelector } from 'react-redux';
|
|
6
|
+
import { Container } from '@plone/components';
|
|
7
|
+
|
|
8
|
+
type FormState = {
|
|
9
|
+
content: {
|
|
10
|
+
data: Content;
|
|
11
|
+
};
|
|
12
|
+
navroot: {
|
|
13
|
+
data: {
|
|
14
|
+
navroot: Content;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const FooterLogos = () => {
|
|
20
|
+
const navroot = useSelector<FormState, Content>(
|
|
21
|
+
(state) => state.navroot.data.navroot,
|
|
22
|
+
);
|
|
23
|
+
const logos = navroot?.footer_logos;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Container layout>
|
|
27
|
+
<ul className="footer-logos">
|
|
28
|
+
{!isEmpty(logos?.blocks)
|
|
29
|
+
? logos.blocks_layout.items.map((itemId) => {
|
|
30
|
+
const logo = logos.blocks[itemId];
|
|
31
|
+
const logoInfo: {
|
|
32
|
+
hrefTitle: string;
|
|
33
|
+
href: string;
|
|
34
|
+
logoHref: string;
|
|
35
|
+
src: string;
|
|
36
|
+
srcAlt: string;
|
|
37
|
+
} = {
|
|
38
|
+
hrefTitle: '',
|
|
39
|
+
href: '',
|
|
40
|
+
logoHref: '',
|
|
41
|
+
src: '',
|
|
42
|
+
srcAlt: '',
|
|
43
|
+
};
|
|
44
|
+
if (logo?.href) {
|
|
45
|
+
logoInfo.hrefTitle = logo.href[0]['title'];
|
|
46
|
+
logoInfo.href = flattenToAppURL(logo.href[0]['@id']);
|
|
47
|
+
}
|
|
48
|
+
if (logo?.logo && logo.logo[0]?.image_scales) {
|
|
49
|
+
logoInfo.logoHref = logo.logo[0]['@id'];
|
|
50
|
+
logoInfo.srcAlt = logo['alt'];
|
|
51
|
+
logoInfo.src = `${flattenToAppURL(logoInfo.logoHref)}/${logo.logo[0].image_scales[logo.logo[0].image_field][0].download}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!logoInfo.src) return null;
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<li className="item" key={logoInfo.href}>
|
|
58
|
+
{/* @ts-ignore */}
|
|
59
|
+
<ConditionalLink
|
|
60
|
+
condition={logoInfo.href}
|
|
61
|
+
to={logoInfo.href}
|
|
62
|
+
title={logoInfo.hrefTitle || logoInfo.srcAlt}
|
|
63
|
+
>
|
|
64
|
+
<img src={logoInfo.src} alt={logoInfo.srcAlt} />
|
|
65
|
+
</ConditionalLink>
|
|
66
|
+
</li>
|
|
67
|
+
);
|
|
68
|
+
})
|
|
69
|
+
: null}
|
|
70
|
+
</ul>
|
|
71
|
+
</Container>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export default FooterLogos;
|
package/src/config/blocks.tsx
CHANGED
|
@@ -63,13 +63,11 @@ declare module '@plone/types' {
|
|
|
63
63
|
|
|
64
64
|
export default function install(config: ConfigType) {
|
|
65
65
|
// Initial block for event content type
|
|
66
|
-
config.blocks.initialBlocks =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
],
|
|
72
|
-
};
|
|
66
|
+
config.blocks.initialBlocks.Event = [
|
|
67
|
+
{ '@type': 'title' },
|
|
68
|
+
{ '@type': 'eventMetadata', fixed: true, required: true },
|
|
69
|
+
{ '@type': 'slate' },
|
|
70
|
+
];
|
|
73
71
|
|
|
74
72
|
// Palettes
|
|
75
73
|
config.blocks.themes = [
|
package/src/config/slots.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ConfigType } from '@plone/registry';
|
|
2
2
|
import Theming from '../components/Theming/Theming';
|
|
3
|
+
import FooterLogos from '../components/Footer/FooterLogos';
|
|
3
4
|
|
|
4
5
|
export default function install(config: ConfigType) {
|
|
5
6
|
config.registerSlotComponent({
|
|
@@ -8,5 +9,11 @@ export default function install(config: ConfigType) {
|
|
|
8
9
|
component: Theming,
|
|
9
10
|
});
|
|
10
11
|
|
|
12
|
+
config.registerSlotComponent({
|
|
13
|
+
name: 'footerLogos',
|
|
14
|
+
slot: 'preFooter',
|
|
15
|
+
component: FooterLogos,
|
|
16
|
+
});
|
|
17
|
+
|
|
11
18
|
return config;
|
|
12
19
|
}
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import installWidgets from './config/widgets';
|
|
|
14
14
|
import installSlots from './config/slots';
|
|
15
15
|
|
|
16
16
|
import '@plone/components/dist/basic.css';
|
|
17
|
+
import type { BlocksData } from '@plone/types';
|
|
17
18
|
|
|
18
19
|
defineMessages({
|
|
19
20
|
Press: {
|
|
@@ -26,6 +27,12 @@ defineMessages({
|
|
|
26
27
|
},
|
|
27
28
|
});
|
|
28
29
|
|
|
30
|
+
declare module '@plone/types' {
|
|
31
|
+
export interface Content {
|
|
32
|
+
footer_logos: BlocksData;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
29
36
|
const applyConfig = (config: ConfigType) => {
|
|
30
37
|
installSettings(config);
|
|
31
38
|
installBlocks(config);
|
package/src/theme/_footer.scss
CHANGED
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
#footer {
|
|
2
|
-
margin-top:
|
|
2
|
+
margin-top: $footer-vertical-spacing-top;
|
|
3
3
|
text-align: center;
|
|
4
4
|
|
|
5
|
+
ul.footer-logos {
|
|
6
|
+
display: grid;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
padding: $pre-footer-vertical-spacing 0;
|
|
9
|
+
padding-left: 0;
|
|
10
|
+
margin-top: 0;
|
|
11
|
+
margin-bottom: $spacing-medium;
|
|
12
|
+
gap: 20px;
|
|
13
|
+
grid-template-columns: repeat(3, 1fr);
|
|
14
|
+
list-style: none;
|
|
15
|
+
|
|
16
|
+
img {
|
|
17
|
+
max-width: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
li.item:nth-child(3n + 1) {
|
|
21
|
+
/* Targets 1st, 4th, 7th, etc. */
|
|
22
|
+
justify-self: start;
|
|
23
|
+
}
|
|
24
|
+
li.item:nth-child(3n + 3) {
|
|
25
|
+
/* Targets 3rd, 6th, 9th, etc. */
|
|
26
|
+
justify-self: end;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
5
30
|
.footer {
|
|
6
31
|
padding: 4.2rem 2rem;
|
|
7
32
|
background-color: $lightgrey;
|
|
@@ -26,6 +51,7 @@
|
|
|
26
51
|
|
|
27
52
|
ul {
|
|
28
53
|
display: flex;
|
|
54
|
+
flex-wrap: wrap;
|
|
29
55
|
justify-content: center;
|
|
30
56
|
padding-left: 0;
|
|
31
57
|
margin-top: 1.4rem;
|
package/src/theme/_layout.scss
CHANGED
|
@@ -60,6 +60,18 @@
|
|
|
60
60
|
z-index: $zindex;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
// RAC Popovers have problems with SemanticUI CSS in the BODY tag
|
|
64
|
+
// SemanticUI by default uses `overflow-x: hidden`.
|
|
65
|
+
// TODO: Remove when https://github.com/plone/volto/pull/6513 is merged and released.
|
|
66
|
+
body {
|
|
67
|
+
overflow-x: initial;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// This helps not to have a little layout shift when the RAC Popovers are shown.
|
|
71
|
+
html[style*='padding-right'] .sidebar-container {
|
|
72
|
+
margin-right: 15px;
|
|
73
|
+
}
|
|
74
|
+
|
|
63
75
|
// We expect initially three main containers
|
|
64
76
|
.header-wrapper {
|
|
65
77
|
.q.container,
|