@bonniernews/dn-design-system-web 14.3.10 → 14.4.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 (36) hide show
  1. package/CHANGELOG.md +19 -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-UXD.md +2 -2
  5. package/components/button/README.md +4 -2
  6. package/components/{button-toggle/button-toggle.js → button/button.js} +3 -3
  7. package/components/button/button.njk +62 -15
  8. package/components/button/button.scss +179 -121
  9. package/components/button-toggle/README.md +4 -4
  10. package/components/button-toggle/button-toggle.njk +17 -36
  11. package/components/button-toggle/button-toggle.scss +1 -215
  12. package/components/byline/README.md +2 -2
  13. package/components/byline/byline.njk +2 -2
  14. package/components/factbox/factbox.njk +4 -4
  15. package/components/group-header/group-header.njk +5 -3
  16. package/components/group-header/group-header.scss +4 -4
  17. package/components/icon-button/README.md +5 -3
  18. package/components/icon-button/icon-button.njk +18 -51
  19. package/components/icon-button/icon-button.scss +19 -126
  20. package/components/icon-button-toggle/README.md +8 -8
  21. package/components/icon-button-toggle/icon-button-toggle.njk +14 -1
  22. package/components/icon-button-toggle/icon-button-toggle.scss +1 -17
  23. package/components/list-item/list-item.js +2 -2
  24. package/components/list-item/list-item.njk +2 -2
  25. package/components/list-item/list-item.scss +1 -1
  26. package/components/modal/modal.njk +3 -2
  27. package/components/modal/modal.scss +4 -4
  28. package/components/tag-header/tag-header.njk +1 -1
  29. package/components/teaser-list-swipe/teaser-list-swipe.njk +4 -2
  30. package/components/teaser-list-vertical/teaser-list-vertical.njk +1 -1
  31. package/components/text-input/text-input.scss +1 -1
  32. package/package.json +1 -1
  33. package/components/floating-button/README.md +0 -41
  34. package/components/floating-button/floating-button.njk +0 -41
  35. package/components/floating-button/floating-button.scss +0 -145
  36. package/components/icon-button-toggle/icon-button-toggle.js +0 -21
package/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All changes to @bonniernews/dn-design-system-web will be documented in this file
4
4
 
5
5
 
6
6
 
