@bonniernews/dn-design-system-web 14.0.4 → 15.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/components/blocked-content/blocked-content.js +1 -1
  3. package/components/blocked-content/blocked-content.njk +2 -2
  4. package/components/button/README.md +4 -2
  5. package/components/{button-toggle/button-toggle.js → button/button.js} +3 -3
  6. package/components/button/button.njk +62 -14
  7. package/components/button/button.scss +169 -110
  8. package/components/button-toggle/README.md +4 -4
  9. package/components/button-toggle/button-toggle.njk +17 -36
  10. package/components/button-toggle/button-toggle.scss +1 -215
  11. package/components/byline/README.md +2 -2
  12. package/components/byline/byline.njk +2 -2
  13. package/components/factbox/factbox.njk +4 -4
  14. package/components/group-header/group-header.njk +5 -3
  15. package/components/group-header/group-header.scss +4 -4
  16. package/components/icon-button/README.md +5 -3
  17. package/components/icon-button/icon-button.njk +17 -51
  18. package/components/icon-button/icon-button.scss +19 -126
  19. package/components/icon-button-toggle/README.md +8 -7
  20. package/components/icon-button-toggle/icon-button-toggle.njk +15 -1
  21. package/components/icon-button-toggle/icon-button-toggle.scss +1 -17
  22. package/components/list-item/list-item.js +2 -2
  23. package/components/list-item/list-item.njk +2 -2
  24. package/components/list-item/list-item.scss +1 -1
  25. package/components/modal/modal.njk +3 -2
  26. package/components/modal/modal.scss +4 -4
  27. package/components/tag-header/tag-header.njk +1 -1
  28. package/components/teaser-list-swipe/teaser-list-swipe.njk +4 -2
  29. package/components/teaser-list-vertical/teaser-list-vertical.njk +1 -1
  30. package/components/text-input/text-input.scss +1 -1
  31. package/package.json +1 -1
  32. package/components/floating-button/README.md +0 -41
  33. package/components/floating-button/floating-button.njk +0 -41
  34. package/components/floating-button/floating-button.scss +0 -145
  35. package/components/icon-button-toggle/icon-button-toggle.js +0 -21
package/CHANGELOG.md CHANGED
@@ -4,6 +4,17 @@ All changes to @bonniernews/dn-design-system-web will be documented in this file
4
4
 
5
5
 
6
6
 
