hr-design-system-handlebars 1.63.15 → 1.64.1
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.md +24 -0
- package/build/handlebars/helpers/handlebar-helpers.js +72 -14
- package/dist/assets/brand/hessenschau/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr-bigband/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr-fernsehen/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr-inforadio/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr-rundfunkrat/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr-sinfonieorchester/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr-werbung/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr1/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr2/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr3/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/hr4/conf/locatags.merged.json +6 -0
- package/dist/assets/brand/you-fm/conf/locatags.merged.json +6 -0
- package/dist/assets/index.css +3 -3
- package/dist/assets/js/components/externalService/dataWrapperNoResponsiveIframe.subfeature.js +4 -2
- package/dist/assets/js/components/externalService/externalServiceDs.feature.js +12 -28
- package/dist/assets/js/components/modal/defaultModal.subfeature.js +58 -0
- package/dist/assets/js/components/modal/modal.feature.js +11 -52
- package/dist/assets/js/components/modal/userConsentModal.subfeature.js +120 -0
- package/dist/views/components/banner/header/banner_image.hbs +1 -1
- package/dist/views/components/base/backlink.hbs +1 -1
- package/dist/views/components/base/link.hbs +1 -1
- package/dist/views/components/dataPolicySettings/data_policy_settings.hbs +4 -4
- package/dist/views/components/event/calendar/event_calendar.hbs +3 -0
- package/dist/views/components/event/event_ticket_button.hbs +10 -18
- package/dist/views/components/externalService/external_service.hbs +7 -14
- package/dist/views/components/externalService/external_service_with_datapolicy_check.hbs +3 -4
- package/dist/views/components/geoTag/geoTag_list.hbs +1 -1
- package/dist/views/components/mediaplayer/media_player.hbs +1 -1
- package/dist/views/components/modal/modal.hbs +1 -1
- package/dist/views/components/modal/user_consent.hbs +13 -0
- package/dist/views/components/navigation/breadcrumb/breadcrumb.hbs +1 -1
- package/dist/views/components/navigation/breadcrumb/breadcrumb_items.ssi.hbs +1 -1
- package/dist/views/components/page/components/author.hbs +1 -1
- package/dist/views/components/page/components/socialsharing.hbs +4 -4
- package/dist/views/components/podcast/components/podcast_subscribe_button.hbs +1 -1
- package/dist/views/components/podcast/podcast_player.hbs +1 -1
- package/dist/views/components/site_header/brand_navigation/brand_navigation_item.hbs +1 -1
- package/dist/views/components/site_header/navigation_flyout/navigation_flyout.hbs +1 -1
- package/dist/views/components/site_header/section_navigation/section_navigation_item.hbs +3 -3
- package/dist/views/components/site_header/service_logo.hbs +1 -1
- package/dist/views/components/site_header/service_navigation/service_navigation_item.hbs +2 -2
- package/dist/views/components/social_sharing/social_sharing_compact_icons.hbs +4 -4
- package/dist/views/components/socialmedia/socialmedia.hbs +4 -4
- package/dist/views/components/teaser/components/teaser_body.hbs +10 -1
- package/dist/views/components/teaser/components/teaser_lead.hbs +1 -1
- package/dist/views/components/teaser/group_teaser/group_teaser.hbs +1 -1
- package/dist/views/components/teaser/group_teaser/group_teaser_accented.hbs +1 -1
- package/dist/views/components/teaser/ticker/teaser_ticker_timeline.hbs +1 -1
- package/dist/views/components/topictag/topictag_list.hbs +1 -1
- package/dist/views_static/components/banner/header/banner_image.hbs +1 -1
- package/dist/views_static/components/base/backlink.hbs +1 -1
- package/dist/views_static/components/base/link.hbs +1 -1
- package/dist/views_static/components/dataPolicySettings/data_policy_settings.hbs +4 -4
- package/dist/views_static/components/event/calendar/event_calendar.hbs +3 -0
- package/dist/views_static/components/event/event_ticket_button.hbs +10 -18
- package/dist/views_static/components/externalService/external_service.hbs +7 -14
- package/dist/views_static/components/externalService/external_service_with_datapolicy_check.hbs +3 -4
- package/dist/views_static/components/geoTag/geoTag_list.hbs +1 -1
- package/dist/views_static/components/mediaplayer/media_player.hbs +1 -1
- package/dist/views_static/components/modal/modal.hbs +1 -1
- package/dist/views_static/components/modal/user_consent.hbs +13 -0
- package/dist/views_static/components/navigation/breadcrumb/breadcrumb.hbs +1 -1
- package/dist/views_static/components/navigation/breadcrumb/breadcrumb_items.ssi.hbs +1 -1
- package/dist/views_static/components/page/components/author.hbs +1 -1
- package/dist/views_static/components/page/components/socialsharing.hbs +4 -4
- package/dist/views_static/components/podcast/components/podcast_subscribe_button.hbs +1 -1
- package/dist/views_static/components/podcast/podcast_player.hbs +1 -1
- package/dist/views_static/components/site_header/brand_navigation/brand_navigation_item.hbs +1 -1
- package/dist/views_static/components/site_header/navigation_flyout/navigation_flyout.hbs +1 -1
- package/dist/views_static/components/site_header/section_navigation/section_navigation_item.hbs +3 -3
- package/dist/views_static/components/site_header/service_logo.hbs +1 -1
- package/dist/views_static/components/site_header/service_navigation/service_navigation_item.hbs +2 -2
- package/dist/views_static/components/social_sharing/social_sharing_compact_icons.hbs +4 -4
- package/dist/views_static/components/socialmedia/socialmedia.hbs +4 -4
- package/dist/views_static/components/teaser/components/teaser_body.hbs +10 -1
- package/dist/views_static/components/teaser/components/teaser_lead.hbs +1 -1
- package/dist/views_static/components/teaser/group_teaser/group_teaser.hbs +1 -1
- package/dist/views_static/components/teaser/group_teaser/group_teaser_accented.hbs +1 -1
- package/dist/views_static/components/teaser/ticker/teaser_ticker_timeline.hbs +1 -1
- package/dist/views_static/components/topictag/topictag_list.hbs +1 -1
- package/package.json +1 -1
- package/src/assets/brand/_default/conf/locatags.json +6 -0
- package/src/assets/brand/hessenschau/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr-bigband/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr-fernsehen/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr-inforadio/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr-rundfunkrat/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr-sinfonieorchester/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr-werbung/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr1/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr2/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr3/conf/locatags.merged.json +6 -0
- package/src/assets/brand/hr4/conf/locatags.merged.json +6 -0
- package/src/assets/brand/you-fm/conf/locatags.merged.json +6 -0
- package/src/assets/fixtures/teaser/teaser_standard_50_serif_link_two_click.json +22 -0
- package/src/assets/fixtures/teaser/teasers.inc.json +2 -1
- package/src/stories/views/components/banner/header/banner_image.hbs +1 -1
- package/src/stories/views/components/base/backlink.hbs +1 -1
- package/src/stories/views/components/base/link.hbs +1 -1
- package/src/stories/views/components/dataPolicySettings/data_policy_settings.hbs +4 -4
- package/src/stories/views/components/event/calendar/event_calendar.hbs +3 -0
- package/src/stories/views/components/event/event_ticket_button.hbs +10 -18
- package/src/stories/views/components/externalService/dataWrapperNoResponsiveIframe.subfeature.js +4 -2
- package/src/stories/views/components/externalService/externalServiceDs.feature.js +12 -28
- package/src/stories/views/components/externalService/external_service.hbs +7 -14
- package/src/stories/views/components/externalService/external_service.mdx +1 -18
- package/src/stories/views/components/externalService/external_service.stories.js +5 -0
- package/src/stories/views/components/externalService/external_service_with_datapolicy_check.hbs +3 -4
- package/src/stories/views/components/externalService/fixtures/external_service_with_datapolicy.json +48 -2
- package/src/stories/views/components/geoTag/geoTag_list.hbs +1 -1
- package/src/stories/views/components/mediaplayer/media_player.hbs +1 -1
- package/src/stories/views/components/modal/defaultModal.subfeature.js +58 -0
- package/src/stories/views/components/modal/modal.feature.js +11 -52
- package/src/stories/views/components/modal/modal.hbs +1 -1
- package/src/stories/views/components/modal/modal.mdx +104 -0
- package/src/stories/views/components/modal/modal.stories.js +79 -0
- package/src/stories/views/components/modal/userConsentModal.subfeature.js +120 -0
- package/src/stories/views/components/modal/user_consent.hbs +13 -0
- package/src/stories/views/components/navigation/breadcrumb/breadcrumb.hbs +1 -1
- package/src/stories/views/components/navigation/breadcrumb/breadcrumb_items.ssi.hbs +1 -1
- package/src/stories/views/components/page/components/author.hbs +1 -1
- package/src/stories/views/components/page/components/socialsharing.hbs +4 -4
- package/src/stories/views/components/pagination/fixtures/page_pagination.json +1 -1
- package/src/stories/views/components/podcast/components/podcast_subscribe_button.hbs +1 -1
- package/src/stories/views/components/podcast/podcast_player.hbs +1 -1
- package/src/stories/views/components/site_header/brand_navigation/brand_navigation_item.hbs +1 -1
- package/src/stories/views/components/site_header/navigation_flyout/navigation_flyout.hbs +1 -1
- package/src/stories/views/components/site_header/section_navigation/section_navigation_item.hbs +3 -3
- package/src/stories/views/components/site_header/service_logo.hbs +1 -1
- package/src/stories/views/components/site_header/service_navigation/service_navigation_item.hbs +2 -2
- package/src/stories/views/components/social_sharing/social_sharing_compact_icons.hbs +4 -4
- package/src/stories/views/components/socialmedia/socialmedia.hbs +4 -4
- package/src/stories/views/components/teaser/components/teaser_body.hbs +10 -1
- package/src/stories/views/components/teaser/components/teaser_lead.hbs +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_alternative_100_serif_link.json +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_alternative_50_serif_link.json +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_alternative_hero_serif_link.json +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_standard_100_serif_link.json +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_standard_25_serif_link.json +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_standard_33_serif_link.json +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_standard_50_serif_link.json +1 -1
- package/src/stories/views/components/teaser/fixtures/teaser_standard_50_serif_link_two_click.json +1 -0
- package/src/stories/views/components/teaser/fixtures/teaser_standard_hero_serif_link.json +1 -1
- package/src/stories/views/components/teaser/group_teaser/group_teaser.hbs +1 -1
- package/src/stories/views/components/teaser/group_teaser/group_teaser_accented.hbs +1 -1
- package/src/stories/views/components/teaser/teaser_standard.mdx +4 -0
- package/src/stories/views/components/teaser/teaser_standard.stories.js +7 -0
- package/src/stories/views/components/teaser/ticker/teaser_ticker_timeline.hbs +1 -1
- package/src/stories/views/components/topictag/topictag_list.hbs +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{{#if this.externalServiceConfig.makeConfigurable}}
|
|
2
|
-
|
|
2
|
+
<!-- Embedding via JS with DataPolicyCheck-->
|
|
3
3
|
{{> components/externalService/external_service_with_datapolicy_check }}
|
|
4
4
|
|
|
5
5
|
{{else}}
|
|
@@ -8,26 +8,19 @@
|
|
|
8
8
|
<div class="clear-both mt-10">
|
|
9
9
|
<span class="sr-only">{{loca "story_externalservice_intro_sr" }}</span>
|
|
10
10
|
{{#if this.externalServiceConfig.embedAsIFrame}}
|
|
11
|
-
|
|
11
|
+
<!-- Embedding via Iframe -->
|
|
12
12
|
<div class="{{#if this.fixedHeight}}overflow-y-hidden{{else}}overflow-hidden{{/if}}" {{#if this.fixedHeight}}style="height:{{this.fixedHeight}}px;"{{/if}}>
|
|
13
13
|
{{#unless this.fixedHeight}}<div class="{{~inline-switch this.aspectRatio '["16x9","16x7","4x3","100x27","100","9x16","7x16"]' '["ar-16-9","ar-16-7","ar-4-3","ar-100-27","ar-1-1","ar-9-16","ar-7-16","ar-16-9"]'~}}">{{/unless}}
|
|
14
|
-
<iframe frameborder="0" width="100%" height="100%"
|
|
15
|
-
src="{{{this.serviceUrl}}}" webkitallowfullscreen mozallowfullscreen
|
|
16
|
-
allowfullscreen scrolling='no'>
|
|
17
|
-
</iframe>
|
|
14
|
+
<iframe frameborder="0" width="100%" height="100%" src="{{{this.serviceUrl}}}" webkitallowfullscreen mozallowfullscreen allowfullscreen scrolling='no'></iframe>
|
|
18
15
|
{{#unless this.fixedHeight}}</div>{{/unless}}
|
|
19
16
|
</div>
|
|
20
|
-
|
|
21
17
|
{{else}}
|
|
22
|
-
|
|
18
|
+
<!-- Embedding via JS without DataPolicyCheck-->
|
|
23
19
|
<div class="c-externalService__{{this.externalServiceConfig.externalServiceId}} js-load"
|
|
24
|
-
data-hr-external-service-ds='{"id":"{{this.externalServiceConfig.externalServiceId}}","embedCode":"{{this.serviceUrl}}",
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
{{/if}}
|
|
28
|
-
|
|
20
|
+
data-hr-external-service-ds='{"id":"{{this.externalServiceConfig.externalServiceId}}","embedCode":"{{this.serviceUrl}}","embedType": "{{this.externalServiceConfig.externalServiceEmbedType}}","dataPolicyCheck": false,"iFrameConfig":{}}'>
|
|
21
|
+
</div>
|
|
22
|
+
{{/if}}
|
|
29
23
|
{{~> components/externalService/components/external_service_caption ~}}
|
|
30
|
-
|
|
31
24
|
<span class="sr-only">{{loca "story_externalservice_outro_sr" }}</span>
|
|
32
25
|
</div>
|
|
33
26
|
{{/if}}
|
|
@@ -26,21 +26,4 @@ Die interaktiven Elemente sind:
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
## Beispiel Dienst Giphy
|
|
29
|
-
<Story of={ExternalServiceStories.ExterneDiensteGiphy} />
|
|
30
|
-
|
|
31
|
-
## Beispiel Dienst Datawrapper mit responsivem Iframe
|
|
32
|
-
Der Datawrapper wird standardmässig mit einem responsiven Iframe geladen, d.h. das der Inhalt des Iframes - die Datengrafik - an den äußeren Container skaliert wird.
|
|
33
|
-
|
|
34
|
-
<Story of={ExternalServiceStories.ExterneDiensteDatawrapper} />
|
|
35
|
-
|
|
36
|
-
## Beispiel Dienst Datawrapper ohne responsives Iframe und fester Höhe
|
|
37
|
-
Ist die Konfiguration "NoResponsiveIFrame" auf TRUE gesetzt werden die Felder für "FixedHeight" und "AspectRatio" ausgelesen. Ist das Feld FixedHeight befüllt, wird der Wert daraus übernommen
|
|
38
|
-
<Story of={ExternalServiceStories.ExterneDiensteDatawrapperNoResponsiveFixedHeight} />
|
|
39
|
-
|
|
40
|
-
## Beispiel Dienst Datawrapper ohne responsives Iframe und AspectRatio
|
|
41
|
-
Ist die Konfiguration "NoResponsiveIFrame" auf TRUE gesetzt werden die Felder für "FixedHeight" und "AspectRatio" ausgelesen. Ist das Feld AspectRatio ausgewählt wird der Wert daraus übernommen
|
|
42
|
-
<Story of={ExternalServiceStories.ExterneDiensteDatawrapperNoResponsiveAspectRatio} />
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
## Beispiel Dienst Datawrapper mit ContentRefresher
|
|
46
|
-
<Story of={ExternalServiceStories.ExterneDiensteDatawrapperContentRefresher} />
|
|
29
|
+
<Story of={ExternalServiceStories.ExterneDiensteGiphy} />
|
|
@@ -28,6 +28,11 @@ export const ExterneDiensteGiphy = {
|
|
|
28
28
|
name: 'Externe Dienste Giphy',
|
|
29
29
|
args: ExternalServiceContent.Giphy,
|
|
30
30
|
}
|
|
31
|
+
export const ExterneDiensteFlourish = {
|
|
32
|
+
render: TemplatePageExternalService.bind({}),
|
|
33
|
+
name: 'Externe Dienste Flourish',
|
|
34
|
+
args: ExternalServiceContent.Flourish,
|
|
35
|
+
}
|
|
31
36
|
export const ExterneDiensteDatawrapper = {
|
|
32
37
|
render: TemplatePageExternalService.bind({}),
|
|
33
38
|
name: 'Externe Dienste Datawrapper MIT Responsivem Iframe',
|
package/src/stories/views/components/externalService/external_service_with_datapolicy_check.hbs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<div class="grid clear-both mt-10">
|
|
2
|
-
{{~> components/base/a11y/hiddenText _locaTag="story_externalservice_intro_sr" ~}}
|
|
2
|
+
{{~> components/base/a11y/hiddenText _locaTag="story_externalservice_intro_sr" ~}}
|
|
3
3
|
<div class="c-externalService c-externalService__{{this.externalServiceConfig.externalServiceId}} js-load"
|
|
4
|
-
data-hr-external-service-ds='{"id":"{{this.externalServiceConfig.externalServiceId}}","embedCode":"{{this.serviceUrl}}",
|
|
5
|
-
|
|
6
|
-
this.aspectRatio}}"aspectRatio":"{{this.aspectRatio}}"{{else}}"aspectRatio":"16x9"{{/if}}{{/if}},"noResponsiveIframe":"{{{this.setResponsiveIframe}}}","refreshContent":"{{{this.setTimedReloadIframe}}}","refreshIntervall":"{{this.setTimeForReload}}"}}'>
|
|
4
|
+
data-hr-external-service-ds='{"id":"{{this.externalServiceConfig.externalServiceId}}","embedCode":"{{this.serviceUrl}}","embedType":"{{this.externalServiceConfig.externalServiceEmbedType}}","dataPolicyCheck": true,"iFrameConfig": { {{#if this.fixedHeight}}
|
|
5
|
+
"fixedHeight":"{{this.fixedHeight}}"{{else}}{{#if this.aspectRatio}}"aspectRatio":"{{this.aspectRatio}}"{{else}}"aspectRatio":"16x9"{{/if}}{{/if}},"noResponsiveIframe":"{{{this.setResponsiveIframe}}}"{{#if this.setTimedReloadIframe}},"refreshContent":"{{{this.setTimedReloadIframe}}}","refreshIntervall":"{{this.setTimeForReload}}"{{/if}} }}'>
|
|
7
6
|
{{~> components/externalService/components/external_service_data_policy ~}}
|
|
8
7
|
</div>
|
|
9
8
|
{{~> components/externalService/components/external_service_caption ~}}
|
package/src/stories/views/components/externalService/fixtures/external_service_with_datapolicy.json
CHANGED
|
@@ -26,7 +26,37 @@
|
|
|
26
26
|
"setTimedReloadIframe": false,
|
|
27
27
|
"setTimeForReload": ""
|
|
28
28
|
},
|
|
29
|
-
"
|
|
29
|
+
"Datawrapper_CDN_NoResponsiveFixedHeightReload": {
|
|
30
|
+
"externalServiceConfig": {
|
|
31
|
+
"makeConfigurable": true,
|
|
32
|
+
"embedAsIFrame": false,
|
|
33
|
+
"externalServiceId": "datawrapper_cdn",
|
|
34
|
+
"externalServiceEmbedType": "js",
|
|
35
|
+
"externalServiceName": "Datawrapper (Datengrafik)"
|
|
36
|
+
},
|
|
37
|
+
"serviceUrl": "https://datawrapper.dwcdn.net/IC3Xn/1/",
|
|
38
|
+
"fixedHeight": "700",
|
|
39
|
+
"aspectRatio": "",
|
|
40
|
+
"setResponsiveIframe": true,
|
|
41
|
+
"setTimedReloadIframe": true,
|
|
42
|
+
"setTimeForReload": "300"
|
|
43
|
+
},
|
|
44
|
+
"Datawrapper_CDN_NoResponsiveFixedHeight": {
|
|
45
|
+
"externalServiceConfig": {
|
|
46
|
+
"makeConfigurable": true,
|
|
47
|
+
"embedAsIFrame": false,
|
|
48
|
+
"externalServiceId": "datawrapper_cdn",
|
|
49
|
+
"externalServiceEmbedType": "js",
|
|
50
|
+
"externalServiceName": "Datawrapper (Datengrafik)"
|
|
51
|
+
},
|
|
52
|
+
"serviceUrl": "https://datawrapper.dwcdn.net/IC3Xn/1/",
|
|
53
|
+
"fixedHeight": "700",
|
|
54
|
+
"aspectRatio": "",
|
|
55
|
+
"setResponsiveIframe": true,
|
|
56
|
+
"setTimedReloadIframe": false,
|
|
57
|
+
"setTimeForReload": ""
|
|
58
|
+
},
|
|
59
|
+
"Datawrapper_CDN_NoResponsiveAspectRatio": {
|
|
30
60
|
"externalServiceConfig": {
|
|
31
61
|
"makeConfigurable": true,
|
|
32
62
|
"embedAsIFrame": false,
|
|
@@ -35,11 +65,27 @@
|
|
|
35
65
|
"externalServiceName": "Datawrapper (Datengrafik)"
|
|
36
66
|
},
|
|
37
67
|
"serviceUrl": "https://datawrapper.dwcdn.net/IC3Xn/1/",
|
|
38
|
-
"fixedHeight": "
|
|
68
|
+
"fixedHeight": "",
|
|
69
|
+
"aspectRatio": "4x3",
|
|
39
70
|
"setResponsiveIframe": true,
|
|
40
71
|
"setTimedReloadIframe": false,
|
|
41
72
|
"setTimeForReload": ""
|
|
42
73
|
},
|
|
74
|
+
"Datawrapper_CDN": {
|
|
75
|
+
"externalServiceConfig": {
|
|
76
|
+
"makeConfigurable": true,
|
|
77
|
+
"embedAsIFrame": false,
|
|
78
|
+
"externalServiceId": "datawrapper_cdn",
|
|
79
|
+
"externalServiceEmbedType": "js",
|
|
80
|
+
"externalServiceName": "Datawrapper (Datengrafik)"
|
|
81
|
+
},
|
|
82
|
+
"serviceUrl": "https://datawrapper.dwcdn.net/IC3Xn/1/",
|
|
83
|
+
"fixedHeight": "",
|
|
84
|
+
"aspectRatio": "",
|
|
85
|
+
"setResponsiveIframe": false,
|
|
86
|
+
"setTimedReloadIframe": false,
|
|
87
|
+
"setTimeForReload": ""
|
|
88
|
+
},
|
|
43
89
|
"Esri": {
|
|
44
90
|
"externalServiceConfig": {
|
|
45
91
|
"makeConfigurable": true,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<ul class="flex flex-wrap gap-x-4 w-fit sm:w-full sm:pt-2 ">
|
|
6
6
|
{{~#each this~}}
|
|
7
7
|
<li class="w-fit sm:w-full text-primary dark:text-standard-text-dark">
|
|
8
|
-
<a class="block hover:underline gap-x-1" href="{{this.url}}">
|
|
8
|
+
<a class="{{if (isUserConsentNeeded this.url) 'js-user-consent-needed ' ''}}block hover:underline gap-x-1" href="{{this.url}}">
|
|
9
9
|
{{~> components/base/image/icon _icon="ortsmarke" _addClass="inline w-5 h-5 mr-2 fill-current"~}}
|
|
10
10
|
|
|
11
11
|
{{~this.title~}}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{{/with~}}
|
|
9
9
|
{{/unless}}
|
|
10
10
|
{{#with _teaser}}
|
|
11
|
-
{{#if this.isTickerTeaser}}<a href="{{this.link.url}}" aria-label="Zum Ticker" tabindex="-1">{{/if}}
|
|
11
|
+
{{#if this.isTickerTeaser}}<a href="{{this.link.url}}" aria-label="Zum Ticker" tabindex="-1"{{#if (isUserConsentNeeded this.link.url)}} class="js-user-consent-needed"{{/if}}>{{/if}}
|
|
12
12
|
{{~> components/base/image/responsive_image this.teaserImage _type=(if this.teaserType this.teaserType 'story') _variant=(if this.content.imageVariant this.content.imageVariant '100-copytext') _addClassImg=(appendToDefault _addClassImg-adjust_context "ar__content") _noDelay=this.dontLazyload ~}}
|
|
13
13
|
{{#if this.isTickerTeaser}}</a>{{/if}}
|
|
14
14
|
{{/with}}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { hr$, listen, unlisten, addLink } from 'hrQuery'
|
|
2
|
+
import dialogPolyfill from 'dialog-polyfill'
|
|
3
|
+
|
|
4
|
+
const DefaultModal = function (options, rootElement) {
|
|
5
|
+
const dialogPolyfillBaseUrl = options.dialogPolyfillBaseUrl || 'vendor/dialog-polyfill',
|
|
6
|
+
modalTrigger = options.trigger || null,
|
|
7
|
+
triggerRoot = document.body,
|
|
8
|
+
modal = hr$('.js-modal', rootElement)[0],
|
|
9
|
+
closeButtonTrigger = ".js-modal-close"
|
|
10
|
+
|
|
11
|
+
const configureEventListeners = () => {
|
|
12
|
+
listen('click', handleClick, triggerRoot)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const handleClick = (event) => {
|
|
16
|
+
if (null !== modalTrigger) {
|
|
17
|
+
let triggerNode = event.target.closest(modalTrigger)
|
|
18
|
+
let nodeToCloseModal = event.target.closest(closeButtonTrigger)
|
|
19
|
+
if (null !== triggerNode) {
|
|
20
|
+
event.preventDefault()
|
|
21
|
+
show()
|
|
22
|
+
} else if (null !== nodeToCloseModal) {
|
|
23
|
+
close()
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const configurePolyfillIfNeeded = () => {
|
|
29
|
+
if (undefined == modal.showModal) {
|
|
30
|
+
addLink('dialog-polyfill-css', `${dialogPolyfillBaseUrl}/dialog-polyfill.css`, {
|
|
31
|
+
type: 'text/css',
|
|
32
|
+
rel: 'stylesheet',
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
dialogPolyfill.registerDialog(modal)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const show = () => {
|
|
39
|
+
modal.showModal()
|
|
40
|
+
listen('click', closeFromOutside, modal)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const closeFromOutside = (event) => {
|
|
44
|
+
if (event.target === modal) {
|
|
45
|
+
unlisten('click', closeFromOutside, modal)
|
|
46
|
+
close()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const close = () => {
|
|
51
|
+
modal.close()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
configurePolyfillIfNeeded()
|
|
55
|
+
configureEventListeners()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default DefaultModal
|
|
@@ -1,60 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import dialogPolyfill from 'dialog-polyfill'
|
|
1
|
+
import DefaultModal from 'components/modal/defaultModal.subfeature'
|
|
2
|
+
import UserConsentModal from 'components/modal/userConsentModal.subfeature'
|
|
4
3
|
|
|
5
4
|
const Modal = (context) => {
|
|
6
5
|
const { options } = context,
|
|
7
6
|
{ element: rootElement } = context,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
listen('click', clickTracking, ticketShopButton)
|
|
18
|
-
listen('click', show, modalTrigger)
|
|
19
|
-
|
|
20
|
-
modalCloseTriggers.forEach((modalCloseTrigger) => {
|
|
21
|
-
listen('click', close, modalCloseTrigger)
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const configurePolyfillIfNeeded = () => {
|
|
26
|
-
if (undefined == modal.showModal) {
|
|
27
|
-
addLink('dialog-polyfill-css', `${dialogPolyfillBaseUrl}/dialog-polyfill.css`, {
|
|
28
|
-
type: 'text/css',
|
|
29
|
-
rel: 'stylesheet',
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
dialogPolyfill.registerDialog(modal)
|
|
7
|
+
type = options.type || "default"
|
|
8
|
+
|
|
9
|
+
switch (type) {
|
|
10
|
+
case "userConsent":
|
|
11
|
+
new UserConsentModal(options, rootElement)
|
|
12
|
+
break;
|
|
13
|
+
default:
|
|
14
|
+
new DefaultModal(options, rootElement)
|
|
15
|
+
break;
|
|
33
16
|
}
|
|
34
|
-
|
|
35
|
-
const clickTracking = () => {
|
|
36
|
-
console.log('tracking')
|
|
37
|
-
uxAction(trackingInformations)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const show = () => {
|
|
41
|
-
modal.showModal()
|
|
42
|
-
listen('click', closeFromOutside, modal)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const closeFromOutside = (event) => {
|
|
46
|
-
if (event.target === modal) {
|
|
47
|
-
unlisten('click', closeFromOutside, modal)
|
|
48
|
-
close()
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const close = () => {
|
|
53
|
-
modal.close()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
configurePolyfillIfNeeded()
|
|
57
|
-
configureEventListeners()
|
|
58
17
|
}
|
|
59
18
|
|
|
60
19
|
export default Modal
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<div class="js-load" data-hr-modal='{"
|
|
1
|
+
<div class="js-load" data-hr-modal='{"trigger":"{{if _trigger _trigger ""}}", "type":"{{defaultIfEmpty _type 'default'}}", "dialogPolyfillBaseUrl":"{{resourceUrl (configProperty 'dialogPolyfill.baseUrl')}}"}'>
|
|
2
2
|
<dialog class='js-modal p-0 backdrop:bg-gray-scorpion/90 shadow-md {{defaultIfEmpty _css "sm:max-w-xl"}}'>
|
|
3
3
|
<form method="dialog" class="js-dialog-content p-4">
|
|
4
4
|
{{> @partial-block }}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ArgsTable, Meta, Story, Canvas, Preview } from '@storybook/blocks'
|
|
2
|
+
import * as ModalStories from './modal.stories'
|
|
3
|
+
|
|
4
|
+
<Meta of={ModalStories} />
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Modal
|
|
8
|
+
|
|
9
|
+
- [Übersicht](#übersicht)
|
|
10
|
+
- [Eigenschaften](#eigenschaften)
|
|
11
|
+
- [Varianten](#varianten)
|
|
12
|
+
- [Verwendung](#verwendung)
|
|
13
|
+
|
|
14
|
+
## Übersicht
|
|
15
|
+
|
|
16
|
+
Die Modal Komponente erlaubt es frei wählbare Inhalte in einem Modal anzuzeigen. Geöffnet werden kann ein Modal durch klicken auf einen
|
|
17
|
+
mit einer bestimmten CSS Klasse ausgezeichneten Link oder Button. Zur Anzeige des Modal wird das native [HTML Dialog Element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog?retiredLocale=de) verwendet.
|
|
18
|
+
Standardmäßig kann dieses durch Drücken der `ESC` Taste geschlossen werden.
|
|
19
|
+
Damit auch ältere Browser, die das Dialog Element noch nicht unterstützen, das Modal anzeigen können, wird ein Polyfill eingebunden.
|
|
20
|
+
|
|
21
|
+
<Canvas>
|
|
22
|
+
<Story of={ModalStories.defaultModal} />
|
|
23
|
+
</Canvas>
|
|
24
|
+
|
|
25
|
+
## Eigenschaften
|
|
26
|
+
|
|
27
|
+
<ArgsTable story="Default Modal" />
|
|
28
|
+
|
|
29
|
+
## Varianten
|
|
30
|
+
|
|
31
|
+
Das Modal existiert derzeit in zwei Varianten. Die zu nutzende Variante wird beim Einbinden der Modal Komponente
|
|
32
|
+
über den Parameter `_variant` konfiguriert.
|
|
33
|
+
|
|
34
|
+
<Canvas>
|
|
35
|
+
<Story of={ModalStories.defaultModal} />
|
|
36
|
+
</Canvas>
|
|
37
|
+
|
|
38
|
+
und `userConsent`
|
|
39
|
+
<Canvas>
|
|
40
|
+
<Story of={ModalStories.userConsentModal} />
|
|
41
|
+
</Canvas>
|
|
42
|
+
|
|
43
|
+
## Verwendung
|
|
44
|
+
|
|
45
|
+
Die Modal Komponente wird mit der Handlebar Komponente `components/modal/modal` eingebunden.
|
|
46
|
+
Die Komponente ist so konzipiert, dass sie im optimalen Fall nur einmal auf einer Seite eingebunden werden muss (am besten in der Nähe des Footers).
|
|
47
|
+
Jeder Link oder jeder Button auf einer Seite kann so konfiguriert werden, dass er das Modal öffnet. Mit welcher CSS Hook Klasse das Modal
|
|
48
|
+
geöffnet werden soll, wird bei der Einbindung der Komponente mit dem Parameter `_trigger` konfiguriert. Jeder Button oder jeder Link auf der Seite
|
|
49
|
+
in der die Komponente eingebunden ist und die im Modal konfigurierte CSS Hook Klasse besitzt, öffnet bei Klick das Modal.
|
|
50
|
+
|
|
51
|
+
Die Modal Komponente ist eine Block Komponente. Auf diese Weise ist es möglich ein Modal mit beliebigem Inhalt anzulegen.
|
|
52
|
+
|
|
53
|
+
### Default
|
|
54
|
+
|
|
55
|
+
Die Einbindung eines Default Modals erfolgt wie anhand folgenden Beispiels zu sehen.
|
|
56
|
+
|
|
57
|
+
```handlebars
|
|
58
|
+
{{#> components/modal/modal _variant="default" _trigger="js-modal"}}
|
|
59
|
+
{{#> components/teaser/components/teaser_headline}}
|
|
60
|
+
{{> components/teaser/components/teaser_title _text="Überschrift Default Modal" _css="text-2xl"}}
|
|
61
|
+
{{/components/teaser/components/teaser_headline}}
|
|
62
|
+
<p class="mt-2 text-base font-copy">Hier steht der Text des Modals. Dies ist nur ein Beispiel. Das modal Template stellt nur den Rahmen
|
|
63
|
+
des Modals zur Verfügung. In dem Modal kann dargestellt werden was man möchte.</p>
|
|
64
|
+
{{/components/modal/modal}}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Innerhalb des Modals kann beliebiges Markup und/oder beliebige andere Komponenten angezeigt werden. Die hier konfigurierte Trigger Klasse
|
|
68
|
+
`js-modal` ist lediglich ein Beispiel. Sie sollte jedoch, um sich klar von normalen CSS-Klassen zu unterscheiden das Prefix `js-` tragen.
|
|
69
|
+
Ein mit der Variante `default` erzeugtes Modal besitzt nur die Grundfunktionalität eines Modals. Sie erlaubt das Modal durch Klick auf ein mit der
|
|
70
|
+
Trigger Klasse ausgezeichneten Link oder Button zu öffnen. Weiterhin kann das geöffnete Modal durch Drücken der `ESC` Taste, durch Klicken in den
|
|
71
|
+
ausgegrauten Bereich außerhalb des Modals oder durch Klicken auf einen Button, dessen `value` Parameter den Wert `cancel` trägt, geschlossen werden.
|
|
72
|
+
Da als Basis der Modal Komponente das native HTML Dialog Element genutzt wird, ist sie auch bereits standarmäßig weitgehend barrierfrei. Ein Focus Trap,
|
|
73
|
+
das heißt sofern ich das Modal nicht explizit schließe bleibe ich bei Drücken der `Tab` Taste ausschließlich innerhalb des Modals, steht standardmäßig zur
|
|
74
|
+
Verfügung.
|
|
75
|
+
|
|
76
|
+
### User Consent
|
|
77
|
+
Dieses Variante wurde speziell für den Anwendungsfall einer Zweiklicklösung erstellt. Sie ermöglicht es, dass bei Klick auf einen Link
|
|
78
|
+
der Nutzer in einem Modal darauf hingewiesen wird, dass er nun das HR Internetangebot verlässt und er erst bei einer aktiven Bestätigung
|
|
79
|
+
mit Hilfe eines weiteren Klicks den eigentlichen Link aufrufen kann. Die Variante kann, wie im Folgenen gezeigt, eingebunden werden.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
```handlebars
|
|
83
|
+
{{#> components/modal/modal _variant="userConsent" _trigger="js-user-consent-needed"}}
|
|
84
|
+
{{> components/modal/user_consent _headline=(loca "modal_user_consent_headline") _text=(loca "modal_user_consent_text") _labelOk=(loca "modal_user_consent_label_ok") _labelCancel=(loca "modal_user_consent_label_cancel")}}
|
|
85
|
+
{{/components/modal/modal}}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Für den Inhalt des Modals wurde eine eigene Komponente `components/modal/user_consent` erstellt. Sie erzeugt eine Überschrift, einen erläuternden Text sowie
|
|
89
|
+
einen Abbrechen- und einen Ok-Button. Die konkreten Texte können der Komponente entweder über die Parameter `_headline`, `_text`, `_labelOk` und `_labelCancel`
|
|
90
|
+
direkt beim Aufruf übergeben werden oder werden, wenn beim Aufruf keine Parameter übergeben werden, aus den Locatags `modal_user_consent_headline`, `modal_user_consent_text`,
|
|
91
|
+
`modal_user_consent_label_ok` und `modal_user_consent_label_cancel` gezogen.
|
|
92
|
+
Für die speziellen Funktionen dieser Variante wurde ein separates Javascript Subfeature erzeugt. Dies sorgt dafür, dass der Variante neben allen
|
|
93
|
+
Eigenschaften der `default` Variante, auch noch speziell für die Zweiklick Lösung benötigte Funktionalitäten zur Verfügung stehen.
|
|
94
|
+
Ist das das Modal aufrufende Element ein Link, werden aus diesem die Werte des `href`, des `target` und des `rel` Attributes ausgelesen und damit
|
|
95
|
+
der Link des `OK`-Buttons erzeugt. Ist das aufrufende Element ein Button (z.B. beim [Event-Ticket-Button](?path=/story/komponenten-teaser-eventkalender--teaser-100)),
|
|
96
|
+
müssen diese Information in dem `data-user-consent-link`-Attribut des Buttons als JSON in der Form
|
|
97
|
+
`{"url":"https://www.beispiel.de","isTargetBlank":true/false}` hinterlegt werden. Wird hier bei `isTargetBlank` der Wert `true` übergeben, erhält der
|
|
98
|
+
im Modal erzeugte Link des OK-Buttons automatisch das attribut `rel="noopener"` gesetzt.
|
|
99
|
+
|
|
100
|
+
### Neue Varianten
|
|
101
|
+
Wird ein Modal mit einer komplett neuen Funktionalität benötigt, muss eine neue Variante erstellt und der Komponente hinzugefügt werden. Hierzu muss
|
|
102
|
+
ein Name für die neue Variante gewählt und die `switch`-Anweisung in `components/modal/modal.feature.js` um einen neuen Fall mit diesem
|
|
103
|
+
Namen erweitert werden. Die eigentliche Funktionalität muss in einem Javascript Subfeature umgesetzt werden.
|
|
104
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const handlebars = require('hrHandlebars')
|
|
2
|
+
|
|
3
|
+
const defaultModalTemplate = (args, { globals: { customConditionalToolbar } }) => {
|
|
4
|
+
let brand =
|
|
5
|
+
undefined !== customConditionalToolbar ? customConditionalToolbar['brands'] : 'hessenschau'
|
|
6
|
+
let hbsTemplate = handlebars.compile(`
|
|
7
|
+
{{#> components/modal/modal}}
|
|
8
|
+
{{#> components/teaser/components/teaser_headline}}
|
|
9
|
+
{{> components/teaser/components/teaser_title _text="Überschrift Default Modal" _css="text-2xl"}}
|
|
10
|
+
{{/components/teaser/components/teaser_headline}}
|
|
11
|
+
<p class="mt-2 text-base font-copy">Hier steht der Text des Modals. Dies ist nur ein Beispiel. Das modal Template stellt nur den Rahmen
|
|
12
|
+
des Modals zur Verfügung. In dem Modal kann dargestellt werden was man möchte.</p>
|
|
13
|
+
{{/components/modal/modal}}
|
|
14
|
+
|
|
15
|
+
{{#> components/base/link _css="js-modal"}}
|
|
16
|
+
Default Modal
|
|
17
|
+
{{/components/base/link}}
|
|
18
|
+
`)
|
|
19
|
+
return hbsTemplate({ brand, ...args })
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const userConsentModalTemplate = (args, { globals: { customConditionalToolbar } }) => {
|
|
23
|
+
let brand =
|
|
24
|
+
undefined !== customConditionalToolbar ? customConditionalToolbar['brands'] : 'hessenschau'
|
|
25
|
+
let link = { url: "https://hessenschau.de", isTargetBlank: true }
|
|
26
|
+
let hbsTemplate = handlebars.compile(`
|
|
27
|
+
{{#> components/modal/modal}}
|
|
28
|
+
{{> components/modal/user_consent _headline=(loca "modal_user_consent_headline") _text=(loca "modal_user_consent_text") _labelOk=(loca "modal_user_consent_label_ok") _labelCancel=(loca "modal_user_consent_label_cancel")}}
|
|
29
|
+
{{/components/modal/modal}}
|
|
30
|
+
|
|
31
|
+
<a href="https://hessenschau.de" class="js-user-consent-needed" rel="noopener" target="_blank">User Consent Modal</a>
|
|
32
|
+
`)
|
|
33
|
+
return hbsTemplate({ brand, ...args })
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default {
|
|
37
|
+
title: 'Komponenten/Modal',
|
|
38
|
+
|
|
39
|
+
argTypes: {
|
|
40
|
+
_trigger: {
|
|
41
|
+
description: 'Hook Klasse des Links oder Buttons, welcher das Modal öffnen soll',
|
|
42
|
+
control: 'text',
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
_type: {
|
|
46
|
+
control: {
|
|
47
|
+
type: 'select',
|
|
48
|
+
options: ['default', 'userConsent'],
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
description: 'Der Typ des Modals, das geöffnet werden soll. Derzeit lassen sich die Typen "default" und "userConsent" auswählen.',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
parameters: {
|
|
56
|
+
controls: {
|
|
57
|
+
sort: 'alpha',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const defaultModal = {
|
|
63
|
+
render: defaultModalTemplate.bind({}),
|
|
64
|
+
name: 'Default Modal',
|
|
65
|
+
args: {
|
|
66
|
+
_trigger: '.js-modal',
|
|
67
|
+
_type: 'default'
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const userConsentModal = {
|
|
72
|
+
render: userConsentModalTemplate.bind({}),
|
|
73
|
+
name: 'User Consent Modal',
|
|
74
|
+
args: {
|
|
75
|
+
_trigger: '.js-user-consent-needed',
|
|
76
|
+
_type: 'userConsent'
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { hr$, listen, unlisten } from 'hrQuery'
|
|
2
|
+
import { uxAction } from 'base/tracking/pianoHelper.subfeature'
|
|
3
|
+
import dialogPolyfill from 'dialog-polyfill'
|
|
4
|
+
|
|
5
|
+
const UserConsentModal = function (options, rootElement) {
|
|
6
|
+
let triggerNode = null,
|
|
7
|
+
isDesktopViewport = true
|
|
8
|
+
const dialogPolyfillBaseUrl = options.dialogPolyfillBaseUrl || 'vendor/dialog-polyfill',
|
|
9
|
+
modalTrigger = options.trigger || '.js-user-consent-needed',
|
|
10
|
+
modalTriggerWithDropdownInDesktopViewport = 'js-dropdown-in-desktop',
|
|
11
|
+
triggerRoot = document.body,
|
|
12
|
+
modal = hr$('.js-modal', rootElement)[0],
|
|
13
|
+
okButtonTrigger = '.js-user-consent-ok',
|
|
14
|
+
okButton = hr$(okButtonTrigger, rootElement)[0],
|
|
15
|
+
closeButtonTrigger = ".js-modal-close",
|
|
16
|
+
desktopViewport = 1024,
|
|
17
|
+
resizeObserver = new ResizeObserver((entries) => {
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
isDesktopViewport = entry.borderBoxSize[0].inlineSize >= desktopViewport
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
const configureEventListeners = () => {
|
|
25
|
+
listen('click', handleClickOnTrigger, triggerRoot)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const handleClickOnTrigger = (event) => {
|
|
29
|
+
if (null !== modalTrigger) {
|
|
30
|
+
triggerNode = event.target.closest(modalTrigger)
|
|
31
|
+
let okButton = event.target.closest(okButtonTrigger)
|
|
32
|
+
let closeButton = event.target.closest(closeButtonTrigger)
|
|
33
|
+
|
|
34
|
+
if (null !== triggerNode) {
|
|
35
|
+
let showModal = triggerNode.classList.contains(modalTriggerWithDropdownInDesktopViewport) && !isDesktopViewport || !triggerNode.classList.contains(modalTriggerWithDropdownInDesktopViewport)
|
|
36
|
+
if (showModal) {
|
|
37
|
+
event.preventDefault()
|
|
38
|
+
setUrlToFollowAfterConsent(triggerNode)
|
|
39
|
+
show()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (null !== okButton) {
|
|
43
|
+
handleClickTracking()
|
|
44
|
+
}
|
|
45
|
+
if (null !== closeButton) {
|
|
46
|
+
close()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const setUrlToFollowAfterConsent = (triggerNode) => {
|
|
52
|
+
let urlToFollowAfterConsent = "",
|
|
53
|
+
target = null,
|
|
54
|
+
rel = null
|
|
55
|
+
if ("userConsentLink" in triggerNode.dataset) {
|
|
56
|
+
let link = null
|
|
57
|
+
try {
|
|
58
|
+
link = JSON.parse(triggerNode.dataset.userConsentLink)
|
|
59
|
+
} catch {
|
|
60
|
+
link = {}
|
|
61
|
+
}
|
|
62
|
+
urlToFollowAfterConsent = link.url || '#'
|
|
63
|
+
target = link.isTargetBlank ? '_blank' : null
|
|
64
|
+
rel = link.isTargetBlank ? 'noopener' : null
|
|
65
|
+
} else {
|
|
66
|
+
urlToFollowAfterConsent = triggerNode.href
|
|
67
|
+
target = triggerNode.hasAttribute("target") ? triggerNode.target : null
|
|
68
|
+
rel = triggerNode.hasAttribute("rel") ? triggerNode.rel : null
|
|
69
|
+
}
|
|
70
|
+
okButton.href = urlToFollowAfterConsent
|
|
71
|
+
if (null !== target) {
|
|
72
|
+
okButton.setAttribute("target", target)
|
|
73
|
+
} else {
|
|
74
|
+
okButton.removeAttribute("target")
|
|
75
|
+
}
|
|
76
|
+
if (null !== rel) {
|
|
77
|
+
okButton.setAttribute("rel", rel)
|
|
78
|
+
} else {
|
|
79
|
+
okButton.removeAttribute("rel")
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const handleClickTracking = () => {
|
|
84
|
+
if (null !== triggerNode && "userConsentTrackingData" in triggerNode.dataset) {
|
|
85
|
+
uxAction(triggerNode.dataset.userConsentTrackingData)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const configurePolyfillIfNeeded = () => {
|
|
90
|
+
if (undefined == modal.showModal) {
|
|
91
|
+
addLink('dialog-polyfill-css', `${dialogPolyfillBaseUrl}/dialog-polyfill.css`, {
|
|
92
|
+
type: 'text/css',
|
|
93
|
+
rel: 'stylesheet',
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
dialogPolyfill.registerDialog(modal)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const show = () => {
|
|
100
|
+
modal.showModal()
|
|
101
|
+
listen('click', closeFromOutside, modal)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const closeFromOutside = (event) => {
|
|
105
|
+
if (event.target === modal) {
|
|
106
|
+
unlisten('click', closeFromOutside, modal)
|
|
107
|
+
close()
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const close = () => {
|
|
112
|
+
modal.close()
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
configurePolyfillIfNeeded()
|
|
116
|
+
configureEventListeners()
|
|
117
|
+
resizeObserver.observe(document.body)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export default UserConsentModal
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{#> components/teaser/components/teaser_headline}}
|
|
2
|
+
{{> components/teaser/components/teaser_title _text=_headline-adjust_context _css="text-2xl"}}
|
|
3
|
+
{{/components/teaser/components/teaser_headline}}
|
|
4
|
+
<p class="mt-2 text-base font-copy">{{_text}}</p>
|
|
5
|
+
|
|
6
|
+
<div class="flex flex-wrap mt-4">
|
|
7
|
+
{{#> components/button/button _size="lg" _variant="tertiary" _value="cancel" _css="mr-4 mt-4"}}
|
|
8
|
+
{{>components/button/components/button_label _label=_labelCancel-adjust_context _css=""}}
|
|
9
|
+
{{/components/button/button}}
|
|
10
|
+
{{#> components/button/link_button _link='{"url":"#", "isTargetBlank": false, "hasIcon": false}' _size="lg" _css="js-user-consent-ok js-modal-close mt-4"}}
|
|
11
|
+
{{>components/button/components/button_label _label=_labelOk-adjust_context _css=""}}
|
|
12
|
+
{{/components/button/link_button}}
|
|
13
|
+
</div>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{{/with}}
|
|
9
9
|
<li class="inline">
|
|
10
10
|
<h1 class="inline{{#unless this.showBreadcrumbTitleAlways}} sr-only sm:not-sr-only{{/unless}}">
|
|
11
|
-
<a href="{{_currentPageUrl}}" class="{{> components/navigation/breadcrumb/utils/breadcrumb_link_classes}}">{{~_currentPageTitle~}}</a>
|
|
11
|
+
<a href="{{_currentPageUrl}}" class="{{if (isUserConsentNeeded _currentPageUrl) 'js-user-consent-needed ' ''}}{{> components/navigation/breadcrumb/utils/breadcrumb_link_classes}}">{{~_currentPageTitle~}}</a>
|
|
12
12
|
</h1>
|
|
13
13
|
</li>
|
|
14
14
|
</ul>
|