@hashicorp/design-system-components 0.11.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/addon/components/hds/alert/index.hbs +1 -3
  3. package/addon/components/hds/button/index.hbs +14 -2
  4. package/addon/components/hds/button/index.js +0 -21
  5. package/addon/components/hds/dropdown/list-item/copy-item.hbs +1 -5
  6. package/addon/components/hds/dropdown/list-item/interactive.hbs +19 -41
  7. package/addon/components/hds/interactive/index.hbs +33 -0
  8. package/addon/components/hds/interactive/index.js +33 -0
  9. package/addon/components/hds/link/inline.hbs +23 -0
  10. package/addon/components/hds/link/inline.js +71 -0
  11. package/addon/components/hds/link/standalone.hbs +15 -5
  12. package/addon/components/hds/link/standalone.js +7 -0
  13. package/addon/components/hds/toast/index.hbs +1 -8
  14. package/app/components/hds/{link/cta.js → interactive/index.js} +1 -1
  15. package/app/components/hds/{link-to/cta.js → link/inline.js} +1 -1
  16. package/app/styles/@hashicorp/design-system-components.scss +4 -1
  17. package/app/styles/components/button.scss +44 -19
  18. package/app/styles/components/dropdown.scss +10 -10
  19. package/app/styles/components/link/inline.scss +66 -0
  20. package/app/styles/components/link/standalone.scss +4 -4
  21. package/app/styles/mixins/_focus-ring.scss +8 -4
  22. package/blueprints/hds-component/files/addon/components/hds/__name__/index.hbs +1 -1
  23. package/blueprints/hds-component/index.js +34 -0
  24. package/package.json +3 -2
  25. package/addon/components/hds/link/cta.hbs +0 -50
  26. package/addon/components/hds/link/cta.js +0 -150
  27. package/addon/components/hds/link-to/cta.hbs +0 -51
  28. package/addon/components/hds/link-to/cta.js +0 -165
  29. package/addon/components/hds/link-to/standalone.hbs +0 -25
  30. package/addon/components/hds/link-to/standalone.js +0 -151
  31. package/app/components/hds/link-to/standalone.js +0 -1
  32. package/app/styles/components/link/cta.scss +0 -28
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @hashicorp/design-system-components
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#217](https://github.com/hashicorp/design-system/pull/217) [`210edd17`](https://github.com/hashicorp/design-system/commit/210edd17431e6e3097260aed0df5a8902f93b7f7) Thanks [@didoo](https://github.com/didoo)! - # Interactive
8
+
9
+ - Introduced `<Hds::Interactive>` (a generic, "utility" component used internally by all the interactive elements like buttons and links)
10
+
11
+ # Button
12
+
13
+ - updated the button API to handle also links as `<a>`/`<LinkTo/LinkToExternal>`
14
+ - it can be used in place of the `<Hds::Link/LinkTo::CTA>` component (see below)
15
+ - when the button is a link - the text is underlined for differentiation with a normal button - ⚠️ **Visual change!** - the button responds to `space` key event
16
+ - removed the `@type` argument from the API in favour of the `type` native attribute - 🚨 **Breaking change!**
17
+
18
+ # Link/LinkTo::CTA
19
+
20
+ - removed the `<Hds::Link/LinkTo::CTA>` component, in favour of `<Hds::Button>` component (see above) - 🚨 **Breaking change!**
21
+
22
+ # Link::Inline
23
+
24
+ - added the `<Hds::Link::Inline>` component (with API very similar to the `<Hds::Link::Standalone>`)
25
+
26
+ # Dropdown
27
+
28
+ - Updated the `Dropdown::ListItem::Interactive` to use the new `<Hds::Interactive>` component
29
+
30
+ # Alert/Toast components
31
+
32
+ - Removed the `<LinkTo::Standalone>` action (now you can use directly `<Link::Standalone>`)
33
+
3
34
  ## 0.11.2
4
35
 
5
36
  ### Patch Changes
@@ -14,9 +14,7 @@
14
14
  <div class="hds-alert__actions">
