@hashicorp/design-system-components 0.11.2 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/addon/components/hds/alert/index.hbs +1 -3
- package/addon/components/hds/breadcrumb/item.hbs +1 -1
- package/addon/components/hds/breadcrumb/truncation.hbs +1 -4
- package/addon/components/hds/button/index.hbs +14 -2
- package/addon/components/hds/button/index.js +0 -21
- package/addon/components/hds/dropdown/list-item/copy-item.hbs +1 -5
- package/addon/components/hds/dropdown/list-item/interactive.hbs +19 -41
- package/addon/components/hds/interactive/index.hbs +33 -0
- package/addon/components/hds/interactive/index.js +33 -0
- package/addon/components/hds/link/inline.hbs +23 -0
- package/addon/components/hds/link/inline.js +71 -0
- package/addon/components/hds/link/standalone.hbs +15 -5
- package/addon/components/hds/link/standalone.js +7 -0
- package/addon/components/hds/toast/index.hbs +1 -8
- package/app/components/hds/{link/cta.js → interactive/index.js} +1 -1
- package/app/components/hds/{link-to/cta.js → link/inline.js} +1 -1
- package/app/styles/@hashicorp/design-system-components.scss +4 -1
- package/app/styles/components/alert.scss +2 -5
- package/app/styles/components/breadcrumb.scss +5 -5
- package/app/styles/components/button.scss +44 -19
- package/app/styles/components/dropdown.scss +9 -9
- package/app/styles/components/link/inline.scss +66 -0
- package/app/styles/components/link/standalone.scss +4 -4
- package/app/styles/mixins/_focus-ring.scss +4 -4
- package/blueprints/hds-component/files/addon/components/hds/__name__/index.hbs +1 -1
- package/blueprints/hds-component/index.js +34 -0
- package/package.json +4 -3
- package/addon/components/hds/link/cta.hbs +0 -50
- package/addon/components/hds/link/cta.js +0 -150
- package/addon/components/hds/link-to/cta.hbs +0 -51
- package/addon/components/hds/link-to/cta.js +0 -165
- package/addon/components/hds/link-to/standalone.hbs +0 -25
- package/addon/components/hds/link-to/standalone.js +0 -151
- package/app/components/hds/link-to/standalone.js +0 -1
- package/app/styles/components/link/cta.scss +0 -28
|
@@ -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
|
-
&.
|
|
37
|
+
&.mock-disabled,
|
|
33
38
|
&:disabled:focus,
|
|
34
39
|
&[disabled]:focus,
|
|
35
|
-
&.
|
|
40
|
+
&.mock-disabled:focus,
|
|
36
41
|
&:disabled:hover,
|
|
37
42
|
&[disabled]:hover,
|
|
38
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
262
|
+
&.mock-disabled,
|
|
258
263
|
&:disabled:focus,
|
|
259
264
|
&[disabled]:focus,
|
|
260
|
-
&.
|
|
265
|
+
&.mock-disabled:focus,
|
|
261
266
|
&:disabled:hover,
|
|
262
267
|
&[disabled]:hover,
|
|
263
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
-
&.
|
|
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
|
}
|
|
@@ -40,7 +40,7 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
40
40
|
padding: 1px;
|
|
41
41
|
|
|
42
42
|
&:hover,
|
|
43
|
-
&.
|
|
43
|
+
&.mock-hover {
|
|
44
44
|
background-color: var(--token-color-surface-interactive);
|
|
45
45
|
border-color: var(--token-color-border-strong);
|
|
46
46
|
cursor: pointer;
|
|
@@ -49,7 +49,7 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
49
49
|
@include hds-focus-ring-with-pseudo-element($top: -1px, $right: -1px, $bottom: -1px, $left: -1px, $radius: $hds-dropdown-toggle-border-radius);
|
|
50
50
|
|
|
51
51
|
&:active,
|
|
52
|
-
&.
|
|
52
|
+
&.mock-active {
|
|
53
53
|
background-color: var(--token-color-surface-interactive-active);
|
|
54
54
|
border-color: var(--token-color-border-strong);
|
|
55
55
|
}
|
|
@@ -166,7 +166,7 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
166
166
|
width: 100%;
|
|
167
167
|
|
|
168
168
|
&:hover,
|
|
169
|
-
&.
|
|
169
|
+
&.mock-hover {
|
|
170
170
|
background-color: var(--token-color-surface-interactive-hover);
|
|
171
171
|
cursor: pointer;
|
|
172
172
|
}
|
|
@@ -174,14 +174,14 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
174
174
|
@include hds-focus-ring-basic();
|
|
175
175
|
|
|
176
176
|
&:focus,
|
|
177
|
-
&.
|
|
177
|
+
&.mock-focus {
|
|
178
178
|
//TODO this focus is just way too complex
|
|
179
179
|
background-color: var(--token-color-surface-action);
|
|
180
180
|
border-color: var(--token-color-focus-action-internal);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
&:active,
|
|
184
|
-
&.
|
|
184
|
+
&.mock-active {
|
|
185
185
|
background-color: var(--token-color-surface-interactive-active);
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -275,7 +275,7 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
275
275
|
// and define their values in the color variants below
|
|
276
276
|
|
|
277
277
|
&:hover,
|
|
278
|
-
&.
|
|
278
|
+
&.mock-hover {
|
|
279
279
|
color: var(--current-color-hover);
|
|
280
280
|
&::before {
|
|
281
281
|
background-color: currentColor;
|
|
@@ -284,7 +284,7 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
284
284
|
|
|
285
285
|
// default focus for browsers that still rely on ":focus"
|
|
286
286
|
&:focus,
|
|
287
|
-
&.
|
|
287
|
+
&.mock-focus {
|
|
288
288
|
color: var(--current-color-focus);
|
|
289
289
|
&::after {
|
|
290
290
|
background-color: var(--current-background-color);
|
|
@@ -312,7 +312,7 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
312
312
|
// remove the focus ring on "active + focused" state (by design)
|
|
313
313
|
&:focus:active,
|
|
314
314
|
&:focus-visible:active,
|
|
315
|
-
&.
|
|
315
|
+
&.mock-focus.mock-active {
|
|
316
316
|
&::after {
|
|
317
317
|
background-color: var(--current-background-color);
|
|
318
318
|
box-shadow: none;
|
|
@@ -321,7 +321,7 @@ $hds-dropdown-toggle-border-radius: 5px;
|
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
&:active,
|
|
324
|
-
&.
|
|
324
|
+
&.mock-active {
|
|
325
325
|
color: var(--current-color-active);
|
|
326
326
|
&::before {
|
|
327
327
|
background-color: currentColor;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//
|
|
2
|
+
// LINK > INLINE COMPONENT
|
|
3
|
+
//
|
|
4
|
+
// properties within each class are sorted alphabetically
|
|
5
|
+
// notice: pseudo-classes for the states *must* follow the order link > visited > focus > hover > active
|
|
6
|
+
// see https://github.com/hashicorp/design-system-components/issues/132
|
|
7
|
+
//
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
.hds-link-inline {
|
|
11
|
+
border-radius: 2px; // this is used by the outline too
|
|
12
|
+
|
|
13
|
+
&:focus,
|
|
14
|
+
&.mock-focus,
|
|
15
|
+
&:focus-visible {
|
|
16
|
+
outline: 2px solid var(--token-color-focus-action-internal);
|
|
17
|
+
outline-offset: 1px;
|
|
18
|
+
text-decoration: none;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.hds-link-inline__icon {
|
|
23
|
+
display: inline-block;
|
|
24
|
+
height: 1em;
|
|
25
|
+
vertical-align: text-bottom; // don't use "middle" here or it will extend beyond the focus ring
|
|
26
|
+
width: 1em;
|
|
27
|
+
|
|
28
|
+
.hds-link-inline--icon-leading > & {
|
|
29
|
+
margin-right: 0.25em;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.hds-link-inline--icon-trailing > & {
|
|
33
|
+
margin-left: 0.25em;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// COLORS & STATES
|
|
39
|
+
|
|
40
|
+
.hds-link-inline--color-primary {
|
|
41
|
+
color: var(--token-color-foreground-action);
|
|
42
|
+
|
|
43
|
+
&:hover,
|
|
44
|
+
&.mock-hover {
|
|
45
|
+
color: var(--token-color-foreground-action-hover);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&:active,
|
|
49
|
+
&.mock-active {
|
|
50
|
+
color: var(--token-color-foreground-action-active);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.hds-link-inline--color-secondary {
|
|
55
|
+
color: var(--token-color-foreground-strong);
|
|
56
|
+
|
|
57
|
+
&:hover,
|
|
58
|
+
&.mock-hover {
|
|
59
|
+
color: var(--token-color-foreground-primary);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&:active,
|
|
63
|
+
&.mock-active {
|
|
64
|
+
color: var(--token-color-foreground-faint);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -84,7 +84,7 @@ $size-props: (
|
|
|
84
84
|
color: var(--token-color-foreground-action);
|
|
85
85
|
|
|
86
86
|
&:hover,
|
|
87
|
-
&.
|
|
87
|
+
&.mock-hover {
|
|
88
88
|
color: var(--token-color-foreground-action-hover);
|
|
89
89
|
|
|
90
90
|
.hds-link-standalone__text {
|
|
@@ -93,7 +93,7 @@ $size-props: (
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
&:active,
|
|
96
|
-
&.
|
|
96
|
+
&.mock-active {
|
|
97
97
|
color: var(--token-color-foreground-action-active);
|
|
98
98
|
|
|
99
99
|
.hds-link-standalone__text {
|
|
@@ -110,14 +110,14 @@ $size-props: (
|
|
|
110
110
|
color: var(--token-color-foreground-strong);
|
|
111
111
|
|
|
112
112
|
&:hover,
|
|
113
|
-
&.
|
|
113
|
+
&.mock-hover {
|
|
114
114
|
.hds-link-standalone__text {
|
|
115
115
|
text-decoration-color: #4D4D4F; // custom color by design
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
&:active,
|
|
120
|
-
&.
|
|
120
|
+
&.mock-active {
|
|
121
121
|
color: var(--token-color-foreground-primary);
|
|
122
122
|
|
|
123
123
|
.hds-link-standalone__text {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
// default focus for browsers that still rely on ":focus"
|
|
10
10
|
&:focus,
|
|
11
|
-
&.
|
|
11
|
+
&.mock-focus {
|
|
12
12
|
box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
|
|
13
13
|
}
|
|
14
14
|
// undo the previous declaration for browsers that support ":focus-visible" but wouldn't normally show default focus styles
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
}
|
|
22
22
|
// remove the focus ring on "active + focused" state (by design)
|
|
23
23
|
&:focus:active,
|
|
24
|
-
&.
|
|
24
|
+
&.mock-focus.mock-active {
|
|
25
25
|
box-shadow: none;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
|
|
46
46
|
// default focus for browsers that still rely on ":focus"
|
|
47
47
|
&:focus,
|
|
48
|
-
&.
|
|
48
|
+
&.mock-focus {
|
|
49
49
|
&::before {
|
|
50
50
|
box-shadow: var(--token-focus-ring-#{$color}-box-shadow);
|
|
51
51
|
}
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
}
|
|
65
65
|
// remove the focus ring on "active + focused" state (by design)
|
|
66
66
|
&:focus:active,
|
|
67
|
-
&.
|
|
67
|
+
&.mock-focus.mock-active {
|
|
68
68
|
&::before {
|
|
69
69
|
box-shadow: none;
|
|
70
70
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
5
|
const stringUtil = require('ember-cli-string-utils');
|
|
6
|
+
const fs = require('fs');
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
description: 'Generates all files for an HDS component',
|
|
@@ -23,4 +24,37 @@ module.exports = {
|
|
|
23
24
|
.join(' > '),
|
|
24
25
|
};
|
|
25
26
|
},
|
|
27
|
+
|
|
28
|
+
afterInstall(options) {
|
|
29
|
+
updateHDSComponentsCSS.call(this, options);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const updateHDSComponentsCSS = (options) => {
|
|
34
|
+
const name = options.entity.name;
|
|
35
|
+
const cssFilePath = `${options.project.root}/app/styles/@hashicorp/design-system-components.scss`;
|
|
36
|
+
const source = fs.readFileSync(cssFilePath, 'utf-8');
|
|
37
|
+
const oldLinesArray = source.split(/\r?\n/);
|
|
38
|
+
const firstComponentImportIndex =
|
|
39
|
+
oldLinesArray.findIndex((line) =>
|
|
40
|
+
line.match(/^\/\/ START COMPONENTS CSS FILES IMPORTS/)
|
|
41
|
+
) + 1;
|
|
42
|
+
const lastComponentImportIndex =
|
|
43
|
+
oldLinesArray.findIndex((line) =>
|
|
44
|
+
line.match(/^\/\/ END COMPONENT CSS FILES IMPORTS/)
|
|
45
|
+
) - 1;
|
|
46
|
+
const importLinesArray = oldLinesArray.slice(
|
|
47
|
+
firstComponentImportIndex,
|
|
48
|
+
lastComponentImportIndex + 1
|
|
49
|
+
);
|
|
50
|
+
importLinesArray.push(`@use "../components/${name}";`);
|
|
51
|
+
const newImportLinesArray = importLinesArray
|
|
52
|
+
.filter((line, index, self) => self.indexOf(line) === index)
|
|
53
|
+
.sort();
|
|
54
|
+
const newLinesArray = [].concat(
|
|
55
|
+
oldLinesArray.slice(0, firstComponentImportIndex),
|
|
56
|
+
newImportLinesArray,
|
|
57
|
+
oldLinesArray.slice(lastComponentImportIndex + 1)
|
|
58
|
+
);
|
|
59
|
+
fs.writeFileSync(cssFilePath, newLinesArray.join('\n'));
|
|
26
60
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hashicorp/design-system-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "HashiCorp Design System Components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hashicorp",
|
|
@@ -35,14 +35,15 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@hashicorp/design-system-tokens": "^0.8.0",
|
|
38
|
-
"@hashicorp/ember-flight-icons": "^2.0.
|
|
38
|
+
"@hashicorp/ember-flight-icons": "^2.0.7",
|
|
39
39
|
"ember-auto-import": "^2.4.1",
|
|
40
40
|
"ember-cli-babel": "^7.26.11",
|
|
41
41
|
"ember-cli-htmlbars": "^6.0.1",
|
|
42
42
|
"ember-cli-sass": "^10.0.1",
|
|
43
43
|
"ember-keyboard": "^8.1.0",
|
|
44
44
|
"ember-named-blocks-polyfill": "^0.2.5",
|
|
45
|
-
"sass": "^1.43.4"
|
|
45
|
+
"sass": "^1.43.4",
|
|
46
|
+
"sinon": "^14.0.0"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@ember/optional-features": "^2.0.0",
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
{{!
|
|
2
|
-
// ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████
|
|
3
|
-
// ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██
|
|
4
|
-
// ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███
|
|
5
|
-
// ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
6
|
-
// ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████
|
|
7
|
-
//
|
|
8
|
-
// Notice: in this component we're using directly the styles from the `Hds::Button` component
|
|
9
|
-
// using the `hds-button` class names (and adding a specialized class for the "cta", see below)
|
|
10
|
-
// If you need to change the styling of the `Button` component, remember that this will impact also
|
|
11
|
-
// this component too.
|
|
12
|
-
// If instead you need to change only the styling of the `CTA` component, you can do it
|
|
13
|
-
// in the CSS file using the specialized class declared there.
|
|
14
|
-
// This is NOT a standard approach that we use in the HDS design system implementation, but it's been
|
|
15
|
-
// the least worst option we could find to solve the problem of sharing the exact same style of the
|
|
16
|
-
// `Button (primary)` with other components.
|
|
17
|
-
}}
|
|
18
|
-
|
|
19
|
-
{{! template-lint-disable link-href-attributes }}
|
|
20
|
-
{{! we can disable this linting rule because the developer will add the html attribute themselves }}
|
|
21
|
-
<a
|
|
22
|
-
class={{this.classNames}}
|
|
23
|
-
target="_blank"
|
|
24
|
-
rel="noopener noreferrer"
|
|
25
|
-
...attributes
|
|
26
|
-
{{did-insert this.didInsert}}
|
|
27
|
-
{{on-key "Space" this.onKeySpace}}
|
|
28
|
-
>
|
|
29
|
-
{{#if this.icon}}
|
|
30
|
-
{{#if (eq this.iconPosition "leading")}}
|
|
31
|
-
<div class="hds-button__icon">
|
|
32
|
-
<FlightIcon @name={{this.icon}} @size={{this.iconSize}} @stretched={{true}} />
|
|
33
|
-
</div>
|
|
34
|
-
<div class="hds-button__text">
|
|
35
|
-
{{this.text}}
|
|
36
|
-
</div>
|
|
37
|
-
{{else}}
|
|
38
|
-
<div class="hds-button__text">
|
|
39
|
-
{{this.text}}
|
|
40
|
-
</div>
|
|
41
|
-
<div class="hds-button__icon">
|
|
42
|
-
<FlightIcon @name={{this.icon}} @size={{this.iconSize}} @stretched={{true}} />
|
|
43
|
-
</div>
|
|
44
|
-
{{/if}}
|
|
45
|
-
{{else}}
|
|
46
|
-
<div class="hds-button__text">
|
|
47
|
-
{{this.text}}
|
|
48
|
-
</div>
|
|
49
|
-
{{/if}}
|
|
50
|
-
</a>
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
// ██ ██ █████ ██████ ███ ██ ██ ███ ██ ██████
|
|
2
|
-
// ██ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██ ██
|
|
3
|
-
// ██ █ ██ ███████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ███
|
|
4
|
-
// ██ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
5
|
-
// ███ ███ ██ ██ ██ ██ ██ ████ ██ ██ ████ ██████
|
|
6
|
-
//
|
|
7
|
-
// Notice: in this component we're using directly the styles from the `Hds::Button` component
|
|
8
|
-
// using the `hds-button` class names (and adding a specialized class for the "cta", see below)
|
|
9
|
-
// If you need to change the styling of the `Button` component, remember that this will impact also
|
|
10
|
-
// this component too.
|
|
11
|
-
// If instead you need to change only the styling of the `CTA` component, you can do it
|
|
12
|
-
// in the CSS file using the specialized class declared there.
|
|
13
|
-
// This is NOT a standard approach that we use in the HDS design system implementation, but it's been
|
|
14
|
-
// the least worst option we could find to solve the problem of sharing the exact same style of the
|
|
15
|
-
// `Button (primary)` with other components.
|
|
16
|
-
|
|
17
|
-
import Component from '@glimmer/component';
|
|
18
|
-
import { assert } from '@ember/debug';
|
|
19
|
-
import { action } from '@ember/object';
|
|
20
|
-
|
|
21
|
-
export const DEFAULT_SIZE = 'medium';
|
|
22
|
-
export const DEFAULT_ICONPOSITION = 'leading';
|
|
23
|
-
export const SIZES = ['small', 'medium', 'large'];
|
|
24
|
-
export const ICONPOSITIONS = ['leading', 'trailing'];
|
|
25
|
-
|
|
26
|
-
export default class HdsLinkCtaComponent extends Component {
|
|
27
|
-
/**
|
|
28
|
-
* @param text
|
|
29
|
-
* @type {string}
|
|
30
|
-
* @description The text of the component. If no text value is defined an error will be thrown.
|
|
31
|
-
*/
|
|
32
|
-
get text() {
|
|
33
|
-
let { text } = this.args;
|
|
34
|
-
|
|
35
|
-
assert(
|
|
36
|
-
'@text for "Hds::Link::Cta" must have a valid value',
|
|
37
|
-
text !== undefined
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
return text;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @param size
|
|
45
|
-
* @type {string}
|
|
46
|
-
* @default medium
|
|
47
|
-
* @description The size of the component; acceptable values are `small`, `medium`, and `large`
|
|
48
|
-
*/
|
|
49
|
-
get size() {
|
|
50
|
-
let { size = DEFAULT_SIZE } = this.args;
|
|
51
|
-
|
|
52
|
-
assert(
|
|
53
|
-
`@size for "Hds::Link::Cta" must be one of the following: ${SIZES.join(
|
|
54
|
-
', '
|
|
55
|
-
)}; received: ${size}`,
|
|
56
|
-
SIZES.includes(size)
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
return size;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* @param icon
|
|
64
|
-
* @type {string}
|
|
65
|
-
* @default null
|
|
66
|
-
* @description The name of the icon to be used.
|
|
67
|
-
*/
|
|
68
|
-
get icon() {
|
|
69
|
-
return this.args.icon ?? null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* @param iconPosition
|
|
74
|
-
* @type {string}
|
|
75
|
-
* @default leading
|
|
76
|
-
* @description Positions the icon before or after the text; allowed values are `leading` or `trailing`
|
|
77
|
-
*/
|
|
78
|
-
get iconPosition() {
|
|
79
|
-
let { iconPosition = DEFAULT_ICONPOSITION } = this.args;
|
|
80
|
-
|
|
81
|
-
assert(
|
|
82
|
-
`@iconPosition for "Hds::Link::Cta" must be one of the following: ${ICONPOSITIONS.join(
|
|
83
|
-
', '
|
|
84
|
-
)}; received: ${iconPosition}`,
|
|
85
|
-
ICONPOSITIONS.includes(iconPosition)
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
return iconPosition;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @param iconSize
|
|
93
|
-
* @type {string}
|
|
94
|
-
* @default 16
|
|
95
|
-
* @description ensures that the correct icon size is used. Automatically calculated.
|
|
96
|
-
*/
|
|
97
|
-
get iconSize() {
|
|
98
|
-
if (this.args.size === 'large') {
|
|
99
|
-
return '24';
|
|
100
|
-
} else {
|
|
101
|
-
return '16';
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* @param isFullWidth
|
|
107
|
-
* @type {boolean}
|
|
108
|
-
* @default false
|
|
109
|
-
* @description Indicates that the component should take up the full width of the parent container. The default is false.
|
|
110
|
-
*/
|
|
111
|
-
get isFullWidth() {
|
|
112
|
-
return this.args.isFullWidth ?? false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Get the class names to apply to the component.
|
|
117
|
-
* @method classNames
|
|
118
|
-
* @return {string} The "class" attribute to apply to the component.
|
|
119
|
-
*/
|
|
120
|
-
get classNames() {
|
|
121
|
-
let classes = [
|
|
122
|
-
'hds-button',
|
|
123
|
-
'hds-button--color-primary',
|
|
124
|
-
'hds-link-cta--inherit-button-styles',
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
// add a class based on the @size argument
|
|
128
|
-
classes.push(`hds-button--size-${this.size}`);
|
|
129
|
-
|
|
130
|
-
// add a class based on the @isFullWidth argument
|
|
131
|
-
if (this.isFullWidth) {
|
|
132
|
-
classes.push('hds-button--width-full');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return classes.join(' ');
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
@action
|
|
139
|
-
didInsert(el) {
|
|
140
|
-
// we need to register the element to compare it with the one that triggered the "key/space" event
|
|
141
|
-
this.el = el;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@action
|
|
145
|
-
onKeySpace(event) {
|
|
146
|
-
if (event.target === this.el) {
|
|
147
|
-
event.target.click();
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|