@bonniernews/dn-design-system-web 8.9.8 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,36 @@ All changes to @bonniernews/dn-design-system-web will be documented in this file
4
4
 
5
5
 
6
6
 
7
+ ## [9.1.0](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@9.0.0...@bonniernews/dn-design-system-web@9.1.0) (2024-01-04)
8
+
9
+
10
+ ### Features
11
+
12
+ * **web:** modal component ([#1150](https://github.com/BonnierNews/dn-design-system/issues/1150)) ([a0a70ec](https://github.com/BonnierNews/dn-design-system/commit/a0a70ec4d431b6b38738a70468e60ed9cc9e93ef))
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **app:** pressable remove hitslop ([#1146](https://github.com/BonnierNews/dn-design-system/issues/1146)) ([4f59509](https://github.com/BonnierNews/dn-design-system/commit/4f59509cc3c29bd1f66c7d064b0fb5e25451b07c))
18
+
19
+
20
+ ### Maintenance
21
+
22
+ * **foundations:** update tokens from Figma ([#1142](https://github.com/BonnierNews/dn-design-system/issues/1142)) ([66cc18e](https://github.com/BonnierNews/dn-design-system/commit/66cc18e2bd91337d5ffd8b38e76f9230ba5d3610))
23
+ * prerelease packages ([d6f9f31](https://github.com/BonnierNews/dn-design-system/commit/d6f9f31c313028d1e3b192a8b4b2dd59732ef192))
24
+ * prerelease packages ([49b5357](https://github.com/BonnierNews/dn-design-system/commit/49b53574003a03a233b63f467a69d9ea55d9b852))
25
+
26
+ ## [9.0.0](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@8.9.8...@bonniernews/dn-design-system-web@9.0.0) (2023-12-08)
27
+
28
+
29
+ ### ⚠ BREAKING CHANGES
30
+
31
+ * **web:** compact renamed to isCompact in teaser standard
32
+
33
+ ### Features
34
+
35
+ * **web:** teaser large compact ([#1143](https://github.com/BonnierNews/dn-design-system/issues/1143)) ([4c578fb](https://github.com/BonnierNews/dn-design-system/commit/4c578fb20fd3b00eb5f1bd0951f512bd0004da75))
36
+
7
37
  ## [8.9.8](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@8.9.7...@bonniernews/dn-design-system-web@8.9.8) (2023-12-08)
8
38
 
9
39
 
@@ -0,0 +1,52 @@
1
+ - GitHub: [BonnierNews/dn-design-system/../web/src/components/modal](https://github.com/BonnierNews/dn-design-system/tree/main/web/src/components/modal)
2
+ - Storybook: [Modal](https://designsystem.dn.se/?path=/docs/basic-modal--docs)
3
+ - Storybook (Latest): [Modal](https://designsystem-latest.dn.se/?path=/docs/basic-modal--docs)
4
+
5
+ ----
6
+
7
+ # Modal
8
+
9
+
10
+ ## Parameters
11
+
12
+ |parameter | type | required | options | default | description |
13
+ |:--- | :--- | :--- | :--- | :--- | :--- |
14
+ | title | String | yes | | | Title in modal |
15
+ | bodyText | String | yes | text | | Text in modal |
16
+ | primaryButton | Object | no | text | | Object with text, href (optional), classNames (optional) and attributes (optional) |
17
+ | secondaryButton | Object | no | text | | Object with text, href (optional), classNames (optional) and attributes (optional). Set isCloseButton to true if you wanna close modal with this button |
18
+ | classNames | String | no | | | Ex. "my-special-class" |
19
+ | attributes | Object | no | | | Ex. { data-prop: value } |
20
+ | forcePx | bool | no | true, false | false | Fixed pixel value is used for typography to prevent scaling based on html font-size
21
+
22
+ ## Minimum requirement example
23
+
24
+ These are copy paste friendly examples to quickliy get started using a component.
25
+
26
+ ### Nunjucks
27
+
28
+ ```javascript
29
+ {% from '@bonniernews/dn-design-system-web/components/modal/modal.njk' import Modal %}
30
+
31
+ {{ Modal({
32
+ title: "Rubrik",
33
+ bodyText: "Text i modalen",
34
+ primaryButton: "Text i knapp",
35
+ secondaryButton: "Text i knapp",
36
+ })}}
37
+ ```
38
+
39
+ ### Scss
40
+
41
+ ```scss
42
+ @use "@bonniernews/dn-design-system-web/components/modal/modal";
43
+ ```
44
+
45
+ ### Javascript
46
+
47
+ ```javascript
48
+ import { initModal, openModal } from '@bonniernews/dn-design-system-web/components/modal/modal.js'
49
+ const modalEl = document.querySelector(".ds-modal");
50
+ initModal(modalEl);
51
+ openModal(modalEl);
52
+ ```
@@ -0,0 +1,59 @@
1
+ export {
2
+ initModal,
3
+ openModal,
4
+ initModalStorybook
5
+ }
6
+
7
+ function initModal(modalEl) {
8
+ const isDialogSupported = typeof HTMLDialogElement === "function";
9
+ let modalWrapper = modalEl.querySelector(".ds-modal__inner");
10
+ if (!isDialogSupported) {
11
+ modalWrapper = modalEl;
12
+ const modalElInner = document.querySelector(".ds-modal__inner");
13
+ const modalAttributes = Array.from(modalElInner.attributes);
14
+ const fallbackDiv = document.createElement("div");
15
+ modalEl.classList.add("ds-modal--hidden", "ds-modal--fallback");
16
+ modalAttributes.forEach((attr) => {
17
+ fallbackDiv.setAttribute(attr.name, attr.value);
18
+ });
19
+ fallbackDiv.setAttribute("role", "dialog");
20
+ fallbackDiv.setAttribute("aria-modal", "true");
21
+ fallbackDiv.innerHTML = modalElInner.innerHTML;
22
+ modalEl.replaceChild(fallbackDiv, modalElInner);
23
+ }
24
+
25
+ modalEl.addEventListener("click", (e) => {
26
+ if (e.target === modalWrapper) closeModal(modalEl, isDialogSupported);
27
+ });
28
+
29
+ const closeButtons = Array.from(modalEl.getElementsByClassName("ds-modal__close"));
30
+ closeButtons.forEach((button) => {
31
+ button.addEventListener("click", () => {
32
+ closeModal(modalEl, isDialogSupported);
33
+ });
34
+ });
35
+ }
36
+
37
+ function openModal(modalEl) {
38
+ if (typeof HTMLDialogElement === "function") {
39
+ const modalElInner = modalEl.querySelector(".ds-modal__inner");
40
+ modalElInner.showModal();
41
+ } else {
42
+ modalEl.classList.remove("ds-modal--hidden");
43
+ }
44
+ }
45
+
46
+ function closeModal(modalEl, isDialogSupported) {
47
+ if (isDialogSupported) {
48
+ const modalElInner = modalEl.querySelector(".ds-modal__inner");
49
+ modalElInner.close();
50
+ } else {
51
+ modalEl.classList.add("ds-modal--hidden");
52
+ }
53
+ }
54
+
55
+ function initModalStorybook() {
56
+ const modalEl = document.querySelector(".ds-modal");
57
+ initModal(modalEl);
58
+ openModal(modalEl);
59
+ }
@@ -0,0 +1,66 @@
1
+ {% from '@bonniernews/dn-design-system-web/components/icon-sprite/icon-sprite.njk' import IconUse %}
2
+ {% from '@bonniernews/dn-design-system-web/components/button/button.njk' import Button %}
3
+ {% from '@bonniernews/dn-design-system-web/components/icon-button/icon-button.njk' import IconButton %}
4
+ {% from '@bonniernews/dn-design-system-web/njk-helpers/attributes.njk' import getAttributes %}
5
+
6
+ {% macro Modal(params) %}
7
+ {% set componentClassName = "ds-modal" %}
8
+
9
+ {%- set classes = [
10
+ componentClassName,
11
+ "ds-force-px" if params.forcePx,
12
+ params.classNames if params.classNames
13
+ ] | join(" ") %}
14
+ {% set attributes = getAttributes(params.attributes) %}
15
+
16
+ <div class="{{ classes }}">
17
+ <dialog class="{{ componentClassName + '__inner' }}" {{- attributes | safe }}>
18
+ <div class="{{ componentClassName + '__content' }}">
19
+ {{ IconButton({
20
+ variant: "transparent",
21
+ size: "small",
22
+ iconName: "close",
23
+ classNames: "ds-modal__close"
24
+ })}}
25
+ <h2>{{ params.title }}</h2>
26
+ <p>{{ params.bodyText }}</p>
27
+
28
+ {% if params.primaryButton or params.secondaryButton %}
29
+ <div class="ds-modal__buttons">
30
+ {% if params.secondaryButton %}
31
+ {%- set secondaryButtonClasses = [
32
+ "ds-modal__close" if params.secondaryButton.isCloseButton,
33
+ params.secondaryButton.classNames if params.secondaryButton.classNames
34
+ ] | join(" ") %}
35
+ {{ Button({
36
+ text: params.secondaryButton.text,
37
+ variant: "secondaryOutlined",
38
+ href: params.secondaryButton.href,
39
+ classNames: secondaryButtonClasses,
40
+ attributes: params.secondaryButton.attributes,
41
+ forcePx: params.forcePx,
42
+ mobile: {
43
+ fullWidth: true
44
+ }
45
+ })}}
46
+ {% endif %}
47
+
48
+ {% if params.primaryButton %}
49
+ {{ Button({
50
+ text: params.primaryButton.text,
51
+ variant: "primary",
52
+ href: params.primaryButton.href,
53
+ classNames: params.primaryButton.classNames,
54
+ attributes: params.primaryButton.attributes,
55
+ forcePx: params.forcePx,
56
+ mobile: {
57
+ fullWidth: true
58
+ }
59
+ })}}
60
+ {% endif %}
61
+ </div>
62
+ {% endif %}
63
+ </div>
64
+ </dialog>
65
+ </div>
66
+ {% endmacro %}
@@ -0,0 +1,115 @@
1
+ @use "../../foundations/helpers/forward.helpers.scss" as *;
2
+ @use "../../components/icon-sprite/icon-sprite.scss";
3
+ @use "../../components/button/button.scss";
4
+ @use "../../components/icon-button/icon-button.scss";
5
+
6
+ .ds-modal {
7
+ &--fallback.ds-modal--hidden {
8
+ display: none;
9
+ }
10
+
11
+ &--fallback {
12
+ display: flex;
13
+ position: fixed;
14
+ top: 0;
15
+ bottom: 0;
16
+ right: 0;
17
+ left: 0;
18
+ z-index: 999;
19
+ background-color: $ds-color-surface-overlay;
20
+
21
+ @include ds-mq-only-breakpoint(mobile) {
22
+ align-items: flex-end;
23
+ }
24
+
25
+ @include ds-mq-smallest-breakpoint(tablet) {
26
+ align-items: center;
27
+ justify-content: center;
28
+ }
29
+
30
+ .ds-modal__inner {
31
+ position: relative;
32
+ }
33
+
34
+ .ds-modal__content {
35
+ @include ds-mq-only-breakpoint(mobile) {
36
+ border-radius: 16px 16px 0 0;
37
+ }
38
+
39
+ @include ds-mq-smallest-breakpoint(tablet) {
40
+ border-radius: ds-border-radius(x1);
41
+ }
42
+ }
43
+ }
44
+
45
+ .ds-modal__inner {
46
+ max-width: 700px;
47
+ border: none;
48
+ padding: 0;
49
+
50
+ @include ds-mq-only-breakpoint(mobile) {
51
+ margin-bottom: 0;
52
+ border-radius: 16px 16px 0 0;
53
+ }
54
+
55
+ @include ds-mq-smallest-breakpoint(tablet) {
56
+ border-radius: ds-border-radius(x1);
57
+ }
58
+
59
+ &::backdrop {
60
+ background-color: $ds-color-surface-overlay;
61
+ }
62
+ }
63
+
64
+ .ds-modal__content {
65
+ padding: ds-spacing($ds-s-400 $ds-s-300 $ds-s-300);
66
+ background-color: $ds-color-surface-background;
67
+
68
+ .ds-icon-btn.ds-modal__close {
69
+ position: absolute;
70
+ top: ds-spacing($ds-s-100);
71
+ right: ds-spacing($ds-s-100);
72
+ }
73
+
74
+ > h2 {
75
+ @include ds-typography($ds-typography-functional-heading03bold);
76
+ margin: ds-spacing(0 0 $ds-s-200);
77
+ color: $ds-color-text-primary;
78
+ text-align: center;
79
+ }
80
+
81
+ > p {
82
+ @include ds-typography($ds-typography-functional-body02regular);
83
+ margin: 0;
84
+ text-align: center;
85
+ color: $ds-color-text-primary;
86
+ }
87
+
88
+ > .ds-modal__buttons {
89
+ margin: ds-spacing($ds-s-200 0 0);
90
+
91
+ @include ds-mq-only-breakpoint(mobile) {
92
+ display: flex;
93
+ flex-wrap: wrap;
94
+
95
+ .ds-btn--primary:not(:only-child) {
96
+ order: 1;
97
+ margin-bottom: ds-spacing($ds-s-100);
98
+ }
99
+
100
+ .ds-btn--secondaryOutlined:not(:only-child) {
101
+ order: 2;
102
+ }
103
+ }
104
+
105
+ @include ds-mq-smallest-breakpoint(tablet) {
106
+ display: flex;
107
+ justify-content: center;
108
+
109
+ .ds-btn--secondaryOutlined:not(:only-child) {
110
+ margin-right: ds-spacing($ds-s-100);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
@@ -24,6 +24,7 @@
24
24
  |bylineHtml | HTML String | no | | | Side image of the author |
25
25
  |isItalicHeadline | bool | no | true, false | false | If the headline should be italic |
26
26
  |isLargeHeadline | bool | no | true, false | false | If the headline should be large. Only has an effect if `isItalicHeadline` is true. |
27
+ |isCompact | bool | no | true, false | false | If the headline should be compact |
27
28
  |isFlashingDot | bool | no | true, false | false | If there should be a flashing ball before the text |
28
29
  |isLocked | bool | no | true, false | false | If the paywall indicator should be shown. It is only shown if the teaser has an image. |
29
30
  |publicationTime | string | no | | null | Publication time text. |
@@ -18,6 +18,7 @@
18
18
  classNamePrefix + "quote-badge" if isQuoteBadge,
19
19
  classNamePrefix + 'top-img' if params.mediaHtml,
20
20
  italicsClass if italicsClass,
21
+ classNamePrefix + "compact" if params.isCompact,
21
22
  params.classNames if params.classNames
22
23
  ] | join(" ") %}
23
24
 
@@ -103,6 +103,17 @@
103
103
  }
104
104
  }
105
105
 
106
+ &.ds-teaser--compact {
107
+ .ds-teaser__title {
108
+ @include ds-typography($ds-typography-detailteaser-large-compact);
109
+ }
110
+
111
+ &.ds-teaser--large-italic .ds-teaser__title,
112
+ &.ds-teaser--large-big-italic .ds-teaser__title {
113
+ @include ds-typography($ds-typography-detailteaser-large-compact-opinion);
114
+ }
115
+ }
116
+
106
117
  @include ds-mq-smallest-breakpoint(tablet) {
107
118
  &.ds-teaser--right {
108
119
  .ds-teaser__title {
@@ -22,6 +22,7 @@
22
22
  |grade | String | no | | | zero, one, two, three, four, five, none |
23
23
  |mediaHtml | HTML String | no | | | Main image or other media |
24
24
  |isItalicHeadline | bool | no | true, false | false | If the headline should be italic |
25
+ |isCompact | bool | no | true, false | false | If the headline should be compact |
25
26
  |isFlashingDot | bool | no | true, false | false | If there should be a flashing ball before the text |
26
27
  |isLocked | bool | no | true, false | false | If the paywall indicator should be shown. It is only shown if the teaser has an image. |
27
28
  |publicationTime | string | no | | null | Publication time text. |
@@ -11,7 +11,7 @@
11
11
  {% set extraClasses = [
12
12
  "ds-teaser--standard",
13
13
  classNamePrefix + params.variant if params.variant,
14
- classNamePrefix + "compact" if params.compact,
14
+ classNamePrefix + "compact" if params.isCompact,
15
15
  classNamePrefix + "quote-badge" if hasQuoteBadge,
16
16
  params.classNames if params.classNames
17
17
  ] | join(" ") %}
@@ -5,6 +5,7 @@
5
5
  @use "./helpers/colors.scss" as *;
6
6
 
7
7
  html,
8
+ ::backdrop, //backdrop can't handle variables in html element. It needs to be defined here
8
9
  .ds-light {
9
10
  @each $name, $value in meta.module-variables("colorsDnLightTokens") {
10
11
  --ds-color-#{string.slice($name, 8)}: #{$value};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bonniernews/dn-design-system-web",
3
- "version": "8.9.8",
3
+ "version": "9.1.0",
4
4
  "description": "DN design system for web.",
5
5
  "main": "index.js",
6
6
  "homepage": "https://github.com/BonnierNews/dn-design-system/tree/main/web/src#readme",