15
15
  {{yield
16
16
  (hash
17
- Button=(component "hds/button" size="small")
18
- Link::Standalone=(component "hds/link/standalone" size="small")
19
- LinkTo::Standalone=(component "hds/link-to/standalone" size="small")
17
+ Button=(component "hds/button" size="small") Link::Standalone=(component "hds/link/standalone" size="small")
20
18
  )
21
19
  }}
22
20
  </div>
@@ -1,4 +1,16 @@
1
- <button class={{this.classNames}} ...attributes aria-label={{if this.isIconOnly this.text null}} type={{this.type}}>
1
+ <Hds::Interactive
2
+ class={{this.classNames}}
3
+ @current-when={{@current-when}}
4
+ @models={{hds-link-to-models @model @models}}
5
+ @query={{hds-link-to-query @query}}
6
+ @replace={{@replace}}
7
+ @route={{@route}}
8
+ @isRouteExternal={{@isRouteExternal}}
9
+ @href={{@href}}
10
+ @isHrefExternal={{@isHrefExternal}}
11
+ ...attributes
12
+ aria-label={{if this.isIconOnly this.text null}}
13
+ >
2
14
  {{#if this.isIconOnly}}
3
15
  <div class="hds-button__icon">
4
16
  <FlightIcon @name={{this.icon}} @size={{this.iconSize}} @stretched={{true}} />
@@ -26,4 +38,4 @@
26
38
  </div>
27
39
  {{/if}}
28
40
  {{/if}}
29
- </button>
41
+ </Hds::Interactive>
@@ -3,11 +3,9 @@ import { assert } from '@ember/debug';
3
3
 
4
4
  export const DEFAULT_SIZE = 'medium';
5
5
  export const DEFAULT_COLOR = 'primary';
6
- export const DEFAULT_TYPE = 'button';
7
6
  export const DEFAULT_ICONPOSITION = 'leading';
8
7
  export const SIZES = ['small', 'medium', 'large'];
9
8
  export const COLORS = ['primary', 'secondary', 'tertiary', 'critical'];
10
- export const TYPES = ['button', 'submit', 'reset'];
11
9
  export const ICONPOSITIONS = ['leading', 'trailing'];
12
10
 
13
11
  export default class HdsButtonIndexComponent extends Component {
@@ -126,25 +124,6 @@ export default class HdsButtonIndexComponent extends Component {
126
124
  }
127
125
  }
128
126
 
129
- /**
130
- * @param type
131
- * @type {string}
132
- * @default button
133
- * @description The value for the button's `type` attribute. Acceptable values are `button`, `submit`, and `reset`
134
- */
135
- get type() {
136
- let { type = DEFAULT_TYPE } = this.args;
137
-
138
- assert(
139
- `@type for "Hds::Button" must be one of the following: ${TYPES.join(
140
- ', '
141
- )}; received: ${type}`,
142
- TYPES.includes(type)
143
- );
144
-
145
- return type;
146
- }
147
-
148
127
  /**
149
128
  * @param isFullWidth
150
129
  * @type {boolean}
@@ -4,11 +4,7 @@
4
4
  class="hds-dropdown-list-item__copy-item-title hds-typography-body-100 hds-font-weight-semibold"
5
5
  >{{@copyItemTitle}}</div>
6
6
  {{/if}}
7
- <button
8
- type="button"
9
- class="{{if @state (concat 'is-' @state)}} {{if this.isSuccess 'is-success'}}"
10
- {{on "click" this.copyCode}}
11
- >
7
+ <button type="button" class="{{if this.isSuccess 'is-success'}}" {{on "click" this.copyCode}}>
12
8
  <div class="hds-dropdown-list-item__copy-item-text hds-typography-code-100">
13
9
  {{this.text}}
14
10
  </div>
@@ -1,44 +1,22 @@
1
1
  <li class={{this.classNames}}>
2
- {{#if @route}}
3
- <LinkTo
4
- class="{{if @state (concat 'is-' @state)}}"
5
- @current-when={{@current-when}}
6
- @models={{hds-link-to-models @model @models}}
7
- @query={{hds-link-to-query @query}}
8
- @replace={{@replace}}
9
- @route={{@route}}
10
- ...attributes
11
- >
12
- {{#if @icon}}
13
- <div class="hds-dropdown-list-item__interactive-icon">
14
- <FlightIcon @name={{@icon}} @isInlineBlock={{false}} />
15
- </div>
16
- {{/if}}
17
- <div class="hds-dropdown-list-item__interactive-text hds-typography-body-200 hds-font-weight-medium">
18
- {{this.text}}
2
+ <Hds::Interactive
3
+ @current-when={{@current-when}}
4
+ @models={{hds-link-to-models @model @models}}
5
+ @query={{hds-link-to-query @query}}
6
+ @replace={{@replace}}
7
+ @route={{@route}}
8
+ @isRouteExternal={{@isRouteExternal}}
9
+ @href={{@href}}
10
+ @isHrefExternal={{@isHrefExternal}}
11
+ ...attributes
12
+ >
13
+ {{#if @icon}}
14
+ <div class="hds-dropdown-list-item__interactive-icon">
15
+ <FlightIcon @name={{@icon}} @isInlineBlock={{false}} />
19
16
  </div>
20
- </LinkTo>
21
- {{else if @href}}
22
- <a target="_blank" rel="noopener noreferrer" href={{@href}} class="{{if @state (concat 'is-' @state)}}">
23
- {{#if @icon}}
24
- <div class="hds-dropdown-list-item__interactive-icon">
25
- <FlightIcon @name={{@icon}} @isInlineBlock={{false}} />
26
- </div>
27
- {{/if}}
28
- <div class="hds-dropdown-list-item__interactive-text hds-typography-body-200 hds-font-weight-medium">
29
- {{this.text}}
30
- </div>
31
- </a>
32
- {{else}}
33
- <button class="{{if @state (concat 'is-' @state)}}" type="button" ...attributes>
34
- {{#if @icon}}
35
- <div class="hds-dropdown-list-item__interactive-icon">
36
- <FlightIcon @name={{@icon}} @isInlineBlock={{false}} />
37
- </div>
38
- {{/if}}
39
- <div class="hds-dropdown-list-item__interactive-text hds-typography-body-200 hds-font-weight-medium">
40
- {{this.text}}
41
- </div>
42
- </button>
43
- {{/if}}
17
+ {{/if}}
18
+ <div class="hds-dropdown-list-item__interactive-text hds-typography-body-200 hds-font-weight-medium">
19
+ {{this.text}}
20
+ </div>
21
+ </Hds::Interactive>
44
22
  </li>
@@ -0,0 +1,33 @@
1
+ {{! IMPORTANT: we removed the newlines before/after the yield to reduce the issues with unexpected whitespaces (see https://github.com/hashicorp/design-system/pull/231#issuecomment-1123502499) }}
2
+ {{! NOTICE: we can't support the direct use of the "href" HTML attribute via ...attributes in the <a> elements, because we need to rely on the "@href" Ember argument to differentiate between different types of generated output }}
3
+ {{#if @route}}
4
+ {{#if this.isRouteExternal}}
5
+ <LinkToExternal
6
+ @current-when={{@current-when}}
7
+ @models={{hds-link-to-models @model @models}}
8
+ @query={{hds-link-to-query @query}}
9
+ @replace={{@replace}}
10
+ @route={{@route}}
11
+ ...attributes
12
+ >{{yield}}</LinkToExternal>
13
+ {{else}}
14
+ <LinkTo
15
+ @current-when={{@current-when}}
16
+ @models={{hds-link-to-models @model @models}}
17
+ @query={{hds-link-to-query @query}}
18
+ @replace={{@replace}}
19
+ @route={{@route}}
20
+ ...attributes
21
+ >{{yield}}</LinkTo>
22
+ {{/if}}
23
+ {{else if @href}}
24
+ {{#if this.isHrefExternal}}
25
+ <a target="_blank" rel="noopener noreferrer" ...attributes href={{@href}} {{on "keyup" this.onKeyUp}}>{{yield}}</a>
26
+ {{else}}
27
+ <a ...attributes href={{@href}} {{on "keyup" this.onKeyUp}}>{{yield}}</a>
28
+ {{/if}}
29
+ {{else}}
30
+ <button type="button" ...attributes>
31
+ {{yield}}
32
+ </button>
33
+ {{/if}}
@@ -0,0 +1,33 @@
1
+ import Component from '@glimmer/component';
2
+ import { action } from '@ember/object';
3
+
4
+ export default class HdsInteractiveComponent extends Component {
5
+ /**
6
+ * Determines if a @href value is "external" (it adds target="_blank" rel="noopener noreferrer")
7
+ *
8
+ * @param isHrefExternal
9
+ * @type boolean
10
+ * @default true
11
+ */
12
+ get isHrefExternal() {
13
+ return this.args.isHrefExternal ?? true;
14
+ }
15
+
16
+ /**
17
+ * Determines if a @route value is "external" (uses the LinkToExternal component instead of LinkTo)
18
+ *
19
+ * @param isRouteExternal
20
+ * @type boolean
21
+ * @default false
22
+ */
23
+ get isRouteExternal() {
24
+ return this.args.isRouteExternal ?? false;
25
+ }
26
+
27
+ @action
28
+ onKeyUp(event) {
29
+ if (event.key === ' ' || event.code === 'Space') {
30
+ event.target.click();
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,23 @@
1
+ {{! IMPORTANT: we removed the newlines before/after the yield to reduce the issues with unexpected whitespaces (see https://github.com/hashicorp/design-system/pull/231#issuecomment-1123502499) }}
2
+ {{! IMPORTANT: we need to add "squishies" here (~) because otherwise the whitespace added by Ember becomes visible in the link (being an inline element) - See https://handlebarsjs.com/guide/expressions.html#whitespace-control }}
3
+ <Hds::Interactive
4
+ class={{this.classNames}}
5
+ @current-when={{@current-when}}
6
+ @models={{hds-link-to-models @model @models}}
7
+ @query={{hds-link-to-query @query}}
8
+ @replace={{@replace}}
9
+ @route={{@route}}
10
+ @isRouteExternal={{@isRouteExternal}}
11
+ @href={{@href}}
12
+ target="_blank"
13
+ rel="noopener noreferrer"
14
+ ...attributes
15
+ >{{#if (and @icon (eq this.iconPosition "leading"))~}}
16
+ <span class="hds-link-inline__icon hds-link-inline__icon--leading">
17
+ <FlightIcon @name={{@icon}} @size="16" @stretched={{true}} />
18
+ </span>
19
+ {{~/if~}}{{yield}}{{~#if (and @icon (eq this.iconPosition "trailing"))~}}
20
+ <span class="hds-link-inline__icon hds-link-inline__icon--trailing">
21
+ <FlightIcon @name={{@icon}} @size="16" @stretched={{true}} />
22
+ </span>
23
+ {{~/if}}</Hds::Interactive>
@@ -0,0 +1,71 @@
1
+ import Component from '@glimmer/component';
2
+ import { assert } from '@ember/debug';
3
+
4
+ export const DEFAULT_ICONPOSITION = 'trailing';
5
+ export const DEFAULT_COLOR = 'primary';
6
+ export const ICONPOSITIONS = ['leading', 'trailing'];
7
+ export const COLORS = ['primary', 'secondary'];
8
+
9
+ export default class HdsLinkInlineComponent extends Component {
10
+ constructor() {
11
+ super(...arguments);
12
+ if (!(this.args.href || this.args.route)) {
13
+ assert('@href or @route must be defined for <Hds::Link::Inline>');
14
+ }
15
+ }
16
+
17
+ /**
18
+ * @param color
19
+ * @type {string}
20
+ * @default primary
21
+ * @description Determines the color of link to be used; acceptable values are `primary` and `secondary`
22
+ */
23
+ get color() {
24
+ let { color = DEFAULT_COLOR } = this.args;
25
+
26
+ assert(
27
+ `@color for "Hds::Link::Inline" must be one of the following: ${COLORS.join(
28
+ ', '
29
+ )}; received: ${color}`,
30
+ COLORS.includes(color)
31
+ );
32
+
33
+ return color;
34
+ }
35
+
36
+ /**
37
+ * @param iconPosition
38
+ * @type {string}
39
+ * @default leading
40
+ * @description Positions the icon before or after the text; allowed values are `leading` or `trailing`
41
+ */
42
+ get iconPosition() {
43
+ let { iconPosition = DEFAULT_ICONPOSITION } = this.args;
44
+
45
+ assert(
46
+ `@iconPosition for "Hds::Link::Inline" must be one of the following: ${ICONPOSITIONS.join(
47
+ ', '
48
+ )}; received: ${iconPosition}`,
49
+ ICONPOSITIONS.includes(iconPosition)
50
+ );
51
+
52
+ return iconPosition;
53
+ }
54
+
55
+ /**
56
+ * Get the class names to apply to the component.
57
+ * @method LinkInline#classNames
58
+ * @return {string} The "class" attribute to apply to the component.
59
+ */
60
+ get classNames() {
61
+ let classes = ['hds-link-inline'];
62
+
63
+ // add a class based on the @color argument
64
+ classes.push(`hds-link-inline--color-${this.color}`);
65
+
66
+ // add a class based on the @iconPosition argument
67
+ classes.push(`hds-link-inline--icon-${this.iconPosition}`);
68
+
69
+ return classes.join(' ');
70
+ }
71
+ }
@@ -1,6 +1,17 @@
1
- {{! template-lint-disable link-href-attributes }}
2
- {{! we can disable this linting rule because the developer will add the html attribute themselves }}
3
- <a class={{this.classNames}} target="_blank" rel="noopener noreferrer" ...attributes>
1
+ <Hds::Interactive
2
+ class={{this.classNames}}
3
+ @current-when={{@current-when}}
4
+ @models={{hds-link-to-models @model @models}}
5
+ @query={{hds-link-to-query @query}}
6
+ @replace={{@replace}}
7
+ @route={{@route}}
8
+ @isRouteExternal={{@isRouteExternal}}
9
+ @href={{@href}}
10
+ @isHrefExternal={{@isHrefExternal}}
11
+ target="_blank"
12
+ rel="noopener noreferrer"
13
+ ...attributes
14
+ >
4
15
  {{#if (eq this.iconPosition "leading")}}
5
16
  <div class="hds-link-standalone__icon">
6
17
  <FlightIcon @name={{this.icon}} @size={{this.iconSize}} @stretched={{true}} />
@@ -16,5 +27,4 @@
16
27
  <FlightIcon @name={{this.icon}} @size={{this.iconSize}} @stretched={{true}} />
17
28
  </div>
18
29
  {{/if}}
19
- </a>
20
- {{! template-lint-enable link-href-attributes }}
30
+ </Hds::Interactive>
@@ -9,6 +9,13 @@ export const COLORS = ['primary', 'secondary'];
9
9
  export const SIZES = ['small', 'medium', 'large'];
10
10
 
11
11
  export default class HdsLinkStandaloneComponent extends Component {
12
+ constructor() {
13
+ super(...arguments);
14
+ if (!(this.args.href || this.args.route)) {
15
+ assert('@href or @route must be defined for <Hds::Link::Standalone>');
16
+ }
17
+ }
18
+
12
19
  /**
13
20
  * @param text
14
21
  * @type {string}
@@ -8,13 +8,6 @@
8
8
  as |A|
9
9
  >
10
10
  {{yield
11
- (hash
12
- Title=A.Title
13
- Description=A.Description
14
- Button=A.Button
15
- Link::Standalone=A.Link::Standalone
16
- LinkTo::Standalone=A.LinkTo::Standalone
17
- Generic=A.Generic
18
- )
11
+ (hash Title=A.Title Description=A.Description Button=A.Button Link::Standalone=A.Link::Standalone Generic=A.Generic)
19
12
  }}
20
13
  </Hds::Alert>
@@ -1 +1 @@
1
- export { default } from '@hashicorp/design-system-components/components/hds/link/cta';
1
+ export { default } from '@hashicorp/design-system-components/components/hds/interactive/index';
@@ -1 +1 @@
1
- export { default } from '@hashicorp/design-system-components/components/hds/link-to/cta';
1
+ export { default } from '@hashicorp/design-system-components/components/hds/link/inline';
@@ -5,6 +5,8 @@
5
5
  @use "helpers/focus-ring";
6
6
  @use "helpers/typography";
7
7
 
8
+ // Notice: this list can be automatically edited by the Ember blueprint, please don't remove the start/end comments
9
+ // START COMPONENTS CSS FILES IMPORTS
8
10
  @use "../components/alert";
9
11
  @use "../components/badge";
10
12
  @use "../components/badge-count";
@@ -14,9 +16,10 @@
14
16
  @use "../components/disclosure";
15
17
  @use "../components/dropdown";
16
18
  @use "../components/icon-tile";
17
- @use "../components/link/cta";
19
+ @use "../components/link/inline";
18
20
  @use "../components/link/standalone";
19
21
  @use "../components/toast";
22
+ // END COMPONENT CSS FILES IMPORTS
20
23
 
21
24
  .sr-only {
22
25
  border: 0 !important;
@@ -26,16 +26,21 @@ $hds-button-focus-border-width: 3px;
26
26
  position: relative;
27
27
  width: auto;
28
28
 
29
+ // the <a> element behaves differently than a <button>
30
+ @at-root a#{&} {
31
+ width: fit-content;
32
+ }
33
+
29
34
  // This covers all of the browsers and focus scenarios (due to the custom focus design).
30
35
  &:disabled,
31
36
  &[disabled],
32
- &.is-disabled,
37
+ &.mock-disabled,
33
38
  &:disabled:focus,
34
39
  &[disabled]:focus,
35
- &.is-disabled:focus,
40
+ &.mock-disabled:focus,
36
41
  &:disabled:hover,
37
42
  &[disabled]:hover,
38
- &.is-disabled:hover {
43
+ &.mock-disabled:hover {
39
44
  background-color: var(--token-color-surface-faint);
40
45
  border-color: var(--token-color-border-primary);
41
46
  box-shadow: none;
@@ -57,7 +62,7 @@ $hds-button-focus-border-width: 3px;
57
62
  }
58
63
 
59
64
  &:focus,
60
- &.is-focus {
65
+ &.mock-focus {
61
66
  box-shadow: none;
62
67
 
63
68
  &::before {
@@ -145,7 +150,7 @@ $size-props: (
145
150
  color: var(--token-color-foreground-high-contrast);
146
151
 
147
152
  &:hover,
148
- &.is-hover {
153
+ &.mock-hover {
149
154
  background-color: var(--token-color-palette-blue-300);
150
155
  border-color: var(--token-color-palette-blue-400);
151
156
  color: var(--token-color-foreground-high-contrast);
@@ -153,7 +158,7 @@ $size-props: (
153
158
  }
154
159
 
155
160
  &:focus,
156
- &.is-focus {
161
+ &.mock-focus {
157
162
  background-color: var(--token-color-palette-blue-200);
158
163
  border-color: var(--token-color-focus-action-internal);
159
164
  color: var(--token-color-foreground-high-contrast);
@@ -172,7 +177,7 @@ $size-props: (
172
177
  }
173
178
 
174
179
  &:active,
175
- &.is-active {
180
+ &.mock-active {
176
181
  background-color: var(--token-color-palette-blue-400);
177
182
  border-color: var(--token-color-palette-blue-400);
178
183
  box-shadow: none;
@@ -190,7 +195,7 @@ $size-props: (
190
195
  color: var(--token-color-foreground-primary);
191
196
 
192
197
  &:hover,
193
- &.is-hover {
198
+ &.mock-hover {
194
199
  background-color: var(--token-color-surface-primary);
195
200
  border-color: var(--token-color-border-strong);
196
201
  color: var(--token-color-foreground-primary);
@@ -198,7 +203,7 @@ $size-props: (
198
203
  }
199
204
 
200
205
  &:focus,
201
- &.is-focus {
206
+ &.mock-focus {
202
207
  background-color: var(--token-color-surface-faint);
203
208
  border-color: var(--token-color-focus-action-internal);
204
209
  color: var(--token-color-foreground-primary);
@@ -208,7 +213,7 @@ $size-props: (
208
213
  }
209
214
 
210
215
  &:active,
211
- &.is-active {
216
+ &.mock-active {
212
217
  background-color: var(--token-color-surface-interactive-active);
213
218
  border-color: var(--token-color-border-strong);
214
219
  box-shadow: none;
@@ -225,7 +230,7 @@ $size-props: (
225
230
  color: var(--token-color-foreground-action);
226
231
 
227
232
  &:hover,
228
- &.is-hover {
233
+ &.mock-hover {
229
234
  background-color: var(--token-color-surface-primary);
230
235
  border-color: var(--token-color-border-strong);
231
236
  color: var(--token-color-foreground-action-hover);
@@ -233,7 +238,7 @@ $size-props: (
233
238
  }
234
239
 
235
240
  &:focus,
236
- &.is-focus {
241
+ &.mock-focus {
237
242
  border-color: var(--token-color-focus-action-internal);
238
243
  color: var(--token-color-foreground-action);
239
244
  &::before {
@@ -242,7 +247,7 @@ $size-props: (
242
247
  }
243
248
 
244
249
  &:active,
245
- &.is-active {
250
+ &.mock-active {
246
251
  background-color: var(--token-color-surface-interactive-active);
247
252
  border-color: var(--token-color-border-strong);
248
253
  box-shadow: none;
@@ -254,13 +259,13 @@ $size-props: (
254
259
 
255
260
  &:disabled,
256
261
  &[disabled],
257
- &.is-disabled,
262
+ &.mock-disabled,
258
263
  &:disabled:focus,
259
264
  &[disabled]:focus,
260
- &.is-disabled:focus,
265
+ &.mock-disabled:focus,
261
266
  &:disabled:hover,
262
267
  &[disabled]:hover,
263
- &.is-disabled:hover {
268
+ &.mock-disabled:hover {
264
269
  background-color: transparent;
265
270
  border-color: transparent;
266
271
 
@@ -277,7 +282,7 @@ $size-props: (
277
282
  color: var(--token-color-foreground-critical-on-surface);
278
283
 
279
284
  &:hover,
280
- &.is-hover {
285
+ &.mock-hover {
281
286
  background-color: var(--token-color-palette-red-300);
282
287
  border-color: var(--token-color-palette-red-400);
283
288
  color: var(--token-color-foreground-high-contrast);
@@ -285,7 +290,7 @@ $size-props: (
285
290
  }
286
291
 
287
292
  &:focus,
288
- &.is-focus {
293
+ &.mock-focus {
289
294
  background-color: var(--token-color-surface-critical);
290
295
  border-color: var(--token-color-focus-critical-internal);
291
296
  color: var(--token-color-foreground-critical-on-surface);
@@ -295,7 +300,7 @@ $size-props: (
295
300
  }
296
301
 
297
302
  &:active,
298
- &.is-active {
303
+ &.mock-active {
299
304
  background-color: var(--token-color-palette-red-400);
300
305
  border-color: var(--token-color-palette-red-400);
301
306
  box-shadow: none;
@@ -304,4 +309,24 @@ $size-props: (
304
309
  border-color: transparent;
305
310
  }
306
311
  }
312
+ }
313
+
314
+
315
+ // SPECIAL
316
+
317
+ // we apply a visual treatment to alert the developer if a "href" HTML attribute is used (instead of the "@href" Ember argument)
318
+
319
+ button.hds-button[href] {
320
+ background-color: red !important;
321
+ color: white !important;
322
+ border: none;
323
+
324
+ .hds-button__text,
325
+ &::before {
326
+ display: none;
327
+ }
328
+
329
+ &::after {
330
+ content: ' Attention: you’re passing a "href" attribute to the "Hds::Button" component, you should use an "@href" argument.';
331
+ }
307
332
  }