hr-design-system-handlebars 1.124.9 → 1.125.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/assets/index.css +3 -3
  3. package/dist/assets/js/alpine.js +1 -0
  4. package/dist/assets/js/components/appBanner/appBanner.alpine.js +32 -23
  5. package/dist/assets/js/components/appBanner/nativeAppBanner.alpine.js +44 -0
  6. package/dist/assets/js/components/external-service/dataWrapperContentRefresher.subfeature.js +73 -65
  7. package/dist/assets/js/components/external-service/dataWrapperNoResponsiveIframe.subfeature.js +50 -72
  8. package/dist/assets/js/components/external-service/externalServiceDs.feature.js +119 -149
  9. package/dist/views/components/appBanner/nativeAppBanner.hbs +27 -0
  10. package/dist/views/components/external-service/external_service_with_datapolicy_check.hbs +1 -1
  11. package/dist/views_static/components/appBanner/nativeAppBanner.hbs +27 -0
  12. package/dist/views_static/components/external-service/external_service_with_datapolicy_check.hbs +1 -1
  13. package/package.json +1 -1
  14. package/src/assets/js/alpine.js +1 -0
  15. package/src/stories/views/components/appBanner/appBanner.alpine.js +32 -23
  16. package/src/stories/views/components/appBanner/appBanner.mdx +3 -4
  17. package/src/stories/views/components/appBanner/appBanner.stories.js +17 -6
  18. package/src/stories/views/components/appBanner/nativeAppBanner.alpine.js +44 -0
  19. package/src/stories/views/components/appBanner/nativeAppBanner.hbs +27 -0
  20. package/src/stories/views/components/external-service/dataWrapperContentRefresher.subfeature.js +73 -65
  21. package/src/stories/views/components/external-service/dataWrapperNoResponsiveIframe.subfeature.js +50 -72
  22. package/src/stories/views/components/external-service/externalServiceDs.feature.js +119 -149
  23. package/src/stories/views/components/external-service/external_service_with_datapolicy_check.hbs +1 -1
