@hashicorp/design-system-components 0.0.19 → 0.1.1

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/.husky/pre-commit CHANGED
@@ -1,14 +1,4 @@
1
1
  #!/bin/sh
2
2
  . "$(dirname "$0")/_/husky.sh"
3
3
 
4
- export NVM_DIR="$HOME/.nvm/nvm.sh"
5
- . "$(dirname $NVM_DIR)/nvm.sh"
6
-
7
- export NVM_DIR="$HOME/.nvm"
8
- a=$(nvm ls | grep 'node')
9
- b=${a#*(-> }
10
- v=${b%%[)| ]*}
11
-
12
- export PATH="$NVM_DIR/versions/node/$v/bin:$PATH"
13
-
14
- npx lint-staged
4
+ yarn lint-staged
package/README.md CHANGED
@@ -21,7 +21,27 @@ Installation
21
21
  yarn add @hashicorp/design-system-components
22
22
  ```
23
23
 
24
- Then add this line to the top of your app's style file (`app.scss` or similar):
24
+ If you do not have `ember-cli-sass` installed, you will need to do three things before importing the styles into your app:
25
+
26
+ 1. Install `ember-cli-sass`
27
+
28
+ ```bash
29
+ ember install ember-cli-sass
30
+ ```
31
+
32
+ 2. Change `app/styles/app.css` to `app/styles/app.scss`
33
+ 3. Add the following to the `app` definition (starts on/around line 6 in new Ember apps) in `ember-cli-build.js`
34
+
35
+ ```js
36
+ sassOptions: {
37
+ precision: 4,
38
+ includePaths: [
39
+ './node_modules/@hashicorp/design-system-tokens/products/css',
40
+ ],
41
+ },
42
+ ```
43
+
44
+ Finally, add this line to the top of your app's style file (`app.scss` or similar):
25
45
 
26
46
  ```
27
47
  @import '@hashicorp/design-system-components';
@@ -6,7 +6,7 @@ export const DEFAULT_COLOR = 'primary';
6
6
  export const DEFAULT_TYPE = 'button';
7
7
  export const DEFAULT_ICONPOSITION = 'leading';
8
8
  export const SIZES = ['small', 'medium', 'large'];
9
- export const COLORS = ['primary', 'secondary', 'destructive'];
9
+ export const COLORS = ['primary', 'secondary', 'critical'];
10
10
  export const TYPES = ['button', 'submit', 'reset'];
11
11
  export const ICONPOSITIONS = ['leading', 'trailing'];
12
12
 
