hr-design-system-handlebars 1.11.12 → 1.12.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 (110) hide show
  1. package/.storybook/main.js +9 -0
  2. package/.storybook/manager.js +18 -18
  3. package/.storybook/preview.js +9 -1
  4. package/CHANGELOG.md +12 -0
  5. package/README.md +13 -2
  6. package/build/handlebars/handlebars.js +1 -1
  7. package/build/scripts/build.js +1 -1
  8. package/config.js +1 -0
  9. package/dist/assets/index.css +223 -190
  10. package/dist/views/components/base/image/icon.hbs +1 -1
  11. package/dist/views/components/base/link.hbs +11 -1
  12. package/dist/views/components/base/link_open.hbs +12 -13
  13. package/dist/views/components/base/link_v2.hbs +14 -0
  14. package/dist/views/components/button/button.hbs +9 -24
  15. package/dist/views/components/button/components/button_icon.hbs +2 -1
  16. package/dist/views/components/button/components/button_label.hbs +1 -1
  17. package/dist/views/components/button/link_button.hbs +6 -0
  18. package/dist/views/components/button/utilities/button_base_classes.hbs +1 -0
  19. package/dist/views/components/button/utilities/button_dimension_classes.hbs +1 -0
  20. package/dist/views/components/button/utilities/button_on_image_classes.hbs +39 -0
  21. package/dist/views/components/button/utilities/button_variation_classes.hbs +14 -0
  22. package/dist/views/components/content_nav/content_nav_container.hbs +1 -1
  23. package/dist/views/components/content_nav/content_nav_item.hbs +1 -1
  24. package/dist/views/components/event/calendar/event_calendar_footer.hbs +1 -1
  25. package/dist/views/components/event/event_ticket_button.hbs +11 -9
  26. package/dist/views/components/grid/grid_group_highlight.hbs +1 -1
  27. package/dist/views/components/label/label_old.hbs +1 -1
  28. package/dist/views/components/mediaplayer/media_player.hbs +4 -22
  29. package/dist/views/components/mediaplayer/mediaplayer_button.hbs +9 -0
  30. package/dist/views/components/modal/modal.hbs +2 -2
  31. package/dist/views/components/site_header/brand_navigation/brand_navigation.hbs +1 -1
  32. package/dist/views/components/teaser/cluster/teaser_cluster.hbs +4 -1
  33. package/dist/views/components/teaser/cluster/teaser_cluster_byline.hbs +1 -1
  34. package/dist/views/components/teaser/cluster/teaser_cluster_item.hbs +1 -1
  35. package/dist/views/components/teaser/components/teaser_av_consumption_close_button.hbs +6 -20
  36. package/dist/views/components/teaser/components/teaser_byline.hbs +1 -1
  37. package/dist/views/components/teaser/components/teaser_image.hbs +6 -14
  38. package/dist/views/components/teaser/podcast/podcast_subscribe_button.hbs +18 -15
  39. package/dist/views/components/teaser/podcast/podcast_title.hbs +2 -2
  40. package/dist/views/components/teaser/tabbox/group_tabbox.hbs +4 -1
  41. package/dist/views/components/teaser/tabbox/teaser_tabbox.hbs +10 -11
  42. package/dist/views/components/teaser/teaser_poster.hbs +5 -1
  43. package/gulpfile.js +9 -0
  44. package/package.json +4 -2
  45. package/src/assets/css/custom-components.css +37 -38
  46. package/src/assets/css/custom-utilities.css +2 -2
  47. package/src/assets/fixtures/event/calendar/event_calendar_months.inc.json +5 -1
  48. package/src/assets/tailwind.css +54 -22
  49. package/src/stories/conventions-and-datastructure.mdx +217 -4
  50. package/src/stories/views/components/base/image/icon.hbs +1 -1
  51. package/src/stories/views/components/base/link.hbs +11 -1
  52. package/src/stories/views/components/base/link_open.hbs +12 -13
  53. package/src/stories/views/components/base/link_v2.hbs +14 -0
  54. package/src/stories/views/components/button/button.hbs +9 -24
  55. package/src/stories/views/components/button/button.mdx +186 -0
  56. package/src/stories/views/components/button/button.stories.js +508 -0
  57. package/src/stories/views/components/button/components/button_icon.hbs +2 -1
  58. package/src/stories/views/components/button/components/button_icon.mdx +25 -0
  59. package/src/stories/views/components/button/components/button_icon.stories.js +44 -0
  60. package/src/stories/views/components/button/components/button_label.hbs +1 -1
  61. package/src/stories/views/components/button/components/button_label.mdx +25 -0
  62. package/src/stories/views/components/button/components/button_label.stories.js +33 -0
  63. package/src/stories/views/components/button/link_button.hbs +6 -0
  64. package/src/stories/views/components/button/link_button.mdx +137 -0
  65. package/src/stories/views/components/button/link_button.stories.js +420 -0
  66. package/src/stories/views/components/button/utilities/button_base_classes.hbs +1 -0
  67. package/src/stories/views/components/button/utilities/button_dimension_classes.hbs +1 -0
  68. package/src/stories/views/components/button/utilities/button_on_image_classes.hbs +39 -0
  69. package/src/stories/views/components/button/utilities/button_variation_classes.hbs +14 -0
  70. package/src/stories/views/components/content_nav/content_nav_container.hbs +1 -1
  71. package/src/stories/views/components/content_nav/content_nav_item.hbs +1 -1
  72. package/src/stories/views/components/event/calendar/event_calendar_footer.hbs +1 -1
  73. package/src/stories/views/components/event/event_ticket_button.hbs +11 -9
  74. package/src/stories/views/components/grid/grid_group_highlight.hbs +1 -1
  75. package/src/stories/views/components/label/label_old.hbs +1 -1
  76. package/src/stories/views/components/mediaplayer/media_player.hbs +4 -22
  77. package/src/stories/views/components/mediaplayer/mediaplayer_button.hbs +9 -0
  78. package/src/stories/views/components/mediaplayer/mediaplayer_button.mdx +82 -0
  79. package/src/stories/views/components/mediaplayer/mediaplayer_button.stories.js +178 -0
  80. package/src/stories/views/components/modal/modal.hbs +2 -2
  81. package/src/stories/views/components/site_header/brand_navigation/brand_navigation.hbs +1 -1
  82. package/src/stories/views/components/teaser/cluster/teaser_cluster.hbs +4 -1
  83. package/src/stories/views/components/teaser/cluster/teaser_cluster_byline.hbs +1 -1
  84. package/src/stories/views/components/teaser/cluster/teaser_cluster_item.hbs +1 -1
  85. package/src/stories/views/components/teaser/components/teaser_av_consumption_close_button.hbs +6 -20
  86. package/src/stories/views/components/teaser/components/teaser_byline.hbs +1 -1
  87. package/src/stories/views/components/teaser/components/teaser_image.hbs +6 -14
  88. package/src/stories/views/components/teaser/fixtures/teaser_event_calendar_100_serif.json +1 -1
  89. package/src/stories/views/components/teaser/podcast/podcast_subscribe_button.hbs +18 -15
  90. package/src/stories/views/components/teaser/podcast/podcast_title.hbs +2 -2
  91. package/src/stories/views/components/teaser/tabbox/group_tabbox.hbs +4 -1
  92. package/src/stories/views/components/teaser/tabbox/teaser_tabbox.hbs +10 -11
  93. package/src/stories/views/components/teaser/teaser_poster.hbs +5 -1
  94. package/tailwind.config.js +8 -1
  95. package/dist/views/components/button/button_pseudo.hbs +0 -8
  96. package/dist/views/components/button/button_pseudo.inc.hbs +0 -18
  97. package/dist/views/components/button/button_pseudo_v2.hbs +0 -12
  98. package/dist/views/components/button/button_round.hbs +0 -23
  99. package/dist/views/components/button/button_round_classes.hbs +0 -46
  100. package/dist/views/components/button/button_transparent.hbs +0 -17
  101. package/dist/views/components/button/button_v2.hbs +0 -7
  102. package/dist/views/components/button/components/button_pseudo_link.hbs +0 -3
  103. package/src/stories/views/components/button/button_pseudo.hbs +0 -8
  104. package/src/stories/views/components/button/button_pseudo.inc.hbs +0 -18
  105. package/src/stories/views/components/button/button_pseudo_v2.hbs +0 -12
  106. package/src/stories/views/components/button/button_round.hbs +0 -23
  107. package/src/stories/views/components/button/button_round_classes.hbs +0 -46
  108. package/src/stories/views/components/button/button_transparent.hbs +0 -17
  109. package/src/stories/views/components/button/button_v2.hbs +0 -7
  110. package/src/stories/views/components/button/components/button_pseudo_link.hbs +0 -3