7
+ ## [14.4.0-beta.0](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@14.3.10...@bonniernews/dn-design-system-web@14.4.0-beta.0) (2024-03-20)
8
+
9
+
10
+ ### Features
11
+
12
+ * **web:** refactor buttons ([e3124c6](https://github.com/BonnierNews/dn-design-system/commit/e3124c686fbe6b370eea0cd0acc8bebda926b29f))
13
+
7
14
  ## [14.3.10](https://github.com/BonnierNews/dn-design-system/compare/@bonniernews/dn-design-system-web@14.3.9...@bonniernews/dn-design-system-web@14.3.10) (2024-03-20)
8
15
 
9
16
 
@@ -120,6 +127,18 @@ All changes to @bonniernews/dn-design-system-web will be documented in this file
120
127
 
121
128
  * prerelease packages ([2a8954c](https://github.com/BonnierNews/dn-design-system/commit/2a8954c0cce43dfc53d0b5617c0d41c6ae2ba94b))
122
129
 
130
+
131
+ ## [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)
132
+
133
+
134
+ ### ⚠ BREAKING CHANGES
135
+
136
+ * **web:** refactor buttons
137
+
138
+ ### Features
139
+
140
+ * **web:** refactor buttons ([6fc9ca6](https://github.com/BonnierNews/dn-design-system/commit/6fc9ca69cdde1e6cb209a86282b863c4fb8a8518))
141
+
123
142
  ## [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)
124
143
 
125
144
 
@@ -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,
@@ -18,8 +18,8 @@ Buttons are used to initialize an action. Button labels express what action will
18
18
  | --------- | ---------------------------------------------------------------------------------------------------- |
19
19
  | [Brand](#brand) | Extra high emphasis button used for actions that are extra important for the user flow and conversion. I.e. ”Logga in” |
20
20
  | [Primary](#primary) | High emphasis button used to attract attention to the most important task of the layout, typically the next step in the user flow. I.e. ”Nästa fråga” in a quiz. |
21
- | Secondary| Medium emphasis button used for alternative non-primary actions. I.e. ”Alla nyheter” in a list of news. |
22
- | Outline | Low emphasis Button used for less important actions. Usually used in combination with a primary or brand Button. |
21
+ | [Secondary](#secondary)| Medium emphasis button used for alternative non-primary actions. I.e. ”Alla nyheter” in a list of news. |
22
+ | [Outline](#primary%20outline) | Low emphasis Button used for less important actions. Usually used in combination with a primary or brand Button. |
23
23
 
24
24
 
25
25
  ## Usage
@@ -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
  }
@@ -1,46 +1,93 @@
1
1
  {% from '@bonniernews/dn-design-system-web/components/icon-sprite/icon-sprite.njk' import IconUse %}
2
2
  {% from '@bonniernews/dn-design-system-web/components/spinner/spinner.njk' import Spinner %}
3
3
  {% from '@bonniernews/dn-design-system-web/njk-helpers/attributes.njk' import getAttributes %}
4
+ {% from '@bonniernews/dn-design-system-web/foundations/a11y/visually-hidden.njk' import VisuallyHidden %}
5
+
6
+ {% macro InnerButton(params) %}
7
+ {% if not params.isIconButton %}
8
+ <span aria-hidden="true">{{ params.text }}</span>
9
+ {% elif not params.attributes["aria-label"] and params.a11y and params.a11y.visuallyHidden %}
10
+ {{- VisuallyHidden({ text: params.a11y.visuallyHidden }) | safe -}}
11
+ {% endif %}
12
+ {{- params.iconSvg | safe if params.iconSvg -}} {{ params.loadingHtml | safe }}
13
+ {% endmacro %}
14
+
15
+ {% macro ToggleWrapper(params) %}
16
+ <button type="button" role="switch" {{ params.ariaLabel | safe }} aria-checked="{{ "true" if params.selected else "false" }}" class="{{ params.classes }}" {{ "disabled" if params.disabled }} {{- params.attributes | safe }}>
17
+ {{ caller() }}
18
+ {{ params.loadingHtml | safe }}
19
+ </button>
20
+ {% endmacro %}
4
21
 
5
22
  {% macro Button(params) %}
6
23
  {%- set componentClassName = "ds-btn" %}
7
24
  {%- set classNamePrefix = componentClassName + "--" %}
8
25
  {%- set text = params.text %}
9
26
  {%- set attributes = getAttributes(params.attributes) %}
10
- {%- set ariaLabel = 'aria-label="' + text + '"' if not params.attributes["aria-label"] else "" %}
27
+ {%- set ariaLabel = 'aria-label="' + text + '"' if params.text and not params.attributes["aria-label"] else "" %}
11
28
  {%- 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") %}
29
+ {%- set emphasis = params.emphasis | default("default") %}
30
+
31
+ {% if params.variant == "staticWhite" %}
32
+ {% if emphasis == "transparent" or emphasis == "outline" %}
33
+ {%- set spinnerVariant = "staticWhite" %}
34
+ {% else %}
35
+ {%- set spinnerVariant = "staticBlack" %}
36
+ {% endif %}
37
+ {% elif emphasis == "transparent" or emphasis == "outline" or params.variant == "secondary" %}
38
+ {%- set spinnerVariant = "primary" %}
39
+ {% else %}
40
+ {%- set spinnerVariant = "secondary" %}
41
+ {% endif %}
42
+
14
43
  {%- set loadingHtml %}
15
44
  {{ Spinner({ size: 'small', variant: spinnerVariant, forcePx: params.forcePx, attributes: { "aria-hidden": "true" } }) }}
16
45
  {% endset %}
17
46
 
18
- {%- if params.iconName and params.iconPosition and params.iconPosition != "none" %}
47
+ {%- if params.iconName and ((params.iconPosition and params.iconPosition != "none") or params.isIconBtn == true) %}
19
48
  {% set iconSvg = IconUse({ icon: params.iconName, attributes: { "aria-hidden": "true" } }) %}
20
49
  {% endif %}
21
50
 
22
51
  {%- set classes = [
23
52
  componentClassName,
24
53
  classNamePrefix + buttonVariant,
54
+ classNamePrefix + emphasis,
25
55
  classNamePrefix + "selected" if params.selected,
26
- classNamePrefix + params.size if params.size and params.size !== "default",
56
+ classNamePrefix + params.size if params.size else classNamePrefix + "large",
27
57
  classNamePrefix + "full-width" if params.fullWidth,
28
58
  classNamePrefix + "mobile-full-width" if params.mobile and params.mobile.fullWidth,
29
- classNamePrefix + "icon-" + params.iconPosition if iconSvg,
59
+ classNamePrefix + "icon-" + params.iconPosition if iconSvg and not params.isIconBtn,
60
+ classNamePrefix + "icon-only" if params.isIconBtn,
61
+ classNamePrefix + "rounded" if params.rounded,
62
+ classNamePrefix + "toggle" if params.isToggle,
63
+ classNamePrefix + "selected" if params.isToggle and params.selected,
30
64
  "ds-loading" if params.loading,
31
65
  "ds-force-px" if params.forcePx,
32
66
  params.classNames if params.classNames
33
67
  ] | join(" ") %}
34
68
 
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>
69
+ {%- if params.isToggle %}
70
+ {% call ToggleWrapper({ ariaLabel: ariaLabel, selected: params.selected, classes: classes, attributes: attributes, disabled: params.disabled, loadingHtml: loadingHtml }) %}
71
+ {%- if params.isIconBtn %}
72
+ <span class="ds-btn__off" aria-hidden="true">{{ IconUse({ icon: params.iconName }) }}</span>
73
+ <span class="ds-btn__on" aria-hidden="true">{{ IconUse({ icon: params.selectedIconName }) }}</span>
74
+ {% else %}
75
+ <span class="ds-btn__off" aria-hidden="true"><span>{{ params.text }}</span></span>
76
+ <span class="ds-btn__on" aria-hidden="true">
77
+ {{ IconUse({ icon: "check" }) }} <span>{{ params.selectedText }}</span>
78
+ </span>
79
+ {% endif %}
80
+ {% endcall %}
40
81
  {% 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>
82
+ {% set buttonParams = { isIconButton: params.isIconBtn, a11y: params.a11y, text: text, iconSvg: iconSvg, loadingHtml: loadingHtml , attributes: params.attributes } %}
83
+ {%- if params.href %}
84
+ <a href="{{ params.href | default('#', true) }}" {{ ariaLabel | safe }} class="{{ classes }}" {{- attributes | safe }}>
85
+ {{ InnerButton(buttonParams) }}
86
+ </a>
87
+ {% else %}
88
+ <button type="{{ params.type | default('button') }}" {{ ariaLabel | safe }} class="{{ classes }}" {{ "disabled" if params.disabled }} {{- attributes | safe }}>
89
+ {{ InnerButton(buttonParams) }}
90
+ </button>
91
+ {% endif %}
45
92
  {% endif %}
46
93
  {% endmacro %}
@@ -4,94 +4,147 @@
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;
7
+ @function _btn-brdr($value, $rem: false) {
8
+ $value: (ds-strip-unit($value) - ds-strip-unit($ds-btn-outlined__border-width)) * 1px;
9
+ @if $rem {
10
+ @return ds-px-to-rem($value);
11
+ }
12
+ @return $value;
13
+ }
8
14
 
9
15
  .ds-btn {
10
- --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};
16
+ --ds-btn__background-color: #{$ds-color-surface-background};
17
+ --ds-btn__border-color: transparent;
14
18
  --ds-btn__outline-color: #{$ds-color-border-focus-02};
15
- --ds-btn__color: #{$ds-color-text-primary};
19
+ --ds-btn__icon-size: #{ds-px-to-rem(24px)};
20
+ @at-root .ds-force-px#{&} {
21
+ --ds-btn__icon-size: 24px;
22
+ }
16
23
 
17
24
  &.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};
25
+ &.ds-btn--default,
26
+ &.ds-btn--elevated {
27
+ --ds-btn__background-color: #{$ds-color-component-primary};
28
+ --ds-btn__color: #{$ds-color-text-secondary};
29
+ }
30
+ &.ds-btn--outline {
31
+ --ds-btn__border-color: #{$ds-color-component-primary};
32
+ --ds-btn__color: #{$ds-color-text-primary};
33
+ }
34
+ &.ds-btn--transparent {
35
+ --ds-btn__color: #{$ds-color-text-primary};
36
+ }
37
+ }
38
+ &.ds-btn--secondary {
39
+ &.ds-btn--default,
40
+ &.ds-btn--elevated {
41
+ --ds-btn__background-color: #{$ds-color-component-primary-overlay};
42
+ --ds-btn__color: #{$ds-color-text-primary};
43
+ }
44
+ &.ds-btn--outline {
45
+ --ds-btn__border-color: #{$ds-color-border-primary-02};
46
+ --ds-btn__color: #{$ds-color-text-primary};
47
+ }
48
+ &.ds-btn--transparent {
49
+ --ds-btn__color: #{$ds-color-text-primary};
50
+ }
23
51
  }
24
-
25
52
  &.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
53
  --ds-btn__outline-color: #{$ds-color-border-focus};
54
+ &.ds-btn--default,
55
+ &.ds-btn--elevated {
56
+ --ds-btn__background-color: #{$ds-color-component-brand};
57
+ --ds-btn__color: #{$ds-color-text-secondary};
58
+ }
59
+ &.ds-btn--outline {
60
+ --ds-btn__border-color: #{$ds-color-component-brand};
61
+ --ds-btn__color: #{$ds-color-text-brand};
62
+ }
63
+ &.ds-btn--transparent {
64
+ --ds-btn__color: #{$ds-color-text-brand};
65
+ }
30
66
  }
31
-
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};
67
+ &.ds-btn--staticWhite {
68
+ --ds-btn__outline-color: #{$ds-color-static-white};
69
+ &.ds-btn--default,
70
+ &.ds-btn--elevated {
71
+ --ds-btn__background-color: #{$ds-color-static-white};
72
+ --ds-btn__color: #{$ds-color-static-black};
73
+ }
74
+ &.ds-btn--outline {
75
+ --ds-btn__background-color: transparent;
76
+ --ds-btn__border-color: #{$ds-color-static-white};
77
+ --ds-btn__color: #{$ds-color-static-white};
78
+ }
79
+ &.ds-btn--transparent {
80
+ --ds-btn__color: #{$ds-color-static-white};
81
+ }
37
82
  }
38
83
 
39
- &.ds-btn--secondaryFilled {
40
- --ds-btn__background-color: #{$ds-color-component-primary-overlay};
41
- --ds-btn__border-color: transparent;
84
+ &.ds-btn--toggle.ds-btn--selected:not(.ds-btn--icon-only) {
85
+ --ds-btn__background-color: transparent;
86
+ --ds-btn__color: #{$ds-color-text-primary};
87
+ --ds-btn__border-color: #{$ds-color-component-primary};
88
+ --ds-btn__outline-color: #{$ds-color-border-focus-02};
42
89
  }
43
-
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};
90
+ &.ds-btn--transparent {
91
+ --ds-btn__background-color: transparent;
92
+ }
93
+ &.ds-btn--rounded {
94
+ border-radius: 100px;
95
+ }
96
+ &.ds-btn--elevated {
97
+ box-shadow: ds-shadow-get-box-shadow($ds-shadow-elevation-m);
50
98
  }
51
99
 
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};
59
- --ds-btn__outline-color: #{$ds-color-static-white};
60
-
61
- &:not(:disabled) .ds-icon {
62
- --ds-btn__color: #{$ds-color-static-white};
100
+ &.ds-btn--small {
101
+ @include ds-typography($ds-typography-detailstandard-button-small);
102
+ --ds-btn__icon-size: #{ds-px-to-rem(20px)};
103
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-050), true)};
104
+ padding: _btn-brdr(ds-spacing($ds-s-025), true) _btn-brdr(ds-spacing($ds-s-075), true);
105
+ @at-root .ds-force-px#{&} {
106
+ @include ds-typography($ds-typography-detailstandard-button-small, true);
107
+ --ds-btn__icon-size: 20px;
108
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-050))};
109
+ padding: _btn-brdr(ds-spacing($ds-s-025)) _btn-brdr(ds-spacing($ds-s-075));
63
110
  }