@@ -50,7 +50,7 @@ export default class HdsButtonIndexComponent extends Component {
50
50
  * @param color
51
51
  * @type {string}
52
52
  * @default primary
53
- * @description Determines the color of button to be used; acceptable values are `primary`, `secondary`, and `destructive`
53
+ * @description Determines the color of button to be used; acceptable values are `primary`, `secondary`, and `critical`
54
54
  */
55
55
  get color() {
56
56
  let { color = DEFAULT_COLOR } = this.args;
@@ -0,0 +1,17 @@
1
+ <div class="hds-disclosure" ...attributes>
2
+ <div class="hds-disclosure__toggle">
3
+ {{yield (hash onClickToggle=this.onClickToggle) to="toggle"}}
4
+ </div>
5
+ {{#if this.isActive}}
6
+ <div
7
+ class="hds-disclosure__content"
8
+ {{focus-trap
9
+ isActive=this.isActive
10
+ shouldSelfFocus=false
11
+ focusTrapOptions=(hash clickOutsideDeactivates=this.clickOutsideDeactivates onDeactivate=this.onDeactivate)
12
+ }}
13
+ >
14
+ {{yield to="content"}}
15
+ </div>
16
+ {{/if}}
17
+ </div>
@@ -0,0 +1,41 @@
1
+ import Component from '@glimmer/component';
2
+ import { tracked } from '@glimmer/tracking';
3
+ import { action } from '@ember/object';
4
+
5
+ export default class HdsDisclosureComponent extends Component {
6
+ @tracked isActive; // notice: if in the future we need to add a "@isActive" prop to control the status from outside (eg to have the Disclosure opened on render) just add "this.args.isActive" here to initalize the variable
7
+ @tracked toggleRef;
8
+ @tracked isToggleClicked;
9
+
10
+ @action
11
+ onClickToggle(event) {
12
+ // we store a reference to the DOM node that has the "onClickToggle" event associated with it
13
+ if (!this.toggleRef) {
14
+ this.toggleRef = event.currentTarget;
15
+ }
16
+ this.isActive = !this.isActive;
17
+ }
18
+
19
+ @action
20
+ clickOutsideDeactivates(event) {
21
+ // we check if the toggle reference belongs to the tree of parent DOM nodes
22
+ // of the element that was clicked and triggered the "click outside" event handling
23
+ this.isToggleClicked = event.path.includes(this.toggleRef);
24
+ // here we need to return `true` to make sure that the focus trap will be deactivated (and allow the click event to do its thing (i.e. to pass-through to the element that was clicked).
25
+ // see: https://github.com/focus-trap/focus-trap#createoptions
26
+ return true;
27
+ }
28
+
29
+ @action
30
+ onDeactivate() {
31
+ // on deactivate we hide the content, except for the case when the button has been clicked
32
+ // the reason is that the "onClickToggle" is called in any case (there's no way to block the event)
33
+ // so when the user clicks the toggle to close the panel, we let the "onClickToggle" handle the closure
34
+ // otherwise we would have two changes of status, this and the toggle, and the panel would remain open
35
+ if (!this.isToggleClicked) {
36
+ this.isActive = false;
37
+ // we need to reset this check
38
+ this.isToggleClicked = false;
39
+ }
40
+ }
41
+ }
@@ -2,7 +2,7 @@
2
2
  class={{this.classNames}}
3
3
  @current-when={{@current-when}}
4
4
  @models={{hds-link-to-models @model @models}}
5
- @query={{this.queryParams}}
5
+ @query={{hds-link-to-query @query}}
6
6
  @replace={{@replace}}
7
7
  @route={{this.route}}
8
8
  ...attributes
@@ -128,16 +128,6 @@ export default class HdsLinkToStandaloneComponent extends Component {
128
128
  }
129
129
  }
130
130
 
131
- // this is a workaround for https://github.com/emberjs/ember.js/issues/19693
132
- // don't remove until we drop support for ember 3.27 and 3.28
133
- get queryParams() {
134
- if (this.args.query) {
135
- return this.args.query;
136
- } else {
137
- return {};
138
- }
139
- }
140
-
141
131
  /**
142
132
  * Get the class names to apply to the component.
143
133
  * @method LinkToStandalone#classNames
@@ -0,0 +1,21 @@
1
+ import { helper } from '@ember/component/helper';
2
+
3
+ /*
4
+ * This helper can be used to safely pass a @query argument to the `<LinkTo>` component
5
+ * without the risk of triggering an assertion if the argument is undefined
6
+ *
7
+ * The result of this helper should be passed into the `@query` argument of the `<LinkTo>` component:
8
+ *
9
+ * ```hbs
10
+ * <LinkTo @query={{hds-link-to-query @query}} />
11
+ * ```
12
+ */
13
+
14
+ // this is a workaround for https://github.com/emberjs/ember.js/issues/19693
15
+ // don't remove until we drop support for ember 3.27 and 3.28
16
+
17
+ export function hdsLinkToQuery([query]) {
18
+ return query ?? {};
19
+ }
20
+
21
+ export default helper(hdsLinkToQuery);
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/disclosure/index';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/helpers/hds-link-to-query';
@@ -1,13 +1,13 @@
1
1
  // these are files coming from the 'design-system-tokens' package
2
2
  @use "tokens";
3
3
  @use "helpers/elevation";
4
-
5
- @use "../mixins/generic-focus-state";
4
+ @use "helpers/focus-ring";
6
5
 
7
6
  @use "../components/badge";
8
7
  @use "../components/badge-count";
9
8
  @use "../components/button";
10
9
  @use "../components/card";
10
+ @use "../components/disclosure";
11
11
  @use "../components/icon-tile";
12
12
  @use "../components/link/standalone";
13
13
 
@@ -63,36 +63,36 @@ $size-props: (
63
63
 
64
64
  .hds-badge-count--color-neutral {
65
65
  &.hds-badge-count--type-filled {
66
- background-color: var(--token-color-palette-neutral-100);
67
- color: var(--token-color-palette-neutral-600);
66
+ background-color: var(--token-color-surface-strong);
67
+ color: var(--token-color-foreground-primary);
68
68
  }
69
69
 
70
70
  &.hds-badge-count--type-inverted {
71
- background-color: var(--token-color-palette-neutral-500);
72
- color: var(--token-color-palette-neutral-0);
71
+ background-color: var(--token-color-foreground-faint);
72
+ color: var(--token-color-foreground-high-contrast);
73
73
  }
74
74
 
75
75
  &.hds-badge-count--type-outlined {
76
76
  background-color: transparent;
77
- border-color: var(--token-color-palette-neutral-500);
78
- color: var(--token-color-palette-neutral-600);
77
+ border-color: var(--token-color-foreground-faint);
78
+ color: var(--token-color-foreground-primary);
79
79
  }
80
80
  }
81
81
 
82
82
  .hds-badge-count--color-neutral-dark-mode {
83
83
  &.hds-badge-count--type-filled {
84
- background-color: var(--token-color-palette-neutral-500);
85
- color: var(--token-color-palette-neutral-0);
84
+ background-color: var(--token-color-foreground-faint);
85
+ color: var(--token-color-foreground-high-contrast);
86
86
  }
87
87
 
88
88
  &.hds-badge-count--type-inverted {
89
- background-color: var(--token-color-palette-neutral-50);
90
- color: var(--token-color-palette-neutral-600);
89
+ background-color: var(--token-color-surface-faint);
90
+ color: var(--token-color-foreground-primary);
91
91
  }
92
92
 
93
93
  &.hds-badge-count--type-outlined {
94
94
  background-color: transparent;
95
95
  border-color: var(--token-color-palette-neutral-100);
96
- color: var(--token-color-palette-neutral-0);
96
+ color: var(--token-color-foreground-high-contrast);
97
97
  }
98
98
  }
@@ -91,56 +91,56 @@ $size-props: (
91
91
 
92
92
  .hds-badge--color-neutral {
93
93
  &.hds-badge--type-filled {
94
- background-color: var(--token-color-palette-neutral-100);
95
- color: var(--token-color-palette-neutral-600);
94
+ background-color: var(--token-color-surface-strong);
95
+ color: var(--token-color-foreground-primary);
96
96
  }
97
97
 
98
98
  &.hds-badge--type-inverted {
99
- background-color: var(--token-color-palette-neutral-500);
100
- color: var(--token-color-palette-neutral-0);
99
+ background-color: var(--token-color-foreground-faint);
100
+ color: var(--token-color-foreground-high-contrast);
101
101
  }
102
102
 
103
103
  &.hds-badge--type-outlined {
104
104
  background-color: transparent;
105
- border-color: var(--token-color-palette-neutral-500);
106
- color: var(--token-color-palette-neutral-600);
105
+ border-color: var(--token-color-foreground-faint);
106
+ color: var(--token-color-foreground-primary);
107
107
  }
108
108
  }
109
109
 
110
110
  .hds-badge--color-neutral-dark-mode {
111
111
  &.hds-badge--type-filled {
112
- background-color: var(--token-color-palette-neutral-500);
113
- color: var(--token-color-palette-neutral-0);
112
+ background-color: var(--token-color-foreground-faint);
113
+ color: var(--token-color-foreground-high-contrast);
114
114
  }
115
115
 
116
116
  &.hds-badge--type-inverted {
117
- background-color: var(--token-color-palette-neutral-50);
118
- color: var(--token-color-palette-neutral-600);
117
+ background-color: var(--token-color-surface-faint);
118
+ color: var(--token-color-foreground-primary);
119
119
  }
120
120
 
121
121
  &.hds-badge--type-outlined {
122
122
  background-color: transparent;
123
123
  border-color: var(--token-color-palette-neutral-100);
124
- color: var(--token-color-palette-neutral-0);
124
+ color: var(--token-color-foreground-high-contrast);
125
125
  }
126
126
  }
127
127
 
128
128
  @each $color in $hds-badge-colors-accents {
129
129
  .hds-badge--color-#{$color} {
130
130
  &.hds-badge--type-filled {
131
- background-color: var(--token-color-#{$color}-background-faint);
132
- color: var(--token-color-#{$color}-foreground-on-faint);
131
+ background-color: var(--token-color-surface-#{$color});
132
+ color: var(--token-color-foreground-#{$color}-on-surface);
133
133
  }
134
134
 
135
135
  &.hds-badge--type-inverted {
136
- background-color: var(--token-color-#{$color}-background-primary);
137
- color: var(--token-color-palette-neutral-0);
136
+ background-color: var(--token-color-foreground-#{$color});
137
+ color: var(--token-color-foreground-high-contrast);
138
138
  }
139
139
 
140
140
  &.hds-badge--type-outlined {
141
141
  background-color: transparent;
142
142
  border-color: currentColor;
143
- color: var(--token-color-#{$color}-background-primary);
143
+ color: var(--token-color-foreground-#{$color});
144
144
  }
145
145
  }
146
146
  }
@@ -22,8 +22,8 @@ $hds-button-focus-border-width: 3px;
22
22
  display: flex;
23
23
  font-family: var(--token-typography-font-stack-text);
24
24
  justify-content: center;
25
+ outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
25
26
  outline-color: transparent; // We need this to be transparent for a11y
26
- max-width: fit-content;
27
27
  position: relative;
28
28
  width: auto;
29
29
 
@@ -34,18 +34,14 @@ $hds-button-focus-border-width: 3px;
34
34
  &:disabled:focus,
35
35
  &[disabled]:focus,
36
36
  &.is-disabled:focus,
37
- &:disabled:focus-visible,
38
- &[disabled]:focus-visible,
39
- &.is-disabled:focus-visible,
40
37
  &:disabled:hover,
41
38
  &[disabled]:hover,
42
39
  &.is-disabled:hover {
43
- background-color: var(--token-color-palette-neutral-50);
44
- border-color: var(--token-color-palette-alpha-200);
40
+ background-color: var(--token-color-surface-faint);
41
+ border-color: var(--token-color-border-primary);
45
42
  box-shadow: none;
46
- color: var(--token-color-palette-neutral-400);
43
+ color: var(--token-color-foreground-disabled);
47
44
  cursor: not-allowed;
48
- outline-color: var(--token-color-palette-alpha-200);
49
45
 
50
46
  &::before {
51
47
  border-color: transparent;
@@ -62,7 +58,6 @@ $hds-button-focus-border-width: 3px;
62
58
  }
63
59
 
64
60
  &:focus,
65
- &:focus-visible,
66
61
  &.is-focus {
67
62
  &::before {
68
63
  // the position absolute of an element is computed from the inside of the border of the container
@@ -144,23 +139,22 @@ $size-props: (
144
139
  // Note: the order of the pseuo-selectors need to stay the way they are; it doesn't match the Figma file but it's the correct order for browsers to render the styles correctly.
145
140
 
146
141
  .hds-button--color-primary {
147
- background-color: var(--token-color-action-background-primary);
148
- border-color: var(--token-color-action-border-on-primary);
149
- color: var(--token-color-palette-neutral-0);
142
+ background-color: var(--token-color-palette-blue-200);
143
+ border-color: var(--token-color-palette-blue-300);
144
+ color: var(--token-color-foreground-high-contrast);
150
145
 
151
146
  &:focus,
152
- &:focus-visible,
153
147
  &.is-focus {
154
- background-color: var(--token-color-action-background-primary);
155
- border-color: var(--token-color-action-border-on-primary);
156
- color: var(--token-color-palette-neutral-0);
148
+ background-color: var(--token-color-palette-blue-200);
149
+ border-color: var(--token-color-focus-action-internal);
150
+ color: var(--token-color-foreground-high-contrast);
157
151
  &::before {
158
152
  // the position absolute of an element is computed from the inside of the border of the container
159
153
  // so we have to take in account the border width of the pseudo-element container itself
160
154
  // plus for the primary button we want to have a 2px gap between the button and the focus
161
155
  $shift: $hds-button-border-width + $hds-button-focus-border-width + 2px;
162
156
  border-radius: $hds-button-border-radius + $hds-button-focus-border-width + 2px;
163
- border-color: var(--token-color-action-background-primary);
157
+ border-color: var(--token-color-focus-action-external);
164
158
  bottom: -$shift;
165
159
  left: -$shift;
166
160
  right: -$shift;
@@ -169,17 +163,17 @@ $size-props: (
169
163
  }
170
164
  &:hover,
171
165
  &.is-hover {
172
- background-color: var(--token-color-action-background-hover);
173
- border-color: var(--token-color-action-border-on-hover);
174
- color: var(--token-color-palette-neutral-0);
166
+ background-color: var(--token-color-palette-blue-300);
167
+ border-color: var(--token-color-palette-blue-400);
168
+ color: var(--token-color-foreground-high-contrast);
175
169
  cursor: pointer;
176
170
  }
177
171
  &:active,
178
172
  &.is-active {
179
- background-color: var(--token-color-action-background-active);
180
- border-color: var(--token-color-action-background-active);
173
+ background-color: var(--token-color-palette-blue-400);
174
+ border-color: var(--token-color-palette-blue-400);
181
175
  box-shadow: none;
182
- color: var(--token-color-palette-neutral-0);
176
+ color: var(--token-color-foreground-high-contrast);
183
177
  &::before {
184
178
  border-color: transparent;
185
179
  }
@@ -187,70 +181,66 @@ $size-props: (
187
181
  }
188
182
 
189
183
  .hds-button--color-secondary {
190
- background-color: var(--token-color-palette-neutral-50);
191
- border-color: var(--token-color-palette-alpha-300);
192
- color: var(--token-color-palette-neutral-600);
184
+ background-color: var(--token-color-surface-faint);
185
+ border-color: var(--token-color-border-strong);
186
+ color: var(--token-color-foreground-primary);
193
187
 
194
188
  &:focus,
195
- &:focus-visible,
196
189
  &.is-focus {
197
- background-color: var(--token-color-palette-neutral-50);
198
- border-color: var(--token-color-action-border-on-primary);
199
- color: var(--token-color-palette-neutral-600);
200
- outline-color: var(--token-color-action-border-on-primary);
190
+ background-color: var(--token-color-surface-faint);
191
+ border-color: var(--token-color-focus-action-internal);
192
+ color: var(--token-color-foreground-primary);
201
193
  &::before {
202
- border-color: #5990FF;
194
+ border-color: var(--token-color-focus-action-external);
203
195
  }
204
196
  }
205
197
  &:hover,
206
198
  &.is-hover {
207
- background-color: var(--token-color-palette-neutral-0);
208
- border-color: var(--token-color-palette-alpha-300);
209
- color: var(--token-color-palette-neutral-600);
199
+ background-color: var(--token-color-surface-primary);
200
+ border-color: var(--token-color-border-strong);
201
+ color: var(--token-color-foreground-primary);
210
202
  cursor: pointer;
211
203
  }
212
204
  &:active,
213
205
  &.is-active {
214
- background-color: var(--token-color-palette-neutral-200);
215
- border-color: var(--token-color-palette-alpha-300);
206
+ background-color: var(--token-color-surface-interactive-active);
207
+ border-color: var(--token-color-border-strong);
216
208
  box-shadow: none;
217
- color: var(--token-color-palette-neutral-600);
209
+ color: var(--token-color-foreground-primary);
218
210
  &::before {
219
211
  border-color: transparent;
220
212
  }
221
213
  }
222
214
  }
223
215
 
224
- .hds-button--color-destructive {
225
- background-color: var(--token-color-palette-neutral-50);
226
- border-color: var(--token-color-palette-alpha-300);
227
- color: var(--token-color-critical-foreground-on-faint);
216
+ .hds-button--color-critical {
217
+ background-color: var(--token-color-surface-critical);
218
+ border-color: var(--token-color-foreground-critical-on-surface);
219
+ color: var(--token-color-foreground-critical-on-surface);
228
220
 
229
221
  &:focus,
230
- &:focus-visible,
231
222
  &.is-focus {
232
- background-color: var(--token-color-palette-neutral-50);
233
- border-color: var(--token-color-critical-border-on-primary);
234
- color: var(--token-color-critical-foreground-on-faint);
235
- outline-color: var(--token-color-critical-border-on-primary);
223
+ background-color: var(--token-color-surface-critical);
224
+ border-color: var(--token-color-focus-critical-internal);
225
+ color: var(--token-color-foreground-critical-on-surface);
236
226
  &::before {
237
- border-color: #DD7578;
227
+ border-color: var(--token-color-focus-critical-external);
238
228
  }
239
229
  }
240
230
  &:hover,
241
231
  &.is-hover {
242
- background-color: var(--token-color-critical-background-hover);
243
- border-color: var(--token-color-critical-border-on-hover);
244
- color: var(--token-color-palette-neutral-0);
232
+ background-color: var(--token-color-palette-red-300);
233
+ border-color: var(--token-color-palette-red-400);
234
+ color: var(--token-color-foreground-high-contrast);
245
235
  cursor: pointer;
246
236
  }
247
237
 
248
238
  &:active,
249
239
  &.is-active {
250
- background-color: var(--token-color-critical-background-active);
251
- border-color: var(--token-color-critical-background-active);
240
+ background-color: var(--token-color-palette-red-400);
241
+ border-color: var(--token-color-palette-red-400);
252
242
  box-shadow: none;
253
- color: var(--token-color-palette-neutral-0);
243
+ color: var(--token-color-foreground-high-contrast);
254
244
  &::before {
255
245
  border-color: transparent;
256
246
  }
@@ -20,11 +20,11 @@ $hds-card-container-border-radius: 6px;
20
20
  // BACKGROUND
21
21
 
22
22
  .hds-card__container--background-neutral-primary {
23
- background-color: var(--token-color-neutral-background-primary);
23
+ background-color: var(--token-color-surface-primary);
24
24
  }
25
25
 
26
26
  .hds-card__container--background-neutral-secondary {
27
- background-color: var(--token-color-neutral-background-secondary);
27
+ background-color: var(--token-color-surface-faint);
28
28
  }
29
29
 
30
30
 
@@ -0,0 +1,10 @@
1
+ //
2
+ // DISCLOSURE COMPONENT
3
+ //
4
+ // properties within each class are sorted alphabetically
5
+ //
6
+
7
+ .hds-disclosure {
8
+ position: relative;
9
+ width: fit-content;
10
+ }
@@ -29,8 +29,8 @@
29
29
  }
30
30
 
31
31
  .hds-icon-tile__extra {
32
- background-color: var(--token-color-neutral-background-primary);
33
- border: 1px solid var(--token-color-palette-alpha-200);
32
+ background-color: var(--token-color-surface-primary);
33
+ border: 1px solid var(--token-color-border-primary);
34
34
  bottom: -6px;
35
35
  box-shadow: $hds-icon-tile-box-shadow;
36
36
  box-sizing: content-box; // the border is outside
@@ -42,7 +42,7 @@
42
42
  .hds-icon-tile__extra-icon {
43
43
  display: flex;
44
44
  margin: auto;
45
- color: var(--token-color-neutral-foreground-primary);
45
+ color: var(--token-color-foreground-strong);
46
46
  }
47
47
 
48
48
  // SIZE
@@ -112,8 +112,8 @@ $size-props: (
112
112
 
113
113
  .hds-icon-tile--logo {
114
114
  // notice: we are using colored icons so we don't need to set the "color" property here
115
- background-color: var(--token-color-neutral-background-primary);
116
- border-color: var(--token-color-neutral-border-primary);
115
+ background-color: var(--token-color-surface-primary);
116
+ border-color: var(--token-color-border-primary);
117
117
  }
118
118
 
119
119
  // ICON - COLOR
@@ -121,18 +121,17 @@ $size-props: (
121
121
  .hds-icon-tile--icon {
122
122
 
123
123
  &.hds-icon-tile--color-neutral {
124
- background-color: var(--token-color-neutral-background-secondary);
125
- border-color: var(--token-color-neutral-border-primary);
126
- color: var(--token-color-neutral-foreground-faint);
124
+ background-color: var(--token-color-surface-faint);
125
+ border-color: var(--token-color-border-primary);
126
+ color: var(--token-color-foreground-faint);
127
127
  }
128
128
 
129
129
  @each $product in $hds-icon-tile-colors-products {
130
130
  @if ($product == 'hcp') {
131
131
  // exception for HCP (we use neutral colors, we don't have specific product colors for foreground/background)
132
- // notice: at the moment we don't have a token for that, that's why we're using an hex value
133
132
  &.hds-icon-tile--color-hcp {
134
- background-color: var(--token-color-neutral-background-secondary);
135
- border-color: var(--token-color-neutral-border-primary);
133
+ background-color: var(--token-color-surface-faint);
134
+ border-color: var(--token-color-border-primary);
136
135
  color: var(--token-color-palette-#{$product}-brand);
137
136
  }
138
137
  } @else {
@@ -7,7 +7,7 @@
7
7
  //
8
8
  //
9
9
 
10
- @use '../../mixins/generic-focus-state.scss' as *;
10
+ @use "../../mixins/focus-ring" as *;
11
11
 
12
12
  $hds-link-standalone-sizes: ( 'small', 'medium', 'large' );
13
13
 
@@ -18,50 +18,19 @@ $hds-link-standalone-border-width: 1px;
18
18
  align-items: center;
19
19
  background-color: transparent; // needs to exist for a11y
20
20
  border: $hds-link-standalone-border-width solid transparent; // needs to exist AND be transparent for a11y
21
- color: var(--token-color-action-foreground-on-faint);
22
21
  display: flex;
23
22
  font-family: var(--token-typography-font-stack-text);
24
- isolation: isolate; // used to create a new stacking context (needed to have the pseudo element below text/icon but not the parent container)
25
23
  justify-content: center;
26
- outline-color: transparent;
27
- position: relative;
28
- text-decoration: underline;
24
+ // notice: the text decoration is applied directly to the "text" container because of a bug in Safari (see https://github.com/hashicorp/design-system-components/issues/159)
29
25
  text-decoration-color: transparent;
30
26
  width: fit-content;
31
-
32
- // this is how much the focus is visually "shifted" from the bounding box of the
33
- // notice: you have to take in account also the inset shadow of the focus (see Figma file and also "generic-focus-state" mixin)
34
- $hds-link-standalone-focus-shift: 4px;
35
- // the position absolute of an element is computed from the inside of the border of the container
36
- // so we have to take in account the border width of the pseudo-element container itself
37
- $shift: $hds-link-standalone-focus-shift + $hds-link-standalone-border-width;
38
- // for visual/optical balance we add an extra 2px to the "shift" near the text (opposite the icon)
39
- $shift-extra: $shift + 2px;
40
-
41
- // this is used not only for the focus, but also to increase the clickable area
42
- &::before {
43
- border-radius: $hds-link-standalone-focus-border-radius;
44
- bottom: -$shift;
45
- box-sizing: border-box;
46
- content: '';
47
- left: -$shift;
48
- position: absolute;
49
- right: -$shift;
50
- top: -$shift;
51
- z-index: -1;
52
- }
53
-
54
- &.hds-link-standalone--icon-position-leading::before {
55
- right: -$shift-extra;
56
- }
57
-
58
- &.hds-link-standalone--icon-position-trailing::before {
59
- left: -$shift-extra;
60
- }
61
27
  }
62
28
 
63
29
  .hds-link-standalone__text {
64
30
  flex: 1 0 0;
31
+ text-decoration: underline;
32
+ text-decoration-color: transparent;
33
+ transition: text-decoration-color 0.25s ease-in;
65
34
 
66
35
  .hds-link-standalone__icon + & {
67
36
  margin-left: 0.375rem;
@@ -72,7 +41,6 @@ $hds-link-standalone-border-width: 1px;
72
41
  }
73
42
  }
74
43
 
75
-
76
44
  // SIZE
77
45
 
78
46
  // these values later may come from the design tokens
@@ -113,66 +81,76 @@ $size-props: (
113
81
  // The "primary" and "secondary" variants share a lot of styles for the interactive states
114
82
  // Note: the order of the pseuo-selectors need to stay the way they are
115
83
 
116
- .hds-link-standalone {
117
- &:focus,
118
- &:focus-visible,
119
- &.is-focus {
120
- &::before {
121
- @include hds-generic-focus-state();
122
- }
123
- }
84
+ .hds-link-standalone--color-primary {
85
+ color: var(--token-color-foreground-action);
86
+
124
87
  &:hover,
125
88
  &.is-hover {
126
- text-decoration: underline;
127
- transition: text-decoration-color 0.25s ease-in;
89
+ color: var(--token-color-foreground-action-hover);
90
+
91
+ .hds-link-standalone__text {
92
+ text-decoration-color: #4E81E8; // custom color by design
93
+ }
128
94
  }
95
+
129
96
  &:active,
130
97
  &.is-active {
131
- text-decoration: underline;
98
+ color: var(--token-color-foreground-action-active);
99
+
100
+ .hds-link-standalone__text {
101
+ text-decoration-color: #396ED6; // custom color by design
102
+ }
132
103
 
133
- }
134
- // remove the focus ring on "active + focused" state (by design)
135
- &:focus:active,
136
- &:focus-visible:active,
137
- &.is-focus.is-active {
138
104
  &::before {
139
- content: none;
105
+ background-color: var(--token-color-action-background-faint);
140
106
  }
141
107
  }
142
-
143
108
  }
144
109
 
145
- .hds-link-standalone--color-primary {
146
- color: var(--token-color-action-foreground-primary);
110
+ .hds-link-standalone--color-secondary {
111
+ color: var(--token-color-foreground-strong);
147
112
 
148
113
  &:hover,
149
114
  &.is-hover {
150
- color: var(--token-color-action-background-hover);
151
- text-decoration-color: #4E81E8; // custom color by design
115
+ .hds-link-standalone__text {
116
+ text-decoration-color: #4D4D4F; // custom color by design
117
+ }
152
118
  }
119
+
153
120
  &:active,
154
121
  &.is-active {
155
- color: var(--token-color-action-background-active);
156
- text-decoration-color: #396ED6; // custom color by design
122
+ color: var(--token-color-foreground-primary);
123
+
124
+ .hds-link-standalone__text {
125
+ text-decoration-color: #6E7075; // custom color by design
126
+ }
127
+
157
128
  &::before {
158
- background-color: var(--token-color-action-background-faint);
129
+ background-color: var(--token-color-surface-interactive-active);
159
130
  }
160
131
  }
161
132
  }
162
133
 
163
- .hds-link-standalone--color-secondary {
164
- color: var(--token-color-neutral-foreground-primary);
134
+ // this is how much the focus is visually "shifted" from the bounding box of the
135
+ // notice: you have to take in account also the inset shadow of the focus (see Figma file and also "focus-ring" mixin)
136
+ $hds-link-standalone-focus-shift: 4px;
165
137
 
166
- &:hover,
167
- &.is-hover {
168
- text-decoration-color: #4D4D4F; // custom color by design
138
+ .hds-link-standalone {
139
+ // the position absolute of an element is computed from the inside of the border of the container
140
+ // so we have to take in account the border width of the pseudo-element container itself
141
+ $shift: $hds-link-standalone-focus-shift + $hds-link-standalone-border-width;
142
+ // for visual/optical balance we add an extra 2px to the "shift" near the text (opposite the icon)
143
+ $shift-extra: $shift + 2px;
144
+
145
+ // notice: this is used not only for the focus, but also to increase the clickable area
146
+ @include hds-focus-ring-with-pseudo-element($top: -$shift, $right: -$shift, $bottom: -$shift, $left: -$shift, $radius: $hds-link-standalone-focus-border-radius);
147
+
148
+ // we need to override a couple of values for better visual alignment
149
+ &.hds-link-standalone--icon-position-leading::before {
150
+ right: -$shift-extra;
169
151
  }
170
- &:active,
171
- &.is-active {
172
- color: var(--token-color-neutral-foreground-secondary);
173
- text-decoration-color: #6E7075; // custom color by design
174
- &::before {
175
- background-color: var(--token-color-palette-neutral-200);
176
- }
152
+
153
+ &.hds-link-standalone--icon-position-trailing::before {
154
+ left: -$shift-extra;
177
155
  }
178
156
  }
@@ -0,0 +1,73 @@
1
+ // For an explanation of the ":focus/:focus-visible" states see:
2
+ // - https://github.com/hashicorp/design-system-components/issues/161
3
+ // - https://www.tpgi.com/focus-visible-and-backwards-compatibility/
4
+
5
+ @mixin hds-focus-ring-basic() {
6
+ outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
7
+ outline-color: transparent;
8
+
9
+ // default focus for browsers that still rely on ":focus"
10
+ &:focus,
11
+ &.is-focus {
12
+ box-shadow: var(--token-focus-ring-box-shadow);
13
+ }
14
+ // undo the previous declaration for browsers that support ":focus-visible" but wouldn't normally show default focus styles
15
+ &:focus:not(:focus-visible) {
16
+ box-shadow: none;
17
+ }
18
+ // set focus for browsers that support ":focus-visible"
19
+ &:focus-visible {
20
+ box-shadow: var(--token-focus-ring-box-shadow);
21
+ }
22
+ // remove the focus ring on "active + focused" state (by design)
23
+ &:focus:active,
24
+ &.is-focus.is-active {
25
+ box-shadow: none;
26
+ }
27
+ }
28
+
29
+ @mixin hds-focus-ring-with-pseudo-element($top: 0, $right: 0, $bottom: 0, $left: 0, $radius: 5px) {
30
+ isolation: isolate; // used to create a new stacking context (needed to have the pseudo element below text/icon but not the parent container)
31
+ outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
32
+ outline-color: transparent;
33
+ position: relative;
34
+
35
+ &::before {
36
+ border-radius: $radius;
37
+ bottom: $bottom;
38
+ box-sizing: border-box;
39
+ content: '';
40
+ left: $left;
41
+ position: absolute;
42
+ right: $right;
43
+ top: $top;
44
+ z-index: -1;
45
+ }
46
+
47
+ // default focus for browsers that still rely on ":focus"
48
+ &:focus,
49
+ &.is-focus {
50
+ &::before {
51
+ box-shadow: var(--token-focus-ring-box-shadow);
52
+ }
53
+ }
54
+ // undo the previous declaration for browsers that support ":focus-visible" but wouldn't normally show default focus styles
55
+ &:focus:not(:focus-visible) {
56
+ &::before {
57
+ box-shadow: none;
58
+ }
59
+ }
60
+ // set focus for browsers that support ":focus-visible"
61
+ &:focus-visible {
62
+ &::before {
63
+ box-shadow: var(--token-focus-ring-box-shadow);
64
+ }
65
+ }
66
+ // remove the focus ring on "active + focused" state (by design)
67
+ &:focus:active,
68
+ &.is-focus.is-active {
69
+ &::before {
70
+ box-shadow: none;
71
+ }
72
+ }
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashicorp/design-system-components",
3
- "version": "0.0.19",
3
+ "version": "0.1.1",
4
4
  "description": "HashiCorp Design System Components",
5
5
  "keywords": [
6
6
  "hashicorp",
@@ -61,11 +61,14 @@
61
61
  "prepare": "husky install"
62
62
  },
63
63
  "dependencies": {
64
- "@hashicorp/design-system-tokens": "^0.4.7",
65
- "@hashicorp/ember-flight-icons": "^2.0.0",
64
+ "@hashicorp/design-system-tokens": "^0.5.0",
65
+ "@hashicorp/ember-flight-icons": "^2.0.1",
66
+ "ember-auto-import": "^2.2.3",
66
67
  "ember-cli-babel": "^7.26.6",
67
68
  "ember-cli-htmlbars": "^5.7.1",
68
69
  "ember-cli-sass": "^10.0.1",
70
+ "ember-focus-trap": "^1.0.1",
71
+ "ember-named-blocks-polyfill": "^0.2.5",
69
72
  "sass": "^1.43.4"
70
73
  },
71
74
  "devDependencies": {
@@ -79,7 +82,6 @@
79
82
  "babel-eslint": "^10.1.0",
80
83
  "broccoli-asset-rev": "^3.0.0",
81
84
  "ember-a11y-refocus": "^2.1.0",
82
- "ember-auto-import": "^2.2.3",
83
85
  "ember-cli": "~3.28.4",
84
86
  "ember-cli-clipboard": "^0.15.0",
85
87
  "ember-cli-dependency-checker": "^3.2.0",
@@ -1,3 +0,0 @@
1
- @mixin hds-generic-focus-state() {
2
- box-shadow: var(--token-focus-ring-box-shadow);
3
- }