@@ -4,6 +4,18 @@ import { Meta, Canvas } from '@storybook/addon-docs'
4
4
 
5
5
  # Konventionen und Datenstrukturen
6
6
 
7
+ - [Übersicht](#übersicht)
8
+ - [Aufbau der Datenstruktur des Designsystems](#aufbau-der-datenstruktur-des-designsystems)
9
+ - [Namenskonventionen](#namenskonventionen)
10
+ - [Stories](#stories)
11
+ - [Handlebar-Komponenten](#handlebar-komponenten)
12
+ - [JSON](#json)
13
+ - [Konventionen beim Bau von Komponenten](#konventionen-beim-bau-von-komponentenn)
14
+ - [Styling von Komponenten](#styling-von-komponenten)
15
+ - [Wiederverwendbarkeit und Erweiterbarkeit von Komponenten](#wiederverwendbarkeit-und-erweiterbarkeit-von-komponenten)
16
+
17
+ ## Übersicht
18
+
7
19
  Dieses Kapitel richtet sich vor allem an die Entwickler des Designsystems. Es erläutert den grundlegenden Aufbau der Datenstruktur und legt Konventionen für die Benennung von Dateien fest.
8
20
 
9
21
  ## Aufbau der Datenstruktur des Designsystems
@@ -159,7 +171,11 @@ svg_optimization.stories.mdx`}
159
171
  </pre>
160
172
  </div>
161
173
 
162
- ### Handlebar Komponenten
174
+ ### Handlebar-Komponenten
175
+
176
+ Bei der Erstellung von Handlebar-Komponenten müssen verschiedenen Namenskonvention eingehalten werden.
177
+
178
+ #### Namen von Komponenten
163
179
 
164
180
  Für die Namen von Handlebar-Komponenten gelten die gleichen Regeln wie für Stories.
165
181
 
@@ -192,8 +208,11 @@ Namen und deren einzelnen Bestandteile sind immer auszuschreiben. Abkürzungen s
192
208
  <pre class="!bg-white !p-4 !leading-8">{`brand_navigation_item.hbs`}</pre>
193
209
  </div>
194
210
 
211
+ #### Namen von Komponenten-Parametern
212
+
195
213
  Die Namen von Parametern in Handlebar-Komponenten sind, anders als der Datainame, in
196
- [Camel-Case](https://en.wikipedia.org/wiki/Camel_case) Notation zu schreiben.
214
+ [Camel-Case](https://en.wikipedia.org/wiki/Camel_case) Notation zu schreiben und mit einem Unterstrich
215
+ zu prefixen.
197
216
 
198
217
  <div class="bg-red-200 !mt-4 p-4">
199
218
  <h4 class="!text-red-900 font-bold">Falsch</h4>
@@ -204,11 +223,58 @@ Die Namen von Parametern in Handlebar-Komponenten sind, anders als der Datainame
204
223
  <div class="bg-green-200 !mt-4 p-4">
205
224
  <h4 class="!text-green-900 font-bold">Korrekt</h4>
206
225
  <pre class="!bg-white !p-4 !leading-8">
207
- &#123;&#123;#>components/base/link cssClasses="" isAriaHidden=true
208
- clickLabelPrefix2="mediaLink"&#125;&#125;
226
+ &#123;&#123;#>components/base/link _cssClasses="" _isAriaHidden=true
227
+ _clickLabelPrefix2="mediaLink"&#125;&#125;
209
228
  </pre>
210
229
  </div>
211
230
 
231
+ #### Namen übergebener Komponenten-Parameter in Partial-Blocks und Inline-Partials
232
+
233
+ Sollen an Subkomponenten, die in Partial-Blocks und/oder Inline-Partials aufgerufen werden Komponenten-Parameter der Parent-Komponente
234
+ übergeben werden, muss an die Namen der zu übergebenden Parameter das Postfix `-adjust_context` angefügt werden.
235
+ Dies ist leider notwendig, da [Handlebars.js](https://handlebarsjs.com) und [Handlebars.java](https://github.com/jknack/handlebars.java)
236
+ innerhalb von Partial-Blocks und Inline-Partials die Datenkontexte anders auflösen. Der Wert des Parameters `_css` kann in
237
+ Handlebars.js direkt, in Handlebars.java aber nur ausgelesen werden, wenn mittels `../../_css` zwei Ebenen nach oben gegangen wird.
238
+ Durch setzen des Postfixes `-adjust_context` können mittels eines Gulp-Skriptes diese Vatriablen in Komponenten herausgefiltert werden
239
+ und je nachdem wofür gerade gebaut wird der Kontext automatisiert angepasst werden oder nicht. Hierzu ein kurzes Beispiel.
240
+
241
+ ```handlebars
242
+ {{#with this}}
243
+ {{> components/base/image/icon _icon="play_button" _addClass="text-media-button fill-white hover:fill-media-button w-10 h-10 inline"}}
244
+ {{#*inline "css"~}}
245
+ {{~> components/button/utilities/button_on_image_classes _isMobile1to1=_isMobile1to1-adjust_context}}
246
+ {{/inline}}
247
+ {{/with}}
248
+ ```
249
+
250
+ Dem Play-Button Icon werden hier in einem Inline-Partial mit der [Style-Komponente](#setzen-kontextabhängiger-css-klassen-mit-style-komponenten)
251
+ `button_on_image_classes` zusätzliche CSS Klassen übergeben. Je nach Wert des Parameters `_isMobile1to1` werden darin unterschiedliche CSS Klassen gesetzt.
252
+ Der Wert dieses Parameters kommt in diesem Beispiel aus einem Parameter gleichen Namens aus dem Parent-Kontext. Damit dieser korrekt von
253
+ den unterschiedlichen Handlebars Implementierungen aufgelöst werden kann, hat er den Postfix `-adjust_context` erhalten. Das oben angesprochene
254
+ Gulp-Skript filtert diesen Parameter jetzt heraus und macht daraus, wenn Storybook mit `yarn storybook` lokal ausgeführt wird wieder den Parameter `_isMobile1to1`.
255
+
256
+ ```handlebars
257
+ {{#with this}}
258
+ {{> components/base/image/icon _icon="play_button" _addClass="text-media-button fill-white hover:fill-media-button w-10 h-10 inline"}}
259
+ {{#*inline "css"~}}
260
+ {{~> components/button/utilities/button_on_image_classes _isMobile1to1=_isMobile1to1}}
261
+ {{/inline}}
262
+ {{/with}}
263
+ ```
264
+
265
+ Anders verhält es sich, wenn mit `yarn build` das Designsystem für die Verwendung im Delivery gebaut wird (dieses Skript wird beim bauen eines Releases
266
+ in Github aufgerufen). Der Parameter `_isMobile1to1-adjust_context` wird jetzt durch `../../_isMobile1to1` ersetzt, sodass auch im Kontext von Handlebars.java
267
+ der Wert des Parameters korrekt ausgelesen werden kann.
268
+
269
+ ```handlebars
270
+ {{#with this}}
271
+ {{> components/base/image/icon _icon="play_button" _addClass="text-media-button fill-white hover:fill-media-button w-10 h-10 inline"}}
272
+ {{#*inline "css"~}}
273
+ {{~> components/button/utilities/button_on_image_classes _isMobile1to1=../../_isMobile1to1}}
274
+ {{/inline}}
275
+ {{/with}}
276
+ ```
277
+
212
278
  ### JSON
213
279
 
214
280
  Im Designsystem werden Testdaten für Komponenten mittels JSON-Dateien bereitgestellt. Auch diese Dateinamen werden in Snake-Case Notation
@@ -238,3 +304,150 @@ sofern sie aus mehreren Worten zusammengesetzt werden, mit Minus voneinander get
238
304
  |— navigation-flyout`}
239
305
  </pre>
240
306
  </div>
307
+
308
+ ## Konventionen beim Bau von Komponenten
309
+
310
+ Bei der Entwicklung neuer Komponenten müssen einige Konventionen beachtet werden.
311
+
312
+ ### Styling von Komponenten
313
+
314
+ Zum Styling von Komponenten verwenden wir das CSS Framework [Tailwind CSS](https://tailwindcss.com/). Tailwind CSS
315
+ ist ein auf dem Utility-First Ansatz basierendes Framework. Für nahezu jede CSS Eigenschaft gibt es eine eigene
316
+ Utility Klasse, mit deren Hilfe die Styles einer Komponente im HTML Markup zusammengesetzt werden. Anstatt
317
+ wie üblich Klassen mit beliebig vielen CSS Eigenschaften zu erstellen, setzen Tailwind CSS Klassen in der Regel
318
+ immer nur jeweils eine einzelne Style Eigenschaft. Auf diese Weise wird ein sehr hohes Maß an Wiederverwendung
319
+ erreicht und die Dateigröße der ausglieferten CSS Dateien ist in der Regel deutlich kleiner als beim klassischen
320
+ Ansatz mit mehreren CSS Eigenschaften pro Klasse.
321
+ Nachteil ist jedoch, dass alle CSS Logik auf diese Weise in die Templates verlagert wird und diese auf den ersten
322
+ Blick recht unübersichtlich wirken können.
323
+
324
+ #### Definition eigener CSS Klassen
325
+
326
+ Tailwind CSS gestattet es auch sehr einfach eigene CSS Klassen zu schreiben. Sollte es für eine bestimmte CSS Eigenschaft
327
+ noch keine eigene Utility Klasse geben, kann diese problemlos in der Datei `custom-utilities.css` definiert werden.
328
+ Auch ist es möglich in der Datei `custom-components.css` eigene, vom Utility-First Ansatz abweichende, Klassen zu schreiben.
329
+
330
+ Von dieser Möglichkeit sollte aber nur in Ausnahmefällen gebrauch gemacht werden, da ansonsten der Vorteil der kleinen Dateigrößen
331
+ sehr schnell zunichte gemacht werden kann.
332
+
333
+ #### Setzen Kontextabhängiger CSS Klassen mit Style-Komponenten
334
+
335
+ An vielen Stellen im Design System müssen CSS Klassen abhängig vom Kontext, in dem die zu stylende Komponente genutzt wird, gesetzt
336
+ werden. Ein Beispiel dafür sind Teaser auf Übersichtsseiten. Wie diese auf der Webseite angezeigt werden sollen, können Redakteure
337
+ auf der Webseite durch setzen entsprechender Parameter dynamisch festlegen.
338
+ Mit der Verwendung von Tailwind CSS und dem Einsatz von Utility Klassen, verlagert sich die ganze Logik aus den CSS Dateien in die
339
+ Komponenten. Als Best-Practice haben sich hierfür separate, ausschließlich CSS Klassen setzende, Handlebar-Komponenten (Style-Komponenten) herausgestellt.
340
+ Diesen Komponenten werden die von den Redakteuren im CMS vorgenommenen Einstellungen als Parameter übergeben. Abhängig von deren Wert
341
+ werden die entsprechenden CSS Utility Klassen gesetzt. Style-Komponenten können beliebig oft und an beliebigen Stellen wiederverwendet werden.
342
+
343
+ ### Wiederverwendbarkeit und Erweiterbarkeit von Komponenten
344
+
345
+ Damit nicht bei jeder neuen Anforderung das Rad neu erfunden werden muss, ist es wichtig, dass
346
+ beim Bau von Komponenten auf ein hohes Maß an Wiederverwendbarkeit sowie eine
347
+ gute und einfache Erweiterbarkeit geachtet wird.
348
+ Komponenten sollten demgemäß möglichst einfach gehalten und nicht mit einer vielzahl an Features überladen werden.
349
+
350
+ Ein gutes Beispiel, wie man es nicht machen sollte ist die Button-Komponente. Bei ihr wurde versucht alle Anforderungen,
351
+ die an einen Button gestellt wurden in einer einzigen Komponente abzubilden. Dies ging bei den initialen Anforderungen
352
+ noch halbwegs, aber je mehr zusätzliche Anforderungen und Features im Laufe der Zeit hinzukamen, desto unübersichtlicher
353
+ und schlechter wartbar wurde die Komponente. Am Ende hatte die Komponente fast zwanzig Parameter, mit denen ihr Verhalten
354
+ gesteuert werden konnte und sie war zu einem richtigen "Monster" angewachsen.
355
+ Aus diesem Grund wurde sie umgebaut und vereinfacht. Gemäß dem Prinzip der "[Component Selfishness](https://www.smashingmagazine.com/2023/01/key-good-component-design-selfishness/)"
356
+ rendert die Komponente nur noch den Rahmen eines Buttons. Alle Inhalte, wie das Label oder ein mögliches Icon,
357
+ werden dem Button mit Hilfe von Subkomponenten hinzugefügt.
358
+
359
+ #### Erweitern von Basis-Komponenten mit Subkomponenten
360
+
361
+ Um einer Basis-Komponente weitere Inhalte mittels Subkomponenten hinzuzufügen, sieht Handlebars das Konzept der
362
+ sogenannten "[Partial-Blocks}(https://handlebarsjs.com/guide/partials.html#partial-blocks)" vor. Mit `@partial-block`
363
+ stellt Handlebars hierfür ein spezielles Partial bereit. Es erlaubt in einer Basis-Komponente, wie z.B. der Button-Komponente,
364
+ an einer bestimmten Stelle im Markup einen Platzhalter für mögliche Subkomponenten anzugeben.
365
+ Schauen wir uns das ganze anhand der Button-Komponente an.
366
+
367
+ ```handlebars
368
+ <button>
369
+ {{> @partial-block }}
370
+ </button>
371
+ ```
372
+
373
+ Die Komponente rendert lediglich das Markup des Button-Elements (alle HTML-Properties des Button wurden der besseren Übersichtlichkeit halber an
374
+ dieser Stelle weggelassen) und ruft das `@partial-block` Partial auf. Der Button Komponente können jetzt, wie nachfolgend gezeigt, Subkomponenten hinzugefügt
375
+ werden.
376
+
377
+ ```handlebars
378
+ {{#> components/button/button _size="lg"}}
379
+ {{> components/button/components/button_label _label="Icon rechts"}}
380
+ {{> components/button/components/button_icon _icon="arrow-right" _iconmap="icons"}}
381
+ {{/components/button/button}}
382
+ ```
383
+
384
+ Auf diese Weise ist es möglich neue Funktionen sehr einfach über Subkomponenten hinzuzufügen.
385
+
386
+ #### Komponenten mit Inline-Partials um zusätzliche Eigenschaften Erweitern
387
+
388
+ Wie im vorigen Abschnitt erläutert, können Basis-Komponenten mit Hilfe des `@partial-block` Partials
389
+ sehr gut mit Hilfe von Subkomponenten erweitert werden. Sollen jedoch einem von einer Komponente gerenderten HTML-Element
390
+ dynamisch weitere Eigenschaften (z.B. über Style-Komponenten bereitgestellte CSS-Klassen) übergeben werden,
391
+ ist dies auf diesem Wege nicht möglich. Hierfür lassen sich in Handlebars sogenannte [`Inline-Partials`](https://handlebarsjs.com/guide/partials.html#inline-partials)
392
+ nutzen. Deren Gebrauch lässt sich am besten mit einem Beispiel erläutern.
393
+
394
+ Für den Abonieren-Button in der Podcast-Player-Komponente wird die Button-Komponente verwendet.
395
+ Diese setzt standardmäßig verschiedenen HTML-Properties im HTML-Button-Element. Der Abonieren-Button
396
+ benötigt darüber hinaus weitere HTML-Properties. Diese sind aber so speziell, dass sie nicht der
397
+ Button-Komponente als weitere Standard-HTML-Properties hinzugefügt wurden. Stattdessen wurde mit einem
398
+ `Inline-Partial` die Möglichkeit geschaffen der Button-Komponente dynamisch beliebige weitere HTML-Properties
399
+ zu übergeben.
400
+
401
+ ```handlebars
402
+ <button class="ds-button" {{#> html_properties}}{{/html_properties}}>
403
+ {{> @partial-block }}
404
+ </button>
405
+ ```
406
+
407
+ Das Beispiel zeigt eine vereinfachte (aus Gründen der Übersichtlichkeit wurden alle anderen HTML-Properties weggelassen)
408
+ Ansicht der Button-Komponente. Innerhalb des HTML-Button-Elements wird hier das Inline-Partial `html_properties`
409
+ aufgerufen. Der Inhalt dieses Partials kann, wie im folgenden Codebeispiel zu sehen, gesetzt werden.
410
+
411
+ ```handlebars
412
+ {{#with this}}
413
+ {{#> components/button/button _size="md" _disableButtonPress=true}}
414
+ {{>components/button/components/button_label _label="Abonnieren" _css="flex-1 truncate mr-2" _type="button"}}
415
+ <span x-cloak x-show="open" class="w-3 h-3">
416
+ {{> components/base/image/icon _icon='arrow-up' _addClass="flex self-center w-3 h-3 fill-white" }}
417
+ </span>
418
+ <span x-show="!open" class="w-3 h-3">
419
+ {{> components/base/image/icon _icon='arrow-down' _addClass="flex self-center w-3 h-3 fill-white" }}
420
+ </span>
421
+ {{/components/button/button}}
422
+ {{#*inline "html_properties"}}
423
+ x-ref="button"
424
+ x-on:click="toggle()"
425
+ :aria-expanded="open"
426
+ :aria-controls="$id('dropdown-button')"
427
+ :class="open ? 'drop-shadow' : ''"
428
+ data-hr-click-tracking='{"settings": [{"type": "uxAction", "clickLabel": "podcastAbonnieren:ButtonClick"}]}'
429
+ {{/inline}}
430
+ {{/with}}
431
+ ```
432
+
433
+ Unterhalb des Aufrufs der Button-Komponente wird hier das Inline-Partial `html_properties` implementiert. Ein Inline-Partial
434
+ muss immer in der Form `{{#*inline NAME_DES_PARTIALS}}` aufgerufen werden. Alle Inhalte die zwischen öffnendem und schließenden
435
+ `inline` stehen, werden in der Komponente in der dieses Inline-Partial aufgerufen wird gerendert.
436
+
437
+ Zu Beachten ist, dass, wie hier im Codebeispiel zu sehen, der Aufruf der Komponente und die Definition des Inline-Partials Von
438
+ einem `with` Block umschlossen werden sollten. Auf diese Weise wird sichergestellt, dass ausschließlich die hier aufgerufene
439
+ Button-Komponente die zusätzlichen Eigenschaften erhält. Würde der `with` Block weggelassen und irgendwo im weitere
440
+ Verlauf der Seite ein weiteres Mal die Button-Komponente aufgerufen, würde auch das HTML-Button-Element in dieser Komponente
441
+ diese zuätzlichen HTML-Properties rendern.
442
+
443
+ <div class="bg-blue-200 !mt-4 p-4">
444
+ <h4 class="!text-stone-950 font-bold">Wichtig</h4>
445
+ <p>
446
+ Sollen beim Aufruf von Subkomponenten in einem Partial-Block oder einem Inline-Partial
447
+ Hash-Parameter (`_NAME_DES_PARAMETERS`) der umliegenden Komponente übergeben werden, muss
448
+ die [hier](#namen-übergebener-komponenten-parameter-in-partial-blocks-und-inline-partials)
449
+ beschriebene Namenskonvention zwingend eingehalten werden. Aufgrund von Unterschieden beim
450
+ Auflösen der Kontexte zwischen Handlebars.js und Handlebars.java können andernfalls die
451
+ Werte der Parameter nicht ausgelesen werden.
452
+ </p>
453
+ </div>
@@ -40,7 +40,7 @@ Erklärung / Hinweise / Best Practices für "Accessible SVG":
40
40
 
41
41
  --}}
42
42
  {{#if _icon}}
43
- <svg class="sb-icon {{~#if _addClass }} {{_addClass}}{{/if}} {{#if _webview}} -webview{{/if}}" role="presentation" aria-hidden="{{defaultIfEmpty _ariaHidden true}}"
43
+ <svg class="sb-icon {{~#if _addClass }} {{_addClass}}{{/if}} {{#if _webview}} -webview{{/if}} {{#>css}}{{/css}}" role="presentation" aria-hidden="{{defaultIfEmpty _ariaHidden true}}"
44
44
  {{# if brand}} data-brand="{{brand}}"{{/if}}
45
45
  {{~#if _iconTitle }} {{changeRandom~}}
46
46
  aria-labelledby="iconTitle--{{getRandom}}"
@@ -1,3 +1,13 @@
1
- {{> components/base/link_open _clickLabelPrefix1=_clickLabelPrefix1 _clickLabelPrefix2=_clickLabelPrefix2 _clickLabelType=_clickLabelType _css=_css _doNavigationTracking=_doNavigationTracking _isAriaHidden=_isAriaHidden _isSelected=_isSelected _selectedCssClass=_selectedCssClass}}
1
+ <a {{#with this.link.webviewUrl}}data-webviewurl="{{this}}"{{/with}} href="{{this.link.url}}{{#if this.hasComments}}#commentList{{/if}}"
2
+ class="sb-link ds-link js-load{{#if _css}} {{_css}}{{/if}} {{#if _isSelected}} {{defaultIfEmpty _selectedCssClass "-current"}}{{/if}}"
3
+ {{#if _doNavigationTracking}}
4
+ data-hr-click-tracking='{"settings": [{"type":"uxAction","secondLevelId": "1","clickLabel":"{{_clickLabelType}}{{#if _clickLabelPrefix1}}::{{_clickLabelPrefix1}}{{/if}}::{{_clickLabelPrefix2}}-Link geklickt"}]}'
5
+ {{/if}}
6
+ {{#if this.isFileDownload}}
7
+ {{#with this.trackingData}}data-hr-click-tracking='{"settings": [{"type":"download","secondLevelId": "{{this.link.secondLevelId}}","clickLabel": "{{this.link.pageName}}"}]}'{{/with}}
8
+ {{/if}}
9
+ {{#if this.link.isTargetBlank}} target="_blank" rel="noopener{{#if this.link.hasNoReferrerFlag}} noreferrer{{/if}}"{{/if}}
10
+ {{#if _isAriaHidden}} aria-hidden="true" tabindex="-1"{{/if}}
11
+ >
2
12
  {{~ decorator_body ~}}
3
13
  </a>
@@ -1,13 +1,12 @@
1
- {{#with this.link}}
2
- <a {{#with this.webviewUrl}}data-webviewurl="{{this}}"{{/with}} href="{{this.url}}{{#if ../this.hasComments}}#commentList{{/if}}"
3
- class="sb-link js-load{{#if ../_css}} {{../_css}}{{/if}} {{#if ../_isSelected}} {{defaultIfEmpty ../_selectedCssClass "-current"}}{{/if}}"
4
- {{#if ../_doNavigationTracking}}
5
- data-hr-click-tracking='{"settings": [{"type":"uxAction","secondLevelId": "1","clickLabel":"{{../_clickLabelType}}{{#if ../_clickLabelPrefix1}}::{{../_clickLabelPrefix1}}{{/if}}::{{../_clickLabelPrefix2}}-Link geklickt"}]}'
6
- {{/if}}
7
- {{#if ../this.isFileDownload}}
8
- {{#with ../this.trackingData}}data-hr-click-tracking='{"settings": [{"type":"download","secondLevelId": "{{this.secondLevelId}}","clickLabel": "{{this.pageName}}"}]}'{{/with}}
9
- {{/if}}
10
- {{#if this.isTargetBlank}} target="_blank" rel="noopener{{#if this.hasNoReferrerFlag}} noreferrer{{/if}}"{{/if}}
11
- {{#if ../_isAriaHidden}} aria-hidden="true" tabindex="-1"{{/if}}
12
- >
13
- {{/with}}
1
+ <a {{#with this.link.webviewUrl}}data-webviewurl="{{this}}"{{/with}} href="{{this.link.url}}{{#if this.hasComments}}#commentList{{/if}}"
2
+ class="sb-link ds-link js-load {{#if _isSelected}} {{defaultIfEmpty _selectedCssClass "-current"}}{{/if}}{{#if _css}} {{_css}}{{/if}} {{#> css}}{{/css}}"
3
+ {{#if _doNavigationTracking}}
4
+ data-hr-click-tracking='{"settings": [{"type":"uxAction","secondLevelId": "1","clickLabel":"{{_clickLabelType}}{{#if _clickLabelPrefix1}}::{{_clickLabelPrefix1}}{{/if}}::{{_clickLabelPrefix2}}-Link geklickt"}]}'
5
+ {{/if}}
6
+ {{#if this.isFileDownload}}
7
+ {{#with this.trackingData}}data-hr-click-tracking='{"settings": [{"type":"download","secondLevelId": "{{this.link.secondLevelId}}","clickLabel": "{{this.link.pageName}}"}]}'{{/with}}
8
+ {{/if}}
9
+ {{#if this.link.isTargetBlank}} target="_blank" rel="noopener{{#if this.link.hasNoReferrerFlag}} noreferrer{{/if}}"{{/if}}
10
+ {{#if _isAriaHidden}} aria-hidden="true" tabindex="-1"{{/if}}
11
+ >
12
+
@@ -0,0 +1,14 @@
1
+ <a {{#with this.link.webviewUrl}}data-webviewurl="{{this}}"{{/with}} href="{{this.link.url}}{{#if this.hasComments}}#commentList{{/if}}"
2
+ class="sb-link ds-link js-load {{#if _isSelected}} {{defaultIfEmpty _selectedCssClass "-current"}}{{/if}}{{#if _css}} {{_css}}{{/if}} {{#> css}}{{/css}}"
3
+ {{#if _doNavigationTracking}}
4
+ data-hr-click-tracking='{"settings": [{"type":"uxAction","secondLevelId": "1","clickLabel":"{{_clickLabelType}}{{#if _clickLabelPrefix1}}::{{_clickLabelPrefix1}}{{/if}}::{{_clickLabelPrefix2}}-Link geklickt"}]}'
5
+ {{/if}}
6
+ {{#if this.isFileDownload}}
7
+ {{#with this.trackingData}}data-hr-click-tracking='{"settings": [{"type":"download","secondLevelId": "{{this.link.secondLevelId}}","clickLabel": "{{this.link.pageName}}"}]}'{{/with}}
8
+ {{/if}}
9
+ {{#if this.link.isTargetBlank}} target="_blank" rel="noopener{{#if this.link.hasNoReferrerFlag}} noreferrer{{/if}}"{{/if}}
10
+ {{#if _isAriaHidden}} aria-hidden="true" tabindex="-1"{{/if}}
11
+ >
12
+
13
+ {{> @partial-block }}
14
+ </a>
@@ -1,30 +1,15 @@
1
- <button
2
- {{~#if _aria}} aria-label="{{_aria}}"{{/if}}
3
- {{~#if _isButton}} type="button"{{else}} type="submit"{{/if~}}
1
+ <button
2
+ {{#if _id}} id="{{_id}}"{{/if}}
3
+ class="ds-button {{> components/button/utilities/button_base_classes}} {{> components/button/utilities/button_variation_classes _variant=_variant _onBackground=_onBackground _disableButtonPress=_disableButtonPress}} {{> components/button/utilities/button_dimension_classes _size=_size}}{{#if _css}} {{_css}}{{/if}} {{#> css}}{{/css}}{{#if _openModal}} js-modalButton{{/if}}"
4
+ {{#if _openModal}} aria-haspopup="true"{{/if}}
5
+ {{~#if _ariaLabel}} aria-label="{{_ariaLabel}}"{{/if}}
6
+ type="{{defaultIfEmpty _type "submit"}}"
4
7
  {{~#if _name}} name="{{_name}}"{{/if}}
5
- {{~#if _title}} title="{{_title}}"{{/if}}
6
- class="{{_addClass}}{{#if _addClass2}} {{_addClass2}}{{/if}}{{#if _buttonColor}} {{_buttonColor}}{{/if}}{{#if _buttonSpace}} {{> components/button/button_round_classes _teaserSize=_teaserSize _teaserType=_teaserType _isMobile1to1=_isMobile1to1}}{{/if}}{{#if _webview}} -webview{{/if}}"
8
+ {{~#if _title}} title="{{_title}}"{{/if}}
7
9
  {{~#if _value}} value="{{_value}}"{{/if}}
8
10
  {{~#if _alpineClick}} @click="{{_alpineClick}}"{{/if}}
9
11
  {{~#if _x-show}} x-show="{{_x-show}}"{{/if}}
10
12
  {{~#if _noFocus}} tabindex="-1"{{/if}}
11
- >
12
- {{~#if _showIcon~}}
13
- {{> components/base/image/icon
14
- _icon=_icon
15
- _iconmap=_iconmap
16
- _addClass=_addIconClass
17
- _webview=_webview
18
- _ariaHidden=false
19
- _iconTitle=false
20
- _iconDesc=false
21
- _iconText=false
22
- _overlayIcon=false
23
- }}
24
- {{/if~}}
25
- {{~#if _label~}}
26
- <span {{#if _srOnly}}class="sr-only"{{/if}}>
27
- {{~_label~}}
28
- </span>
29
- {{/if~}}
13
+ {{#> html_properties}}{{/html_properties}}>
14
+ {{> @partial-block }}
30
15
  </button>
@@ -0,0 +1,186 @@
1
+ import { ArgsTable, Meta, Story, Canvas } from '@storybook/blocks'
2
+ import * as ButtonStories from './button.stories'
3
+
4
+ <Meta of={ButtonStories} />
5
+
6
+ # Button
7
+
8
+ - [Übersicht](#übersicht)
9
+ - [Eigenschaften](#eigenschaften)
10
+ - [Varianten](#varianten)
11
+ - [Verwendung](#verwendung)
12
+
13
+ ## Übersicht
14
+
15
+ Buttons erlauben es eine Aktion oder ein Ereignis mit einem Klick auszulösen. Sie werden z.B. in der Navigation einer Tab-Box verwendet, um zwischen
16
+ den unterschiedlichen Tabs umzuschalten oder werden genutzt, um ein ein Modal zu öffnen.
17
+ Soll die Schaltfläche optisch wie ein Button aussehen, bei einem Klick aber eine neue Seite öffnen, darf nicht die Button-Komponente genutzt werden.
18
+ Für diesen Anwendungsfall gibt es mit dem Button-Link eine eigene Komponente. Sie erzeugt technisch ein HTML Link Element,
19
+ das optisch genauso wie ein Button aussieht. Beispiele hierfür sind die Schaltfläche am unteren Rand einer Tab-Box, die es
20
+ ermöglicht auf eine Seite mit weiteren Inhalten zu kommen, die Schaltfläche innerhalb eines Cluster-Teasers, die auf eine Seite mit weiteren Beiträgen verlinkt
21
+ oder die Schaltfläche innerhalb eines Poster-Teasers, die auf den konkreten Inhalt verlinkt.
22
+
23
+ Die Button-Komponente als solches ist sehr einfach gehalten. Sie stellt nur ein Grundgerüst (ein gestyltes HTML-Button Element) zur Verfügung.
24
+ Alle Inhalte des Buttons, wie das [Label](?path=/docs/komponenten-buttons-komponenten-label--label) oder ein mögliches
25
+ [Icon](?path=/docs/komponenten-buttons-komponenten-icon--icon), können flexibel durch Subkomponenten hinzugefügt werden.
26
+
27
+ <Canvas>
28
+ <Story of={ButtonStories.Spielplatz} />
29
+ </Canvas>
30
+
31
+ ## Eigenschaften
32
+
33
+ <ArgsTable story="Spielplatz" />
34
+
35
+ ## Varianten
36
+
37
+ Auf einer Inhaltsseite kann mehr als ein Button platziert werden. Um wichtige von weniger wichtigen Aktionen
38
+ unterscheidbar zu machen, sind unterschiedliche optische Varianten und Größen von Buttons zu verwenden.
39
+
40
+ ### Größen
41
+
42
+ <Canvas>
43
+ <Story of={ButtonStories.ButtonLg} />
44
+ <Story of={ButtonStories.ButtonMd} />
45
+ <Story of={ButtonStories.ButtonSm} />
46
+ </Canvas>
47
+
48
+ ### Button-Arten
49
+
50
+ <Canvas>
51
+ <Story of={ButtonStories.ButtonPrimary} />
52
+ <Story of={ButtonStories.ButtonSecondary} />
53
+ <Story of={ButtonStories.ButtonTertiary} />
54
+ </Canvas>
55
+
56
+ ### Button mit Icon <a id="button-icon" />
57
+
58
+ <Canvas>
59
+ <Story of={ButtonStories.ButtonIconRechts} />
60
+ <Story of={ButtonStories.ButtonIconLinks} />
61
+ </Canvas>
62
+
63
+ ## Verwendung
64
+
65
+ Ein Button wird mit der Handlebar Komponente `button` eingebunden. Wie einleitend schon beschrieben, stellt diese
66
+ Komponente lediglich das Grundgerüst eines Buttons dar. Die Beschriftung und/oder ein Icon müssen mit Subkomponenten hinzugefügt
67
+ werden.
68
+
69
+ <div class="bg-blue-200 !mt-4 p-4">
70
+ <h4 class="!text-stone-950 font-bold">Hinweis</h4>
71
+
72
+ <p>
73
+ Sowohl die Button-Komponente als auch die Subkomponenten Button-Label und Button-Icon sind
74
+ standardmäßig bereits gestyled. Das setzen von zusätzlichen Style Klassen über den Parameter{' '}
75
+ <pre class="inline">\_css</pre> ist zwar bei jeder Komponente möglich, sollte aber nur dann
76
+ gemacht werden, wenn es gar nicht anders geht.
77
+ </p>
78
+ </div>
79
+
80
+ ### Button mit Text
81
+
82
+ Ein Button der Ausprägung `primary` mit Beschriftung wird, wie in folgendem Codebeispiel gezeigt, gebaut.
83
+
84
+ <Canvas>
85
+ <Story of={ButtonStories.ButtonPrimary} />
86
+ </Canvas>
87
+
88
+ ```handlebars
89
+ {{#> components/button/button _size="lg"}}
90
+ {{> components/button/components/button_label _label="Primary"}}
91
+ {{/components/button/button}}
92
+ ```
93
+
94
+ ### Button mit Text und Icon
95
+
96
+ Ein Button der Ausprägung `primary` mit einem Label und einem rechts daneben stehenden Icon wird, wie
97
+ in folgendem Codebeispiel gezeigt, gebaut.
98
+
99
+ <Canvas>
100
+ <Story of={ButtonStories.ButtonIconRechts} />
101
+ </Canvas>
102
+
103
+ ```handlebars
104
+ {{#> components/button/button _size="lg"}}
105
+ {{> components/button/components/button_label _label="Icon rechts"}}
106
+ {{> components/button/components/button_icon _icon="arrow-right" _iconmap="icons"}}
107
+ {{/components/button/button}}
108
+ ```
109
+
110
+ Soll das Icon links vom Label stehen, muss der Aufruf der Subkomponenten einfach vertauscht werden.
111
+
112
+ <Canvas>
113
+ <Story of={ButtonStories.ButtonIconLinks} />{' '}
114
+ </Canvas>
115
+
116
+ ```handlebars
117
+ {{#> components/button/button _size="lg"}}
118
+ {{> components/button/components/button_icon _icon="arrow-left" _iconmap="icons"}}
119
+ {{> components/button/components/button_label _label="Icon links"}}
120
+ {{/components/button/button}}
121
+ ```
122
+
123
+ Der passende Abstand zwischen Icon und Label wird automatisch per CSS gesetzt.
124
+
125
+ ### Button auf farbigem Hintergund
126
+
127
+ Soll ein Button auf einem farbigen Hintergrund (bietet sich vor allem bei dunklen Hintergründen an) genutzt werden, kann durch setzen des Parameters
128
+ `_onBackground` eine auf dunkle Hintergründe abgestimmte kontrastreichere optische Variante der Button aktiviert werden.
129
+
130
+ <Canvas>
131
+ <Story of={ButtonStories.ButtonPrimaryAufFarbigemHintergrund} />
132
+ <Story of={ButtonStories.ButtonSecondaryAufFarbigemHintergrund} />
133
+ <Story of={ButtonStories.ButtonTertiaryAufFarbigemHintergrund} />
134
+ </Canvas>
135
+
136
+ ```handlebars
137
+ {{#> components/button/link_button _size="lg" _onBackground=true}}
138
+ {{> components/button/components/button_label _label="Primary"}}
139
+ {{/components/button/link_button}}
140
+ ```
141
+
142
+ ### Besonderheiten
143
+
144
+ Die Button-Komponente kann mit [Inline-Partials](?path=/docs/grundlegendes-konventionen-und-datenstrukturen--docs#namen-übergebener-komponenten-parameter-in-partial-blocks-und-inline-partials)
145
+ um zusätzliche HTML-Properties oder in Style-Komponenten ausgelagerte CSS-Klassen erweitert werden.
146
+
147
+ #### Setzen zusätzlicher HTML Attribute
148
+
149
+ In manchen Fällen reichen die standardmäßig von der Button-Komponente gesetzten HTML-Attribute nicht aus. Sollen weitere
150
+ Attribute gesetzt werden (z.B. zum Setzen von alpine.js Direktiven), muss dies wie in folgendem Beispiel gezeigt umgesetzt werden.
151
+
152
+ ```handlebars
153
+ {{#> components/button/button _size="lg"}}
154
+ {{> components/button/components/button_label _label="Button"}}
155
+ {{/components/button/button}}
156
+ {{#*inline "html_properties"}}
157
+ x-ref="button"
158
+ x-on:click="toggle()"
159
+ :aria-expanded="open"
160
+ :aria-controls="$id('dropdown-button')"
161
+ :class="open ? 'drop-shadow' : ''"
162
+ data-hr-click-tracking='{"settings": [{"type": "uxAction", "clickLabel": "podcastAbonnieren:ButtonClick"}]}'
163
+ {{/inline}}
164
+ ```
165
+
166
+ Dem hier gerenderten HTML-Button werden mit Hilfe des Inline-Partials `html_properties` die Attribute `x-ref`, `x-on`, `:aria-expanded`, `:aria-controls`, `:class`
167
+ sowie `data-hr-click-tracking` hinzugefügt.
168
+
169
+ #### Setzen von in Subkomponenten ausgelagerte CSS Klassen
170
+
171
+ Müssen CSS Klassen abhängig von bestimmten Eigenschaften (z.B. Teaser-Größe, Teaser-Art, etc.) gesetzt werden, hat sich mit der Zeit
172
+ als Best-Practice eine Auslagerung der ganzen Logik in Subkomponenten herausgestellt. Um den Inhalt dieser Subkomponenten einer
173
+ anderen Komponente dynamisch zu übergeben, können die bislang genutzten Standard Handlebar Properties (im Kontext der Button Komponente
174
+ `_css`) nicht genutzt werden. Einer solchen Property können ausschließlich Strings übergeben werden. Stattdessen werden auch hierfür
175
+ Inline-Partials eingesetzt.
176
+
177
+ ```handlebars
178
+ {{#> components/button/button _size="lg"}}
179
+ {{> components/button/components/button_label _label="Button"}}
180
+ {{/components/button/button}}
181
+ {{#*inline "css"}}
182
+ {{> components/button/utilities/button_on_image_classes _teaserSize=_teaserSize _teaserType=_teaserType _isMobile1to1=_isMobile1to1}}
183
+ {{/inline}}
184
+ ```
185
+
186
+ Über das Inline-Partial `css` können auf diese Weise theoretisch beliebig viele in Subkomponenten ausgelagerte CSS Klassen übergeben werden.