64
111
  }
65
-
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};
112
+ &.ds-btn--medium {
113
+ @include ds-typography($ds-typography-detailstandard-button);
114
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-100), true)};
115
+ padding: _btn-brdr(ds-spacing($ds-s-050), true) _btn-brdr(ds-spacing($ds-s-125), true);
116
+ @at-root .ds-force-px#{&} {
117
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-100))};
118
+ @include ds-typography($ds-typography-detailstandard-button, true);
119
+ padding: _btn-brdr(ds-spacing($ds-s-050)) _btn-brdr(ds-spacing($ds-s-125));
73
120
  }
74
121
  }
75
-
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;
122
+ &.ds-btn--large {
123
+ @include ds-typography($ds-typography-detailstandard-button);
124
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-125), true)};
125
+ padding: _btn-brdr(ds-spacing($ds-s-075), true) _btn-brdr(ds-spacing($ds-s-150), true);
126
+ @at-root .ds-force-px#{&} {
127
+ @include ds-typography($ds-typography-detailstandard-button, true);
128
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-125))};
129
+ padding: _btn-brdr(ds-spacing($ds-s-075)) _btn-brdr(ds-spacing($ds-s-150));
130
+ }
131
+ }
132
+ &.ds-btn--xlarge {
133
+ @include ds-typography($ds-typography-detailstandard-button-xlarge);
134
+ --ds-btn__icon-size: #{ds-px-to-rem(32px)};
135
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-200), true) - ds-px-to-rem(4px)};
136
+ padding: _btn-brdr(ds-spacing($ds-s-075), true) _btn-brdr(ds-spacing($ds-s-200), true);
137
+ @at-root .ds-force-px#{&} {
138
+ @include ds-typography($ds-typography-detailstandard-button-xlarge, true);
139
+ --ds-btn__icon-size: 32px;
140
+ --ds-btn__icon-padding: #{_btn-brdr(ds-spacing($ds-s-200)) - 4px};
141
+ padding: _btn-brdr(ds-spacing($ds-s-075)) _btn-brdr(ds-spacing($ds-s-200));
85
142
  }
