@bonniernews/dn-design-system-web 16.2.1 → 18.0.0-beta.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,28 @@ All changes to @bonniernews/dn-design-system-web will be documented in this file
4
4
 
5
5
 
6
6
 
7
+ ## [18.0.0-beta.0](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@17.0.0...@bonniernews/dn-design-system-web@18.0.0-beta.0) (2024-08-13)
8
+
9
+
10
+ ### ⚠ BREAKING CHANGES
11
+
12
+ * list item design updates
13
+
14
+ ### Features
15
+
16
+ * list item design updates ([b281389](https://github.com/BonnierNews/dn-design-system/commit/b2813893022fc7d95ac070a85ee53db81a60b6a9))
17
+
18
+ ## [17.0.0](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@16.2.1...@bonniernews/dn-design-system-web@17.0.0) (2024-07-19)
19
+
20
+
21
+ ### ⚠ BREAKING CHANGES
22
+
23
+ * **web:** remove support for deprecated typography (#1342)
24
+
25
+ ### Maintenance
26
+
27
+ * **web:** remove support for deprecated typography ([#1342](https://github.com/BonnierNews/dn-design-system/issues/1342)) ([9ed4e56](https://github.com/BonnierNews/dn-design-system/commit/9ed4e566a5eae3225f7003645827a6768077fbab))
28
+
7
29
  ## [16.2.1](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@16.2.0...@bonniernews/dn-design-system-web@16.2.1) (2024-07-18)
8
30
 
9
31
 
@@ -85,7 +85,7 @@
85
85
  border-bottom-right-radius: ds-border-radius(x2);
86
86
  overflow: hidden;
87
87
  margin: 0;
88
- padding: 0;
88
+ padding: ds-spacing(0 $ds-s-100);
89
89
  }
90
90
 
91
91
  &.ds-force-px {
@@ -1,47 +1,11 @@
1
1
  {% from '@bonniernews/dn-design-system-web/njk-helpers/attributes.njk' import getAttributes %}
2
- {% from '@bonniernews/dn-design-system-web/components/icon-sprite/icon-sprite.njk' import IconUse %}
3
- {% from '@bonniernews/dn-design-system-web/components/button-toggle/button-toggle.njk' import ButtonToggle %}
2
+ {% from '@bonniernews/dn-design-system-web/components/list-item/list-item.njk' import ListItem %}
4
3
 
5
4
  {% macro Byline(params) %}
6
- {% set componentClassName = "ds-byline" %}
7
- <li class="{{ componentClassName + '__outer'}}">
8
- {% call BylineInner(params, componentClassName) %}
9
- <div class="{{ componentClassName + '__inner'}}">
10
- {% set componentClassName = componentClassName %}
11
- {% call BylineContent(params, componentClassName, useOuterAnchorElement) %}
12
- {% if params.bylineImage %}
13
- <span class="{{ componentClassName + '__image'}}">{{- params.bylineImage | safe -}}</span>
14
- {% endif %}
15
- <div class="{{ componentClassName + '__titles'}}">
16
- {% if params.authorName %}
17
- <span class="{{ componentClassName + '__title'}}">{{ params.authorName }}</span>
18
- {% endif %}
19
- {%- if subtitle %}
20
- <span class="{{ componentClassName + '__subtitle'}}">{{ subtitle }}</span>
21
- {% endif %}
22
- </div>
23
- {% endcall %}
24
- {% if useArrowIcon %}
25
- <span class="{{ componentClassName + '__icon-right'}}">{{- IconUse({ icon: 'arrow_forward' }) | safe -}}</span>
26
- {% elif useFollowButton %}
27
- {{ ButtonToggle({
28
- text: "Följ",
29
- selectedText: "Följer",
30
- selected: params.followed,
31
- variant: "secondary",
32
- size: "small",
33
- attributes: params.elementAttributes,
34
- classNames: elementClassNames | join(" "),
35
- forcePx: params.forcePx
36
- })}}
37
- {% endif %}
38
- </div>
39
- {% endcall %}
40
- </li>
41
- {% endmacro %}
5
+ {% set useOuterAnchorElement = params.authorPageUrl and not params.followable %}
6
+ {% set useArrowIcon = true if (useOuterAnchorElement and params.variant !== 'direkt') %}
7
+ {% set useFollowButton = true if (params.variant == 'follow' and params.followable) %}
42
8
 
43
- {# Internal helper macro - not intended for use outside of this file #}
44
- {% macro BylineContent(params, componentClassName, useOuterAnchorElement) %}
45
9
  {% if params.variant == 'link' %}
46
10
  {% set subtitle = params.role %}
47
11
  {% elif params.variant == 'follow' %}
@@ -50,54 +14,24 @@
50
14
  {% set subtitle = false %}
51
15
  {% endif %}
52
16
 
53
- {# This inner link can exist in combination with a button. It's been decided that it should only be used for authorPageUrls, not for email #}
54
- {% if not useOuterAnchorElement and params.authorPageUrl %}
55
- {% set linkAttributes = getAttributes(params.linkAttributes) %}
56
- {%- set ariaLabel = 'aria-label="Läs mer från ' + params.authorName + '"' %}
57
- <a href="{{params.authorPageUrl}}" {{- linkAttributes | safe }} {{ ariaLabel | safe if not params.email }} class="{{ componentClassName + '__content-wrapper'}}">
58
- {{ caller() if caller }}
59
- </a>
60
- {% else %}
61
- <div class="{{ componentClassName + '__content-wrapper'}}">
62
- {{ caller() if caller }}
63
- </div>
64
- {% endif %}
65
- {% endmacro %}
66
-
67
- {# Internal helper macro - not intended for use outside of this file #}
68
- {% macro BylineInner(params, componentClassName) %}
69
- {% set classNamePrefix = componentClassName + "--" %}
70
- {% set attributes = getAttributes(params.attributes) %}
71
-
72
- {% set useOuterAnchorElement = true if (params.authorPageUrl and not params.followable) %}
73
- {% set useArrowIcon = true if (useOuterAnchorElement and params.variant !== 'direkt') %}
74
- {% set useFollowButton = true if (params.variant == 'follow' and params.followable) %}
75
-
76
- {%- set classes = [
77
- componentClassName,
78
- "ds-force-px" if params.forcePx,
79
- classNamePrefix + "noninteractive" if not params.authorPageUrl,
80
- classNamePrefix + params.variant,
81
- params.classNames if params.classNames
82
- ] | join(" ") %}
83
-
84
- {% if params.bylineImage %}
85
- {% set bylineImage = params.bylineImage %}
86
- {% endif %}
87
-
88
- {% set elementClassNames = [ componentClassName + "__btn-toggle" ]%}
89
- {% if params.elementClassNames %}
90
- {% set elementClassNames = (elementClassNames.push(params.elementClassNames), elementClassNames) %}
91
- {% endif %}
92
-
93
- {% if useOuterAnchorElement %}
94
- {% set linkAttributes = getAttributes(params.linkAttributes) %}
95
- <a href="{{ params.authorPageUrl }}" aria-label="Läs mer från {{ params.authorName }}" class="{{ classes }}" {{- attributes | safe }} {{- linkAttributes | safe }}>
96
- {{ caller() if caller }}
97
- </a>
98
- {% else %}
99
- <div class="{{ classes }}" {{- attributes | safe }}>
100
- {{ caller() if caller }}
101
- </div>
102
- {% endif %}
17
+ {% set classNames = (params.classNames or '') + ' ds-byline--' + params.variant %}
18
+
19
+ {{ ListItem({
20
+ listItemType: 'byline',
21
+ title: params.authorName,
22
+ subtitle: subtitle,
23
+ mediaHtml: params.bylineImage,
24
+ trailingIcon: 'arrow_forward' if useArrowIcon,
25
+ toggleText: 'Följ' if useFollowButton,
26
+ toggleSelectedText: 'Följer' if useFollowButton,
27
+ selected: params.followed if useFollowButton,
28
+ href: params.authorPageUrl if useOuterAnchorElement,
29
+ titleHref: params.authorPageUrl if not useOuterAnchorElement,
30
+ linkAttributes: params.linkAttributes,
31
+ elementAttributes: params.elementAttributes,
32
+ elementClassNames: params.elementClassNames,
33
+ forcePx: params.forcePx,
34
+ classNames: classNames,
35
+ attributes: params.attributes
36
+ }) }}
103
37
  {% endmacro %}
@@ -1,187 +1 @@
1
- @use "../../foundations/helpers/forward.helpers.scss" as *;
2
- @use "../../components/icon-sprite/icon-sprite.scss";
3
- @use "../../components/button-toggle/button-toggle.scss" as *;
4
-
5
- $ds-byline__icon-size: 24px;
6
- $ds-byline__image-size: 44px;
7
- $ds-byline__image-size--direkt: 36px;
8
-
9
- .ds-byline__outer {
10
- list-style: none;
11
- line-height: 0;
12
- }
13
-
14
- .ds-byline {
15
- background-color: transparent;
16
- border: 0;
17
- display: inline-flex;
18
- align-items: center;
19
- justify-content: center;
20
- padding: 0;
21
- width: 100%;
22
- position: relative;
23
-
24
- &::after {
25
- content: "";
26
- height: ds-border-width(x1);
27
- width: calc(100% - ds-spacing($ds-s-200));
28
- background-color: $ds-color-border-primary;
29
- position: absolute;
30
- left: ds-spacing($ds-s-100);
31
- bottom: 0;
32
- }
33
-
34
- .ds-byline__inner {
35
- box-sizing: border-box;
36
- border-radius: 0;
37
- margin: 0;
38
- display: flex;
39
- align-items: center;
40
- justify-content: space-between;
41
- position: relative;
42
- padding: ds-spacing($ds-s-100 $ds-s-100);
43
- width: 100%;
44
-
45
- &::before {
46
- content: "";
47
- border-radius: inherit;
48
- pointer-events: none;
49
- position: absolute;
50
- top: 0;
51
- left: 0;
52
- bottom: 0;
53
- right: 0;
54
- }
55
- }
56
-
57
- .ds-byline__content-wrapper {
58
- display: flex;
59
- align-items: center;
60
- justify-content: space-between;
61
- flex-grow: 1;
62
- text-decoration: none;
63
-
64
- &:focus-visible {
65
- outline: ds-border-width(x2) solid $ds-color-border-focus-02;
66
- outline-offset: 2px;
67
- }
68
- }
69
-
70
- .ds-byline__image {
71
- height: $ds-byline__image-size;
72
- width: $ds-byline__image-size;
73
- border-radius: 50%;
74
- overflow: hidden;
75
- margin-right: ds-spacing($ds-s-100);
76
- background-color: $ds-color-component-primary-overlay;
77
- flex-shrink: 0;
78
- }
79
-
80
- .ds-byline__titles {
81
- display: flex;
82
- flex-grow: 1;
83
- flex-direction: column;
84
- align-items: flex-start;
85
- word-break: break-all;
86
-
87
- .ds-byline__title {
88
- @include ds-typography(
89
- $ds-typography-functionalheading01,
90
- $lineHeight: $ds-lineheight-m,
91
- $fontWeight: $ds-fontweight-semibold
92
- );
93
- @at-root .ds-force-px#{&} {
94
- @include ds-typography(
95
- $ds-typography-functionalheading01,
96
- $forcePx: true,
97
- $lineHeight: $ds-lineheight-m,
98
- $fontWeight: $ds-fontweight-semibold
99
- );
100
- }
101
- color: $ds-color-text-primary;
102
- text-align: left;
103
- }
104
-
105
- .ds-byline__subtitle {
106
- @include ds-typography($ds-typography-functionalbody02);
107
- @at-root .ds-force-px#{&} {
108
- @include ds-typography($ds-typography-functionalbody02, true);
109
- }
110
- color: $ds-color-text-primary-02;
111
- text-align: left;
112
- }
113
- }
114
-
115
- .ds-byline__icon-right {
116
- color: $ds-color-icon-primary;
117
- display: inline-flex;
118
- margin-left: ds-spacing($ds-s-100);
119
-
120
- .ds-icon {
121
- position: relative;
122
- display: flex;
123
- height: ds-px-to-rem($ds-byline__icon-size);
124
- width: ds-px-to-rem($ds-byline__icon-size);
125
- margin: 0;
126
- @at-root .ds-force-px#{&} {
127
- height: $ds-byline__icon-size;
128
- width: $ds-byline__icon-size;
129
- }
130
- svg {
131
- fill: currentColor;
132
- }
133
- }
134
- }
135
-
136
- .ds-byline__btn-toggle {
137
- margin-left: ds-spacing($ds-s-100);
138
- }
139
-
140
- @include ds-hover() {
141
- &:hover:not(.ds-byline--noninteractive) {
142
- cursor: pointer;
143
-
144
- .ds-byline__inner::before {
145
- background-color: $ds-color-component-primary-overlay;
146
- }
147
- }
148
- }
149
-
150
- &.ds-byline--direkt {
151
- .ds-byline__titles {
152
- .ds-byline__subtitle {
153
- line-height: ds-spacing($ds-s-100);
154
- }
155
- }
156
- .ds-byline__image {
157
- height: $ds-byline__image-size--direkt;
158
- width: $ds-byline__image-size--direkt;
159
- }
160
-
161
- .ds-byline__btn-toggle {
162
- min-height: $ds-byline__image-size--direkt;
163
- }
164
-
165
- .ds-byline__inner {
166
- padding-top: ds-spacing($ds-s-075);
167
- padding-bottom: ds-spacing($ds-s-075);
168
- }
169
- }
170
-
171
- &:active:not(.ds-byline--noninteractive) .ds-byline__inner::before {
172
- background-color: $ds-color-component-primary-overlay-02;
173
- }
174
- &:focus-visible {
175
- outline: none;
176
- .ds-byline__inner {
177
- outline: ds-border-width(x2) solid $ds-color-border-focus-02;
178
- outline-offset: -2px;
179
- }
180
- }
181
-
182
- @at-root a#{&} {
183
- box-sizing: border-box;
184
- text-align: center;
185
- text-decoration: none;
186
- }
187
- }
1
+ @use "../../components/list-item/list-item.scss";
@@ -28,6 +28,6 @@ function dsListItemToggle(toggleEl) {
28
28
  }
29
29
 
30
30
  function dsListItemAll() {
31
- const listElements = Array.from(document.getElementsByClassName("ds-list-item"));
31
+ const listElements = Array.from(document.getElementsByClassName("ds-list-item__content"));
32
32
  dsListItem(listElements);
33
33
  }
@@ -7,39 +7,40 @@
7
7
 
8
8
  {% macro ListItem(params) %}
9
9
  {% set componentClassName = "ds-list-item" %}
10
- <li class="{{ componentClassName + '__outer'}}">
10
+ <li class="{{ componentClassName }}{% if params.border %} {{componentClassName}}--border{% endif %}">
11
11
  {% call ListItemInner(params, componentClassName) %}
12
- <div class="{{ componentClassName + '__inner'}}">
13
- {% set componentClassName = componentClassName %}
14
- {% if iconLeftSvg %}
15
- <span class="{{ componentClassName + '__icon-left'}}">{{- iconLeftSvg | safe -}}</span>
16
- {% endif %}
17
- {% if params.listItemType == 'image' %}
18
- <div class="{{ componentClassName + '__image'}}">{{ params.mediaHtml }}</div>
19
- {% endif %}
20
- {% if params.title %}
21
- <div class="{{ componentClassName + '__titles'}}">
22
- {% if params.titleHref and not params.disabled %}
23
- {% set linkAttributes = getAttributes(params.linkAttributes) %}
24
- <a class="{{ componentClassName + '__title'}}" href="{{ params.titleHref }}" {{ linkAttributes | safe }}>{{ params.title }}</a>
25
- {% else %}
26
- <span class="{{ componentClassName + '__title'}}">{{ params.title }}</span>
27
- {% endif %}
28
- {%- if params.subtitle %}
29
- <span class="{{ componentClassName + '__subtitle'}}">{{ params.subtitle }}</span>
30
- {% endif %}
31
- </div>
32
- {% endif %}
33
- {% if params.meta %}
34
- <span class="{{ componentClassName + '__meta'}}">{{ params.meta }}</span>
35
- {% endif %}
36
- {% if iconRightSvg %}
37
- <span class="{{ componentClassName + '__icon-right'}}">{{- iconRightSvg | safe -}}</span>
38
- {% endif %}
39
- {% if elementRight %}
40
- {{- elementRight | safe -}}
41
- {% endif %}
42
- </div>
12
+ {% set componentClassName = componentClassName %}
13
+ {% if iconLeftSvg %}
14
+ <span class="{{ componentClassName + '__icon-left'}}">{{- iconLeftSvg | safe -}}</span>
15
+ {% endif %}
16
+ {% if params.listItemType == 'image' %}
17
+ <div class="{{ componentClassName + '__image'}}">{{ params.mediaHtml }}</div>
18
+ {% endif %}
19
+ {% if params.listItemType == 'byline' and params.mediaHtml %}
20
+ <div class="{{ componentClassName + '__portrait'}}">{{ params.mediaHtml }}</div>
21
+ {% endif %}
22
+ {% if params.title %}
23
+ <div class="{{ componentClassName + '__titles'}}">
24
+ {% if params.titleHref and not params.disabled %}
25
+ {% set linkAttributes = getAttributes(params.linkAttributes) %}
26
+ <a class="{{ componentClassName + '__title'}}" href="{{ params.titleHref }}" {{ linkAttributes | safe }}>{{ params.title }}</a>
27
+ {% else %}
28
+ <span class="{{ componentClassName + '__title'}}">{{ params.title }}</span>
29
+ {% endif %}
30
+ {%- if params.subtitle %}
31
+ <span class="{{ componentClassName + '__subtitle'}}">{{ params.subtitle }}</span>
32
+ {% endif %}
33
+ </div>
34
+ {% endif %}
35
+ {% if params.meta %}
36
+ <span class="{{ componentClassName + '__meta'}}">{{ params.meta }}</span>
37
+ {% endif %}
38
+ {% if iconRightSvg %}
39
+ <span class="{{ componentClassName + '__icon-right'}}">{{- iconRightSvg | safe -}}</span>
40
+ {% endif %}
41
+ {% if elementRight %}
42
+ {{- elementRight | safe -}}
43
+ {% endif %}
43
44
  {% endcall %}
44
45
  </li>
45
46
  {% endmacro %}
@@ -66,9 +67,8 @@
66
67
  {% endif %}
67
68
 
68
69
  {%- set classes = [
69
- componentClassName,
70
+ componentClassName + "__content",
70
71
  "ds-force-px" if params.forcePx,
71
- classNamePrefix + "border" if params.border,
72
72
  classNamePrefix + "disabled" if params.disabled,
73
73
  variantClass,
74
74
  params.classNames if params.classNames
@@ -83,8 +83,7 @@
83
83
  {{ caller() if caller }}
84
84
  </button>
85
85
  {% elif element == 'checkbox' %}
86
- <div class="{{ classes }}" {{- attributes | safe }}>
87
- <label class="{{ componentClassName + '__wrapping-label'}}" for="{{ params.name }}"></label>
86
+ <label class="{{ classes }}" for="{{ params.name }}" {{- attributes | safe }}>
88
87
  {% set iconLeftSvg %}
89
88
  {{ Checkbox({
90
89
  name: params.name,
@@ -93,28 +92,27 @@
93
92
  disabled: params.disabled,
94
93
  forcePx: params.forcePx,
95
94
  stripLabel: true,
96
- attributes: params.elementAttributes
95
+ attributes: params.elementAttributes,
96
+ classNames: params.elementClassNames
97
97
  })}}
98
98
  {% endset %}
99
99
  {{ caller() if caller }}
100
- </div>
100
+ </label>
101
101
  {% elif element == 'radio' %}
102
- <div class="{{ classes }}" {{- attributes | safe }}>
103
- <label class="{{ componentClassName + '__wrapping-label'}}" for="{{ params.id }}"></label>
102
+ <label class="{{ classes }}" for="{{ params.id }}" {{- attributes | safe }}>
104
103
  {% set iconLeftSvg %}
105
104
  {{ RadioButton({
106
105
  name: params.name,
107
106
  condensed: true,
108
107
  disabled: params.disabled,
109
108
  forcePx: params.forcePx,
110
- buttons: [{ id: params.id, checked: params.selected, attributes: params.elementAttributes }]
109
+ buttons: [{ id: params.id, checked: params.selected, attributes: params.elementAttributes, classNames: params.elementClassNames }]
111
110
  })}}
112
111
  {% endset %}
113
112
  {{ caller() if caller }}
114
- </div>
113
+ </label>
115
114
  {% elif element == 'switch' %}
116
- <div class="{{ classes }}" {{- attributes | safe }}>
117
- <label class="{{ componentClassName + '__wrapping-label'}}" for="{{ params.name }}"></label>
115
+ <label class="{{ classes }}" for="{{ params.name }}" {{- attributes | safe }} >
118
116
  {% set iconRightSvg %}
119
117
  {{ Switch({
120
118
  name: params.name,
@@ -124,11 +122,12 @@
124
122
  disabled: params.disabled,
125
123
  forcePx: params.forcePx,
126
124
  stripLabel: true,
127
- attributes: params.elementAttributes
125
+ attributes: params.elementAttributes,
126
+ classNames: params.elementClassNames
128
127
  })}}
129
128
  {% endset %}
130
129
  {{ caller() if caller }}
131
- </div>
130
+ </label>
132
131
  {% elif element == 'accordion' %}
133
132
  {% set iconRightSvg %}
134
133
  {{ IconUse({ icon: "expand_less" }) }}
@@ -151,11 +150,38 @@
151
150
  disabled: params.disabled,
152
151
  forcePx: params.forcePx,
153
152
  size: "small",
154
- attributes: params.elementAttributes
153
+ attributes: params.elementAttributes,
154
+ classNames: params.elementClassNames
155
155
  })}}
156
156
  {% endset %}
157
157
  {{ caller() if caller }}
158
158
  </div>
159
+ {% elif element == 'byline' %}
160
+ {% set elementRight %}
161
+ {% if params.toggleText %}
162
+ {{ ButtonToggle({
163
+ text: params.toggleText,
164
+ selected: params.selected,
165
+ selectedText: params.toggleSelectedText,
166
+ variant: params.variant | default("secondary"),
167
+ disabled: params.disabled,
168
+ forcePx: params.forcePx,
169
+ size: "small",
170
+ attributes: params.elementAttributes,
171
+ classNames: params.elementClassNames
172
+ })}}
173
+ {% endif %}
174
+ {% endset %}
175
+ {% if params.href %}
176
+ {% set linkAttributes = getAttributes(params.linkAttributes) %}
177
+ <a href="{{ params.href }}" class="{{ classes }}" {{- attributes | safe }} {{- linkAttributes | safe }}>
178
+ {{ caller() if caller }}
179
+ </a>
180
+ {% else %}
181
+ <div class="{{ classes }}" {{- attributes | safe }}>
182
+ {{ caller() if caller }}
183
+ </div>
184
+ {% endif %}
159
185
  {% else %}
160
186
  <div class="{{ classes }}" {{- attributes | safe }}>
161
187
  {{ caller() if caller }}