@kitconcept/volto-light-theme 1.0.0-rc.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 (201) hide show
  1. package/.dockerignore +1 -0
  2. package/.editorconfig +36 -0
  3. package/.eslintignore +2 -0
  4. package/.eslintrc.local.js +50 -0
  5. package/.github/workflows/changelog.yml +43 -0
  6. package/.github/workflows/code.yml +15 -0
  7. package/.github/workflows/unit.yml +15 -0
  8. package/.prettierignore +3 -0
  9. package/.release-it.json +19 -0
  10. package/.stylelintrc +33 -0
  11. package/.yarn/releases/yarn-3.2.3.cjs +783 -0
  12. package/.yarnrc.yml +3 -0
  13. package/CHANGELOG.md +80 -0
  14. package/Makefile +129 -0
  15. package/README.md +133 -0
  16. package/acceptance/.gitkeep +0 -0
  17. package/acceptance/ci.yml +29 -0
  18. package/acceptance/cypress/.gitkeep +0 -0
  19. package/acceptance/cypress/fixtures/broccoli.jpg +0 -0
  20. package/acceptance/cypress/fixtures/example.json +5 -0
  21. package/acceptance/cypress/fixtures/file.pdf +0 -0
  22. package/acceptance/cypress/fixtures/image.png +0 -0
  23. package/acceptance/cypress/plugins/index.js +17 -0
  24. package/acceptance/cypress/support/commands.js +1 -0
  25. package/acceptance/cypress/support/e2e.js +14 -0
  26. package/acceptance/cypress/support/reset-fixture.js +45 -0
  27. package/acceptance/cypress/support/slate.js +14 -0
  28. package/acceptance/cypress/tests/.gitkeep +0 -0
  29. package/acceptance/cypress/tests/basic.cy.js +71 -0
  30. package/acceptance/cypress.config.js +9 -0
  31. package/acceptance/docker-compose.yml +57 -0
  32. package/acceptance/package.json +5 -0
  33. package/acceptance/yarn.lock +2597 -0
  34. package/dockerfiles/Dockerfile +24 -0
  35. package/dockerfiles/Dockerfile.acceptance +13 -0
  36. package/dockerfiles/Dockerfile.dev +20 -0
  37. package/dockerfiles/docker-compose.yml +33 -0
  38. package/locales/de/LC_MESSAGES/volto.po +68 -0
  39. package/locales/en/LC_MESSAGES/volto.po +62 -0
  40. package/locales/volto.pot +64 -0
  41. package/news/.gitkeep +0 -0
  42. package/package.json +55 -0
  43. package/src/components/Anontools/Anontools.jsx +79 -0
  44. package/src/components/Atoms/Container/Container.jsx +28 -0
  45. package/src/components/Atoms/helpers.jsx +9 -0
  46. package/src/components/Blocks/Accordion/schema.jsx +11 -0
  47. package/src/components/Blocks/Button/schema.js +28 -0
  48. package/src/components/Blocks/Listing/GridTemplate.jsx +80 -0
  49. package/src/components/Blocks/Listing/SummaryTemplate.jsx +66 -0
  50. package/src/components/Blocks/Search/TopSideFacets.jsx +159 -0
  51. package/src/components/Blocks/Slate/ExtraAlignWrapper.js +22 -0
  52. package/src/components/Blocks/Teaser/schema.js +5 -0
  53. package/src/components/Blocks/schema.js +38 -0
  54. package/src/components/Breadcrumbs/Breadcrumbs.jsx +117 -0
  55. package/src/components/CQPolyfill.jsx +9 -0
  56. package/src/components/Footer/Footer.jsx +131 -0
  57. package/src/components/Header/Header.jsx +64 -0
  58. package/src/components/Logo/Logo.jsx +39 -0
  59. package/src/components/Navigation/Navigation.jsx +199 -0
  60. package/src/components/SearchWidget/SearchWidget.jsx +173 -0
  61. package/src/components/Widgets/AlignWidget.jsx +80 -0
  62. package/src/customizations/@root/theme.js +5 -0
  63. package/src/customizations/volto/components/manage/Blocks/Grid/View.jsx +44 -0
  64. package/src/customizations/volto/components/manage/Blocks/Listing/DefaultTemplate.jsx +47 -0
  65. package/src/customizations/volto/components/manage/Blocks/Listing/SummaryTemplate.jsx +11 -0
  66. package/src/customizations/volto/components/manage/Blocks/Search/components/SearchDetails.jsx +33 -0
  67. package/src/customizations/volto/components/manage/Blocks/Search/components/SearchInput.jsx +56 -0
  68. package/src/customizations/volto/components/manage/Form/Form.jsx +803 -0
  69. package/src/customizations/volto/components/theme/Anontools/Anontools.jsx +11 -0
  70. package/src/customizations/volto/components/theme/Breadcrumbs/Breadcrumbs.jsx +11 -0
  71. package/src/customizations/volto/components/theme/Footer/Footer.jsx +11 -0
  72. package/src/customizations/volto/components/theme/Header/Header.jsx +11 -0
  73. package/src/customizations/volto/components/theme/Logo/Logo.jsx +11 -0
  74. package/src/customizations/volto/components/theme/Navigation/Navigation.jsx +11 -0
  75. package/src/customizations/volto/components/theme/SearchWidget/SearchWidget.jsx +11 -0
  76. package/src/customizations/volto/components/theme/View/RenderBlocks.jsx +164 -0
  77. package/src/customizations/volto/components/theme/View/RenderBlocks.test.jsx +308 -0
  78. package/src/icons/block_icn_accordion.svg +1 -0
  79. package/src/icons/block_icn_grid.svg +1 -0
  80. package/src/index.js +239 -0
  81. package/src/static/container-query-polyfill.modern.js +1 -0
  82. package/src/theme/_bgcolor-blocks-layout.scss +47 -0
  83. package/src/theme/_breadcrumbs.scss +39 -0
  84. package/src/theme/_content.scss +7 -0
  85. package/src/theme/_footer.scss +44 -0
  86. package/src/theme/_header.scss +253 -0
  87. package/src/theme/_layout.scss +271 -0
  88. package/src/theme/_temp.scss +2 -0
  89. package/src/theme/_toolbar.scss +3 -0
  90. package/src/theme/_typo-custom.scss +193 -0
  91. package/src/theme/_typography.scss +271 -0
  92. package/src/theme/_utils.scss +43 -0
  93. package/src/theme/_variables.scss +254 -0
  94. package/src/theme/atoms/_container.scss +11 -0
  95. package/src/theme/blocks/_accordion.scss +4 -0
  96. package/src/theme/blocks/_button.scss +29 -0
  97. package/src/theme/blocks/_grid.scss +242 -0
  98. package/src/theme/blocks/_highlight.scss +11 -0
  99. package/src/theme/blocks/_image.scss +357 -0
  100. package/src/theme/blocks/_introduction.scss +27 -0
  101. package/src/theme/blocks/_listing.scss +77 -0
  102. package/src/theme/blocks/_search.scss +168 -0
  103. package/src/theme/blocks/_separator.scss +13 -0
  104. package/src/theme/blocks/_slate.scss +5 -0
  105. package/src/theme/blocks/_slider.scss +135 -0
  106. package/src/theme/blocks/_teaser.scss +109 -0
  107. package/src/theme/blocks/_toc.scss +9 -0
  108. package/src/theme/collections/grid.variables +2 -0
  109. package/src/theme/custom/_main.scss +2 -0
  110. package/src/theme/custom/_variables.scss +2 -0
  111. package/src/theme/extras/README.md +8 -0
  112. package/src/theme/extras/custom.less +2 -0
  113. package/src/theme/extras/custom.overrides +3 -0
  114. package/src/theme/fonts/Inter-Black.ttf +0 -0
  115. package/src/theme/fonts/Inter-Bold.ttf +0 -0
  116. package/src/theme/fonts/Inter-ExtraBold.ttf +0 -0
  117. package/src/theme/fonts/Inter-ExtraLight.ttf +0 -0
  118. package/src/theme/fonts/Inter-Light.ttf +0 -0
  119. package/src/theme/fonts/Inter-Medium.ttf +0 -0
  120. package/src/theme/fonts/Inter-Regular.ttf +0 -0
  121. package/src/theme/fonts/Inter-SemiBold.ttf +0 -0
  122. package/src/theme/fonts/Inter-Thin.ttf +0 -0
  123. package/src/theme/fonts/metropolis/Metropolis-Black.eot +0 -0
  124. package/src/theme/fonts/metropolis/Metropolis-Black.ttf +0 -0
  125. package/src/theme/fonts/metropolis/Metropolis-Black.woff +0 -0
  126. package/src/theme/fonts/metropolis/Metropolis-Black.woff2 +0 -0
  127. package/src/theme/fonts/metropolis/Metropolis-BlackItalic.eot +0 -0
  128. package/src/theme/fonts/metropolis/Metropolis-BlackItalic.ttf +0 -0
  129. package/src/theme/fonts/metropolis/Metropolis-BlackItalic.woff +0 -0
  130. package/src/theme/fonts/metropolis/Metropolis-BlackItalic.woff2 +0 -0
  131. package/src/theme/fonts/metropolis/Metropolis-Bold.eot +0 -0
  132. package/src/theme/fonts/metropolis/Metropolis-Bold.ttf +0 -0
  133. package/src/theme/fonts/metropolis/Metropolis-Bold.woff +0 -0
  134. package/src/theme/fonts/metropolis/Metropolis-Bold.woff2 +0 -0
  135. package/src/theme/fonts/metropolis/Metropolis-BoldItalic.eot +0 -0
  136. package/src/theme/fonts/metropolis/Metropolis-BoldItalic.ttf +0 -0
  137. package/src/theme/fonts/metropolis/Metropolis-BoldItalic.woff +0 -0
  138. package/src/theme/fonts/metropolis/Metropolis-BoldItalic.woff2 +0 -0
  139. package/src/theme/fonts/metropolis/Metropolis-ExtraBold.eot +0 -0
  140. package/src/theme/fonts/metropolis/Metropolis-ExtraBold.ttf +0 -0
  141. package/src/theme/fonts/metropolis/Metropolis-ExtraBold.woff +0 -0
  142. package/src/theme/fonts/metropolis/Metropolis-ExtraBold.woff2 +0 -0
  143. package/src/theme/fonts/metropolis/Metropolis-ExtraBoldItalic.eot +0 -0
  144. package/src/theme/fonts/metropolis/Metropolis-ExtraBoldItalic.ttf +0 -0
  145. package/src/theme/fonts/metropolis/Metropolis-ExtraBoldItalic.woff +0 -0
  146. package/src/theme/fonts/metropolis/Metropolis-ExtraBoldItalic.woff2 +0 -0
  147. package/src/theme/fonts/metropolis/Metropolis-ExtraLight.eot +0 -0
  148. package/src/theme/fonts/metropolis/Metropolis-ExtraLight.ttf +0 -0
  149. package/src/theme/fonts/metropolis/Metropolis-ExtraLight.woff +0 -0
  150. package/src/theme/fonts/metropolis/Metropolis-ExtraLight.woff2 +0 -0
  151. package/src/theme/fonts/metropolis/Metropolis-ExtraLightItalic.eot +0 -0
  152. package/src/theme/fonts/metropolis/Metropolis-ExtraLightItalic.ttf +0 -0
  153. package/src/theme/fonts/metropolis/Metropolis-ExtraLightItalic.woff +0 -0
  154. package/src/theme/fonts/metropolis/Metropolis-ExtraLightItalic.woff2 +0 -0
  155. package/src/theme/fonts/metropolis/Metropolis-Light.eot +0 -0
  156. package/src/theme/fonts/metropolis/Metropolis-Light.ttf +0 -0
  157. package/src/theme/fonts/metropolis/Metropolis-Light.woff +0 -0
  158. package/src/theme/fonts/metropolis/Metropolis-Light.woff2 +0 -0
  159. package/src/theme/fonts/metropolis/Metropolis-LightItalic.eot +0 -0
  160. package/src/theme/fonts/metropolis/Metropolis-LightItalic.ttf +0 -0
  161. package/src/theme/fonts/metropolis/Metropolis-LightItalic.woff +0 -0
  162. package/src/theme/fonts/metropolis/Metropolis-LightItalic.woff2 +0 -0
  163. package/src/theme/fonts/metropolis/Metropolis-Medium.eot +0 -0
  164. package/src/theme/fonts/metropolis/Metropolis-Medium.ttf +0 -0
  165. package/src/theme/fonts/metropolis/Metropolis-Medium.woff +0 -0
  166. package/src/theme/fonts/metropolis/Metropolis-Medium.woff2 +0 -0
  167. package/src/theme/fonts/metropolis/Metropolis-MediumItalic.eot +0 -0
  168. package/src/theme/fonts/metropolis/Metropolis-MediumItalic.ttf +0 -0
  169. package/src/theme/fonts/metropolis/Metropolis-MediumItalic.woff +0 -0
  170. package/src/theme/fonts/metropolis/Metropolis-MediumItalic.woff2 +0 -0
  171. package/src/theme/fonts/metropolis/Metropolis-Regular.eot +0 -0
  172. package/src/theme/fonts/metropolis/Metropolis-Regular.ttf +0 -0
  173. package/src/theme/fonts/metropolis/Metropolis-Regular.woff +0 -0
  174. package/src/theme/fonts/metropolis/Metropolis-Regular.woff2 +0 -0
  175. package/src/theme/fonts/metropolis/Metropolis-RegularItalic.eot +0 -0
  176. package/src/theme/fonts/metropolis/Metropolis-RegularItalic.ttf +0 -0
  177. package/src/theme/fonts/metropolis/Metropolis-RegularItalic.woff +0 -0
  178. package/src/theme/fonts/metropolis/Metropolis-RegularItalic.woff2 +0 -0
  179. package/src/theme/fonts/metropolis/Metropolis-SemiBold.eot +0 -0
  180. package/src/theme/fonts/metropolis/Metropolis-SemiBold.ttf +0 -0
  181. package/src/theme/fonts/metropolis/Metropolis-SemiBold.woff +0 -0
  182. package/src/theme/fonts/metropolis/Metropolis-SemiBold.woff2 +0 -0
  183. package/src/theme/fonts/metropolis/Metropolis-SemiBoldItalic.eot +0 -0
  184. package/src/theme/fonts/metropolis/Metropolis-SemiBoldItalic.ttf +0 -0
  185. package/src/theme/fonts/metropolis/Metropolis-SemiBoldItalic.woff +0 -0
  186. package/src/theme/fonts/metropolis/Metropolis-SemiBoldItalic.woff2 +0 -0
  187. package/src/theme/fonts/metropolis/Metropolis-Thin.eot +0 -0
  188. package/src/theme/fonts/metropolis/Metropolis-Thin.ttf +0 -0
  189. package/src/theme/fonts/metropolis/Metropolis-Thin.woff +0 -0
  190. package/src/theme/fonts/metropolis/Metropolis-Thin.woff2 +0 -0
  191. package/src/theme/fonts/metropolis/Metropolis-ThinItalic.eot +0 -0
  192. package/src/theme/fonts/metropolis/Metropolis-ThinItalic.ttf +0 -0
  193. package/src/theme/fonts/metropolis/Metropolis-ThinItalic.woff +0 -0
  194. package/src/theme/fonts/metropolis/Metropolis-ThinItalic.woff2 +0 -0
  195. package/src/theme/fonts/metropolis/demo.html +685 -0
  196. package/src/theme/fonts/metropolis/stylesheet.css +217 -0
  197. package/src/theme/globals/site.variables +64 -0
  198. package/src/theme/main.scss +33 -0
  199. package/src/theme/theme.config +88 -0
  200. package/towncrier.toml +33 -0
  201. package/volto.config.js +7 -0