86
143
  }
87
144
 
88
- @include ds-typography($ds-typography-detailstandard-button);
89
145
  cursor: pointer;
90
146
  border: $ds-btn-outlined__border-width solid var(--ds-btn__border-color);
91
147
  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
148
  position: relative;
96
149
  background-color: var(--ds-btn__background-color);
97
150
  color: var(--ds-btn__color);
@@ -108,6 +161,11 @@ $ds-btn__icon-size: 24px;
108
161
  outline-offset: 2px;
109
162
  }
110
163
 
164
+ &:not(.ds-loading):disabled {
165
+ opacity: $ds-opacity-component-disabled;
166
+ cursor: not-allowed;
167
+ }
168
+
111
169
  @at-root a#{&} {
112
170
  box-sizing: border-box;
113
171
  text-align: center;
@@ -134,12 +192,12 @@ $ds-btn__icon-size: 24px;
134
192
  }
135
193
 
136
194
  @include ds-hover() {
137
- &:hover:not(:disabled):not(.ds-loading)::before {
138
- background: var(--ds-btn__background-color-hover);
195
+ &:hover:not(:disabled):not(.ds-loading) {
196
+ opacity: $ds-opacity-component-hover-pressed;
139
197
  }
140
198
  }
141
199
  &:active:not(:disabled):not(.ds-loading)::before {
142
- background: var(--ds-btn__background-color-active);
200
+ opacity: $ds-opacity-component-hover-pressed;
143
201
  }
144
202
 
145
203
  @include ds-loading();
@@ -150,11 +208,6 @@ $ds-btn__icon-size: 24px;
150
208
  box-sizing: border-box;
151
209
  }
