hr-design-system-handlebars 0.50.1 → 0.50.2
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/.storybook/main.js +12 -0
- package/CHANGELOG.md +12 -0
- package/dist/assets/index.css +7 -0
- package/dist/views/components/site_header/header_alpine.js +56 -9
- package/package.json +1 -1
- package/src/assets/images/navi_default.png +0 -0
- package/src/assets/images/navi_flyout_section.PNG +0 -0
- package/src/assets/images/navi_flyout_service.PNG +0 -0
- package/src/assets/images/navi_mobil_burger_open.PNG +0 -0
- package/src/assets/images/navi_mobil_default.PNG +0 -0
- package/src/assets/images/navi_mobil_scroll_1percent.PNG +0 -0
- package/src/assets/images/navi_mobil_scroll_50percent.PNG +0 -0
- package/src/assets/images/navi_mobil_search.PNG +0 -0
- package/src/assets/images/navi_mobil_search.jpg +0 -0
- package/src/assets/images/navi_scroll_50percent.PNG +0 -0
- package/src/assets/images/navi_scroll_90percent.PNG +0 -0
- package/src/assets/images/navi_tablet.PNG +0 -0
- package/src/assets/images/navi_tablet_flyout_service.PNG +0 -0
- package/src/assets/images/navi_tablet_scroll_1percent.PNG +0 -0
- package/src/assets/images/navi_tablet_scroll_50percent.PNG +0 -0
- package/src/assets/tailwind.css +4 -0
- package/src/stories/views/components/site_header/header.stories.mdx +317 -5
- package/src/stories/views/components/site_header/header_alpine.js +56 -9
package/.storybook/main.js
CHANGED
|
@@ -72,6 +72,18 @@ module.exports = {
|
|
|
72
72
|
},
|
|
73
73
|
],
|
|
74
74
|
include: path.resolve(__dirname, '../'),
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
test: /\.(png|woff|woff2|eot|ttf|jpg|jpeg|gif|svg)$/,
|
|
78
|
+
use: [
|
|
79
|
+
{
|
|
80
|
+
loader: "file-loader",
|
|
81
|
+
options: {
|
|
82
|
+
name: "[path][name].[ext]",
|
|
83
|
+
context: "",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
],
|
|
75
87
|
}
|
|
76
88
|
)
|
|
77
89
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# v0.50.2 (Fri Jul 15 2022)
|
|
2
|
+
|
|
3
|
+
#### 🐛 Bug Fix
|
|
4
|
+
|
|
5
|
+
- refactor header.stories.mdx [#276](https://github.com/mumprod/hr-design-system-handlebars/pull/276) ([@StefanVesper](https://github.com/StefanVesper))
|
|
6
|
+
|
|
7
|
+
#### Authors: 1
|
|
8
|
+
|
|
9
|
+
- SonicSoulSurfer ([@StefanVesper](https://github.com/StefanVesper))
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
1
13
|
# v0.50.1 (Fri Jul 15 2022)
|
|
2
14
|
|
|
3
15
|
#### 🐛 Bug Fix
|
package/dist/assets/index.css
CHANGED
|
@@ -596,6 +596,10 @@ video {
|
|
|
596
596
|
.relative {
|
|
597
597
|
position: relative;
|
|
598
598
|
}
|
|
599
|
+
.sticky {
|
|
600
|
+
position: -webkit-sticky;
|
|
601
|
+
position: sticky;
|
|
602
|
+
}
|
|
599
603
|
.bottom-0 {
|
|
600
604
|
bottom: 0px;
|
|
601
605
|
}
|
|
@@ -2417,6 +2421,9 @@ video {
|
|
|
2417
2421
|
--color-topline: #c20016;
|
|
2418
2422
|
}
|
|
2419
2423
|
/*! purgecss end ignore */
|
|
2424
|
+
.sbdocs-content {
|
|
2425
|
+
max-width:1140px !important;
|
|
2426
|
+
}
|
|
2420
2427
|
.hide-scroll-bar {
|
|
2421
2428
|
-ms-overflow-style: none;
|
|
2422
2429
|
scrollbar-width: none;
|
|
@@ -32,23 +32,25 @@ document.addEventListener('alpine:init', () => {
|
|
|
32
32
|
init(){
|
|
33
33
|
let lastScrollTop = 0
|
|
34
34
|
let height = window.innerHeight
|
|
35
|
+
|
|
36
|
+
//Globale Variable, true = user initiated scroll / false = programmatic scroll via JS (e.g. click on Anchor Link)
|
|
35
37
|
let userScroll = false;
|
|
36
38
|
window.userScroll = userScroll;
|
|
37
39
|
|
|
40
|
+
// gets fired when user initated scroll happened, global variable is used in Ticker-Topnews and other anchor links to prevent expanding of the navigation if scrollposition gets corrected by JS.
|
|
38
41
|
const mouseEvent = () => {
|
|
39
42
|
userScroll = true;
|
|
40
43
|
window.userScroll = true;
|
|
41
|
-
//console.log('user action detected')
|
|
42
44
|
}
|
|
43
|
-
|
|
45
|
+
// detect if the user clicked/dragged the scrollbar manually
|
|
44
46
|
const clickedOnScrollbar = mouseX => {
|
|
45
47
|
return document.documentElement.offsetWidth <= mouseX ? true : false;
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
// if clicked on scrollbar, fire user initiated mouse event
|
|
48
50
|
const mouseDownHandler = e => {
|
|
49
51
|
clickedOnScrollbar(e.clientX) ? mouseEvent() : null
|
|
50
52
|
};
|
|
51
|
-
|
|
53
|
+
// main scroll handler, defines scroll direction, percent of viewport scrolled, visibility of navigation and subnavigation
|
|
52
54
|
const scrollHandler = () => {
|
|
53
55
|
let winScroll = document.body.scrollTop || document.documentElement.scrollTop
|
|
54
56
|
winScroll > lastScrollTop ? this.scrollingDown = true : this.scrollingDown = false
|
|
@@ -59,14 +61,19 @@ document.addEventListener('alpine:init', () => {
|
|
|
59
61
|
//console.log('winscroll: '+winScroll+' screen height: '+height + ' percent scrolled: '+ this.percent)
|
|
60
62
|
//console.log('Scroll initiated by ' + (window.userScroll == true ? "user" : "browser"));
|
|
61
63
|
}
|
|
62
|
-
|
|
64
|
+
// Listeners
|
|
63
65
|
window.addEventListener('mousedown', mouseDownHandler, false)
|
|
64
66
|
window.addEventListener('wheel', mouseEvent, false);
|
|
65
67
|
window.addEventListener('touchmove', mouseEvent, false)
|
|
66
68
|
window.addEventListener('scroll', this.debounce( scrollHandler,50), { passive: true })
|
|
67
69
|
},
|
|
70
|
+
//Holds the percentage of scrolled viewport
|
|
68
71
|
percent: 0,
|
|
72
|
+
|
|
73
|
+
//defines the scroll direction
|
|
69
74
|
scrollingDown: true,
|
|
75
|
+
|
|
76
|
+
//returns true if section navigation is hidden on desktop OR service navigation is hidden on mobile
|
|
70
77
|
isNavHidden() {
|
|
71
78
|
if(this.$screen('lg')) {
|
|
72
79
|
return this.shouldSectionNavBeHidden()
|
|
@@ -74,6 +81,8 @@ document.addEventListener('alpine:init', () => {
|
|
|
74
81
|
return this.shouldServiceNavBeHidden()
|
|
75
82
|
}
|
|
76
83
|
},
|
|
84
|
+
|
|
85
|
+
//returns false if subnav is visible and true if subnav is hidden
|
|
77
86
|
isSubNavHidden() {
|
|
78
87
|
if(this.$screen('lg')){
|
|
79
88
|
if (document.querySelector('.isSelectedAndOpen') !== null) {
|
|
@@ -85,9 +94,13 @@ document.addEventListener('alpine:init', () => {
|
|
|
85
94
|
return true
|
|
86
95
|
}
|
|
87
96
|
},
|
|
97
|
+
|
|
98
|
+
// returns true if the user scrolled at least 1px from top
|
|
88
99
|
shouldBrandNavBeHidden() {
|
|
89
100
|
return this.percent > 0
|
|
90
101
|
},
|
|
102
|
+
|
|
103
|
+
// returns true if user scrolled >50% and scrolls down, no burger menu is open and the screen size is desktop. If scroll was initiated by script, ignore scroll direction.
|
|
91
104
|
shouldSectionNavBeHidden() {
|
|
92
105
|
if(window.userScroll == true){
|
|
93
106
|
return this.percent > 50 && this.scrollingDown && this.$store.burgeropen == false && this.$screen('lg')
|
|
@@ -96,6 +109,8 @@ document.addEventListener('alpine:init', () => {
|
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
},
|
|
112
|
+
|
|
113
|
+
// returns true if user scrolled >90% and scrolls further down, no burger menu is open and the screen is NOT desktop. If scroll was initiated by script, ignore scroll direction.
|
|
99
114
|
shouldServiceNavBeHidden() {
|
|
100
115
|
if(window.userScroll == true) {
|
|
101
116
|
return (this.percent > 90 && !this.$screen('lg') && this.scrollingDown && this.$store.burgeropen == false)
|
|
@@ -103,12 +118,18 @@ document.addEventListener('alpine:init', () => {
|
|
|
103
118
|
return (this.percent > 90 && !this.$screen('lg') && this.$store.burgeropen == false)
|
|
104
119
|
}
|
|
105
120
|
},
|
|
121
|
+
|
|
122
|
+
//returns true if user scrolled >50% and scrolls further down, no burger menu is open, no serviceNav is open and screen is not larger than mobile. OR: same same, but scrolling up.
|
|
106
123
|
shouldServiceIconsBeHidden() {
|
|
107
124
|
return (this.percent > 50 && !this.$screen('md') && this.$store.burgeropen == false && this.$store.serviceNavIsOpen == false && this.scrollingDown == true) || (this.percent > 50 && !this.$screen('md') && this.$store.burgeropen == false && this.$store.serviceNavIsOpen == false && this.scrollingDown == false)
|
|
108
125
|
},
|
|
126
|
+
|
|
127
|
+
// returns true if user scrolled >50% and scrolls further down and is a desktop viewport
|
|
109
128
|
shouldFlyoutBeHidden() {
|
|
110
129
|
return (this.percent > 50 && this.scrollingDown && this.$screen('lg') )
|
|
111
130
|
},
|
|
131
|
+
|
|
132
|
+
// resets the navigation back to the initial state. Happens f.ex. on resize of window.
|
|
112
133
|
resetNav() {
|
|
113
134
|
if(window.innerWidth > 1023) {
|
|
114
135
|
this.$refs.sectionnavigation.setAttribute("style","")
|
|
@@ -143,6 +164,8 @@ document.addEventListener('alpine:init', () => {
|
|
|
143
164
|
this.$store.clientWidth = nowClientWidth
|
|
144
165
|
}
|
|
145
166
|
},
|
|
167
|
+
|
|
168
|
+
// toggles the maxHeight of the section nav and makes sure there is enough space to display all items.
|
|
146
169
|
toggleSectionNav() {
|
|
147
170
|
//false = sectionNav schließt ( mobile/tablet? --> maxHeight = 0 /// desktop? just clear maxHeight attribute )
|
|
148
171
|
//true = sectionNav öffnet (maxheight = scrollheight)
|
|
@@ -168,16 +191,22 @@ document.addEventListener('alpine:init', () => {
|
|
|
168
191
|
}
|
|
169
192
|
}
|
|
170
193
|
},
|
|
194
|
+
|
|
195
|
+
// no scrolling when overlay is visible
|
|
171
196
|
disableScrolling() {
|
|
172
197
|
document.body.classList.add('overflow-hidden','h-full','w-full')
|
|
173
198
|
this.$refs.myOverlay.ontouchmove = (e) => e.preventDefault();
|
|
174
199
|
console.log("disableScrolling")
|
|
175
200
|
},
|
|
201
|
+
|
|
202
|
+
//only scroll when no overlay is visible
|
|
176
203
|
enableScrolling() {
|
|
177
204
|
document.body.classList.remove('overflow-hidden','h-full','w-full')
|
|
178
205
|
this.$refs.myOverlay.ontouchmove = (e) => true;
|
|
179
206
|
console.log("enableScrolling")
|
|
180
207
|
},
|
|
208
|
+
|
|
209
|
+
// toggles scrolling ability
|
|
181
210
|
toggleScrolling(mode){
|
|
182
211
|
if(this.$screen(0) && !this.$screen('lg')){
|
|
183
212
|
mode == false ? this.disableScrolling() : this.enableScrolling()
|
|
@@ -191,9 +220,13 @@ document.addEventListener('alpine:init', () => {
|
|
|
191
220
|
|
|
192
221
|
// context for the overlay
|
|
193
222
|
Alpine.data('overlayHandler', () => ({
|
|
223
|
+
|
|
224
|
+
// show the overlay on mobile and tablet if burger menu is open OR service nav is open OR search field is open
|
|
194
225
|
shouldOverlayBeShown() {
|
|
195
226
|
return (!this.$screen('lg') && ( this.$store.burgeropen == true || this.$store.serviceNavIsOpen == true || this.$store.searchFieldOpen == true ))
|
|
196
227
|
},
|
|
228
|
+
|
|
229
|
+
// on click on overlay change global var for servicenav, dispatch events to close burger and service menu, re-enable scrolling.
|
|
197
230
|
overlayWasClicked() {
|
|
198
231
|
this.$store.serviceNavIsOpen ? this.$store.serviceNavIsOpen = false : null
|
|
199
232
|
this.$dispatch('burger-close')
|
|
@@ -203,18 +236,28 @@ document.addEventListener('alpine:init', () => {
|
|
|
203
236
|
}
|
|
204
237
|
}))
|
|
205
238
|
|
|
206
|
-
// context for all dropdowns
|
|
239
|
+
// context for all dropdowns, used in section nav submenus and service nav flyout submenus
|
|
207
240
|
Alpine.data('dropdown', () => ({
|
|
241
|
+
|
|
242
|
+
// state of the dropdown
|
|
208
243
|
dropped: false,
|
|
244
|
+
|
|
245
|
+
// toggle() interpolates state
|
|
209
246
|
toggle() {
|
|
210
247
|
this.dropped = ! this.dropped;
|
|
211
248
|
},
|
|
249
|
+
|
|
250
|
+
// toggles visibility of service nav and sets global variables in stores
|
|
212
251
|
toggleServiceNav(){
|
|
213
252
|
this.dropped = ! this.dropped;
|
|
253
|
+
|
|
254
|
+
// close search if open
|
|
214
255
|
this.$store.searchFieldOpen = false;
|
|
215
256
|
|
|
257
|
+
// if clicked element is not the current serviceID, leave the servicenav open, else interpolate servicenav state
|
|
216
258
|
this.$el.id != this.$store.serviceID.current ? this.$store.serviceNavIsOpen = true : this.$el.id == this.$store.serviceID.current ? this.$store.serviceNavIsOpen = !this.$store.serviceNavIsOpen : null;
|
|
217
259
|
|
|
260
|
+
//if burger is open, dispatch event to close it
|
|
218
261
|
this.$store.burgeropen == true ? this.$dispatch('burger-close') : null
|
|
219
262
|
|
|
220
263
|
console.log('currentID: '+ this.$store.serviceID.current)
|
|
@@ -222,10 +265,13 @@ document.addEventListener('alpine:init', () => {
|
|
|
222
265
|
console.log('element-id: '+this.$el.id)
|
|
223
266
|
console.log('serviceNav is open:'+ this.$store.serviceNavIsOpen)
|
|
224
267
|
|
|
268
|
+
//set the serviceID to the current element´s ID.
|
|
225
269
|
this.$store.serviceID.current = this.$el.id
|
|
226
270
|
|
|
271
|
+
//enable/disable scrolling
|
|
227
272
|
this.toggleScrolling(!this.$store.serviceNavIsOpen)
|
|
228
273
|
|
|
274
|
+
//defines behaviour for servicenav on mobile viewports, taking care of viewport sizes
|
|
229
275
|
let myFlyout = document.querySelector('#flyout-'+this.$el.id)
|
|
230
276
|
let brandNavHeight = this.percent > 0 ? 40 : 0
|
|
231
277
|
|
|
@@ -252,8 +298,9 @@ document.addEventListener('alpine:init', () => {
|
|
|
252
298
|
this.$el.setAttribute("x-collapse","")
|
|
253
299
|
}
|
|
254
300
|
},
|
|
301
|
+
|
|
302
|
+
//Adds scrollheight of the flyout to sectionNav container to make sure all following items stay visible
|
|
255
303
|
sectionNavFlyoutWatcher() {
|
|
256
|
-
//Adds scrollheight of the flyout to sectionNav container to make sure all following items stay visible
|
|
257
304
|
this.$watch('dropped', value => {
|
|
258
305
|
let a = this.$refs.sectionnavigation.scrollHeight + this.$el.scrollHeight;
|
|
259
306
|
let brandNavHeight = this.percent > 0 ? 40 : 0
|
|
@@ -278,8 +325,9 @@ document.addEventListener('alpine:init', () => {
|
|
|
278
325
|
|
|
279
326
|
})
|
|
280
327
|
},
|
|
328
|
+
|
|
329
|
+
//sets/cleansup the x-collapse attributes depending on window.innerWidth, gets fired @resize.window in NavigationFlyout.hbs
|
|
281
330
|
setFlyoutAnimationStyle() {
|
|
282
|
-
//sets/cleansup the x-collapse attributes depending on window.innerWidth, gets fired @resize.window in NavigationFlyout.hbs
|
|
283
331
|
if(window.innerWidth > 1023) {
|
|
284
332
|
if(this.$el.hasAttribute("x-collapse.duration.500ms")) {
|
|
285
333
|
this.$el.removeAttribute("x-collapse.duration.500ms")
|
|
@@ -289,7 +337,6 @@ document.addEventListener('alpine:init', () => {
|
|
|
289
337
|
if (! this.$el._x_isShown) this.$el.style.display = 'none'
|
|
290
338
|
if(this.$el.hasAttribute("hidden")) this.$el.removeAttribute("hidden")
|
|
291
339
|
}
|
|
292
|
-
|
|
293
340
|
} else {
|
|
294
341
|
if(!this.$el.hasAttribute("x-collapse.duration.500ms")) this.$el.setAttribute("x-collapse.duration.500ms","")
|
|
295
342
|
}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"repository": "https://github.com/szuelch/hr-design-system-handlebars",
|
|
9
|
-
"version": "0.50.
|
|
9
|
+
"version": "0.50.2",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
12
12
|
"storybook": "start-storybook -p 6006 public",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/assets/tailwind.css
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ArgsTable, Meta, Story, Canvas, Preview } from '@storybook/addon-docs'
|
|
2
|
-
|
|
2
|
+
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'
|
|
3
3
|
import navigation from './header.hbs'
|
|
4
|
+
import brandnav from './brand_navigation/brand_navigation.hbs'
|
|
4
5
|
import JsonData from './fixtures/site_header_default.json'
|
|
5
6
|
import JsonData2 from './fixtures/site_header_mit_warnung.json'
|
|
6
|
-
import JsonData3 from './fixtures/site_header_mit_submenu.json'
|
|
7
|
+
import JsonData3 from './fixtures/site_header_mit_submenu.json'
|
|
7
8
|
|
|
8
9
|
<Meta title="Komponenten/Header/Header"
|
|
9
10
|
argTypes={{}}
|
|
@@ -12,7 +13,10 @@ import JsonData3 from './fixtures/site_header_mit_submenu.json'
|
|
|
12
13
|
viewports: [360, 768, 1024],
|
|
13
14
|
},
|
|
14
15
|
layout: 'fullscreen',
|
|
15
|
-
docs: { inlineStories : false, iframeHeight:
|
|
16
|
+
docs: { inlineStories : false, iframeHeight: 200 },
|
|
17
|
+
viewport: {
|
|
18
|
+
viewports: INITIAL_VIEWPORTS
|
|
19
|
+
},
|
|
16
20
|
}}
|
|
17
21
|
|
|
18
22
|
/>
|
|
@@ -25,22 +29,330 @@ export const Template = (args, { globals: { customConditionalToolbar } }) => {
|
|
|
25
29
|
return navigation({ brand, ...args })
|
|
26
30
|
}
|
|
27
31
|
|
|
32
|
+
|
|
33
|
+
|
|
28
34
|
# Header
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
[Frameworks](#frameworks) - [Varianten](#varianten) - [Scrollverhalten](#scrollverhalten) - [Templates & Codes](#templates) - [Sub-Komponenten](#subkomponenten)
|
|
31
37
|
|
|
32
38
|
<Canvas>
|
|
33
|
-
<Story name="Default"
|
|
39
|
+
<Story name="Default"
|
|
40
|
+
args={JsonData}
|
|
41
|
+
parameters={{}}>
|
|
34
42
|
{Template.bind({})}
|
|
35
43
|
</Story>
|
|
36
44
|
</Canvas>
|
|
37
45
|
|
|
46
|
+
## Beschreibung
|
|
47
|
+
|
|
48
|
+
Die <b>Header</b>-Komponente ist die Haupt-Navigation der Hessenschau. Sie ist in der Komponente 'Page' eingebunden und besteht grundsätzlich aus 4 Subkomponenten:
|
|
49
|
+
|
|
50
|
+
<ul>
|
|
51
|
+
<li>components/site_header/<b>anchor_navigation</b></li>
|
|
52
|
+
<li>components/site_header/<b>brand_navigation</b></li>
|
|
53
|
+
<li>components/site_header/<b>service_navigation</b></li>
|
|
54
|
+
<li>components/site_header/<b>section_navigation</b></li>
|
|
55
|
+
</ul>
|
|
56
|
+
<br />
|
|
57
|
+
Die Header-Komponente wird in handlebars wie folgt eingebaut:
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
{{> components/site_header/header}}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
<a name="frameworks" />
|
|
64
|
+
|
|
65
|
+
### Frameworks
|
|
66
|
+
|
|
67
|
+
Die wesentlichen Funktionen und Features der Navigation sind mit dem Javascript-Framework [**Alpine.js**](https://alpinejs.dev/) realisiert. Alpine regelt u.a. die Sichtbarkeit der einzelnen Elemente und ist für die Interaktivität der Navigation zuständig. Alle Codes, die in der Header-Komponente Alpine.js direkt betreffen, sind in der Datei **"header_alpine.js** ausgelagert. Hier finden sich global verwendete dynamische Variablen (via Alpine.store) und zu verwendende Kontexte (via Alpine.data).
|
|
68
|
+
|
|
69
|
+
Für das CSS wird das Framework [**TailwindCSS**](https://www.tailwindcss.com) verwendet.
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
<a name="varianten" />
|
|
74
|
+
|
|
75
|
+
### Varianten
|
|
76
|
+
|
|
77
|
+
Die Navigation ist sticky und responsiv mit drei Breakpoints für Smartphone, Tablet und Desktop. Für diese drei Viewportgrößen gibt es jeweils unterschiedliche Darstellungen der Subkomponenten innerhalb der Navigation. Grundsätzlich kann die Navigation z.B. in der Anzahl der ServiceNavigation-Items und der Sichtbarkeit von Flyouts und/oder Submenus variieren.
|
|
78
|
+
|
|
79
|
+
Desktop:
|
|
80
|
+
<img src="/images/navi_default.png" />
|
|
81
|
+
<br />
|
|
82
|
+
|
|
83
|
+
***
|
|
84
|
+
|
|
85
|
+
Tablet:
|
|
86
|
+
<img src="/images/navi_tablet.PNG" />
|
|
87
|
+
<br />
|
|
88
|
+
|
|
89
|
+
***
|
|
90
|
+
|
|
91
|
+
Mobil:
|
|
92
|
+
<img src="/images/navi_mobil_default.png" />
|
|
93
|
+
<br />
|
|
94
|
+
|
|
95
|
+
***
|
|
96
|
+
<br />
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
<a name="scrollverhalten" />
|
|
100
|
+
|
|
101
|
+
### Scrollverhalten
|
|
102
|
+
|
|
103
|
+
Es gibt 3 Scrollpositionen, die relevant sind: 0%, 50% und 90%. Die Höhe des Viewports wird hierbei als Referenz bzw. 100% angenommen. (Programmatisch wird die Scrollposition in der Variable **"percent"** abgebildet und zur Verarbeitung genutzt) Scrollt man bei ausgeblendeter Navigation die Seite wieder um 1px zurück, wird im Desktop-Viewport die Section-Navigation wieder eingeblendet, im Tablet und Mobil-Viewport kommt je nach Scrollposition die Navigation wieder in den sichtbaren Bereich bzw. die Service-List mit den Service-Icons wird wieder eingeblendet. Die Brand-Navigation wird erst wieder angezeigt, wenn ganz nach oben gescrollt wird.
|
|
104
|
+
|
|
105
|
+
| Scrollposition | Viewport | Beschreibung |
|
|
106
|
+
|:---------------|:---------|:-------------|
|
|
107
|
+
|`>0%`| alle Viewports | Brand-Navigation wird ausgeblendet |
|
|
108
|
+
|`>50%`| Desktop | Section-Navigation wird ausgeblendet & Logo verkleinert |
|
|
109
|
+
|| Tablet | Logo wird verkleinert |
|
|
110
|
+
|| Mobil | Logo wird verkleinert & ServiceList wird ausgeblendet |
|
|
111
|
+
|`>90%`| Desktop | keine weitere Änderung |
|
|
112
|
+
|| Tablet | Navigation verschwindet ganz |
|
|
113
|
+
|| Mobil | Navigation verschwindet ganz |
|
|
114
|
+
|
|
115
|
+
<br />
|
|
116
|
+
|
|
117
|
+
**Desktop >0%:**
|
|
118
|
+
<img src="/images/navi_scroll_50percent.png" />
|
|
119
|
+
|
|
120
|
+
**Desktop >50%:**
|
|
121
|
+
<img src="/images/navi_scroll_90percent.png" />
|
|
122
|
+
<br />
|
|
123
|
+
|
|
124
|
+
***
|
|
125
|
+
|
|
126
|
+
**Tablet > 0% / < 50%:**
|
|
127
|
+
<img src="/images/navi_tablet_scroll_1percent.PNG" />
|
|
128
|
+
<br />
|
|
129
|
+
|
|
130
|
+
**Tablet > 50% / < 90%:**
|
|
131
|
+
<img src="/images/navi_tablet_scroll_50percent.PNG" />
|
|
132
|
+
<br />
|
|
133
|
+
|
|
134
|
+
***
|
|
135
|
+
|
|
136
|
+
**Mobil >0% / < 50%:**
|
|
137
|
+
<img src="/images/navi_mobil_scroll_1percent.png" />
|
|
138
|
+
<br />
|
|
139
|
+
|
|
140
|
+
**Mobil >50% / < 90%:**
|
|
141
|
+
<img src="/images/navi_mobil_scroll_50percent.PNG" />
|
|
142
|
+
<br />
|
|
143
|
+
|
|
144
|
+
***
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
<br />
|
|
149
|
+
<a href="#top">Back to top</a>
|
|
150
|
+
<a name="templates" />
|
|
151
|
+
|
|
152
|
+
### Template & Codes
|
|
153
|
+
|
|
154
|
+
Im Haupt-Template **header.hbs** wird für den umschließenden Hauptcontainer mittels der Alpine-Direktive **"x-data"** der Kontext auf das Data-Objekt **"mainNavigationHandler()"** gesetzt und beim erstmaligen Initialisieren die Unter-Funktion **"init()"** aufgerufen. Durch den angegebenen Kontext stehen innerhalb der Navigation nun alle Unterfunktionen von mainNavigationHandler() bereit. Hier finden sich neben der "init()"-Funktion z.B. auch alle Hilfsfunktionen, die zur Ermittlung der Scrollposition bzw. der Sichtbarkeit der jeweiligen Elemente benötig werden.
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<div class="sb-main-navigation" x-data="mainNavigationHandler()" x-init="init()">
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Innerhalb von "init()" werden die Listener und deren Handler für das Scrollen via Scrollrad oder Mouse- bzw. Touch-Aktionen definiert:
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
init(){
|
|
164
|
+
let lastScrollTop = 0
|
|
165
|
+
let height = window.innerHeight
|
|
166
|
+
let userScroll = false;
|
|
167
|
+
window.userScroll = userScroll;
|
|
168
|
+
|
|
169
|
+
const mouseEvent = () => {
|
|
170
|
+
userScroll = true;
|
|
171
|
+
window.userScroll = true;
|
|
172
|
+
}
|
|
173
|
+
const clickedOnScrollbar = mouseX => {
|
|
174
|
+
return document.documentElement.offsetWidth <= mouseX ? true : false;
|
|
175
|
+
}
|
|
176
|
+
const mouseDownHandler = e => {
|
|
177
|
+
clickedOnScrollbar(e.clientX) ? mouseEvent() : null
|
|
178
|
+
};
|
|
179
|
+
const scrollHandler = () => {
|
|
180
|
+
let winScroll = document.body.scrollTop || document.documentElement.scrollTop
|
|
181
|
+
winScroll > lastScrollTop ? this.scrollingDown = true : this.scrollingDown = false
|
|
182
|
+
this.percent = Math.round((winScroll / height) * 100)
|
|
183
|
+
lastScrollTop = winScroll
|
|
184
|
+
this.$store.navIsVisible = !this.isNavHidden()
|
|
185
|
+
this.$store.subNavIsVisible = !this.isSubNavHidden()
|
|
186
|
+
}
|
|
187
|
+
window.addEventListener('mousedown', mouseDownHandler, false)
|
|
188
|
+
window.addEventListener('wheel', mouseEvent, false);
|
|
189
|
+
window.addEventListener('touchmove', mouseEvent, false)
|
|
190
|
+
window.addEventListener('scroll', this.debounce( scrollHandler,50), { passive: true })
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
*Beispielhaft wird hier eine der weiteren Hilfsfunktionen aus dem mainNavigationHandler() erklärt:*
|
|
195
|
+
|
|
196
|
+
Innerhalb des serviceNavWrappers wird mit Alpine die Function "shouldServiceNavBeHidden()" zum Setzen der korrekten CSS-Klassen via Ternary Expression verwendet: Wenn shouldServiceNavBeHidden() den Wert '_true_' zurückgibt, wird die CSS-Klasse "-mt-40" gesetzt, welche den Wrapper mit einem negativen Margin von -10rem aus dem Viewport schiebt:
|
|
197
|
+
|
|
198
|
+
**header.hbs:**
|
|
199
|
+
|
|
200
|
+
```html
|
|
201
|
+
<div id="serviceNavWrapper"
|
|
202
|
+
:class="shouldServiceNavBeHidden() ? '-mt-40' : ''"
|
|
203
|
+
```
|
|
204
|
+
WENN _percent > 90_ ist, der _Viewport NICHT Desktop_ ist, die _Scrollrichtung nach unten_ ist und es _kein offenes Burger-Menu_ gibt, sendet die Funktion *true* als Rückgabewert zurück. Wenn die Seite _via JS_ (z.B. durch einen Ankerlink) gescrollt wird, verstecke die ServiceNavigation unter den gleichen Bedingungen, aber _unabhängig von der Scrollrichtung_:
|
|
205
|
+
|
|
206
|
+
**header_alpine.js:**
|
|
207
|
+
|
|
208
|
+
```js
|
|
209
|
+
shouldServiceNavBeHidden() {
|
|
210
|
+
if(window.userScroll == true) {
|
|
211
|
+
return (this.percent > 90 && !this.$screen('lg') && this.scrollingDown && this.$store.burgeropen == false)
|
|
212
|
+
} else {
|
|
213
|
+
return (this.percent > 90 && !this.$screen('lg') && this.$store.burgeropen == false)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
***
|
|
220
|
+
|
|
221
|
+
Weiterhin sind in der Datei **header_alpine.js** weitere Alpine.data-Kontexte für das Overlay, die Dropdown-Menus und die Flyouts hinterlegt.
|
|
222
|
+
Für die Erklärung können die Kommentare direkt in der Datei herangezogen werden.
|
|
223
|
+
|
|
224
|
+
<a href="#top">Back to top</a>
|
|
225
|
+
<br />
|
|
226
|
+
<a name="subkomponenten" />
|
|
227
|
+
|
|
228
|
+
### Sub-Komponenten
|
|
229
|
+
<br />
|
|
230
|
+
|
|
231
|
+
<b>Anchor Navigation</b> <br/>
|
|
232
|
+
|
|
233
|
+
**anchor_navigation.hbs** Inkludiert folgende Subkomponenten:
|
|
234
|
+
|
|
235
|
+
* featurebox_anchor.hbs
|
|
236
|
+
|
|
237
|
+
In dieser (nicht sichtbaren) Sub-Komponente werden Anchorlinks zu den Teilbereichen der Navigation bereitgestellt, um sie für Screen-Reader direkt erreichbar zu machen.
|
|
238
|
+
|
|
239
|
+
**header.hbs:**
|
|
240
|
+
```html
|
|
241
|
+
<div id="anchorNavWrapper" class="hidden">
|
|
242
|
+
{{> components/site_header/anchor_navigation}}
|
|
243
|
+
</div>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
<hr/>
|
|
247
|
+
<br/>
|
|
248
|
+
<b>Brand Navigation</b> <br/>
|
|
249
|
+
|
|
250
|
+
**brand_navigation.hbs** inkludiert folgende Subkomponenten:
|
|
251
|
+
|
|
252
|
+
* brand_navigation_item
|
|
253
|
+
|
|
254
|
+
Die Brand-Navigation stellt im obersten Bereich des Headers direkte Links zu den einzelnen Angeboten des HR zur Verfügung.
|
|
255
|
+
|
|
256
|
+
```html
|
|
257
|
+
<div id="brandNavWrapper" class="relative flex items-center justify-center order-1 w-full bg-white z-10000 print:hidden">
|
|
258
|
+
{{> components/site_header/brand_navigation/brand_navigation }}
|
|
259
|
+
</div>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
<hr/>
|
|
263
|
+
<br/>
|
|
264
|
+
<b>Service Navigation</b>
|
|
265
|
+
|
|
266
|
+
**service_navigation.hbs** inkludiert folgende Subkomponenten:
|
|
267
|
+
|
|
268
|
+
* service_logo.hbs
|
|
269
|
+
* service_list.hbs
|
|
270
|
+
* service_navigation_item.hbs
|
|
271
|
+
* navigation_flyout.hbs
|
|
272
|
+
* navigation_search.hbs
|
|
273
|
+
* burger.hbs
|
|
274
|
+
<br/>
|
|
275
|
+
|
|
276
|
+
Die Service-Navigation beinhaltet das Logo **(service_logo.hbs)**, die Service-Items und die Suchfunktion **(navigation_search.hbs)**, sowie bei mobilen Viewports das Burger-Menu **(burger.hbs)**, welches die mobile Variante der **SectionNavigation** darstellt.<br />
|
|
277
|
+
Die gesamte ServiceNavigation liegt innerhalb des **"serviceNavWrapper"**. Bei mobilem Viewport wird dieser Wrapper beim Scrollen der Seite mit Hilfe der Funktion **"shouldServiceNavBeHidden()"** ein- bzw. ausgeblendet.
|
|
278
|
+
|
|
279
|
+
Innerhalb des Hauptwrappers liegt der **"serviceNavMainContainer"** welcher die serviceNavHeadline, einen Wrapper für das Logo sowie den **"serviceItemsWrapper"** beinhaltet. In diesem wiederum liegt die Service-List **(service_list.hbs)** und die Komponente für die Suchfunktion **(navigation_search.hbs)**.
|
|
280
|
+
|
|
281
|
+
**header.hbs:**
|
|
282
|
+
|
|
283
|
+
```html
|
|
284
|
+
<div id="serviceNavWrapper" :class="shouldServiceNavBeHidden() ? '-mt-40' : ''"
|
|
285
|
+
class="relative flex justify-center order-2 w-full transition-all duration-500 ease-in-out md:border-white lg:border-b bg-blue-congress z-10002">
|
|
286
|
+
<div id="serviceNavMainContainer" class="flex w-full h-10 lg:container md:h-12 lg:px-10 lg:h-16 z-10001">
|
|
287
|
+
<span id="serviceNavHeadline" class="hidden print:hidden">Service Navigation</span>
|
|
288
|
+
<div id="serviceLogoWrapper" class="flex items-center order-1 w-full pl-4 pr-2 tablet:pl-5 lg:items-end lg:pb-3 bg-blue-congress md:px-0 md:h-12 lg:h-16 md:w-1/2 md:max-w-1/2 lg:w-1/4 lg:max-w-1/4">
|
|
289
|
+
{{> components/site_header/service_logo }}
|
|
290
|
+
</div>
|
|
291
|
+
<div id="serviceItemsWrapper" class="flex items-center justify-end flex-initial order-2 inline-block w-full max-w-full align-top bg-blue-congress md:h-12 lg:h-16 lg:order-2 lg:w-3/4 lg:max-w-3/4 md:mt-0 md:w-1/2 md:max-w-1/2 md:order-2 md:border-0 print:hidden ">
|
|
292
|
+
|
|
293
|
+
{{> components/site_header/service_navigation/service_list }}
|
|
294
|
+
{{> components/site_header/navigation_search/quick_search_button }}
|
|
295
|
+
|
|
296
|
+
<div class="hidden lg:flex">
|
|
297
|
+
{{> components/site_header/navigation_search/quick_search_form }}
|
|
298
|
+
</div>
|
|
299
|
+
<div id="burgerWrapper" class="flex justify-end flex-none order-2 lg:order-4 md:order-4 lg:hidden ">
|
|
300
|
+
{{> components/site_header/burger }}
|
|
301
|
+
</div>
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Innerhalb der Komponente **'service_list'** befinden sich die Service-Navigation-Items. Es existieren derzeit folgende Items: "Warnung", "Video/Podcast", "Verkehr", "Wetter". Das "Warnung"-Item führt direkt zu einer Verlinkten Seite. Ein Click auf die anderen Items öffnet jeweils ein Flyout, in welchem Links zu den Unterseiten des jeweiligen Strukturknotens/Bereichs oder externen Zielen dargstellt sind.
|
|
308
|
+
Innerhalb der Service-List können mittels der Funktion **"shouldServiceIconsBeHidden()"** je nach Scrollposition die Service-Icons ausgeblendet werden.
|
|
309
|
+
<br />
|
|
310
|
+
|
|
311
|
+
<img src="/images/navi_flyout_service.png" />
|
|
312
|
+
<br />
|
|
313
|
+
<br />
|
|
314
|
+
<a href="#top">Back to top</a>
|
|
315
|
+
<br />
|
|
316
|
+
|
|
317
|
+
***
|
|
318
|
+
<br />
|
|
319
|
+
<b>Section Navigation</b>
|
|
320
|
+
|
|
321
|
+
**section_navigation.hbs** inkludiert folgende Subkomponenten:
|
|
322
|
+
|
|
323
|
+
* section_navigation_item.hbs
|
|
324
|
+
* navigation_flyout.hbs
|
|
325
|
+
|
|
326
|
+
<br/>
|
|
327
|
+
Die Section-Navigation stellt die Links zu den einzelnen Themenbereichen der Hessenschau bereit. Die Navigation-Items der Section Navigation können je nach Einstellung vom CMS direkt zur Themen-Indexseite verlinken oder ihrerseits ein Submenu öffnen, über dessen Einträge dann Themenbereiche angesteuert werden können:
|
|
328
|
+
<br />
|
|
329
|
+
<br />
|
|
330
|
+
<img src="/images/navi_flyout_section.png" />
|
|
331
|
+
<br/><br/>
|
|
332
|
+
Bei den Viewports "mobil" und "tablet" wird die Section-Navigation in Form eines Burger-Menus dargstellt:
|
|
333
|
+
<br />
|
|
334
|
+
<br />
|
|
335
|
+
<img src="/images/navi_mobil_burger_open.png" />
|
|
336
|
+
<br/><br/>
|
|
337
|
+
<hr/>
|
|
338
|
+
<br />
|
|
339
|
+
<a href="#top">Back to top</a>
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
### Header-Komponente mit Warnung-Item in der ServiceList:
|
|
343
|
+
|
|
344
|
+
Hier ist die Navigation mit zusätzlichem Service-Item zu sehen.
|
|
345
|
+
|
|
38
346
|
<Canvas>
|
|
39
347
|
<Story name="Mit Warnung" args={JsonData2}>
|
|
40
348
|
{Template.bind({})}
|
|
41
349
|
</Story>
|
|
42
350
|
</Canvas>
|
|
43
351
|
|
|
352
|
+
### Header-Komponente mit Subnavigation:
|
|
353
|
+
|
|
354
|
+
Hier ist die Navigation mit zusätzlicher Subnavigation zu sehen.
|
|
355
|
+
|
|
44
356
|
<Canvas>
|
|
45
357
|
<Story name="Mit Subnavigation" args={JsonData3}>
|
|
46
358
|
{Template.bind({})}
|
|
@@ -32,23 +32,25 @@ document.addEventListener('alpine:init', () => {
|
|
|
32
32
|
init(){
|
|
33
33
|
let lastScrollTop = 0
|
|
34
34
|
let height = window.innerHeight
|
|
35
|
+
|
|
36
|
+
//Globale Variable, true = user initiated scroll / false = programmatic scroll via JS (e.g. click on Anchor Link)
|
|
35
37
|
let userScroll = false;
|
|
36
38
|
window.userScroll = userScroll;
|
|
37
39
|
|
|
40
|
+
// gets fired when user initated scroll happened, global variable is used in Ticker-Topnews and other anchor links to prevent expanding of the navigation if scrollposition gets corrected by JS.
|
|
38
41
|
const mouseEvent = () => {
|
|
39
42
|
userScroll = true;
|
|
40
43
|
window.userScroll = true;
|
|
41
|
-
//console.log('user action detected')
|
|
42
44
|
}
|
|
43
|
-
|
|
45
|
+
// detect if the user clicked/dragged the scrollbar manually
|
|
44
46
|
const clickedOnScrollbar = mouseX => {
|
|
45
47
|
return document.documentElement.offsetWidth <= mouseX ? true : false;
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
// if clicked on scrollbar, fire user initiated mouse event
|
|
48
50
|
const mouseDownHandler = e => {
|
|
49
51
|
clickedOnScrollbar(e.clientX) ? mouseEvent() : null
|
|
50
52
|
};
|
|
51
|
-
|
|
53
|
+
// main scroll handler, defines scroll direction, percent of viewport scrolled, visibility of navigation and subnavigation
|
|
52
54
|
const scrollHandler = () => {
|
|
53
55
|
let winScroll = document.body.scrollTop || document.documentElement.scrollTop
|
|
54
56
|
winScroll > lastScrollTop ? this.scrollingDown = true : this.scrollingDown = false
|
|
@@ -59,14 +61,19 @@ document.addEventListener('alpine:init', () => {
|
|
|
59
61
|
//console.log('winscroll: '+winScroll+' screen height: '+height + ' percent scrolled: '+ this.percent)
|
|
60
62
|
//console.log('Scroll initiated by ' + (window.userScroll == true ? "user" : "browser"));
|
|
61
63
|
}
|
|
62
|
-
|
|
64
|
+
// Listeners
|
|
63
65
|
window.addEventListener('mousedown', mouseDownHandler, false)
|
|
64
66
|
window.addEventListener('wheel', mouseEvent, false);
|
|
65
67
|
window.addEventListener('touchmove', mouseEvent, false)
|
|
66
68
|
window.addEventListener('scroll', this.debounce( scrollHandler,50), { passive: true })
|
|
67
69
|
},
|
|
70
|
+
//Holds the percentage of scrolled viewport
|
|
68
71
|
percent: 0,
|
|
72
|
+
|
|
73
|
+
//defines the scroll direction
|
|
69
74
|
scrollingDown: true,
|
|
75
|
+
|
|
76
|
+
//returns true if section navigation is hidden on desktop OR service navigation is hidden on mobile
|
|
70
77
|
isNavHidden() {
|
|
71
78
|
if(this.$screen('lg')) {
|
|
72
79
|
return this.shouldSectionNavBeHidden()
|
|
@@ -74,6 +81,8 @@ document.addEventListener('alpine:init', () => {
|
|
|
74
81
|
return this.shouldServiceNavBeHidden()
|
|
75
82
|
}
|
|
76
83
|
},
|
|
84
|
+
|
|
85
|
+
//returns false if subnav is visible and true if subnav is hidden
|
|
77
86
|
isSubNavHidden() {
|
|
78
87
|
if(this.$screen('lg')){
|
|
79
88
|
if (document.querySelector('.isSelectedAndOpen') !== null) {
|
|
@@ -85,9 +94,13 @@ document.addEventListener('alpine:init', () => {
|
|
|
85
94
|
return true
|
|
86
95
|
}
|
|
87
96
|
},
|
|
97
|
+
|
|
98
|
+
// returns true if the user scrolled at least 1px from top
|
|
88
99
|
shouldBrandNavBeHidden() {
|
|
89
100
|
return this.percent > 0
|
|
90
101
|
},
|
|
102
|
+
|
|
103
|
+
// returns true if user scrolled >50% and scrolls down, no burger menu is open and the screen size is desktop. If scroll was initiated by script, ignore scroll direction.
|
|
91
104
|
shouldSectionNavBeHidden() {
|
|
92
105
|
if(window.userScroll == true){
|
|
93
106
|
return this.percent > 50 && this.scrollingDown && this.$store.burgeropen == false && this.$screen('lg')
|
|
@@ -96,6 +109,8 @@ document.addEventListener('alpine:init', () => {
|
|
|
96
109
|
}
|
|
97
110
|
|
|
98
111
|
},
|
|
112
|
+
|
|
113
|
+
// returns true if user scrolled >90% and scrolls further down, no burger menu is open and the screen is NOT desktop. If scroll was initiated by script, ignore scroll direction.
|
|
99
114
|
shouldServiceNavBeHidden() {
|
|
100
115
|
if(window.userScroll == true) {
|
|
101
116
|
return (this.percent > 90 && !this.$screen('lg') && this.scrollingDown && this.$store.burgeropen == false)
|
|
@@ -103,12 +118,18 @@ document.addEventListener('alpine:init', () => {
|
|
|
103
118
|
return (this.percent > 90 && !this.$screen('lg') && this.$store.burgeropen == false)
|
|
104
119
|
}
|
|
105
120
|
},
|
|
121
|
+
|
|
122
|
+
//returns true if user scrolled >50% and scrolls further down, no burger menu is open, no serviceNav is open and screen is not larger than mobile. OR: same same, but scrolling up.
|
|
106
123
|
shouldServiceIconsBeHidden() {
|
|
107
124
|
return (this.percent > 50 && !this.$screen('md') && this.$store.burgeropen == false && this.$store.serviceNavIsOpen == false && this.scrollingDown == true) || (this.percent > 50 && !this.$screen('md') && this.$store.burgeropen == false && this.$store.serviceNavIsOpen == false && this.scrollingDown == false)
|
|
108
125
|
},
|
|
126
|
+
|
|
127
|
+
// returns true if user scrolled >50% and scrolls further down and is a desktop viewport
|
|
109
128
|
shouldFlyoutBeHidden() {
|
|
110
129
|
return (this.percent > 50 && this.scrollingDown && this.$screen('lg') )
|
|
111
130
|
},
|
|
131
|
+
|
|
132
|
+
// resets the navigation back to the initial state. Happens f.ex. on resize of window.
|
|
112
133
|
resetNav() {
|
|
113
134
|
if(window.innerWidth > 1023) {
|
|
114
135
|
this.$refs.sectionnavigation.setAttribute("style","")
|
|
@@ -143,6 +164,8 @@ document.addEventListener('alpine:init', () => {
|
|
|
143
164
|
this.$store.clientWidth = nowClientWidth
|
|
144
165
|
}
|
|
145
166
|
},
|
|
167
|
+
|
|
168
|
+
// toggles the maxHeight of the section nav and makes sure there is enough space to display all items.
|
|
146
169
|
toggleSectionNav() {
|
|
147
170
|
//false = sectionNav schließt ( mobile/tablet? --> maxHeight = 0 /// desktop? just clear maxHeight attribute )
|
|
148
171
|
//true = sectionNav öffnet (maxheight = scrollheight)
|
|
@@ -168,16 +191,22 @@ document.addEventListener('alpine:init', () => {
|
|
|
168
191
|
}
|
|
169
192
|
}
|
|
170
193
|
},
|
|
194
|
+
|
|
195
|
+
// no scrolling when overlay is visible
|
|
171
196
|
disableScrolling() {
|
|
172
197
|
document.body.classList.add('overflow-hidden','h-full','w-full')
|
|
173
198
|
this.$refs.myOverlay.ontouchmove = (e) => e.preventDefault();
|
|
174
199
|
console.log("disableScrolling")
|
|
175
200
|
},
|
|
201
|
+
|
|
202
|
+
//only scroll when no overlay is visible
|
|
176
203
|
enableScrolling() {
|
|
177
204
|
document.body.classList.remove('overflow-hidden','h-full','w-full')
|
|
178
205
|
this.$refs.myOverlay.ontouchmove = (e) => true;
|
|
179
206
|
console.log("enableScrolling")
|
|
180
207
|
},
|
|
208
|
+
|
|
209
|
+
// toggles scrolling ability
|
|
181
210
|
toggleScrolling(mode){
|
|
182
211
|
if(this.$screen(0) && !this.$screen('lg')){
|
|
183
212
|
mode == false ? this.disableScrolling() : this.enableScrolling()
|
|
@@ -191,9 +220,13 @@ document.addEventListener('alpine:init', () => {
|
|
|
191
220
|
|
|
192
221
|
// context for the overlay
|
|
193
222
|
Alpine.data('overlayHandler', () => ({
|
|
223
|
+
|
|
224
|
+
// show the overlay on mobile and tablet if burger menu is open OR service nav is open OR search field is open
|
|
194
225
|
shouldOverlayBeShown() {
|
|
195
226
|
return (!this.$screen('lg') && ( this.$store.burgeropen == true || this.$store.serviceNavIsOpen == true || this.$store.searchFieldOpen == true ))
|
|
196
227
|
},
|
|
228
|
+
|
|
229
|
+
// on click on overlay change global var for servicenav, dispatch events to close burger and service menu, re-enable scrolling.
|
|
197
230
|
overlayWasClicked() {
|
|
198
231
|
this.$store.serviceNavIsOpen ? this.$store.serviceNavIsOpen = false : null
|
|
199
232
|
this.$dispatch('burger-close')
|
|
@@ -203,18 +236,28 @@ document.addEventListener('alpine:init', () => {
|
|
|
203
236
|
}
|
|
204
237
|
}))
|
|
205
238
|
|
|
206
|
-
// context for all dropdowns
|
|
239
|
+
// context for all dropdowns, used in section nav submenus and service nav flyout submenus
|
|
207
240
|
Alpine.data('dropdown', () => ({
|
|
241
|
+
|
|
242
|
+
// state of the dropdown
|
|
208
243
|
dropped: false,
|
|
244
|
+
|
|
245
|
+
// toggle() interpolates state
|
|
209
246
|
toggle() {
|
|
210
247
|
this.dropped = ! this.dropped;
|
|
211
248
|
},
|
|
249
|
+
|
|
250
|
+
// toggles visibility of service nav and sets global variables in stores
|
|
212
251
|
toggleServiceNav(){
|
|
213
252
|
this.dropped = ! this.dropped;
|
|
253
|
+
|
|
254
|
+
// close search if open
|
|
214
255
|
this.$store.searchFieldOpen = false;
|
|
215
256
|
|
|
257
|
+
// if clicked element is not the current serviceID, leave the servicenav open, else interpolate servicenav state
|
|
216
258
|
this.$el.id != this.$store.serviceID.current ? this.$store.serviceNavIsOpen = true : this.$el.id == this.$store.serviceID.current ? this.$store.serviceNavIsOpen = !this.$store.serviceNavIsOpen : null;
|
|
217
259
|
|
|
260
|
+
//if burger is open, dispatch event to close it
|
|
218
261
|
this.$store.burgeropen == true ? this.$dispatch('burger-close') : null
|
|
219
262
|
|
|
220
263
|
console.log('currentID: '+ this.$store.serviceID.current)
|
|
@@ -222,10 +265,13 @@ document.addEventListener('alpine:init', () => {
|
|
|
222
265
|
console.log('element-id: '+this.$el.id)
|
|
223
266
|
console.log('serviceNav is open:'+ this.$store.serviceNavIsOpen)
|
|
224
267
|
|
|
268
|
+
//set the serviceID to the current element´s ID.
|
|
225
269
|
this.$store.serviceID.current = this.$el.id
|
|
226
270
|
|
|
271
|
+
//enable/disable scrolling
|
|
227
272
|
this.toggleScrolling(!this.$store.serviceNavIsOpen)
|
|
228
273
|
|
|
274
|
+
//defines behaviour for servicenav on mobile viewports, taking care of viewport sizes
|
|
229
275
|
let myFlyout = document.querySelector('#flyout-'+this.$el.id)
|
|
230
276
|
let brandNavHeight = this.percent > 0 ? 40 : 0
|
|
231
277
|
|
|
@@ -252,8 +298,9 @@ document.addEventListener('alpine:init', () => {
|
|
|
252
298
|
this.$el.setAttribute("x-collapse","")
|
|
253
299
|
}
|
|
254
300
|
},
|
|
301
|
+
|
|
302
|
+
//Adds scrollheight of the flyout to sectionNav container to make sure all following items stay visible
|
|
255
303
|
sectionNavFlyoutWatcher() {
|
|
256
|
-
//Adds scrollheight of the flyout to sectionNav container to make sure all following items stay visible
|
|
257
304
|
this.$watch('dropped', value => {
|
|
258
305
|
let a = this.$refs.sectionnavigation.scrollHeight + this.$el.scrollHeight;
|
|
259
306
|
let brandNavHeight = this.percent > 0 ? 40 : 0
|
|
@@ -278,8 +325,9 @@ document.addEventListener('alpine:init', () => {
|
|
|
278
325
|
|
|
279
326
|
})
|
|
280
327
|
},
|
|
328
|
+
|
|
329
|
+
//sets/cleansup the x-collapse attributes depending on window.innerWidth, gets fired @resize.window in NavigationFlyout.hbs
|
|
281
330
|
setFlyoutAnimationStyle() {
|
|
282
|
-
//sets/cleansup the x-collapse attributes depending on window.innerWidth, gets fired @resize.window in NavigationFlyout.hbs
|
|
283
331
|
if(window.innerWidth > 1023) {
|
|
284
332
|
if(this.$el.hasAttribute("x-collapse.duration.500ms")) {
|
|
285
333
|
this.$el.removeAttribute("x-collapse.duration.500ms")
|
|
@@ -289,7 +337,6 @@ document.addEventListener('alpine:init', () => {
|
|
|
289
337
|
if (! this.$el._x_isShown) this.$el.style.display = 'none'
|
|
290
338
|
if(this.$el.hasAttribute("hidden")) this.$el.removeAttribute("hidden")
|
|
291
339
|
}
|
|
292
|
-
|
|
293
340
|
} else {
|
|
294
341
|
if(!this.$el.hasAttribute("x-collapse.duration.500ms")) this.$el.setAttribute("x-collapse.duration.500ms","")
|
|
295
342
|
}
|