7
+ ## [15.0.0-beta.0](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@14.0.4...@bonniernews/dn-design-system-web@15.0.0-beta.0) (2024-03-11)
8
+
9
+
10
+ ### ⚠ BREAKING CHANGES
11
+
12
+ * **web:** refactor buttons
13
+
14
+ ### Features
15
+
16
+ * **web:** refactor buttons ([6fc9ca6](https://github.com/BonnierNews/dn-design-system/commit/6fc9ca69cdde1e6cb209a86282b863c4fb8a8518))
17
+
7
18
  ## [14.0.4](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@14.0.3...@bonniernews/dn-design-system-web@14.0.4) (2024-03-07)
8
19
 
9
20
 
@@ -15,7 +15,7 @@ function dsBlockedContent(params) {
15
15
  <h2 class="ds-blocked-content__title">Hoppsan, här saknas något</h2>
16
16
  <div class="ds-blocked-content__body">Innehållet ${ params.vendor ? `från ${params.vendor}` : '' } kunde inte visas på grund av dina val i kakinställningarna.</div>
17
17
  </div>
18
- <button type="button" class="ds-btn ds-btn--secondaryFilled ds-btn--small ds-btn--full-width">
18
+ <button type="button" class="ds-btn ds-btn--secondary ds-btn--default ds-btn--medium ds-btn--full-width">
19
19
  <div class="ds-btn__inner">
20
20
  <span>Hantera kakor</span>
21
21
  <div class="ds-spinner ds-spinner--small ds-spinner--primary">
@@ -23,8 +23,8 @@
23
23
  </div>
24
24
  {{ Button({
25
25
  text: 'Hantera kakor',
26
- variant: 'secondaryFilled',
27
- size: 'small',
26
+ variant: 'secondary',
27
+ size: 'medium',
28
28
  classNames: '',
29
29
  fullWidth: true,
30
30
  forcePx: params.forcePx,
@@ -12,8 +12,10 @@
12
12
  |:--- | :--- | :--- | :--- | :--- | :--- |
13
13
  |text | String | yes | | | |
14
14
  |disabled | bool | no | true, false | false | Note: only works on button-tag, not on a-tag |
15
- |variant | String | no | brand, business, criticalOutlined, primary, secondaryFilled, secondaryOutlined, staticWhiteFilled, staticWhiteOutlined | primary | Design variant |
16
- |size| String | no | default, small | default | |
15
+ |variant | String | no | primary, secondary, brand, staticWhite | primary | Design variant |
16
+ |emphasis | String | no | default, elevated, outline, transparent | default | |
17
+ |rounded | bool | no | true, false | false | Button will be rounded |
18
+ |size| String | no | small, medium, large, xlarge | medium | |
17
19
  |fullWidth | bool | no | true, false | false | Button will be full width on both desktop and mobile |
18
20
  |mobile.fullWidth | bool | no | true, false | false | Ex mobile: { fullWidth: true } |
19
21
  |iconPosition | String | no | none, left, right | none | |
@@ -7,8 +7,8 @@ function dsButtonToggle(toggleElements = []) {
7
7
  if (!toggleElements.length) return;
8
8
  toggleElements.forEach((toggleEl) => {
9
9
  toggleEl.addEventListener("click", () => {
10
- if (toggleEl.classList.contains("ds-btn-toggle--disabled")) return;
11
- toggleEl.classList.toggle("ds-btn-toggle--selected");
10
+ if (toggleEl.classList.contains("ds-btn--disabled")) return;
11
+ toggleEl.classList.toggle("ds-btn--selected");
12
12
  const ariaChecked = toggleEl.getAttribute("aria-checked") === "true" ? "false" : "true";
13
13
  toggleEl.setAttribute("aria-checked", ariaChecked);
14
14
  });
@@ -16,6 +16,6 @@ function dsButtonToggle(toggleElements = []) {
16
16
  }
17
17
 
18
18
  function dsButtonToggleAll() {
19
- const toggleElements = Array.from(document.getElementsByClassName("ds-btn-toggle"));
19
+ const toggleElements = Array.from(document.getElementsByClassName("ds-btn--toggle"));
20
20
  dsButtonToggle(toggleElements);
21
21
  }
@@ -9,38 +9,86 @@
9
9
  {%- set attributes = getAttributes(params.attributes) %}
10
10
  {%- set ariaLabel = 'aria-label="' + text + '"' if not params.attributes["aria-label"] else "" %}
11
11
  {%- set buttonVariant = params.variant | default("primary") %}
12
- {%- set spinnerMap = { primary: "secondary", brand: "onBrand", business: "onBusiness", staticWhiteFilled: "staticBlack", staticWhiteOutlined: "staticWhite" } %}
13
- {%- set spinnerVariant = spinnerMap[buttonVariant] | default("primary") %}
12
+ {%- set emphasis = params.emphasis | default("default") %}
13
+
14
+ {% if params.variant == "staticWhite" %}
15
+ {% if emphasis == "transparent" or emphasis == "outline" %}
16
+ {%- set spinnerVariant = "staticWhite" %}
17
+ {% else %}
18
+ {%- set spinnerVariant = "staticBlack" %}
19
+ {% endif %}
20
+ {% elif emphasis == "transparent" or emphasis == "outline" or params.variant == "secondary" %}
21
+ {%- set spinnerVariant = "primary" %}
22
+ {% else %}
23
+ {%- set spinnerVariant = "secondary" %}
24
+ {% endif %}
25
+
14
26
  {%- set loadingHtml %}
15
27
  {{ Spinner({ size: 'small', variant: spinnerVariant, forcePx: params.forcePx, attributes: { "aria-hidden": "true" } }) }}
16
28
  {% endset %}
17
29
 
18
- {%- if params.iconName and params.iconPosition and params.iconPosition != "none" %}
30
+ {%- if params.iconName and ((params.iconPosition and params.iconPosition != "none") or params.isIconBtn == true) %}
19
31
  {% set iconSvg = IconUse({ icon: params.iconName, attributes: { "aria-hidden": "true" } }) %}
20
32
  {% endif %}
21
33
 
34
+ {%- if params.a11y and params.a11y.visuallyHidden %}
35
+ {% set visuallyHidden = VisuallyHidden({ text: params.a11y.visuallyHidden }) %}
36
+ {% endif %}
37
+
22
38
  {%- set classes = [
23
39
  componentClassName,
24
40
  classNamePrefix + buttonVariant,
41
+ classNamePrefix + emphasis,
25
42
  classNamePrefix + "selected" if params.selected,
26
- classNamePrefix + params.size if params.size and params.size !== "default",
43
+ classNamePrefix + params.size if params.size else classNamePrefix + "large",
27
44
  classNamePrefix + "full-width" if params.fullWidth,
28
45
  classNamePrefix + "mobile-full-width" if params.mobile and params.mobile.fullWidth,
29
- classNamePrefix + "icon-" + params.iconPosition if iconSvg,
46
+ classNamePrefix + "icon-" + params.iconPosition if iconSvg and not params.isIconBtn,
47
+ classNamePrefix + "icon-only" if params.isIconBtn,
48
+ classNamePrefix + "rounded" if params.rounded,
49
+ classNamePrefix + "toggle" if params.isToggle,
50
+ classNamePrefix + "selected" if params.isToggle and params.selected,
30
51
  "ds-loading" if params.loading,
31
52
  "ds-force-px" if params.forcePx,
32
53
  params.classNames if params.classNames
33
54
  ] | join(" ") %}
34
55
 
35
- {%- if params.href %}
36
- <a href="{{ params.href | default('#', true) }}" {{ ariaLabel | safe }} class="{{ classes }}" {{- attributes | safe}}>
37
- <span aria-hidden="true">{{ text }}</span>
38
- {{- iconSvg | safe if iconSvg -}} {{ loadingHtml | safe }}
39
- </a>
56
+ {%- if params.isToggle %}
57
+ {%- if params.isIconBtn %}
58
+ <button type="button" role="switch" aria-checked="{{ "true" if params.selected else "false" }}" class="{{ classes }}" {{ "disabled" if params.disabled }} {{- attributes | safe }}>
59
+ {{- visuallyHidden | safe if visuallyHidden -}}
60
+ <span class="{{ componentClassName + '__off' }}" aria-hidden="true">{{ IconUse({ icon: params.iconName }) }}</span>
61
+ <span class="{{ componentClassName + '__on' }}" aria-hidden="true">{{ IconUse({ icon: params.selectedIconName }) }}</span>
62
+ {{ loadingHtml | safe }}
63
+ </button>
64
+ {% else %}
65
+ <button type="button" role="switch" {{ ariaLabel | safe }} aria-checked="{{ "true" if params.selected else "false" }}" class="{{ classes }}" {{ "disabled" if params.disabled }} {{- attributes | safe }}>
66
+ <span class="{{ componentClassName + '__off' }}" aria-hidden="true"><span>{{ params.text }}</span></span>
67
+ <span class="{{ componentClassName + '__on' }}" aria-hidden="true">
68
+ {{ IconUse({ icon: "check" }) }} <span>{{ params.selectedText }}</span>
69
+ </span>
70
+ {{ loadingHtml | safe }}
71
+ </button>
72
+ {% endif %}
40
73
  {% else %}
41
- <button type="{{ params.type | default('button') }}" {{ ariaLabel | safe }} class="{{ classes }}" {{ "disabled" if params.disabled }} {{- attributes | safe}}>
42
- <span aria-hidden="true">{{ text }}</span>
43
- {{- iconSvg | safe if iconSvg -}} {{ loadingHtml | safe }}
44
- </button>
74
+ {%- if params.href %}
75
+ <a href="{{ params.href | default('#', true) }}" {{ ariaLabel | safe }} class="{{ classes }}" {{- attributes | safe}}>
76
+ {% if isIconButton %}
77
+ {{- visuallyHidden | safe if visuallyHidden -}}
78
+ {% else %}
79
+ <span aria-hidden="true">{{ text }}</span>
80
+ {% endif %}
81
+ {{- iconSvg | safe if iconSvg -}} {{ loadingHtml | safe }}
82
+ </a>
83
+ {% else %}
84
+ <button type="{{ params.type | default('button') }}" {{ ariaLabel | safe }} class="{{ classes }}" {{ "disabled" if params.disabled }} {{- attributes | safe}}>
85
+ {% if isIconButton %}
86
+ {{- visuallyHidden | safe if visuallyHidden -}}
87
+ {% else %}
88
+ <span aria-hidden="true">{{ text }}</span>
89
+ {% endif %}
90
+ {{- iconSvg | safe if iconSvg -}} {{ loadingHtml | safe }}
91
+ </button>
92
+ {% endif %}
45
93
  {% endif %}
46
94
  {% endmacro %}
@@ -4,94 +4,114 @@
4
4
  @use "../spinner/spinner.scss" as *;
5
5
 
6
6
  $ds-btn-outlined__border-width: ds-border-width(x1);
7
- $ds-btn__icon-size: 24px;
8
7
 
9
8
  .ds-btn {
10
9
  --ds-btn__background-color: transparent;
11
- --ds-btn__background-color-hover: #{$ds-color-component-primary-overlay};
12
- --ds-btn__background-color-active: #{$ds-color-component-primary-overlay-02};
13
- --ds-btn__border-color: #{$ds-color-border-primary-03};
10
+ --ds-btn__border-color: transparent;
14
11
  --ds-btn__outline-color: #{$ds-color-border-focus-02};
15
- --ds-btn__color: #{$ds-color-text-primary};
16
-
17
- &.ds-btn--primary {
18
- --ds-btn__background-color: #{$ds-color-component-primary};
19
- --ds-btn__background-color-hover: #{$ds-color-component-secondary-overlay};
20
- --ds-btn__background-color-active: #{$ds-color-component-secondary-overlay-02};
21
- --ds-btn__border-color: transparent;
22
- --ds-btn__color: #{$ds-color-text-secondary};
12
+ --ds-btn__icon-size: #{ds-px-to-rem(24px)};
13
+ @at-root .ds-force-px#{&} {
14
+ --ds-btn__icon-size: 24px;
23
15
  }
24
16
 
25
- &.ds-btn--brand {
26
- --ds-btn__background-color: #{$ds-color-component-brand};
27
- --ds-btn__border-color: transparent;
28
- --ds-btn__color: #{$ds-color-text-on-brand};
29
- --ds-btn__outline-color: #{$ds-color-border-focus};
17
+ &.ds-btn--default,
18
+ &.ds-btn--elevated {
19
+ &.ds-btn--primary {
20
+ --ds-btn__background-color: #{$ds-color-component-primary};
21
+ --ds-btn__color: #{$ds-color-text-secondary};
22
+ }
23
+ &.ds-btn--secondary {
24
+ --ds-btn__background-color: #{$ds-color-component-primary-overlay};
25
+ --ds-btn__color: #{$ds-color-text-primary};
26
+ }
27
+ &.ds-btn--brand {
28
+ --ds-btn__background-color: #{$ds-color-component-brand};
29
+ --ds-btn__color: #{$ds-color-text-secondary};
30
+ }
31
+ &.ds-btn--staticWhite {
32
+ --ds-btn__background-color: #{$ds-color-static-white};
33
+ --ds-btn__color: #{$ds-color-static-black};
34
+ }
30
35
  }
31
36
 
32
- &.ds-btn--business {
33
- --ds-btn__background-color: #{$ds-color-component-business};
34
- --ds-btn__border-color: transparent;
35
- --ds-btn__color: #{$ds-color-text-on-business};
36
- --ds-btn__outline-color: #{$ds-color-border-focus-04};
37
+ &.ds-btn--outline,
38
+ &.ds-btn--transparent {
39
+ &.ds-btn--primary,
40
+ &.ds-btn--secondary {
41
+ --ds-btn__color: #{$ds-color-text-primary};
42
+ }
43
+ &.ds-btn--brand {
44
+ --ds-btn__color: #{$ds-color-text-brand};
45
+ }
46
+ &.ds-btn--staticWhite {
47
+ --ds-btn__color: #{$ds-color-static-white};
48
+ }
37
49
  }
38
50
 
39
- &.ds-btn--secondaryFilled {
40
- --ds-btn__background-color: #{$ds-color-component-primary-overlay};
41
- --ds-btn__border-color: transparent;
51
+ &.ds-btn--outline {
52
+ &.ds-btn--primary {
53
+ --ds-btn__border-color: #{$ds-color-component-primary};
54
+ }
55
+ &.ds-btn--secondary {
56
+ --ds-btn__border-color: #{$ds-color-border-primary-02};
57
+ }
58
+ &.ds-btn--brand {
59
+ --ds-btn__border-color: #{$ds-color-component-brand};
60
+ }
61
+ &.ds-btn--staticWhite {
62
+ --ds-btn__border-color: #{$ds-color-static-white};
63
+ }
42
64
  }
43
65
 
44
- &.ds-btn--staticWhiteFilled {
45
- --ds-btn__background-color: #{$ds-color-static-white};
46
- --ds-btn__background-color-hover: #0808081a; // static version of lightmode component-secondary-overlay
47
- --ds-btn__background-color-active: #08080833; // static version of lightmode component-secondary-overlay-2
48
- --ds-btn__border-color: transparent;
49
- --ds-btn__color: #{$ds-color-static-black};
66
+ &.ds-btn--toggle.ds-btn--selected:not(.ds-btn--icon-only) {
67
+ --ds-btn__background-color: transparent;
68
+ --ds-btn__color: #{$ds-color-text-primary};
69
+ --ds-btn__border-color: #{$ds-color-component-primary};
70
+ --ds-btn__outline-color: #{$ds-color-border-focus-02};
50
71
  }
51
72
 
52
- &.ds-btn--staticWhiteOutlined {
53
- // static version of darkmode component-secondary-overlay
54
- --ds-btn__background-color-hover: rgba(255, 255, 255, 0.101960784);
55
- // static version of darkmode component-secondary-overlay-2
56
- --ds-btn__background-color-active: rgba(255, 255, 255, 0.2);
57
- --ds-btn__border-color: #{$ds-color-static-white};
58
- --ds-btn__color: #{$ds-color-static-white};
73
+ &.ds-btn--brand {
74
+ --ds-btn__outline-color: #{$ds-color-border-focus};
75
+ }
76
+ &.ds-btn--staticWhite {
59
77
  --ds-btn__outline-color: #{$ds-color-static-white};
78
+ }
79
+ &.ds-btn--rounded {
80
+ border-radius: 100px;
81
+ }
82
+ &.ds-btn--elevated {
83
+ box-shadow: ds-shadow-get-box-shadow($ds-shadow-elevation-m);
84
+ }
60
85
 
61
- &:not(:disabled) .ds-icon {
62
- --ds-btn__color: #{$ds-color-static-white};
86
+ &.ds-btn--small {
87
+ @include ds-typography($ds-typography-detailstandard-button-small);
88
+ --ds-btn__icon-size: #{ds-px-to-rem(20px)};
89
+ @at-root .ds-force-px#{&} {
90
+ @include ds-typography($ds-typography-detailstandard-button-small, true);
91
+ --ds-btn__icon-size: 20px;
63
92
  }
64
93
  }
65
94
 
66
- &.ds-btn--criticalOutlined {
67
- --ds-btn__border-color: #{$ds-color-border-critical};
68
- --ds-btn__color: #{$ds-color-text-critical};
69
- --ds-btn__outline-color: #{$ds-color-border-focus-03};
70
-
71
- &:not(:disabled) .ds-icon {
72
- --ds-btn__color: #{$ds-color-icon-critical};
95
+ &.ds-btn--medium,
96
+ &.ds-btn--large {
97
+ @include ds-typography($ds-typography-detailstandard-button);
98
+ @at-root .ds-force-px#{&} {
99
+ @include ds-typography($ds-typography-detailstandard-button, true);
73
100
  }
74
101
  }
75
102
 
76
- &.ds-btn--secondaryFilled,
77
- &.ds-btn--secondaryOutlined,
78
- &.ds-btn--criticalOutlined,
79
- &.ds-btn--staticWhiteOutlined {
80
- &:not(.ds-loading):disabled {
81
- --ds-btn__background-color: #{$ds-color-component-primary-overlay};
82
- --ds-btn__border-color: transparent;
83
- --ds-btn__color: #{ds-color-text-disabled};
84
- cursor: not-allowed;
103
+ &.ds-btn--xlarge {
104
+ @include ds-typography($ds-typography-detailstandard-button-xlarge);
105
+ --ds-btn__icon-size: #{ds-px-to-rem(32px)};
106
+ @at-root .ds-force-px#{&} {
107
+ @include ds-typography($ds-typography-detailstandard-button-xlarge, true);
108
+ --ds-btn__icon-size: 32px;
85
109
  }
86
110
  }
87
111
 
88
- @include ds-typography($ds-typography-detailstandard-button);
89
112
  cursor: pointer;
90
113
  border: $ds-btn-outlined__border-width solid var(--ds-btn__border-color);
91
114
  border-radius: ds-border-radius(x1);
92
- padding: ds-spacing($ds-s-075, rem) - ds-px-to-rem($ds-btn-outlined__border-width) ds-spacing($ds-s-150, rem) - ds-px-to-rem(
93
- $ds-btn-outlined__border-width
94
- );
95
115
  position: relative;
96
116
  background-color: var(--ds-btn__background-color);
97
117
  color: var(--ds-btn__color);
@@ -108,6 +128,11 @@ $ds-btn__icon-size: 24px;
108
128
  outline-offset: 2px;
109
129
  }
110
130
 
131
+ &:not(.ds-loading):disabled {
132
+ opacity: $ds-opacity-component-disabled;
133
+ cursor: not-allowed;
134
+ }
135
+
111
136
  @at-root a#{&} {
112
137
  box-sizing: border-box;
113
138
  text-align: center;
@@ -134,12 +159,12 @@ $ds-btn__icon-size: 24px;
134
159
  }
135
160
 
136
161
  @include ds-hover() {
137
- &:hover:not(:disabled):not(.ds-loading)::before {
138
- background: var(--ds-btn__background-color-hover);
162
+ &:hover:not(:disabled):not(.ds-loading) {
163
+ opacity: $ds-opacity-component-hover-pressed;
139
164
  }
140
165
  }
141
166
  &:active:not(:disabled):not(.ds-loading)::before {
142
- background: var(--ds-btn__background-color-active);
167
+ opacity: $ds-opacity-component-hover-pressed;
143
168
  }
144
169
 
145
170
  @include ds-loading();
@@ -151,8 +176,43 @@ $ds-btn__icon-size: 24px;
151
176
  }
152
177
 
153
178
  .ds-btn--small {
179
+ padding: ds-px-to-rem(ds-spacing($ds-s-025) - $ds-btn-outlined__border-width)
180
+ ds-px-to-rem(ds-spacing($ds-s-075) - $ds-btn-outlined__border-width);
181
+ @at-root .ds-force-px#{&} {
182
+ /* stylelint-disable-next-line */
183
+ padding: ds-spacing($ds-s-025) - $ds-btn-outlined__border-width ds-spacing($ds-s-075) -
184
+ $ds-btn-outlined__border-width;
185
+ }
186
+ }
187
+
188
+ .ds-btn--medium {
154
189
  padding: ds-px-to-rem(ds-spacing($ds-s-050) - $ds-btn-outlined__border-width)
155
190
  ds-px-to-rem(ds-spacing($ds-s-125) - $ds-btn-outlined__border-width);
191
+ @at-root .ds-force-px#{&} {
192
+ /* stylelint-disable-next-line */
193
+ padding: ds-spacing($ds-s-050) - $ds-btn-outlined__border-width ds-spacing($ds-s-125) -
194
+ $ds-btn-outlined__border-width;
195
+ }
196
+ }
197
+
198
+ .ds-btn--large {
199
+ padding: ds-px-to-rem(ds-spacing($ds-s-075) - $ds-btn-outlined__border-width)
200
+ ds-px-to-rem(ds-spacing($ds-s-150) - $ds-btn-outlined__border-width);
201
+ @at-root .ds-force-px#{&} {
202
+ /* stylelint-disable-next-line */
203
+ padding: ds-spacing($ds-s-075) - $ds-btn-outlined__border-width ds-spacing($ds-s-150) -
204
+ $ds-btn-outlined__border-width;
205
+ }
206
+ }
207
+
208
+ .ds-btn--xlarge {
209
+ padding: ds-px-to-rem(ds-spacing($ds-s-075) - $ds-btn-outlined__border-width)
210
+ ds-px-to-rem(ds-spacing($ds-s-200) - $ds-btn-outlined__border-width);
211
+ @at-root .ds-force-px#{&} {
212
+ /* stylelint-disable-next-line */
213
+ padding: ds-spacing($ds-s-075) - $ds-btn-outlined__border-width ds-spacing($ds-s-200) -
214
+ $ds-btn-outlined__border-width;
215
+ }
156
216
  }
157
217
 
158
218
  @include ds-mq-only-breakpoint(mobile) {
@@ -162,15 +222,16 @@ $ds-btn__icon-size: 24px;
162
222
  }
163
223
 
164
224
  .ds-btn--icon-left,
165
- .ds-btn--icon-right {
225
+ .ds-btn--icon-right,
226
+ .ds-btn--selected,
227
+ .ds-btn--icon-only {
166
228
  display: inline-flex;
167
229
  align-items: center;
168
230
  justify-content: center;
169
231
  .ds-icon {
170
232
  display: flex;
171
- height: ds-px-to-rem($ds-btn__icon-size);
172
- width: ds-px-to-rem($ds-btn__icon-size);
173
- margin: ds-spacing(0 0 0 $ds-s-050, rem);
233
+ height: var(--ds-btn__icon-size);
234
+ width: var(--ds-btn__icon-size);
174
235
  svg {
175
236
  fill: currentColor;
176
237
  }
@@ -178,63 +239,61 @@ $ds-btn__icon-size: 24px;
178
239
  }
179
240
 
180
241
  .ds-btn--icon-right {
181
- padding-right: ds-px-to-rem(ds-spacing($ds-s-125) - $ds-btn-outlined__border-width);
182
- &.ds-btn--small {
183
- padding-right: ds-px-to-rem(ds-spacing($ds-s-100) - $ds-btn-outlined__border-width);
242
+ .ds-icon {
243
+ margin: ds-spacing(0 0 0 $ds-s-050, rem);
244
+ @at-root .ds-force-px#{&} {
245
+ margin: ds-spacing(0 0 0 $ds-s-050);
246
+ }
247
+ }
248
+ &.ds-btn--small .ds-icon {
249
+ margin: ds-spacing(0 0 0 $ds-s-025, rem);
250
+ @at-root .ds-force-px#{&} {
251
+ margin: ds-spacing(0 0 0 $ds-s-025);
252
+ }
184
253
  }
185
254
  }
186
255
 
187
- .ds-btn--icon-left {
256
+ .ds-btn--icon-left,
257
+ .ds-btn--selected:not(.ds-btn--icon-only) {
188
258
  flex-direction: row-reverse;
189
- padding-left: ds-px-to-rem(ds-spacing($ds-s-125) - $ds-btn-outlined__border-width);
190
259
  .ds-icon {
191
260
  margin: ds-spacing(0 $ds-s-050 0 0, rem);
261
+ @at-root .ds-force-px#{&} {
262
+ margin: ds-spacing(0 $ds-s-050 0 0);
263
+ }
192
264
  }
193
- &.ds-btn--small {
194
- padding-left: ds-px-to-rem(ds-spacing($ds-s-100) - $ds-btn-outlined__border-width);
195
- }
196
- }
197
-
198
- .ds-btn--brand,
199
- .ds-btn--business,
200
- .ds-btn--primary,
201
- .ds-btn--staticWhiteFilled {
202
- &:not(.ds-loading):disabled {
203
- opacity: $ds-opacity-component-disabled;
204
- cursor: not-allowed;
265
+ &.ds-btn--small .ds-icon {
266
+ margin: ds-spacing(0 $ds-s-025 0 0, rem);
267
+ @at-root .ds-force-px#{&} {
268
+ margin: ds-spacing(0 $ds-s-025 0 0);
269
+ }
205
270
  }
206
271
  }
207
272
 
208
- .ds-btn.ds-force-px {
209
- /* stylelint-disable-next-line */
210
- padding: ds-spacing($ds-s-075) - $ds-btn-outlined__border-width ds-spacing($ds-s-150) -
211
- $ds-btn-outlined__border-width;
212
- @include ds-typography($ds-typography-detailstandard-button, true);
213
-
214
- &.ds-btn--icon-left,
215
- &.ds-btn--icon-right {
216
- .ds-icon {
217
- margin: ds-spacing(0 0 0 $ds-s-050);
218
- height: $ds-btn__icon-size;
219
- width: $ds-btn__icon-size;
220
- }
273
+ .ds-btn--toggle {
274
+ .ds-btn__on,
275
+ .ds-btn__off {
276
+ align-items: center;
221
277
  }
222
- &.ds-btn--icon-right {
223
- padding-right: ds-spacing($ds-s-125)-$ds-btn-outlined__border-width;
278
+ .ds-btn__on {
279
+ display: none;
224
280
  }
225
- &.ds-btn--icon-left {
226
- padding-left: ds-spacing($ds-s-125)-$ds-btn-outlined__border-width;
227
- .ds-icon {
228
- margin: ds-spacing(0 $ds-s-050 0 0);
281
+ &.ds-btn--selected {
282
+ .ds-btn__on {
283
+ display: flex;
229
284
  }
230
- }
231
- &.ds-btn--small {
232
- padding: ds-spacing($ds-s-050)-$ds-btn-outlined__border-width ds-spacing($ds-s-125)-$ds-btn-outlined__border-width;
233
- &.ds-btn--icon-right {
234
- padding-right: ds-spacing($ds-s-100)-$ds-btn-outlined__border-width;
285
+ .ds-btn__off {
286
+ display: none;
235
287
  }
236
- &.ds-btn--icon-left {
237
- padding-left: ds-spacing($ds-s-100)-$ds-btn-outlined__border-width;
288
+ }
289
+
290
+ // we have to override spinner styling since spinner variant is based on "off" button variant
291
+ &.ds-btn--selected.ds-loading:not(.ds-btn--icon-only) {
292
+ .ds-spinner__inner {
293
+ border-top-color: $ds-color-icon-primary;
294
+ &::before {
295
+ border-color: $ds-color-icon-primary;
296
+ }
238
297
  }
239
298
  }
240
299
  }
@@ -14,8 +14,8 @@
14
14
  |text | String | yes | | | |
15
15
  |selectedText | String | yes | | | |
16
16
  |disabled | bool | no | true, false | false | |
17
- |variant | String | no | brand, SecondaryFilled | brand | Design variant |
18
- |size| String | no | default, small, xsmall | default | |
17
+ |variant | String | no | primary, secondary, brand | primary | Design variant |
18
+ |size| String | no | small, medium, large | medium | |
19
19
  |fullWidth | bool | no | true, false | false | Button will be full width on both desktop and mobile |
20
20
  |mobile.fullWidth | bool | no | true, false | false | Ex mobile: { fullWidth: true } |
21
21
  |loading | bool | no | true, false | false | |
@@ -50,7 +50,7 @@ These are copy paste friendly examples to quickliy get started using a component
50
50
  ### Javascript
51
51
 
52
52
  ```javascript
53
- import dsButtonToggle from '@bonniernews/dn-design-system-web/components/button-toggle/button-toggle.js'
54
- const toggleElements = Array.from(document.getElementsByClassName("ds-btn-toggle"));
53
+ import dsButtonToggle from '@bonniernews/dn-design-system-web/components/button/button.js'
54
+ const toggleElements = Array.from(document.getElementsByClassName("ds-btn--toggle"));
55
55
  dsButtonToggle(toggleElements);
56
56
  ```
@@ -1,39 +1,20 @@
1
- {% from '@bonniernews/dn-design-system-web/components/icon-sprite/icon-sprite.njk' import IconUse %}
2
- {% from '@bonniernews/dn-design-system-web/components/spinner/spinner.njk' import Spinner %}
3
- {% from '@bonniernews/dn-design-system-web/njk-helpers/attributes.njk' import getAttributes %}
1
+ {% from '@bonniernews/dn-design-system-web/components/button/button.njk' import Button %}
4
2
 
5
3
  {% macro ButtonToggle(params) %}
6
- {%- set componentClassName = "ds-btn-toggle" %}
7
- {%- set classNamePrefix = componentClassName + "--" %}
8
- {%- set attributes = getAttributes(params.attributes) %}
9
- {%- set ariaLabel = 'aria-label="' + params.text + '"' if not params.attributes["aria-label"] else "" %}
10
- {%- set buttonVariant = params.variant | default("brand") %}
11
-
12
- {%- set spinnerMap = { primary: "secondary", brand: "onBrand", business: "onBusiness" } %}
13
- {%- set spinnerVariant = spinnerMap[buttonVariant] | default("primary") %}
14
- {%- set spinnerSize = "xsmall" if params.size == "xsmall" else "small" %}
15
-
16
- {%- set loadingHtml %}
17
- {{ Spinner({ size: spinnerSize, variant: spinnerVariant, forcePx: params.forcePx, attributes: { "aria-hidden": "true" } }) }}
18
- {% endset %}
19
-
20
- {%- set classes = [
21
- componentClassName,
22
- classNamePrefix + buttonVariant,
23
- classNamePrefix + "selected" if params.selected,
24
- classNamePrefix + params.size if params.size and params.size !== "default",
25
- classNamePrefix + "full-width" if params.fullWidth,
26
- classNamePrefix + "mobile-full-width" if params.mobile and params.mobile.fullWidth,
27
- "ds-loading" if params.loading,
28
- "ds-force-px" if params.forcePx,
29
- params.classNames if params.classNames
30
- ] | join(" ") %}
31
-
32
- <button type="button" role="switch" {{ ariaLabel | safe }} aria-checked="{{ "true" if params.selected else "false" }}" class="{{ classes }}" {{ "disabled" if params.disabled }} {{- attributes | safe }}>
33
- <span class="{{ componentClassName + '__off' }}" aria-hidden="true"><span>{{ params.text }}</span></span>
34
- <span class="{{ componentClassName + '__on' }}" aria-hidden="true">
35
- {{ IconUse({ icon: "check" }) }} <span>{{ params.selectedText }}</span>
36
- </span>
37
- {{ loadingHtml | safe }}
38
- </button>
4
+ {{ Button({
5
+ isToggle: true,
6
+ rounded: true,
7
+ selected: params.selected,
8
+ text: params.text,
9
+ selectedText: params.selectedText,
10
+ variant: params.variant,
11
+ disabled: params.disabled,
12
+ size: params.size,
13
+ fullWidth: params.fullWidth,
14
+ mobile: params.mobile,
15
+ loading: params.loading,
16
+ forcePx: params.forcePx,
17
+ classNames: params.classNames,
18
+ attributes: params.attributes
19
+ }) }}
39
20
  {% endmacro %}