@@ -0,0 +1,159 @@
1
+ import React from 'react';
2
+ import {
3
+ SearchInput,
4
+ SearchDetails,
5
+ Facets,
6
+ // FilterList,
7
+ SortOn,
8
+ } from '@plone/volto/components/manage/Blocks/Search/components';
9
+ import { Grid } from 'semantic-ui-react';
10
+ import { flushSync } from 'react-dom';
11
+ import { defineMessages, useIntl } from 'react-intl';
12
+
13
+ const messages = defineMessages({
14
+ searchButtonText: {
15
+ id: 'Search',
16
+ defaultMessage: 'Search',
17
+ },
18
+ sort: {
19
+ id: 'Sorting',
20
+ defaultMessage: 'Sorting',
21
+ },
22
+ });
23
+
24
+ const TopSideFacets = (props) => {
25
+ const {
26
+ children,
27
+ data,
28
+ totalItems,
29
+ facets,
30
+ setFacets,
31
+ setSortOn,
32
+ setSortOrder,
33
+ sortOn,
34
+ sortOrder,
35
+ onTriggerSearch,
36
+ searchedText, // search text for previous search
37
+ // searchText, // search text currently being entered (controlled input)
38
+ isEditMode,
39
+ querystring = {},
40
+ // searchData,
41
+ // mode = 'view',
42
+ // variation,
43
+ } = props;
44
+ const { showSearchButton } = data;
45
+ const isLive = !showSearchButton;
46
+ const intl = useIntl();
47
+
48
+ const FacetWrapper = ({ children }) => {
49
+ const colWidth = data.facets.length < 5 ? 12 / data.facets.length : 4;
50
+ return (
51
+ <Grid.Column mobile={12} tablet={colWidth} computer={colWidth}>
52
+ {children}
53
+ </Grid.Column>
54
+ );
55
+ };
56
+
57
+ return (
58
+ <>
59
+ {data.headline && <h2 className="headline">{data.headline}</h2>}
60
+
61
+ <Grid className="searchBlock-facets" stackable>
62
+ <Grid.Row>
63
+ <Grid.Column>
64
+ {(Object.keys(data).includes('showSearchInput')
65
+ ? data.showSearchInput
66
+ : true) && (
67
+ <div className="search-input-resultscount-sort">
68
+ <div className="search-wrapper">
69
+ <SearchInput {...props} isLive={isLive} />
70
+ {/* {data.showSearchButton && (
71
+ <Button primary onClick={() => onTriggerSearch(searchText)}>
72
+ {data.searchButtonLabel ||
73
+ intl.formatMessage(messages.searchButtonText)}
74
+ </Button>
75
+ )} */}
76
+ </div>
77
+
78
+ <div className="search-details-sort">
79
+ <SearchDetails
80
+ text={searchedText}
81
+ total={totalItems}
82
+ as="h5"
83
+ />
84
+ <div className="sort-on-wrapper">
85
+ <span className="sort-label">
86
+ {intl.formatMessage(messages.sort)}
87
+ </span>
88
+ <SortOn
89
+ data={data}
90
+ querystring={querystring}
91
+ isEditMode={isEditMode}
92
+ sortOn={sortOn}
93
+ sortOrder={sortOrder}
94
+ setSortOn={(sortOn) => {
95
+ flushSync(() => {
96
+ setSortOn(sortOn);
97
+ onTriggerSearch(searchedText || '', facets, sortOn);
98
+ });
99
+ }}
100
+ setSortOrder={(sortOrder) => {
101
+ flushSync(() => {
102
+ setSortOrder(sortOrder);
103
+ onTriggerSearch(
104
+ searchedText || '',
105
+ facets,
106
+ sortOn,
107
+ sortOrder,
108
+ );
109
+ });
110
+ }}
111
+ />
112
+ </div>
113
+ </div>
114
+ </div>
115
+ )}
116
+
117
+ {data.facets?.length > 0 && (
118
+ <div className="facets">
119
+ {data.facetsTitle && <h3>{data.facetsTitle}</h3>}
120
+ <Grid verticalAlign="bottom" columns={12}>
121
+ <Facets
122
+ data={data}
123
+ querystring={querystring}
124
+ facets={facets}
125
+ setFacets={(f) => {
126
+ flushSync(() => {
127
+ setFacets(f);
128
+ onTriggerSearch(searchedText || '', f);
129
+ });
130
+ }}
131
+ facetWrapper={FacetWrapper}
132
+ />
133
+ </Grid>
134
+ </div>
135
+ )}
136
+ {/* <div className="search-filters-sort">
137
+ <FilterList
138
+ {...props}
139
+ isEditMode={isEditMode}
140
+ setFacets={(f) => {
141
+ flushSync(() => {
142
+ setFacets(f);
143
+ onTriggerSearch(searchedText || '', f);
144
+ });
145
+ }}
146
+ />
147
+ </div> */}
148
+ </Grid.Column>
149
+ </Grid.Row>
150
+
151
+ <Grid.Row>
152
+ <Grid.Column>{children}</Grid.Column>
153
+ </Grid.Row>
154
+ </Grid>
155
+ </>
156
+ );
157
+ };
158
+
159
+ export default TopSideFacets;
@@ -0,0 +1,22 @@
1
+ import cx from 'classnames';
2
+
3
+ // This extra wrapper is required to fulfill the "all blocks snap to 1440"
4
+ // on some of the blocks, the ones that are more pure, eg. the ones the view is
5
+ // super simple, and a single element (p or an h)... So it's required on slate
6
+ // blocks and heading
7
+ const ExtraAlignWrapper = (Component) => ({ ...props }) => {
8
+ const { data } = props;
9
+
10
+ return (
11
+ <div
12
+ className={cx(`${data['@type']}`, {
13
+ [data.align]: data.align,
14
+ [data.styles?.align]: data.styles?.align,
15
+ })}
16
+ >
17
+ <Component {...props} />
18
+ </div>
19
+ );
20
+ };
21
+
22
+ export default ExtraAlignWrapper;
@@ -0,0 +1,5 @@
1
+ export const teaserSchemaEnhancer = ({ schema, formData, intl }) => {
2
+ schema.properties.href.selectedItemAttrs.push('getRemoteUrl');
3
+
4
+ return schema;
5
+ };
@@ -0,0 +1,38 @@
1
+ import { addStyling } from '@plone/volto/helpers/Extensions/withBlockSchemaEnhancer';
2
+ import { defineMessages } from 'react-intl';
3
+ import config from '@plone/volto/registry';
4
+
5
+ const messages = defineMessages({
6
+ backgroundColor: {
7
+ id: 'Background color',
8
+ defaultMessage: 'Background color',
9
+ },
10
+ });
11
+
12
+ export const defaultStylingSchema = ({ schema, formData, intl }) => {
13
+ const BG_COLORS = [
14
+ { name: 'transparent', label: 'Transparent' },
15
+ { name: 'grey', label: 'Grey' },
16
+ ];
17
+
18
+ const colors =
19
+ config.blocks?.blocksConfig?.[formData['@type']]?.colors || BG_COLORS;
20
+
21
+ const defaultBGColor =
22
+ config.blocks?.blocksConfig?.[formData['@type']]?.defaultBGColor;
23
+
24
+ addStyling({ schema, intl });
25
+
26
+ schema.properties.styles.schema.fieldsets[0].fields = [
27
+ ...schema.properties.styles.schema.fieldsets[0].fields,
28
+ 'backgroundColor',
29
+ ];
30
+ schema.properties.styles.schema.properties.backgroundColor = {
31
+ widget: 'color_picker',
32
+ title: intl.formatMessage(messages.backgroundColor),
33
+ colors,
34
+ default: defaultBGColor,
35
+ };
36
+
37
+ return schema;
38
+ };
@@ -0,0 +1,117 @@
1
+ // SemanticUI-free pre-@plone/components
2
+ import React, { Component } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { connect } from 'react-redux';
5
+ import { compose } from 'redux';
6
+ import { Link } from 'react-router-dom';
7
+ import { defineMessages, injectIntl } from 'react-intl';
8
+ import Container from '@kitconcept/volto-light-theme/components/Atoms/Container/Container';
9
+
10
+ import { Icon } from '@plone/volto/components';
11
+ import { getBreadcrumbs } from '@plone/volto/actions';
12
+ import { getBaseUrl, hasApiExpander } from '@plone/volto/helpers';
13
+
14
+ import homeSVG from '@plone/volto/icons/home.svg';
15
+
16
+ const messages = defineMessages({
17
+ home: {
18
+ id: 'Home',
19
+ defaultMessage: 'Home',
20
+ },
21
+ breadcrumbs: {
22
+ id: 'Breadcrumbs',
23
+ defaultMessage: 'Breadcrumbs',
24
+ },
25
+ });
26
+
27
+ /**
28
+ * Breadcrumbs container class.
29
+ */
30
+ export class BreadcrumbsComponent extends Component {
31
+ /**
32
+ * Property types.
33
+ * @property {Object} propTypes Property types.
34
+ * @static
35
+ */
36
+ static propTypes = {
37
+ getBreadcrumbs: PropTypes.func.isRequired,
38
+ pathname: PropTypes.string.isRequired,
39
+ root: PropTypes.string,
40
+ items: PropTypes.arrayOf(
41
+ PropTypes.shape({
42
+ title: PropTypes.string,
43
+ url: PropTypes.string,
44
+ }),
45
+ ).isRequired,
46
+ };
47
+
48
+ componentDidMount() {
49
+ if (!hasApiExpander('breadcrumbs', getBaseUrl(this.props.pathname))) {
50
+ this.props.getBreadcrumbs(getBaseUrl(this.props.pathname));
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Component will receive props
56
+ * @method componentWillReceiveProps
57
+ * @param {Object} nextProps Next properties
58
+ * @returns {undefined}
59
+ */
60
+ UNSAFE_componentWillReceiveProps(nextProps) {
61
+ if (nextProps.pathname !== this.props.pathname) {
62
+ if (!hasApiExpander('breadcrumbs', getBaseUrl(this.props.pathname))) {
63
+ this.props.getBreadcrumbs(getBaseUrl(nextProps.pathname));
64
+ }
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Render method.
70
+ * @method render
71
+ * @returns {string} Markup for the component.
72
+ */
73
+ render() {
74
+ return (
75
+ <div
76
+ role="navigation"
77
+ aria-label={this.props.intl.formatMessage(messages.breadcrumbs)}
78
+ className="breadcrumbs"
79
+ >
80
+ <Container layout>
81
+ <div className="breadcrumb">
82
+ <Link
83
+ to={this.props.root || '/'}
84
+ className="home"
85
+ title={this.props.intl.formatMessage(messages.home)}
86
+ >
87
+ <Icon name={homeSVG} size="25px" />
88
+ </Link>
89
+ {this.props.items.map((item, index, items) => [
90
+ <div className="divider" key={`divider-${item.url}`} />,
91
+ index < items.length - 1 ? (
92
+ <Link key={item.url} to={item.url} className="section">
93
+ {item.title}
94
+ </Link>
95
+ ) : (
96
+ <div className="section active" key={item.url}>
97
+ {item.title}
98
+ </div>
99
+ ),
100
+ ])}
101
+ </div>
102
+ </Container>
103
+ </div>
104
+ );
105
+ }
106
+ }
107
+
108
+ export default compose(
109
+ injectIntl,
110
+ connect(
111
+ (state) => ({
112
+ items: state.breadcrumbs.items,
113
+ root: state.breadcrumbs.root,
114
+ }),
115
+ { getBreadcrumbs },
116
+ ),
117
+ )(BreadcrumbsComponent);
@@ -0,0 +1,9 @@
1
+ // import CQpolifillJS from 'file-loader?name=[name].[ext]!../static/container-query-polyfill.modern';
2
+
3
+ const ContainerQueriesPolyfill = () => {
4
+ return (
5
+ <script src="https://cdn.jsdelivr.net/npm/container-query-polyfill@1/dist/container-query-polyfill.modern.js"></script>
6
+ );
7
+ };
8
+
9
+ export default ContainerQueriesPolyfill;
@@ -0,0 +1,131 @@
1
+ // SemanticUI-free pre-@plone/components
2
+ import React from 'react';
3
+
4
+ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
5
+ import { useSelector, shallowEqual } from 'react-redux';
6
+ import { UniversalLink, Logo } from '@plone/volto/components';
7
+ import Container from '@kitconcept/volto-light-theme/components/Atoms/Container/Container';
8
+ import { flattenToAppURL, addAppURL } from '@plone/volto/helpers';
9
+ import config from '@plone/volto/registry';
10
+
11
+ const messages = defineMessages({
12
+ copyright: {
13
+ id: 'Copyright',
14
+ defaultMessage: 'Copyright',
15
+ },
16
+ });
17
+
18
+ /**
19
+ * Component to display the footer.
20
+ * @function Footer
21
+ * @param {Object} intl Intl object
22
+ * @returns {string} Markup of the component
23
+ */
24
+ const Footer = ({ intl }) => {
25
+ const { settings } = config;
26
+ const { lang, siteActions = [] } = useSelector(
27
+ (state) => ({
28
+ lang: state.intl.locale,
29
+ siteActions: state.actions?.actions?.site_actions,
30
+ }),
31
+ shallowEqual,
32
+ );
33
+ return (
34
+ <footer id="footer">
35
+ <Container layout className="footer">
36
+ <div className="footer-message">
37
+ <FormattedMessage
38
+ id="The {plonecms} is {copyright} 2000-{current_year} by the {plonefoundation} and friends."
39
+ defaultMessage="The {plonecms} is {copyright} 2000-{current_year} by the {plonefoundation} and friends."
40
+ values={{
41
+ plonecms: (
42
+ <FormattedMessage
43
+ id="Plone{reg} Open Source CMS/WCM"
44
+ defaultMessage="Plone{reg} Open Source CMS/WCM"
45
+ values={{ reg: <sup>®</sup> }}
46
+ />
47
+ ),
48
+ copyright: (
49
+ <abbr title={intl.formatMessage(messages.copyright)}>©</abbr>
50
+ ),
51
+ current_year: new Date().getFullYear(),
52
+ plonefoundation: (
53
+ <a className="item" href="http://plone.org/foundation">
54
+ <FormattedMessage
55
+ id="Plone Foundation"
56
+ defaultMessage="Plone Foundation"
57
+ />
58
+ </a>
59
+ ),
60
+ }}
61
+ />{' '}
62
+ <br />
63
+ <FormattedMessage
64
+ id="Distributed under the {license}."
65
+ defaultMessage="Distributed under the {license}."
66
+ values={{
67
+ license: (
68
+ <a
69
+ className="item"
70
+ href="http://creativecommons.org/licenses/GPL/2.0/"
71
+ >
72
+ <FormattedMessage
73
+ id="GNU GPL license"
74
+ defaultMessage="GNU GPL license"
75
+ />
76
+ </a>
77
+ ),
78
+ }}
79
+ />
80
+ </div>
81
+ <ul>
82
+ {/* wrap in div for a11y reasons: listitem role cannot be on the <a> element directly */}
83
+ {siteActions?.length
84
+ ? siteActions.map((item) => (
85
+ <li className="item" key={item.id}>
86
+ <UniversalLink
87
+ className="item"
88
+ href={
89
+ settings.isMultilingual
90
+ ? `/${lang}/${
91
+ item.url
92
+ ? flattenToAppURL(item.url)
93
+ : addAppURL(item.id)
94
+ }`
95
+ : item.url
96
+ ? flattenToAppURL(item.url)
97
+ : addAppURL(item.id)
98
+ }
99
+ >
100
+ {item?.title}
101
+ </UniversalLink>
102
+ </li>
103
+ ))
104
+ : null}
105
+ </ul>
106
+ <div className="logo">
107
+ <Logo />
108
+ </div>
109
+ <a className="item powered-by" href="https://plone.org">
110
+ <FormattedMessage
111
+ id="Powered by Plone & Python"
112
+ defaultMessage="Powered by Plone & Python"
113
+ />
114
+ </a>
115
+ </Container>
116
+ </footer>
117
+ );
118
+ };
119
+
120
+ /**
121
+ * Property types.
122
+ * @property {Object} propTypes Property types.
123
+ * @static
124
+ */
125
+ Footer.propTypes = {
126
+ /**
127
+ * i18n object
128
+ */
129
+ };
130
+
131
+ export default injectIntl(Footer);
@@ -0,0 +1,64 @@
1
+ // SemanticUI-free pre-@plone/components
2
+ import PropTypes from 'prop-types';
3
+ import { useSelector } from 'react-redux';
4
+ import Container from '@kitconcept/volto-light-theme/components/Atoms/Container/Container';
5
+ import { Link } from 'react-router-dom';
6
+ import { FormattedMessage } from 'react-intl';
7
+
8
+ import {
9
+ Anontools,
10
+ LanguageSelector,
11
+ Logo,
12
+ Navigation,
13
+ SearchWidget,
14
+ } from '@plone/volto/components';
15
+
16
+ const Header = (props) => {
17
+ const { pathname } = props;
18
+ const token = useSelector((state) => state.userSession.token);
19
+
20
+ return (
21
+ <header className="header-wrapper">
22
+ <Container layout>
23
+ <div className="header">
24
+ <div className="logo-nav-wrapper">
25
+ <div className="logo">
26
+ <Logo />
27
+ </div>
28
+ <Navigation pathname={pathname} />
29
+ <div className="search-wrapper">
30
+ <div className="search">
31
+ <SearchWidget />
32
+ </div>
33
+ </div>
34
+ </div>
35
+ <div className="tools-wrapper">
36
+ <LanguageSelector />
37
+
38
+ <div className="tools">
39
+ {!token && <Anontools />}
40
+
41
+ <Link aria-label="register" to="/register">
42
+ <FormattedMessage id="Register" defaultMessage="Registration" />
43
+ </Link>
44
+ <Link aria-label="sitemap" to="/sitemap">
45
+ <FormattedMessage id="Sitemap" defaultMessage="Sitemap" />
46
+ </Link>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </Container>
51
+ </header>
52
+ );
53
+ };
54
+
55
+ Header.propTypes = {
56
+ token: PropTypes.string,
57
+ pathname: PropTypes.string.isRequired,
58
+ };
59
+
60
+ Header.defaultProps = {
61
+ token: null,
62
+ };
63
+
64
+ export default Header;
@@ -0,0 +1,39 @@
1
+ // SemanticUI-free pre-@plone/components
2
+ import { defineMessages, useIntl } from 'react-intl';
3
+ import { useSelector } from 'react-redux';
4
+ import config from '@plone/volto/registry';
5
+ import { UniversalLink } from '@plone/volto/components';
6
+ import { toBackendLang } from '@plone/volto/helpers';
7
+ import LogoImage from '@plone/volto/components/theme/Logo/Logo.svg';
8
+
9
+ const messages = defineMessages({
10
+ site: {
11
+ id: 'Site',
12
+ defaultMessage: 'Site',
13
+ },
14
+ plonesite: {
15
+ id: 'Plone Site',
16
+ defaultMessage: 'Plone Site',
17
+ },
18
+ });
19
+
20
+ const Logo = () => {
21
+ const { settings } = config;
22
+ const lang = useSelector((state) => state.intl.locale);
23
+ const intl = useIntl();
24
+
25
+ return (
26
+ <UniversalLink
27
+ href={settings.isMultilingual ? `/${toBackendLang(lang)}` : '/'}
28
+ title={intl.formatMessage(messages.site)}
29
+ >
30
+ <img
31
+ src={LogoImage}
32
+ alt={intl.formatMessage(messages.plonesite)}
33
+ title={intl.formatMessage(messages.plonesite)}
34
+ />
35
+ </UniversalLink>
36
+ );
37
+ };
38
+
39
+ export default Logo;