@@ -29,10 +29,7 @@ const ExternalService = function (context) {
29
29
  let embedCode = options.embedCode,
30
30
  iframe,
31
31
  settingsCookie = new SettingsCookie(),
32
- noResponsiveIframe,
33
- contentRefresher,
34
32
  gemeindewahlergebnis,
35
- uniqueId,
36
33
  isExternalServiceLoaded = false,
37
34
  tiktokOnPage = []
38
35
 
@@ -74,61 +71,34 @@ const ExternalService = function (context) {
74
71
  }
75
72
 
76
73
  const insertExternalService = function () {
77
- switch (embedType) {
78
- case 'js':
79
- switch (id) {
80
- case '23degrees':
81
- createTwentyThreeDegreesEmbed()
82
- break
83
- case 'facebook-post':
84
- createFacebookEmbed()
85
- break
86
- case 'instagram':
87
- createInstagramEmbed()
88
- break
89
- case 'tiktok':
90
- createTikTokEmbed()
91
- break
92
- case 'twitter':
93
- createTwitterEmbed()
94
- break
95
- case 'twitter-post':
96
- createTwitterPostEmbed()
97
- break
98
- case 'datawrapper_cdn':
99
- createDataWrapperEmbed()
100
- break
101
- case 'wahlmonitor':
102
- createWahlEmbed()
103
- break
104
- case 'wahlmonitor_v2':
105
- createWahlEmbed()
106
- break
107
- case 'wahlkreiskarte':
108
- createWahlEmbed()
109
- break
110
- case 'wahlkreiskarte_v2':
111
- createWahlEmbed()
112
- break
113
- case 'wahlomat-euwa':
114
- createWahlOMatEuwaEmbed()
115
- break
116
- case 'wahlomat-butawa':
117
- createWahlOMatButawaEmbed()
118
- break
119
- case 'wahl-gemeinde-ergebnis':
120
- createWahlGemeindeErgebnisEmbed()
121
- break
122
- case 'wer-waehlte-wen':
123
- werWaehlteWenEmbed()
124
- break
125
- default:
126
- console.error('No JS Config for external service ' + id)
127
- break
128
- }
129
- break
130
- default:
131
- loadIframe() //für alle Dienste die nicht der DSGVO Datapolicy unterliegen
74
+ if (embedType !== 'js') {
75
+ loadIframe() // Für alle Dienste, die nicht der DSGVO Datapolicy unterliegen
76
+ return
77
+ }
78
+
79
+ const externalServiceMap = {
80
+ '23degrees': createTwentyThreeDegreesEmbed,
81
+ 'facebook-post': createFacebookEmbed,
82
+ 'instagram': createInstagramEmbed,
83
+ 'tiktok': createTikTokEmbed,
84
+ 'twitter': createTwitterEmbed,
85
+ 'twitter-post': createTwitterPostEmbed,
86
+ 'datawrapper_cdn': createDataWrapperEmbed,
87
+ 'wahlmonitor': createWahlEmbed,
88
+ 'wahlmonitor_v2': createWahlEmbed,
89
+ 'wahlkreiskarte': createWahlEmbed,
90
+ 'wahlkreiskarte_v2': createWahlEmbed,
91
+ 'wahlomat-euwa': createWahlOMatEuwaEmbed,
92
+ 'wahlomat-butawa': createWahlOMatButawaEmbed,
93
+ 'wahl-gemeinde-ergebnis': createWahlGemeindeErgebnisEmbed,
94
+ 'wer-waehlte-wen': werWaehlteWenEmbed,
95
+ }
96
+
97
+ const service = externalServiceMap[id]
98
+ if (service) {
99
+ service()
100
+ } else {
101
+ console.error(`No JS Config for external service ${id}`)
132
102
  }
133
103
  }
134
104
 
@@ -206,14 +176,6 @@ const ExternalService = function (context) {
206
176
  })
207
177
  }
208
178
 