152
210
 
153
- .ds-btn--small {
154
- padding: ds-px-to-rem(ds-spacing($ds-s-050) - $ds-btn-outlined__border-width)
155
- ds-px-to-rem(ds-spacing($ds-s-125) - $ds-btn-outlined__border-width);
156
- }
157
-
158
211
  @include ds-mq-only-breakpoint(mobile) {
159
212
  .ds-btn--mobile-full-width {
160
213
  width: 100%;
@@ -162,79 +215,84 @@ $ds-btn__icon-size: 24px;
162
215
  }
163
216
 
164
217
  .ds-btn--icon-left,
165
- .ds-btn--icon-right {
218
+ .ds-btn--icon-right,
219
+ .ds-btn--toggle.ds-btn--selected,
220
+ .ds-btn--icon-only {
166
221
  display: inline-flex;
167
222
  align-items: center;
168
223
  justify-content: center;
169
224
  .ds-icon {
170
225
  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);
226
+ height: var(--ds-btn__icon-size);
227
+ width: var(--ds-btn__icon-size);
174
228
  svg {
175
229
  fill: currentColor;
176
230
  }
177
231
  }
178
232
  }
179
-
180
- .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);
233
+ .ds-btn.ds-btn--icon-right {
234
+ padding-right: var(--ds-btn__icon-padding);
235
+ &.ds-force-px {
236
+ padding-right: var(--ds-btn__icon-padding);
237
+ }
238
+ .ds-icon {
239
+ margin: ds-spacing(0 0 0 $ds-s-050, rem);
240
+ @at-root .ds-force-px#{&} {
241
+ margin: ds-spacing(0 0 0 $ds-s-050);
242
+ }
243
+ }
244
+ &.ds-btn--small .ds-icon {
245
+ margin: ds-spacing(0 0 0 $ds-s-025, rem);
246
+ @at-root .ds-force-px#{&} {
247
+ margin: ds-spacing(0 0 0 $ds-s-025);
248
+ }
184
249
  }
