@kitconcept/volto-light-theme 3.3.2 → 4.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 +21 -3
- package/.release-it.json +2 -1
- package/CHANGELOG.md +25 -0
- package/locales/de/LC_MESSAGES/volto.po +17 -17
- package/locales/en/LC_MESSAGES/volto.po +5 -5
- package/locales/es/LC_MESSAGES/volto.po +5 -5
- package/locales/eu/LC_MESSAGES/volto.po +5 -5
- package/locales/pt_BR/volto.po +5 -5
- package/locales/volto.pot +6 -6
- package/package.json +2 -11
- package/src/components/Header/Header.jsx +12 -12
- package/src/components/Logo/Logo.jsx +5 -5
- package/src/components/MobileNavigation/MobileNavigation.jsx +138 -243
- package/src/components/MobileNavigation/MobileNavigationToggler.jsx +16 -0
- package/src/theme/_header.scss +14 -4
- package/src/theme/_layout.scss +2 -1
- package/src/theme/blocks/_introduction.scss +2 -0
package/.changelog.draft
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
|
-
##
|
|
1
|
+
## 4.0.0 (2024-06-21)
|
|
2
|
+
|
|
3
|
+
### Breaking
|
|
4
|
+
|
|
5
|
+
- Fix tabbing order in the top header. It modifies the underlying HTML to move the top header to the bottom, and modifies CSS to adjust. @iRohitSingh @sneridagh [#374](https://github.com/kitconcept/volto-light-theme/pull/374)
|
|
6
|
+
- Updated the MobileNavigation component to be more easily customizable.
|
|
7
|
+
The component can now handle infinite navigation depth instead of only three levels, if configured to do so.
|
|
8
|
+
The Burger Menu can now be easily customized by overriding the new MobileNavigationToggler.jsx file.
|
|
9
|
+
@lenadax
|
|
10
|
+
|
|
11
|
+
Breaking:
|
|
12
|
+
- The "hamburger" icon in the mobile navigation now has an additional wrapper that allows for better customization.
|
|
13
|
+
|
|
14
|
+
If you have overriden the hamburger icon, you should make sure that your customizations still work and adjust otherwise. [#393](https://github.com/kitconcept/volto-light-theme/pull/393)
|
|
2
15
|
|
|
3
16
|
### Bugfix
|
|
4
17
|
|
|
5
|
-
-
|
|
6
|
-
-
|
|
18
|
+
- Fix Logo alt-Title @jonaspiterek [#337](https://github.com/kitconcept/volto-light-theme/pull/337)
|
|
19
|
+
- fix link in introduction block being smaller than normal text @jonaspiterek [#365](https://github.com/kitconcept/volto-light-theme/pull/365)
|
|
20
|
+
- Fix Description block width in Edit and Add mode. @danalvrz [#394](https://github.com/kitconcept/volto-light-theme/pull/394)
|
|
21
|
+
|
|
22
|
+
### Internal
|
|
23
|
+
|
|
24
|
+
- Update the setup. Use new images. @sneridagh [#390](https://github.com/kitconcept/volto-light-theme/pull/390)
|
|
7
25
|
|
|
8
26
|
|
package/.release-it.json
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
"pipx run towncrier build --draft --yes --version ${version} > .changelog.draft",
|
|
5
5
|
"pipx run towncrier build --yes --version ${version}",
|
|
6
6
|
"cp ../../README.md ./ && cp CHANGELOG.md ../../CHANGELOG.md",
|
|
7
|
-
"
|
|
7
|
+
"python3 -c 'import json; data = json.load(open(\"../../package.json\")); data[\"version\"] = \"${version}\"; json.dump(data, open(\"../../package.json\", \"w\"), indent=2)'",
|
|
8
|
+
"git add ../../CHANGELOG.md ../../package.json"
|
|
8
9
|
],
|
|
9
10
|
"after:release": "rm .changelog.draft"
|
|
10
11
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,31 @@
|
|
|
8
8
|
|
|
9
9
|
<!-- towncrier release notes start -->
|
|
10
10
|
|
|
11
|
+
## 4.0.0 (2024-06-21)
|
|
12
|
+
|
|
13
|
+
### Breaking
|
|
14
|
+
|
|
15
|
+
- Fix tabbing order in the top header. It modifies the underlying HTML to move the top header to the bottom, and modifies CSS to adjust. @iRohitSingh @sneridagh [#374](https://github.com/kitconcept/volto-light-theme/pull/374)
|
|
16
|
+
- Updated the MobileNavigation component to be more easily customizable.
|
|
17
|
+
The component can now handle infinite navigation depth instead of only three levels, if configured to do so.
|
|
18
|
+
The Burger Menu can now be easily customized by overriding the new MobileNavigationToggler.jsx file.
|
|
19
|
+
@lenadax
|
|
20
|
+
|
|
21
|
+
Breaking:
|
|
22
|
+
- The "hamburger" icon in the mobile navigation now has an additional wrapper that allows for better customization.
|
|
23
|
+
|
|
24
|
+
If you have overriden the hamburger icon, you should make sure that your customizations still work and adjust otherwise. [#393](https://github.com/kitconcept/volto-light-theme/pull/393)
|
|
25
|
+
|
|
26
|
+
### Bugfix
|
|
27
|
+
|
|
28
|
+
- Fix Logo alt-Title @jonaspiterek [#337](https://github.com/kitconcept/volto-light-theme/pull/337)
|
|
29
|
+
- fix link in introduction block being smaller than normal text @jonaspiterek [#365](https://github.com/kitconcept/volto-light-theme/pull/365)
|
|
30
|
+
- Fix Description block width in Edit and Add mode. @danalvrz [#394](https://github.com/kitconcept/volto-light-theme/pull/394)
|
|
31
|
+
|
|
32
|
+
### Internal
|
|
33
|
+
|
|
34
|
+
- Update the setup. Use new images. @sneridagh [#390](https://github.com/kitconcept/volto-light-theme/pull/390)
|
|
35
|
+
|
|
11
36
|
## 3.3.2 (2024-05-31)
|
|
12
37
|
|
|
13
38
|
### Bugfix
|
|
@@ -19,7 +19,12 @@ msgstr ""
|
|
|
19
19
|
#. Default: "Back"
|
|
20
20
|
#: components/MobileNavigation/MobileNavigation
|
|
21
21
|
msgid "Back"
|
|
22
|
-
msgstr ""
|
|
22
|
+
msgstr "Zurück"
|
|
23
|
+
|
|
24
|
+
#. Default: "Back to homepage"
|
|
25
|
+
#: components/Logo/Logo
|
|
26
|
+
msgid "Back to homepage"
|
|
27
|
+
msgstr "Zurück zur Startseite"
|
|
23
28
|
|
|
24
29
|
#. Default: "Background color"
|
|
25
30
|
#: components/Blocks/schema
|
|
@@ -34,7 +39,7 @@ msgstr "Block Breite"
|
|
|
34
39
|
#. Default: "Breadcrumbs"
|
|
35
40
|
#: components/Breadcrumbs/Breadcrumbs
|
|
36
41
|
msgid "Breadcrumbs"
|
|
37
|
-
msgstr ""
|
|
42
|
+
msgstr "Brotkrumen"
|
|
38
43
|
|
|
39
44
|
#. Default: "Browse the site, drop an image, or type an URL"
|
|
40
45
|
#: components/Blocks/Image/Edit
|
|
@@ -44,7 +49,7 @@ msgstr "Bild auswählen, hochladen oder URL angeben"
|
|
|
44
49
|
#. Default: "Button text"
|
|
45
50
|
#: components/Blocks/Slider/schema
|
|
46
51
|
msgid "Button text"
|
|
47
|
-
msgstr ""
|
|
52
|
+
msgstr "Button Text"
|
|
48
53
|
|
|
49
54
|
#. Default: "Center"
|
|
50
55
|
#: components/Widgets/AlignWidget
|
|
@@ -65,7 +70,7 @@ msgstr "Kontakt"
|
|
|
65
70
|
#. Default: "Continue reading"
|
|
66
71
|
#: components/Blocks/Slider/DefaultBody
|
|
67
72
|
msgid "Continue reading"
|
|
68
|
-
msgstr ""
|
|
73
|
+
msgstr "Weiterlesen"
|
|
69
74
|
|
|
70
75
|
#. Default: "Copyright"
|
|
71
76
|
#: components/Footer/Footer
|
|
@@ -80,7 +85,7 @@ msgstr "Beschreibung"
|
|
|
80
85
|
#. Default: "Distributed under the {license}."
|
|
81
86
|
#: components/Footer/Footer
|
|
82
87
|
msgid "Distributed under the {license}."
|
|
83
|
-
msgstr ""
|
|
88
|
+
msgstr "Vertrieben unter {license}"
|
|
84
89
|
|
|
85
90
|
#. Default: "End"
|
|
86
91
|
#: components/Blocks/EventMetadata/View
|
|
@@ -100,18 +105,18 @@ msgstr "Volle Breite"
|
|
|
100
105
|
#. Default: "GNU GPL license"
|
|
101
106
|
#: components/Footer/Footer
|
|
102
107
|
msgid "GNU GPL license"
|
|
103
|
-
msgstr ""
|
|
108
|
+
msgstr "GNU GPL Lizenz"
|
|
104
109
|
|
|
105
110
|
#. Default: "Hide Button"
|
|
106
111
|
#: components/Blocks/Slider/schema
|
|
107
112
|
msgid "Hide Button"
|
|
108
|
-
msgstr "
|
|
113
|
+
msgstr "keinen Button anzeigen"
|
|
109
114
|
|
|
110
115
|
#. Default: "Home"
|
|
111
116
|
#: components/Breadcrumbs/Breadcrumbs
|
|
112
117
|
#: components/MobileNavigation/MobileNavigation
|
|
113
118
|
msgid "Home"
|
|
114
|
-
msgstr ""
|
|
119
|
+
msgstr "Startseite"
|
|
115
120
|
|
|
116
121
|
#. Default: "ICS Download"
|
|
117
122
|
#: components/Blocks/EventMetadata/View
|
|
@@ -177,18 +182,13 @@ msgstr "Telefon"
|
|
|
177
182
|
#. Default: "Please choose an existing content as source for this element"
|
|
178
183
|
#: components/Blocks/Slider/DefaultBody
|
|
179
184
|
msgid "Please choose an existing content as source for this element"
|
|
180
|
-
msgstr ""
|
|
185
|
+
msgstr "Bitte wählen sie einen bestehenden Inhalt als Quelle für dieses Element"
|
|
181
186
|
|
|
182
187
|
#. Default: "Plone Foundation"
|
|
183
188
|
#: components/Footer/Footer
|
|
184
189
|
msgid "Plone Foundation"
|
|
185
190
|
msgstr ""
|
|
186
191
|
|
|
187
|
-
#. Default: "Plone Site"
|
|
188
|
-
#: components/Logo/Logo
|
|
189
|
-
msgid "Plone Site"
|
|
190
|
-
msgstr ""
|
|
191
|
-
|
|
192
192
|
#. Default: "Plone{reg} Open Source CMS/WCM"
|
|
193
193
|
#: components/Footer/Footer
|
|
194
194
|
msgid "Plone{reg} Open Source CMS/WCM"
|
|
@@ -272,7 +272,7 @@ msgstr "Sortierung"
|
|
|
272
272
|
#. Default: "Source"
|
|
273
273
|
#: components/Blocks/Slider/DefaultBody
|
|
274
274
|
msgid "Source"
|
|
275
|
-
msgstr ""
|
|
275
|
+
msgstr "Quelle"
|
|
276
276
|
|
|
277
277
|
#. Default: "Start"
|
|
278
278
|
#: components/Blocks/EventMetadata/View
|
|
@@ -317,7 +317,7 @@ msgstr "Bild löschen"
|
|
|
317
317
|
#. Default: "Image preview"
|
|
318
318
|
#: components/Blocks/Image/ImageSidebar
|
|
319
319
|
msgid "image_block_preview"
|
|
320
|
-
msgstr ""
|
|
320
|
+
msgstr "Bild Vorschau"
|
|
321
321
|
|
|
322
322
|
#. Default: "Loading"
|
|
323
323
|
#: components/Blocks/Listing/ListingBody
|
|
@@ -327,7 +327,7 @@ msgstr "laden"
|
|
|
327
327
|
#. Default: "More info"
|
|
328
328
|
#: components/Blocks/Slider/DefaultBody
|
|
329
329
|
msgid "moreInfo"
|
|
330
|
-
msgstr ""
|
|
330
|
+
msgstr "Mehr Informationen"
|
|
331
331
|
|
|
332
332
|
#. Default: "of"
|
|
333
333
|
#: components/Blocks/Listing/ListingBody
|
|
@@ -16,6 +16,11 @@ msgstr ""
|
|
|
16
16
|
msgid "Back"
|
|
17
17
|
msgstr ""
|
|
18
18
|
|
|
19
|
+
#. Default: "Back to homepage"
|
|
20
|
+
#: components/Logo/Logo
|
|
21
|
+
msgid "Back to homepage"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
19
24
|
#. Default: "Background color"
|
|
20
25
|
#: components/Blocks/schema
|
|
21
26
|
msgid "Background color"
|
|
@@ -179,11 +184,6 @@ msgstr ""
|
|
|
179
184
|
msgid "Plone Foundation"
|
|
180
185
|
msgstr ""
|
|
181
186
|
|
|
182
|
-
#. Default: "Plone Site"
|
|
183
|
-
#: components/Logo/Logo
|
|
184
|
-
msgid "Plone Site"
|
|
185
|
-
msgstr ""
|
|
186
|
-
|
|
187
187
|
#. Default: "Plone{reg} Open Source CMS/WCM"
|
|
188
188
|
#: components/Footer/Footer
|
|
189
189
|
msgid "Plone{reg} Open Source CMS/WCM"
|
|
@@ -22,6 +22,11 @@ msgstr ""
|
|
|
22
22
|
msgid "Back"
|
|
23
23
|
msgstr "Atrás"
|
|
24
24
|
|
|
25
|
+
#. Default: "Back to homepage"
|
|
26
|
+
#: components/Logo/Logo
|
|
27
|
+
msgid "Back to homepage"
|
|
28
|
+
msgstr ""
|
|
29
|
+
|
|
25
30
|
#. Default: "Background color"
|
|
26
31
|
#: components/Blocks/schema
|
|
27
32
|
msgid "Background color"
|
|
@@ -185,11 +190,6 @@ msgstr "Elija un contenido para utilizarlo como fuente de datos para este elemen
|
|
|
185
190
|
msgid "Plone Foundation"
|
|
186
191
|
msgstr "Fundación Plone"
|
|
187
192
|
|
|
188
|
-
#. Default: "Plone Site"
|
|
189
|
-
#: components/Logo/Logo
|
|
190
|
-
msgid "Plone Site"
|
|
191
|
-
msgstr "Sitio Plone"
|
|
192
|
-
|
|
193
193
|
#. Default: "Plone{reg} Open Source CMS/WCM"
|
|
194
194
|
#: components/Footer/Footer
|
|
195
195
|
msgid "Plone{reg} Open Source CMS/WCM"
|
|
@@ -22,6 +22,11 @@ msgstr ""
|
|
|
22
22
|
msgid "Back"
|
|
23
23
|
msgstr "Atzera"
|
|
24
24
|
|
|
25
|
+
#. Default: "Back to homepage"
|
|
26
|
+
#: components/Logo/Logo
|
|
27
|
+
msgid "Back to homepage"
|
|
28
|
+
msgstr ""
|
|
29
|
+
|
|
25
30
|
#. Default: "Background color"
|
|
26
31
|
#: components/Blocks/schema
|
|
27
32
|
msgid "Background color"
|
|
@@ -185,11 +190,6 @@ msgstr "Aukeratu eduki bat elementu honen iturburu gisa"
|
|
|
185
190
|
msgid "Plone Foundation"
|
|
186
191
|
msgstr "Plone Fundazioa"
|
|
187
192
|
|
|
188
|
-
#. Default: "Plone Site"
|
|
189
|
-
#: components/Logo/Logo
|
|
190
|
-
msgid "Plone Site"
|
|
191
|
-
msgstr "Plone Ataria"
|
|
192
|
-
|
|
193
193
|
#. Default: "Plone{reg} Open Source CMS/WCM"
|
|
194
194
|
#: components/Footer/Footer
|
|
195
195
|
msgid "Plone{reg} Open Source CMS/WCM"
|
package/locales/pt_BR/volto.po
CHANGED
|
@@ -16,6 +16,11 @@ msgstr ""
|
|
|
16
16
|
msgid "Back"
|
|
17
17
|
msgstr "Voltar"
|
|
18
18
|
|
|
19
|
+
#. Default: "Back to homepage"
|
|
20
|
+
#: components/Logo/Logo
|
|
21
|
+
msgid "Back to homepage"
|
|
22
|
+
msgstr "Voltar à página inicial"
|
|
23
|
+
|
|
19
24
|
#. Default: "Background color"
|
|
20
25
|
#: components/Blocks/schema
|
|
21
26
|
msgid "Background color"
|
|
@@ -179,11 +184,6 @@ msgstr "Por favor, escolha um conteúdo existente como fonte para esse elemento"
|
|
|
179
184
|
msgid "Plone Foundation"
|
|
180
185
|
msgstr "Plone Foundation"
|
|
181
186
|
|
|
182
|
-
#. Default: "Plone Site"
|
|
183
|
-
#: components/Logo/Logo
|
|
184
|
-
msgid "Plone Site"
|
|
185
|
-
msgstr "Site Plone"
|
|
186
|
-
|
|
187
187
|
#. Default: "Plone{reg} Open Source CMS/WCM"
|
|
188
188
|
#: components/Footer/Footer
|
|
189
189
|
msgid "Plone{reg} Open Source CMS/WCM"
|
package/locales/volto.pot
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
msgid ""
|
|
2
2
|
msgstr ""
|
|
3
3
|
"Project-Id-Version: Plone\n"
|
|
4
|
-
"POT-Creation-Date: 2024-
|
|
4
|
+
"POT-Creation-Date: 2024-05-31T09:46:26.312Z\n"
|
|
5
5
|
"Last-Translator: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
6
6
|
"Language-Team: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
7
7
|
"Content-Type: text/plain; charset=utf-8\n"
|
|
@@ -18,6 +18,11 @@ msgstr ""
|
|
|
18
18
|
msgid "Back"
|
|
19
19
|
msgstr ""
|
|
20
20
|
|
|
21
|
+
#. Default: "Back to homepage"
|
|
22
|
+
#: components/Logo/Logo
|
|
23
|
+
msgid "Back to homepage"
|
|
24
|
+
msgstr ""
|
|
25
|
+
|
|
21
26
|
#. Default: "Background color"
|
|
22
27
|
#: components/Blocks/schema
|
|
23
28
|
msgid "Background color"
|
|
@@ -181,11 +186,6 @@ msgstr ""
|
|
|
181
186
|
msgid "Plone Foundation"
|
|
182
187
|
msgstr ""
|
|
183
188
|
|
|
184
|
-
#. Default: "Plone Site"
|
|
185
|
-
#: components/Logo/Logo
|
|
186
|
-
msgid "Plone Site"
|
|
187
|
-
msgstr ""
|
|
188
|
-
|
|
189
189
|
#. Default: "Plone{reg} Open Source CMS/WCM"
|
|
190
190
|
#: components/Footer/Footer
|
|
191
191
|
msgid "Plone{reg} Open Source CMS/WCM"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitconcept/volto-light-theme",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Volto Light Theme by kitconcept",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/types/index.d.ts",
|
|
@@ -37,17 +37,8 @@
|
|
|
37
37
|
"@plone/scripts": "^3.6.1",
|
|
38
38
|
"release-it": "^17.1.1"
|
|
39
39
|
},
|
|
40
|
-
"peerAddons": [
|
|
41
|
-
"@eeacms/volto-accordion-block",
|
|
42
|
-
"@kitconcept/volto-button-block",
|
|
43
|
-
"@kitconcept/volto-heading-block",
|
|
44
|
-
"@kitconcept/volto-highlight-block",
|
|
45
|
-
"@kitconcept/volto-introduction-block",
|
|
46
|
-
"@kitconcept/volto-separator-block",
|
|
47
|
-
"@kitconcept/volto-slider-block"
|
|
48
|
-
],
|
|
49
40
|
"dependencies": {
|
|
50
|
-
"@plone/components": "
|
|
41
|
+
"@plone/components": "workspace:*"
|
|
51
42
|
},
|
|
52
43
|
"peerDependencies": {
|
|
53
44
|
"@eeacms/volto-accordion-block": "^10.4.6",
|
|
@@ -28,18 +28,6 @@ const InternetHeader = ({ pathname, siteLabel, token, siteAction }) => {
|
|
|
28
28
|
return (
|
|
29
29
|
<>
|
|
30
30
|
<div className="header">
|
|
31
|
-
<div className="logo-nav-wrapper">
|
|
32
|
-
<div className="logo">
|
|
33
|
-
<Logo />
|
|
34
|
-
</div>
|
|
35
|
-
<Navigation pathname={pathname} />
|
|
36
|
-
<MobileNavigation pathname={pathname} />
|
|
37
|
-
<div className="search-wrapper navigation-desktop">
|
|
38
|
-
<div className="search">
|
|
39
|
-
<SearchWidget />
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
31
|
<div className="tools-wrapper">
|
|
44
32
|
<LanguageSelector />
|
|
45
33
|
|
|
@@ -58,6 +46,18 @@ const InternetHeader = ({ pathname, siteLabel, token, siteAction }) => {
|
|
|
58
46
|
</div>
|
|
59
47
|
)}
|
|
60
48
|
</div>
|
|
49
|
+
<div className="logo-nav-wrapper">
|
|
50
|
+
<div className="logo">
|
|
51
|
+
<Logo />
|
|
52
|
+
</div>
|
|
53
|
+
<Navigation pathname={pathname} />
|
|
54
|
+
<MobileNavigation pathname={pathname} />
|
|
55
|
+
<div className="search-wrapper navigation-desktop">
|
|
56
|
+
<div className="search">
|
|
57
|
+
<SearchWidget />
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
61
|
</div>
|
|
62
62
|
</>
|
|
63
63
|
);
|
|
@@ -12,9 +12,9 @@ const messages = defineMessages({
|
|
|
12
12
|
id: 'Site',
|
|
13
13
|
defaultMessage: 'Site',
|
|
14
14
|
},
|
|
15
|
-
|
|
16
|
-
id: '
|
|
17
|
-
defaultMessage: '
|
|
15
|
+
homepage: {
|
|
16
|
+
id: 'Back to homepage',
|
|
17
|
+
defaultMessage: 'Back to homepage',
|
|
18
18
|
},
|
|
19
19
|
});
|
|
20
20
|
|
|
@@ -35,8 +35,8 @@ const Logo = () => {
|
|
|
35
35
|
? flattenToAppURL(site['plone.site_logo'])
|
|
36
36
|
: LogoImage
|
|
37
37
|
}
|
|
38
|
-
alt={intl.formatMessage(messages.
|
|
39
|
-
title={intl.formatMessage(messages.
|
|
38
|
+
alt={intl.formatMessage(messages.homepage)}
|
|
39
|
+
title={intl.formatMessage(messages.homepage)}
|
|
40
40
|
/>
|
|
41
41
|
</UniversalLink>
|
|
42
42
|
);
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useCallback, useState, useEffect, useRef } from 'react';
|
|
2
2
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
|
3
3
|
import { useSelector } from 'react-redux';
|
|
4
4
|
import { Link, useHistory } from 'react-router-dom';
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import { CSSTransition } from 'react-transition-group';
|
|
7
|
+
import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib';
|
|
7
8
|
|
|
8
9
|
import config from '@plone/volto/registry';
|
|
9
10
|
import { Icon, SearchWidget } from '@plone/volto/components';
|
|
10
11
|
import { toBackendLang } from '@plone/volto/helpers';
|
|
11
12
|
import arrowRightSVG from '@plone/volto/icons/right-key.svg';
|
|
12
13
|
import arrowLeftSVG from '@plone/volto/icons/left-key.svg';
|
|
14
|
+
import { MobileNavigationToggler } from './MobileNavigationToggler';
|
|
13
15
|
import { MobileToolsFooter } from './MobileToolsFooter';
|
|
14
16
|
|
|
15
17
|
const messages = defineMessages({
|
|
@@ -25,27 +27,106 @@ const messages = defineMessages({
|
|
|
25
27
|
id: 'Search',
|
|
26
28
|
defaultMessage: 'Search',
|
|
27
29
|
},
|
|
30
|
+
back: {
|
|
31
|
+
id: 'Back',
|
|
32
|
+
defaultMessage: 'Back',
|
|
33
|
+
},
|
|
28
34
|
});
|
|
29
35
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const MenuItem = ({
|
|
37
|
+
section,
|
|
38
|
+
level,
|
|
39
|
+
closeMenus,
|
|
40
|
+
handleLinkClicked,
|
|
41
|
+
resetToRoot,
|
|
42
|
+
pathname,
|
|
43
|
+
}) => {
|
|
44
|
+
const [isSubMenuOpen, setSubMenuOpen] = useState(false);
|
|
45
|
+
|
|
46
|
+
const openSubMenu = useCallback((e) => {
|
|
47
|
+
e.stopPropagation();
|
|
48
|
+
setSubMenuOpen(true);
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
const closeSubMenu = useCallback((e) => {
|
|
52
|
+
e.stopPropagation();
|
|
53
|
+
setSubMenuOpen(false);
|
|
54
|
+
}, []);
|
|
55
|
+
|
|
56
|
+
// Reset submenus when history changes
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (resetToRoot) {
|
|
59
|
+
setSubMenuOpen(false);
|
|
60
|
+
}
|
|
61
|
+
}, [resetToRoot]);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<li className={section.url === pathname ? 'current' : ''}>
|
|
65
|
+
<Link
|
|
66
|
+
to={section.url === '' ? '/' : section.url}
|
|
67
|
+
onClick={(e) =>
|
|
68
|
+
handleLinkClicked(e, section, openSubMenu, closeSubMenu, level)
|
|
69
|
+
}
|
|
70
|
+
>
|
|
71
|
+
{section.nav_title || section.title}
|
|
72
|
+
{section.items.length > 0 && <Icon name={arrowRightSVG} />}
|
|
73
|
+
</Link>
|
|
74
|
+
<CSSTransition
|
|
75
|
+
in={isSubMenuOpen}
|
|
76
|
+
timeout={500}
|
|
77
|
+
classNames="menu-drawer"
|
|
78
|
+
unmountOnExit
|
|
79
|
+
>
|
|
80
|
+
<div className="menu-drawer subsection">
|
|
81
|
+
<div className="search-header">
|
|
82
|
+
<div className="search-wrapper">
|
|
83
|
+
<div className="search">
|
|
84
|
+
<SearchWidget />
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
<button onClick={closeSubMenu}>
|
|
88
|
+
<Icon name={arrowLeftSVG} size="60px" />
|
|
89
|
+
<span>
|
|
90
|
+
<FormattedMessage {...messages.back} />
|
|
91
|
+
</span>
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
<ul className="sections">
|
|
95
|
+
<li className="header">{section.nav_title || section.title}</li>
|
|
96
|
+
<li>
|
|
97
|
+
<Link
|
|
98
|
+
to={section.url === '' ? '/' : section.url}
|
|
99
|
+
onClick={closeMenus}
|
|
100
|
+
>
|
|
101
|
+
<FormattedMessage id="Overview" defaultMessage="Overview" />
|
|
102
|
+
</Link>
|
|
103
|
+
</li>
|
|
104
|
+
{section.items &&
|
|
105
|
+
section.items.map((subsection, index) => (
|
|
106
|
+
<MenuItem
|
|
107
|
+
key={subsection.url}
|
|
108
|
+
section={subsection}
|
|
109
|
+
level={level + 1}
|
|
110
|
+
closeMenus={closeMenus}
|
|
111
|
+
handleLinkClicked={handleLinkClicked}
|
|
112
|
+
resetToRoot={resetToRoot}
|
|
113
|
+
pathname={pathname}
|
|
114
|
+
/>
|
|
115
|
+
))}
|
|
116
|
+
</ul>
|
|
117
|
+
<MobileToolsFooter />
|
|
118
|
+
</div>
|
|
119
|
+
</CSSTransition>
|
|
120
|
+
</li>
|
|
121
|
+
);
|
|
122
|
+
};
|
|
38
123
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
isSecondaryMobileMenuOpen,
|
|
43
|
-
tertiaryMenuOpened,
|
|
44
|
-
isTertiaryMobileMenuOpen,
|
|
45
|
-
} = menuState;
|
|
124
|
+
const MobileNavigation = (props) => {
|
|
125
|
+
const [isMobileMenuOpen, setMobileMenuOpen] = useState(false);
|
|
126
|
+
const [resetToRoot, setResetToRoot] = useState(false);
|
|
46
127
|
const { settings } = config;
|
|
47
128
|
const intl = useIntl();
|
|
48
|
-
const menus =
|
|
129
|
+
const menus = useRef(null);
|
|
49
130
|
const currentLang = useSelector((state) => state.intl.locale);
|
|
50
131
|
const items = useSelector((state) => state.navigation.items || []);
|
|
51
132
|
const history = useHistory();
|
|
@@ -55,94 +136,64 @@ const MobileNavigation = (props) => {
|
|
|
55
136
|
const toggleMobileMenu = useCallback(() => {
|
|
56
137
|
const body = document.getElementsByTagName('body')[0];
|
|
57
138
|
body.classList.toggle('has-menu-open');
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}, []);
|
|
64
|
-
|
|
65
|
-
const openSecondaryMenu = useCallback((e, index) => {
|
|
66
|
-
e.stopPropagation();
|
|
67
|
-
|
|
68
|
-
setMenuState((prevState) => ({
|
|
69
|
-
...prevState,
|
|
70
|
-
secondaryMenuOpened: index,
|
|
71
|
-
isSecondaryMobileMenuOpen: true,
|
|
72
|
-
}));
|
|
73
|
-
}, []);
|
|
74
|
-
|
|
75
|
-
const closeSecondaryMenu = useCallback((e) => {
|
|
76
|
-
e.stopPropagation();
|
|
77
|
-
setMenuState((prevState) => ({
|
|
78
|
-
...prevState,
|
|
79
|
-
isSecondaryMobileMenuOpen: false,
|
|
80
|
-
secondaryMenuOpened: null,
|
|
81
|
-
}));
|
|
82
|
-
}, []);
|
|
83
|
-
|
|
84
|
-
const openTertiaryMenu = useCallback((e, index) => {
|
|
85
|
-
e.stopPropagation();
|
|
86
|
-
|
|
87
|
-
setMenuState((prevState) => ({
|
|
88
|
-
...prevState,
|
|
89
|
-
tertiaryMenuOpened: index,
|
|
90
|
-
isTertiaryMobileMenuOpen: true,
|
|
91
|
-
}));
|
|
92
|
-
}, []);
|
|
93
|
-
|
|
94
|
-
const closeTertiaryMenu = useCallback((e) => {
|
|
95
|
-
e.stopPropagation();
|
|
96
|
-
|
|
97
|
-
setMenuState((prevState) => ({
|
|
98
|
-
...prevState,
|
|
99
|
-
isTertiaryMobileMenuOpen: false,
|
|
100
|
-
tertiaryMenuOpened: null,
|
|
101
|
-
}));
|
|
102
|
-
}, []);
|
|
139
|
+
setMobileMenuOpen((prev) => !prev);
|
|
140
|
+
if (!isMobileMenuOpen) {
|
|
141
|
+
setResetToRoot(false); // Disable reset to root when opening menu
|
|
142
|
+
}
|
|
143
|
+
}, [isMobileMenuOpen]);
|
|
103
144
|
|
|
104
145
|
const closeMenus = useCallback((e) => {
|
|
105
146
|
if (e && e.stopPropagation) {
|
|
106
147
|
e.stopPropagation();
|
|
107
148
|
}
|
|
108
|
-
|
|
109
|
-
setMenuState(() => ({
|
|
110
|
-
isSecondaryMobileMenuOpen: false,
|
|
111
|
-
isTertiaryMobileMenuOpen: false,
|
|
112
|
-
secondaryMenuOpened: null,
|
|
113
|
-
tertiaryMenuOpened: null,
|
|
114
|
-
isMobileMenuOpen: false,
|
|
115
|
-
}));
|
|
149
|
+
setMobileMenuOpen(false);
|
|
116
150
|
}, []);
|
|
117
151
|
|
|
118
152
|
const handleLinkClicked = useCallback(
|
|
119
|
-
(e, section,
|
|
153
|
+
(e, section, openSubMenu, closeSubMenu, level) => {
|
|
120
154
|
e.preventDefault();
|
|
121
155
|
if (section.items.length > 0) {
|
|
122
|
-
|
|
156
|
+
openSubMenu(e);
|
|
123
157
|
} else {
|
|
124
158
|
history.push(section.url);
|
|
125
|
-
|
|
159
|
+
closeMenus(e);
|
|
160
|
+
setResetToRoot(true);
|
|
126
161
|
}
|
|
127
162
|
},
|
|
128
163
|
[history, closeMenus],
|
|
129
164
|
);
|
|
130
165
|
|
|
131
|
-
|
|
132
|
-
const closeMenuOnHistoryChange = history.listen(() =>
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
const closeMenuOnHistoryChange = history.listen(() => {
|
|
168
|
+
closeMenus({});
|
|
169
|
+
setResetToRoot(true);
|
|
170
|
+
});
|
|
133
171
|
return () => {
|
|
134
172
|
closeMenuOnHistoryChange();
|
|
135
173
|
};
|
|
136
174
|
}, [history, closeMenus]);
|
|
137
175
|
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
const handleClickOutside = (e) => {
|
|
178
|
+
if (menus.current && !doesNodeContainClick(menus.current, e)) {
|
|
179
|
+
closeMenus(e);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
document.addEventListener('mousedown', handleClickOutside, false);
|
|
183
|
+
|
|
184
|
+
return () => {
|
|
185
|
+
document.removeEventListener('mousedown', handleClickOutside, false);
|
|
186
|
+
};
|
|
187
|
+
}, [closeMenus]);
|
|
188
|
+
|
|
138
189
|
return (
|
|
139
190
|
<div className="mobile-nav mobile only tablet only" ref={menus}>
|
|
140
191
|
<div className="hamburger-wrapper">
|
|
141
192
|
<button
|
|
142
|
-
className={cx('hamburger hamburger--collapse', {
|
|
193
|
+
className={cx('hamburger-toggler hamburger-toggler--collapse', {
|
|
143
194
|
'is-active': isMobileMenuOpen,
|
|
144
195
|
})}
|
|
145
|
-
aria-expanded={isMobileMenuOpen
|
|
196
|
+
aria-expanded={isMobileMenuOpen}
|
|
146
197
|
aria-label={
|
|
147
198
|
isMobileMenuOpen
|
|
148
199
|
? intl.formatMessage(messages.closeMobileMenu)
|
|
@@ -156,9 +207,7 @@ const MobileNavigation = (props) => {
|
|
|
156
207
|
type="button"
|
|
157
208
|
onClick={toggleMobileMenu}
|
|
158
209
|
>
|
|
159
|
-
<
|
|
160
|
-
<span className="hamburger-inner" />
|
|
161
|
-
</span>
|
|
210
|
+
<MobileNavigationToggler isMobileMenuOpen={isMobileMenuOpen} />
|
|
162
211
|
</button>
|
|
163
212
|
</div>
|
|
164
213
|
|
|
@@ -169,7 +218,7 @@ const MobileNavigation = (props) => {
|
|
|
169
218
|
>
|
|
170
219
|
<div className="menu-drawer">
|
|
171
220
|
<div className="search-header">
|
|
172
|
-
<div className="
|
|
221
|
+
<div className="search-wrapper">
|
|
173
222
|
<div className="search">
|
|
174
223
|
<SearchWidget />
|
|
175
224
|
</div>
|
|
@@ -190,169 +239,15 @@ const MobileNavigation = (props) => {
|
|
|
190
239
|
</li>
|
|
191
240
|
{items &&
|
|
192
241
|
items.map((section, index) => (
|
|
193
|
-
<
|
|
242
|
+
<MenuItem
|
|
194
243
|
key={section.url}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
>
|
|
203
|
-
{section.nav_title || section.title}
|
|
204
|
-
{section.items.length > 0 && <Icon name={arrowRightSVG} />}
|
|
205
|
-
</Link>
|
|
206
|
-
<CSSTransition
|
|
207
|
-
in={
|
|
208
|
-
isSecondaryMobileMenuOpen && secondaryMenuOpened === index
|
|
209
|
-
}
|
|
210
|
-
timeout={500}
|
|
211
|
-
classNames="menu-drawer"
|
|
212
|
-
unmountOnExit
|
|
213
|
-
>
|
|
214
|
-
<div className="menu-drawer subsection">
|
|
215
|
-
<div className="search-header">
|
|
216
|
-
<div className=" search-wrapper ">
|
|
217
|
-
<div className="search">
|
|
218
|
-
<SearchWidget />
|
|
219
|
-
</div>
|
|
220
|
-
</div>
|
|
221
|
-
|
|
222
|
-
<button onClick={(e) => closeSecondaryMenu(e)}>
|
|
223
|
-
<Icon name={arrowLeftSVG} size="60px" />
|
|
224
|
-
<span>
|
|
225
|
-
<FormattedMessage id="Back" defaultMessage="Back" />
|
|
226
|
-
</span>
|
|
227
|
-
</button>
|
|
228
|
-
</div>
|
|
229
|
-
<ul className="sections">
|
|
230
|
-
<li className="header">
|
|
231
|
-
{section.nav_title || section.title}
|
|
232
|
-
</li>
|
|
233
|
-
<li>
|
|
234
|
-
<Link
|
|
235
|
-
to={section.url === '' ? '/' : section.url}
|
|
236
|
-
onClick={closeMenus}
|
|
237
|
-
>
|
|
238
|
-
<FormattedMessage
|
|
239
|
-
id="Overview"
|
|
240
|
-
defaultMessage="Overview"
|
|
241
|
-
/>
|
|
242
|
-
</Link>
|
|
243
|
-
</li>
|
|
244
|
-
|
|
245
|
-
{section.items &&
|
|
246
|
-
section.items.map((subsection, index) => (
|
|
247
|
-
<li
|
|
248
|
-
key={subsection.url}
|
|
249
|
-
className={
|
|
250
|
-
subsection.url === props.pathname
|
|
251
|
-
? 'current'
|
|
252
|
-
: ''
|
|
253
|
-
}
|
|
254
|
-
>
|
|
255
|
-
<Link
|
|
256
|
-
to={
|
|
257
|
-
subsection.url === '' ? '/' : subsection.url
|
|
258
|
-
}
|
|
259
|
-
onClick={(e) =>
|
|
260
|
-
handleLinkClicked(
|
|
261
|
-
e,
|
|
262
|
-
subsection,
|
|
263
|
-
openTertiaryMenu,
|
|
264
|
-
index,
|
|
265
|
-
)
|
|
266
|
-
}
|
|
267
|
-
>
|
|
268
|
-
{subsection.nav_title || subsection.title}
|
|
269
|
-
{subsection.items.length > 0 && (
|
|
270
|
-
<Icon name={arrowRightSVG} />
|
|
271
|
-
)}
|
|
272
|
-
</Link>
|
|
273
|
-
<CSSTransition
|
|
274
|
-
in={
|
|
275
|
-
isTertiaryMobileMenuOpen &&
|
|
276
|
-
tertiaryMenuOpened === index
|
|
277
|
-
}
|
|
278
|
-
timeout={500}
|
|
279
|
-
classNames="menu-drawer"
|
|
280
|
-
unmountOnExit
|
|
281
|
-
>
|
|
282
|
-
<div className="menu-drawer subsection">
|
|
283
|
-
<div className="search-header">
|
|
284
|
-
<div className=" search-wrapper ">
|
|
285
|
-
<div className="search">
|
|
286
|
-
<SearchWidget />
|
|
287
|
-
</div>
|
|
288
|
-
</div>
|
|
289
|
-
|
|
290
|
-
<button
|
|
291
|
-
onClick={(e) => closeTertiaryMenu(e)}
|
|
292
|
-
>
|
|
293
|
-
<Icon name={arrowLeftSVG} size="60px" />
|
|
294
|
-
<span>
|
|
295
|
-
<FormattedMessage
|
|
296
|
-
id="Back"
|
|
297
|
-
defaultMessage="Back"
|
|
298
|
-
/>
|
|
299
|
-
</span>
|
|
300
|
-
</button>
|
|
301
|
-
</div>
|
|
302
|
-
<ul className="sections">
|
|
303
|
-
<li className="header">
|
|
304
|
-
{subsection.nav_title || subsection.title}
|
|
305
|
-
</li>
|
|
306
|
-
<li>
|
|
307
|
-
<Link
|
|
308
|
-
to={
|
|
309
|
-
subsection.url === ''
|
|
310
|
-
? '/'
|
|
311
|
-
: subsection.url
|
|
312
|
-
}
|
|
313
|
-
onClick={closeMenus}
|
|
314
|
-
>
|
|
315
|
-
<FormattedMessage
|
|
316
|
-
id="Overview"
|
|
317
|
-
defaultMessage="Overview"
|
|
318
|
-
/>
|
|
319
|
-
</Link>
|
|
320
|
-
</li>
|
|
321
|
-
{subsection.items &&
|
|
322
|
-
subsection.items.map(
|
|
323
|
-
(subsubsection, subindex) => (
|
|
324
|
-
<li
|
|
325
|
-
key={subsubsection.url}
|
|
326
|
-
className={cx('sub-section', {
|
|
327
|
-
'last-child':
|
|
328
|
-
subindex ===
|
|
329
|
-
subsection.items.length - 1,
|
|
330
|
-
current:
|
|
331
|
-
subsubsection.url ===
|
|
332
|
-
props.pathname,
|
|
333
|
-
})}
|
|
334
|
-
>
|
|
335
|
-
<Link
|
|
336
|
-
to={subsubsection.url}
|
|
337
|
-
onClick={closeMenus}
|
|
338
|
-
>
|
|
339
|
-
{subsubsection.nav_title ||
|
|
340
|
-
subsubsection.title}
|
|
341
|
-
</Link>
|
|
342
|
-
</li>
|
|
343
|
-
),
|
|
344
|
-
)}
|
|
345
|
-
</ul>
|
|
346
|
-
<Footer />
|
|
347
|
-
</div>
|
|
348
|
-
</CSSTransition>
|
|
349
|
-
</li>
|
|
350
|
-
))}
|
|
351
|
-
</ul>
|
|
352
|
-
<Footer />
|
|
353
|
-
</div>
|
|
354
|
-
</CSSTransition>
|
|
355
|
-
</li>
|
|
244
|
+
section={section}
|
|
245
|
+
level={0}
|
|
246
|
+
closeMenus={closeMenus}
|
|
247
|
+
handleLinkClicked={handleLinkClicked}
|
|
248
|
+
resetToRoot={resetToRoot}
|
|
249
|
+
pathname={props.pathname}
|
|
250
|
+
/>
|
|
356
251
|
))}
|
|
357
252
|
</ul>
|
|
358
253
|
<Footer />
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
|
|
4
|
+
export const MobileNavigationToggler = ({ isMobileMenuOpen }) => {
|
|
5
|
+
return (
|
|
6
|
+
<div
|
|
7
|
+
className={cx('hamburger hamburger--collapse', {
|
|
8
|
+
'is-active': isMobileMenuOpen,
|
|
9
|
+
})}
|
|
10
|
+
>
|
|
11
|
+
<span className="hamburger-box">
|
|
12
|
+
<span className="hamburger-inner" />
|
|
13
|
+
</span>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
};
|
package/src/theme/_header.scss
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.header-wrapper .header {
|
|
2
2
|
display: flex;
|
|
3
|
-
flex-direction: column
|
|
3
|
+
flex-direction: column;
|
|
4
4
|
|
|
5
5
|
.logo-nav-wrapper {
|
|
6
6
|
display: flex;
|
|
@@ -672,8 +672,13 @@ body.has-toolbar.has-sidebar {
|
|
|
672
672
|
padding: 15px;
|
|
673
673
|
}
|
|
674
674
|
|
|
675
|
-
.hamburger {
|
|
676
|
-
|
|
675
|
+
.hamburger-toggler {
|
|
676
|
+
width: 40px;
|
|
677
|
+
height: 24px;
|
|
678
|
+
padding: 0;
|
|
679
|
+
border: none;
|
|
680
|
+
background-color: transparent;
|
|
681
|
+
cursor: pointer;
|
|
677
682
|
}
|
|
678
683
|
|
|
679
684
|
.hamburger-wrapper {
|
|
@@ -716,7 +721,7 @@ body.has-toolbar.has-sidebar {
|
|
|
716
721
|
.search-wrapper .search {
|
|
717
722
|
padding-top: 20px;
|
|
718
723
|
button {
|
|
719
|
-
padding
|
|
724
|
+
padding: 0px;
|
|
720
725
|
margin-right: 20px;
|
|
721
726
|
}
|
|
722
727
|
}
|
|
@@ -880,6 +885,11 @@ body.has-toolbar.has-sidebar {
|
|
|
880
885
|
cursor: pointer;
|
|
881
886
|
}
|
|
882
887
|
|
|
888
|
+
&.header {
|
|
889
|
+
align-items: flex-start;
|
|
890
|
+
line-height: 36px;
|
|
891
|
+
}
|
|
892
|
+
|
|
883
893
|
&.current {
|
|
884
894
|
font-weight: 700;
|
|
885
895
|
}
|
package/src/theme/_layout.scss
CHANGED
|
@@ -291,7 +291,8 @@ External link removal for all the blocks.
|
|
|
291
291
|
.block.separator
|
|
292
292
|
.line,
|
|
293
293
|
.block-editor-codeBlock,
|
|
294
|
-
.block-editor-mermaidBlock
|
|
294
|
+
.block-editor-mermaidBlock,
|
|
295
|
+
.block-editor-description .documentDescription {
|
|
295
296
|
@include narrow-container-width();
|
|
296
297
|
@include adjustMarginsToEditContainer($narrow-container-width);
|
|
297
298
|
}
|