209
- const createUniqueID = function () {
210
- console.log('Erzeuge einzigartige ID')
211
- uniqueId = Math.random()
212
- .toString(36)
213
- .replace(/[^a-z]+/g, '')
214
- .substring(2, 10)
215
- }
216
-
217
179
  const getAspectRatioClass = function () {
218
180
  switch (iFrameConfig.aspectRatio) {
219
181
  case '16x9':
@@ -237,96 +199,104 @@ const ExternalService = function (context) {
237
199
 
238
200
  const createDataWrapperEmbed = function () {
239
201
  removeDatapolicyBox()
240
- createUniqueID()
241
- console.log('UniqueID' + uniqueId)
242
- if (iFrameConfig.noResponsiveIframe == 'true') {
202
+ const uniqueId = createUniqueID()
203
+ const {
204
+ isNoResponsiveIframe,
205
+ isWebcomponent,
206
+ refreshContent,
207
+ aspectRatio,
208
+ fixedHeight,
209
+ refreshIntervall,
210
+ } = iFrameConfig
211
+
212
+ const addContentRefresher = (isWebcomponent) => {
213
+ new DataWrapperContentRefresher({
214
+ rootElement,
215
+ id: uniqueId,
216
+ refreshIntervall,
217
+ isWebcomponent,
218
+ }).createRefresher()
219
+ }
220
+
221
+ if (isNoResponsiveIframe == 'true') {
243
222
  //Klassisches Iframe mit AR-Wrapper oder fester Höhe
244
- noResponsiveIframe = new DataWrapperNoResponsiveIframe(
245
- context,
246
- iFrameConfig.aspectRatio,
247
- iFrameConfig.fixedHeight,
248
- uniqueId,
249
- embedCode,
250
- lazyLoad
251
- )
252
- noResponsiveIframe.createNoResponsiveIframe()
253
-
254
- if (iFrameConfig.refreshContent == 'true') {
255
- console.log('contentRefresher anfügen')
256
- contentRefresher = new DataWrapperContentRefresher(
257
- context,
258
- uniqueId,
259
- iFrameConfig.refreshIntervall,
260
- false
261
- )
262
- contentRefresher.createRefresher()
223
+ new DataWrapperNoResponsiveIframe({
224
+ rootElement: rootElement,
225
+ aspectRatio: aspectRatio,
226
+ fixedHeight: fixedHeight,
227
+ id: uniqueId,
228
+ embedCode: embedCode,
229
+ lazyLoad: lazyLoad,
230
+ }).createNoResponsiveIframe()
231
+
232
+ if (refreshContent == 'true') {
233
+ addContentRefresher(false)
263
234
  }
264
- } else {
265
- if (iFrameConfig.webcomponent == 'true') {
266
- // Webcomponent
267
- const divTag = document.createElement('div')
268
- divTag.id = 'datawrapper-chart-' + uniqueId
269
- rootElement.insertBefore(divTag, null)
270
- const scriptTag = document.createElement('script')
271
- scriptTag.setAttribute('id', 'datawrapper-component-js')
272
- scriptTag.setAttribute('type', 'text/javascript')
273
- scriptTag.setAttribute('defer', 'defer')
274
- scriptTag.setAttribute('src', embedCode + 'embed.js?v=1')
275
- scriptTag.setAttribute('charset', 'utf-8')
276
- const noScriptTag = document.createElement('noscript')
277
- const imageTag = document.createElement('img')
278
- imageTag.src = embedCode + 'full.png'
279
- imageTag.alt = ''
280
- noScriptTag.appendChild(imageTag)
281
- divTag.appendChild(scriptTag)
282
- divTag.appendChild(noScriptTag)
283
-
284
- if (iFrameConfig.refreshContent == 'true') {
285
- console.log('contentRefresher anfügen')
286
- contentRefresher = new DataWrapperContentRefresher(
287
- context,
288
- uniqueId,
289
- iFrameConfig.refreshIntervall,
290
- true
291
- )
292
- contentRefresher.createRefresher()
293
- }
294
- } else {
295
- //Responsives Iframe
296
- var iframe = document.createElement('iframe')
297
- //Auflösen nach Tailwind-Klassen //dataWrapper-embed
298
- iframe.className = 'w-0 !min-w-full border-0'
299
- iframe.setAttribute('webkitallowfullscreen', '')
300
- iframe.setAttribute('mozallowfullscreen', '')
301
- iframe.setAttribute('allowfullscreen', '')
302
- iframe.setAttribute('scrolling', 'no')
303
- iframe.setAttribute('frameborder', '0')
304
- iframe.src = embedCode
305
- iframe.id = 'datawrapper-chart-' + uniqueId
306
- if (lazyLoad) {
307
- iframe.loading = 'lazy'
308
- }
309
- rootElement.insertBefore(iframe, null)
235
+ return
236
+ }
310
237
 
311
- loadScript(
312
- 'datawrapper-js',
313
- 'https://static.hr.de/hessenschau/datawrapper/responsiveIframe.js',
314
- true
315
- )
316
- if (iFrameConfig.refreshContent == 'true') {
317
- console.log('contentRefresher anfügen')
318
- contentRefresher = new DataWrapperContentRefresher(
319
- context,
320
- uniqueId,
321
- iFrameConfig.refreshIntervall,
322
- false
323
- )
324
- contentRefresher.createRefresher()
325
- }
238
+ if (isWebcomponent == 'true') {
239
+ // Webcomponent
240
+ const divTag = document.createElement('div')
241
+ divTag.id = `datawrapper-chart-${uniqueId}`
242
+ rootElement.appendChild(divTag)
243
+
244
+ const scriptTag = document.createElement('script')
245
+ Object.assign(scriptTag, {
246
+ id: 'datawrapper-component-js',
247
+ type: 'text/javascript',
248
+ defer: true,
249
+ src: `${embedCode}embed.js?v=1`,
250
+ charset: 'utf-8',
251
+ })
252
+
253
+ const noScriptTag = document.createElement('noscript')
254
+ const imageTag = document.createElement('img')
255
+ imageTag.src = `${embedCode}full.png`
256
+ imageTag.alt = ''
257
+ noScriptTag.appendChild(imageTag)
258
+
259
+ divTag.append(scriptTag, noScriptTag)
260
+
261
+ if (refreshContent == 'true') {
262
+ addContentRefresher(true)
326
263
  }
264
+ return
265
+ }
266
+ //Responsives Iframe
267
+ const iframe = document.createElement('iframe')
268
+ //Auflösen nach Tailwind-Klassen //dataWrapper-embed
269
+ iframe.className = 'w-0 !min-w-full border-0'
270
+ iframe.setAttribute('webkitallowfullscreen', '')
271
+ iframe.setAttribute('mozallowfullscreen', '')
272
+ iframe.setAttribute('allowfullscreen', '')
273
+ iframe.setAttribute('scrolling', 'no')
274
+ iframe.setAttribute('frameborder', '0')
275
+ iframe.src = embedCode
276
+ iframe.id = `datawrapper-chart-${uniqueId}`
277
+ if (lazyLoad) {
278
+ iframe.loading = 'lazy'
279
+ }
280
+ rootElement.appendChild(iframe)
281
+
282
+ loadScript(
283
+ 'datawrapper-js',
284
+ 'https://static.hr.de/hessenschau/datawrapper/responsiveIframe.js',
285
+ true
286
+ )
287
+ if (refreshContent == 'true') {
288
+ addContentRefresher(false)
327
289
  }
328
290
  }
329
291
 
292
+ const createUniqueID = function () {
293
+ console.log('Erzeuge einzigartige ID')
294
+ return Math.random()
295
+ .toString(36)
296
+ .replace(/[^a-z]+/g, '')
297
+ .substring(2, 10)
298
+ }
299
+
330
300
  const createTwentyThreeDegreesEmbed = function () {
331
301
  removeDatapolicyBox()
332
302
 
@@ -0,0 +1,27 @@
1
+ <div
2
+ x-data="nativeAppBanner()" x-cloak x-show="showBanner" ax-load x-ignore
3
+ id="marketing-banner" tabindex="-1" class="fixed bottom-0 z-50 flex flex-row justify-end w-full gap-4 p-4 -translate-x-1/2 flex-nowrap bg-blue-aqua lg:max-w-7xl left-1/2">
4
+ <div class="flex flex-row items-center gap-4 grow">
5
+ <div class="flex items-center justify-center rounded-lg w-11 h-11 bg-blue-congress-hex shrink-0">
6
+ <img width="24" height="24" src="{{resourceUrl "assets/base/icons/logo/brandlogo--mobile.min.svg" _brand=(defaultIfEmpty this.brand "hessenschau")}}"
7
+ class="w-7 h-7" alt="{{loca "meta_application_name"}}">
8
+ </div>
9
+ <div class="flex flex-col items-start text-sm sm:text-base font-heading">
10
+ <span class="font-bold">hessenschau App</span>
11
+ <span>Kostenlos bei Google Play</span>
12
+ </div>
13
+ </div>
14
+ <div class="flex items-center gap-4 ">
15
+ {{#> components/button/button _size="md" _alpineClick="installClickHandler"}}
16
+ {{> components/button/components/button_label _label="Laden" _css="text-sm sm:text-base"}}
17
+ {{/components/button/button}}
18
+ {{#> components/button/button _size="md" _variant="tertiary" _css="h-10" _alpineClick="closeClickHandler"}}
19
+ {{> components/button/components/button_icon _icon="close" _css="" _iconmap="icons"}}
20
+ {{> components/button/components/button_label _label="schließen" _css="sr-only"}}
21
+ {{/components/button/button}}
22
+ </div>
23
+ </div>
24
+
25
+
26
+
27
+
@@ -3,7 +3,7 @@
3
3
  <div class="c-externalService c-externalService__{{this.externalServiceConfig.externalServiceId}}{{#unless
4
4
  this.fixedHeight }} -noFixedHeight{{/unless}} js-load"
5
5
  data-hr-external-service-ds='{"id":"{{this.externalServiceConfig.externalServiceId}}","embedCode":"{{this.serviceUrl}}","embedType":"{{this.externalServiceConfig.externalServiceEmbedType}}","lazyLoad":{{defaultIfEmpty _lazyLoad false}},"dataPolicyCheck": true, "whiteList":{{this.externalServiceConfig.isWhitelisted}},"iFrameConfig": { {{~#if this.fixedHeight~}}
6
- "fixedHeight":"{{this.fixedHeight}}"{{~else~}}{{~#if this.aspectRatio}}"aspectRatio":"{{this.aspectRatio}}"{{~else~}}"aspectRatio":"16x9"{{/if}}{{~/if}},"noResponsiveIframe":"{{{this.setResponsiveIframe}}}","webcomponent":"{{{this.setWebcomponent}}}"{{~#if this.setTimedReloadIframe}},"refreshContent":"{{{this.setTimedReloadIframe}}}","refreshIntervall":"{{this.setTimeForReload}}"{{~/if}} }}'>
6
+ "fixedHeight":"{{this.fixedHeight}}"{{~else~}}{{~#if this.aspectRatio}}"aspectRatio":"{{this.aspectRatio}}"{{~else~}}"aspectRatio":"16x9"{{/if}}{{~/if}},"isNoResponsiveIframe":"{{{this.setResponsiveIframe}}}","isWebcomponent":"{{{this.setWebcomponent}}}"{{~#if this.setTimedReloadIframe}},"refreshContent":"{{{this.setTimedReloadIframe}}}","refreshIntervall":"{{this.setTimeForReload}}"{{~/if}} }}'>
7
7
  {{~> components/external-service/components/external_service_data_policy ~}}
8
8
  </div>
9
9
  {{~> components/external-service/components/external_service_caption ~}}
@@ -0,0 +1,27 @@
1
+ <div
2
+ x-data="nativeAppBanner()" x-cloak x-show="showBanner" ax-load x-ignore
3
+ id="marketing-banner" tabindex="-1" class="fixed bottom-0 z-50 flex flex-row justify-end w-full gap-4 p-4 -translate-x-1/2 flex-nowrap bg-blue-aqua lg:max-w-7xl left-1/2">
4
+ <div class="flex flex-row items-center gap-4 grow">
5
+ <div class="flex items-center justify-center rounded-lg w-11 h-11 bg-blue-congress-hex shrink-0">
6
+ <img width="24" height="24" src="{{resourceUrl "assets/base/icons/logo/brandlogo--mobile.min.svg" _brand=(defaultIfEmpty this.brand "hessenschau")}}"
7
+ class="w-7 h-7" alt="{{loca "meta_application_name"}}">
8
+ </div>
9
+ <div class="flex flex-col items-start text-sm sm:text-base font-heading">
10
+ <span class="font-bold">hessenschau App</span>
11
+ <span>Kostenlos bei Google Play</span>
12
+ </div>
13
+ </div>
14
+ <div class="flex items-center gap-4 ">
15
+ {{#> components/button/button _size="md" _alpineClick="installClickHandler"}}
16
+ {{> components/button/components/button_label _label="Laden" _css="text-sm sm:text-base"}}
17
+ {{/components/button/button}}
18
+ {{#> components/button/button _size="md" _variant="tertiary" _css="h-10" _alpineClick="closeClickHandler"}}
19
+ {{> components/button/components/button_icon _icon="close" _css="" _iconmap="icons"}}
20
+ {{> components/button/components/button_label _label="schließen" _css="sr-only"}}
21
+ {{/components/button/button}}
22
+ </div>
23
+ </div>
24
+
25
+
26
+
27
+
@@ -3,7 +3,7 @@
3
3
  <div class="c-externalService c-externalService__{{this.externalServiceConfig.externalServiceId}}{{#unless
4
4
  this.fixedHeight }} -noFixedHeight{{/unless}} js-load"
5
5
  data-hr-external-service-ds='{"id":"{{this.externalServiceConfig.externalServiceId}}","embedCode":"{{this.serviceUrl}}","embedType":"{{this.externalServiceConfig.externalServiceEmbedType}}","lazyLoad":{{defaultIfEmpty _lazyLoad false}},"dataPolicyCheck": true, "whiteList":{{this.externalServiceConfig.isWhitelisted}},"iFrameConfig": { {{~#if this.fixedHeight~}}
6
- "fixedHeight":"{{this.fixedHeight}}"{{~else~}}{{~#if this.aspectRatio}}"aspectRatio":"{{this.aspectRatio}}"{{~else~}}"aspectRatio":"16x9"{{/if}}{{~/if}},"noResponsiveIframe":"{{{this.setResponsiveIframe}}}","webcomponent":"{{{this.setWebcomponent}}}"{{~#if this.setTimedReloadIframe}},"refreshContent":"{{{this.setTimedReloadIframe}}}","refreshIntervall":"{{this.setTimeForReload}}"{{~/if}} }}'>
6
+ "fixedHeight":"{{this.fixedHeight}}"{{~else~}}{{~#if this.aspectRatio}}"aspectRatio":"{{this.aspectRatio}}"{{~else~}}"aspectRatio":"16x9"{{/if}}{{~/if}},"isNoResponsiveIframe":"{{{this.setResponsiveIframe}}}","isWebcomponent":"{{{this.setWebcomponent}}}"{{~#if this.setTimedReloadIframe}},"refreshContent":"{{{this.setTimedReloadIframe}}}","refreshIntervall":"{{this.setTimeForReload}}"{{~/if}} }}'>
7
7
  {{~> components/external-service/components/external_service_data_policy ~}}
8
8
  </div>
9
9
  {{~> components/external-service/components/external_service_caption ~}}
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": "1.124.9",
9
+ "version": "1.125.0",
10
10
  "scripts": {
11
11
  "test": "echo \"Error: no test specified\" && exit 1",
12
12
  "storybook": "storybook dev -p 6006 public",
@@ -14,6 +14,7 @@ import dropdown from 'components/site_header/dropdown.alpine'
14
14
  AsyncAlpine.init(Alpine)
15
15
  .data('podcastPlayer', () => import('components/podcast/podcast_player.alpine.js'))
16
16
  .data('appBanner', () => import('components/appBanner/appBanner.alpine.js'))
17
+ .data('nativeAppBanner', () => import('components/appBanner/nativeAppBanner.alpine.js'))
17
18
  .data('slider', () =>
18
19
  import('components/horizontal_scroll_container/horizontal_scroll_container.alpine.js')
19
20
  )
@@ -4,38 +4,47 @@ export default function appBanner() {
4
4
  return {
5
5
  showBanner: false,
6
6
  deferredPrompt: null,
7
+ isAndroid: /Android/i.test(navigator.userAgent),
8
+ packageId: "de.hr.hessenschau",
7
9
  init: function () {
8
- window.addEventListener('beforeinstallprompt', (e) => {
9
- // Prevent Chrome 67 and earlier from automatically showing the prompt
10
- e.preventDefault();
11
- // Stash the event so it can be triggered later.
12
- this.deferredPrompt = e;
13
- // Update UI notify the user they can add to home screen
10
+
11
+ if(this.isAndroid){
14
12
  this.showBanner = true;
15
- });
13
+ }
14
+
16
15
  if(window.IS_STORYBOOK){ this.showBanner = true;}
17
16
  },
18
17
  installClickHandler: function(){
19
- if(this.deferredPrompt){
20
- this.deferredPrompt.prompt();
21
- // Wait for the user to respond to the prompt
22
- this.deferredPrompt.userChoice
23
- .then((choiceResult) => {
24
- if (choiceResult.outcome === 'accepted') {
25
- uxAction('installNativeApp::promt::accepted');
26
- console.log('User accepted the A2HS prompt');
27
- } else {
28
- uxAction('installNativeApp::promt::dismissed');
29
- console.log('User dismissed the A2HS prompt');
30
- }
31
- this.deferredPrompt = null;
32
- });
33
- }
18
+ this.openPlayStore()
34
19
  this.showBanner = false
35
20
  },
36
21
  closeClickHandler: function(){
37
- uxAction('installNativeApp::bannerClosed');
22
+ uxAction('appBanner::bannerClosed');
38
23
  this.showBanner = false
24
+ },
25
+ openPlayStore: function() {
26
+ let fallbackTriggered = false;
27
+
28
+ const fallback = () => {
29
+ if (fallbackTriggered) return;
30
+ fallbackTriggered = true;
31
+
32
+ window.open(`https://play.google.com/store/apps/details?id=${this.packageId}`, "googlePlayStore");
33
+
34
+ };
35
+
36
+ document.addEventListener('visibilitychange', () => {
37
+ if (document.hidden) {
38
+ // App switch happened → cancel fallback
39
+ fallbackTriggered = true;
40
+ }
41
+ }, { once: true });
42
+
43
+ window.location.href =
44
+ `intent://details?id=${this.packageId}` +
45
+ `#Intent;scheme=market;package=com.android.vending;end`;
46
+
47
+ setTimeout(fallback, 700);
39
48
  }
40
49
  }
41
50
  }
@@ -1,14 +1,14 @@
1
1
  import { ArgTypes, Meta, Story, Canvas, ColorPalette, ColorItem } from '@storybook/blocks'
2
2
  import * as AppBannerStories from './appBanner.stories';
3
3
 
4
- import geoTag from './appBanner.hbs'
4
+ import appBanner from './appBanner.hbs'
5
5
 
6
6
  <Meta of={AppBannerStories} />
7
7
 
8
8
  export const Template = ({ ...args }) => {
9
9
  // You can either use a function to create DOM elements or use a plain html string!
10
- // return `<div>${geoTag}</div>`;
11
- return geoTag({ ...args })
10
+ // return `<div>${appBanner}</div>`;
11
+ return appBanner({ ...args })
12
12
  }
13
13
 
14
14
  # AppBanner
@@ -16,4 +16,3 @@ export const Template = ({ ...args }) => {
16
16
  <Canvas withToolbar>
17
17
  <Story of={AppBannerStories.AppBanner} />
18
18
  </Canvas>
19
-
@@ -1,19 +1,21 @@
1
1
  import appBanner from './appBanner.hbs'
2
+ import nativeAppBanner from './nativeAppBanner.hbs'
2
3
 
3
4
  const Template = ({ ...args }) => {
4
5
  // You can either use a function to create DOM elements or use a plain html string!
5
6
  // return `<div>${appBanner}</div>`;
6
7
  return appBanner({ ...args })
7
8
  }
8
-
9
+ const NativeTemplate = ({ ...args }) => {
10
+ // You can either use a function to create DOM elements or use a plain html string!
11
+ // return `<div>${nativeAppBanner}</div>`;
12
+ return nativeAppBanner({ ...args })
13
+ }
9
14
  export default {
10
15
  title: 'Komponenten/App Banner',
11
16
 
12
17
  argTypes: {
13
- _text: {
14
- control: 'text',
15
- description: 'Beschriftung der Ortsmarke',
16
- },
18
+
17
19
  },
18
20
 
19
21
  decorators: [
@@ -28,6 +30,15 @@ export const AppBanner = {
28
30
  name: 'AppBanner',
29
31
 
30
32
  args: {
31
- _text: 'AppBanner',
33
+
32
34
  },
33
35
  }
36
+ export const NativeAppBanner = {
37
+ render: NativeTemplate.bind({}),
38
+ name: 'NativeAppBanner',
39
+
40
+ args: {
41
+
42
+ },
43
+ }
44
+
@@ -0,0 +1,44 @@
1
+ import { uxAction } from 'base/tracking/pianoHelper.subfeature'
2
+
3
+ export default function nativeAppBanner() {
4
+ return {
5
+ showBanner: false,
6
+ deferredPrompt: null,
7
+ isAndroid: /Android/i.test(navigator.userAgent),
8
+ init: function () {
9
+ window.addEventListener('beforeinstallprompt', (e) => {
10
+ // Prevent Chrome 67 and earlier from automatically showing the prompt
11
+ e.preventDefault();
12
+ // Stash the event so it can be triggered later.
13
+ this.deferredPrompt = e;
14
+ // Update UI notify the user they can add to home screen
15
+ if(this.isAndroid){
16
+ this.showBanner = true;
17
+ }
18
+ });
19
+ if(window.IS_STORYBOOK){ this.showBanner = true;}
20
+ },
21
+ installClickHandler: function(){
22
+ if(this.deferredPrompt){
23
+ this.deferredPrompt.prompt();
24
+ // Wait for the user to respond to the prompt
25
+ this.deferredPrompt.userChoice
26
+ .then((choiceResult) => {
27
+ if (choiceResult.outcome === 'accepted') {
28
+ uxAction('nativeAppBanner::promt::accepted');
29
+ console.log('User accepted the A2HS prompt');
30
+ } else {
31
+ uxAction('nativeAppBanner::promt::dismissed');
32
+ console.log('User dismissed the A2HS prompt');
33
+ }
34
+ this.deferredPrompt = null;
35
+ });
36
+ }
37
+ this.showBanner = false
38
+ },
39
+ closeClickHandler: function(){
40
+ uxAction('nativeAppBanner::bannerClosed');
41
+ this.showBanner = false
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,27 @@
1
+ <div
2
+ x-data="nativeAppBanner()" x-cloak x-show="showBanner" ax-load x-ignore
3
+ id="marketing-banner" tabindex="-1" class="fixed bottom-0 z-50 flex flex-row justify-end w-full gap-4 p-4 -translate-x-1/2 flex-nowrap bg-blue-aqua lg:max-w-7xl left-1/2">
4
+ <div class="flex flex-row items-center gap-4 grow">
5
+ <div class="flex items-center justify-center rounded-lg w-11 h-11 bg-blue-congress-hex shrink-0">
6
+ <img width="24" height="24" src="{{resourceUrl "assets/base/icons/logo/brandlogo--mobile.min.svg" _brand=(defaultIfEmpty this.brand "hessenschau")}}"
7
+ class="w-7 h-7" alt="{{loca "meta_application_name"}}">
8
+ </div>
9
+ <div class="flex flex-col items-start text-sm sm:text-base font-heading">
10
+ <span class="font-bold">hessenschau App</span>
11
+ <span>Kostenlos bei Google Play</span>
12
+ </div>
13
+ </div>
14
+ <div class="flex items-center gap-4 ">
15
+ {{#> components/button/button _size="md" _alpineClick="installClickHandler"}}
16
+ {{> components/button/components/button_label _label="Laden" _css="text-sm sm:text-base"}}
17
+ {{/components/button/button}}
18
+ {{#> components/button/button _size="md" _variant="tertiary" _css="h-10" _alpineClick="closeClickHandler"}}
19
+ {{> components/button/components/button_icon _icon="close" _css="" _iconmap="icons"}}
20
+ {{> components/button/components/button_label _label="schließen" _css="sr-only"}}
21
+ {{/components/button/button}}
22
+ </div>
23
+ </div>
24
+
25
+
26
+
27
+