185
250
  }
186
-
187
- .ds-btn--icon-left {
251
+ .ds-btn.ds-btn--icon-left,
252
+ .ds-btn.ds-btn--selected:not(.ds-btn--icon-only) {
188
253
  flex-direction: row-reverse;
189
- padding-left: ds-px-to-rem(ds-spacing($ds-s-125) - $ds-btn-outlined__border-width);
254
+ padding-left: var(--ds-btn__icon-padding);
190
255
  .ds-icon {
191
256
  margin: ds-spacing(0 $ds-s-050 0 0, rem);
192
257
  }
193
- &.ds-btn--small {
194
- padding-left: ds-px-to-rem(ds-spacing($ds-s-100) - $ds-btn-outlined__border-width);
258
+ &.ds-btn--small .ds-icon {
259
+ margin: ds-spacing(0 $ds-s-025 0 0, rem);
195
260
  }
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;
261
+ &.ds-force-px {
262
+ padding-left: var(--ds-btn__icon-padding);
263
+ .ds-icon {
264
+ margin: ds-spacing(0 $ds-s-050 0 0);
265
+ }
266
+ &.ds-btn--small .ds-icon {
267
+ margin: ds-spacing(0 $ds-s-025 0 0);
268
+ }
205
269
  }
206
270
  }
207
271
 
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
- }
272
+ .ds-btn--toggle {
273
+ .ds-btn__on,
274
+ .ds-btn__off {
275
+ align-items: center;
221
276
  }
222
- &.ds-btn--icon-right {
223
- padding-right: ds-spacing($ds-s-125)-$ds-btn-outlined__border-width;
277
+ .ds-btn__on {
278
+ display: none;
224
279
  }
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);
280
+ &.ds-btn--selected {
281
+ .ds-btn__on {
282
+ display: flex;
229
283
  }
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;
284
+ .ds-btn__off {
285
+ display: none;
235
286
  }
236
- &.ds-btn--icon-left {
237
- padding-left: ds-spacing($ds-s-100)-$ds-btn-outlined__border-width;
287
+ }
288
+
289
+ // we have to override spinner styling since spinner variant is based on "off" button variant
290
+ &.ds-btn--selected.ds-loading:not(.ds-btn--icon-only) {
291
+ .ds-spinner__inner {
292
+ border-top-color: $ds-color-icon-primary;
293
+ &::before {
294
+ border-color: $ds-color-icon-primary;
295
+ }
238
296
  }
239
297
  }
240
298
  }
@@ -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
  ```