@hashicorp/design-system-components 1.8.1 → 2.0.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 (34) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/addon/components/hds/dropdown/footer.hbs +3 -0
  3. package/addon/components/hds/dropdown/header.hbs +3 -0
  4. package/addon/components/hds/dropdown/index.hbs +20 -13
  5. package/addon/components/hds/dropdown/index.js +27 -10
  6. package/addon/components/hds/dropdown/list-item/checkbox.hbs +14 -0
  7. package/addon/components/hds/dropdown/list-item/checkbox.js +11 -0
  8. package/addon/components/hds/dropdown/list-item/checkmark.hbs +34 -0
  9. package/addon/components/hds/dropdown/list-item/checkmark.js +23 -0
  10. package/addon/components/hds/dropdown/list-item/copy-item.js +1 -1
  11. package/addon/components/hds/dropdown/list-item/description.js +1 -1
  12. package/addon/components/hds/dropdown/list-item/generic.hbs +1 -1
  13. package/addon/components/hds/dropdown/list-item/interactive.js +1 -1
  14. package/addon/components/hds/dropdown/list-item/radio.hbs +12 -0
  15. package/addon/components/hds/dropdown/list-item/radio.js +11 -0
  16. package/addon/components/hds/dropdown/list-item/separator.hbs +1 -1
  17. package/addon/components/hds/dropdown/list-item/title.js +4 -1
  18. package/addon/components/hds/dropdown/toggle/button.hbs +30 -21
  19. package/addon/components/hds/dropdown/toggle/button.js +52 -0
  20. package/addon/components/hds/dropdown/toggle/chevron.hbs +3 -0
  21. package/addon/components/hds/dropdown/toggle/icon.hbs +2 -2
  22. package/addon/components/hds/dropdown/toggle/icon.js +40 -0
  23. package/app/components/hds/dropdown/footer.js +1 -0
  24. package/app/components/hds/dropdown/header.js +1 -0
  25. package/app/components/hds/dropdown/list-item/checkbox.js +1 -0
  26. package/app/components/hds/dropdown/list-item/checkmark.js +1 -0
  27. package/app/components/hds/dropdown/list-item/radio.js +1 -0
  28. package/app/components/hds/dropdown/toggle/chevron.js +6 -0
  29. package/app/styles/components/button.scss +9 -254
  30. package/app/styles/components/dropdown.scss +260 -65
  31. package/app/styles/mixins/_button.scss +280 -0
  32. package/blueprints/hds-component-test/index.js +4 -2
  33. package/package.json +1 -1
  34. /package/blueprints/hds-component-test/files/tests/dummy/app/styles/{pages → showcase-pages}/__dummyCSSFileName__.scss +0 -0
@@ -3,30 +3,16 @@
3
3
  * SPDX-License-Identifier: MPL-2.0
4
4
  */
5
5
 
6
- /* stylelint-disable selector-class-pattern */
7
- // >>>>>>>>>> WARNING <<<<<<<<<<<
8
- //
9
- // Notice: in this component we're using directly the `Hds::Button` component
10
- // (and adding a specialized class for the "toggle-button" variant, see below)
11
- // If you need to change the styling of the `Button` component, remember that this will impact also
12
- // this component too.
13
- // If instead you need to change only the styling of the `toggle-button` component, you can do it here using
14
- // the specialized class declared below.
15
- // This is NOT a standard approach that we use in the HDS design system implementation, but it's been
16
- // the least worst option we could find to solve the problem of sharing the exact same style of the
17
- // `Button (primary)` with other components.
18
-
19
6
  //
20
7
  // DROPDOWN COMPONENT
21
8
  //
22
9
  // notice: pseudo-classes for the states *must* follow the order link > visited > hover > focus > active
23
10
  //
24
11
 
12
+ @use "../mixins/button" as *;
25
13
  @use "../mixins/focus-ring" as *;
26
14
 
27
- $hds-dropdown-toggle-base-height: 36px;
28
- $hds-dropdown-toggle-border-radius: 5px;
29
-
15
+ $hds-dropdown-toggle-border-radius: $hds-button-border-radius;
30
16
 
31
17
  // TOGGLE/ICON
32
18
 
@@ -34,11 +20,9 @@ $hds-dropdown-toggle-border-radius: 5px;
34
20
  display: flex;
35
21
  align-items: center;
36
22
  justify-content: center;
37
- min-width: $hds-dropdown-toggle-base-height;
38
- height: $hds-dropdown-toggle-base-height;
39
23
  padding: 1px;
40
- background-color: transparent;
41
- border: 1px solid transparent; // We need this to be transparent for a11y
24
+ background-color: var(--token-color-surface-faint);
25
+ border: 1px solid var(--token-color-border-strong);
42
26
  border-radius: $hds-dropdown-toggle-border-radius;
43
27
  outline-style: solid; // used to avoid double outline+focus-ring in Safari (see https://github.com/hashicorp/design-system-components/issues/161#issuecomment-1031548656)
44
28
  outline-color: transparent; // We need this to be transparent for a11y
@@ -46,7 +30,6 @@ $hds-dropdown-toggle-border-radius: 5px;
46
30
  &:hover,
47
31
  &.mock-hover {
48
32
  background-color: var(--token-color-surface-interactive);
49
- border-color: var(--token-color-border-strong);
50
33
  cursor: pointer;
51
34
  }
52
35
 
@@ -57,15 +40,21 @@ $hds-dropdown-toggle-border-radius: 5px;
57
40
  background-color: var(--token-color-surface-interactive-active);
58
41
  border-color: var(--token-color-border-strong);
59
42
  }
43
+
44
+ &:disabled,
45
+ &.mock-disabled {
46
+ @include hds-button-state-disabled();
47
+ }
48
+
49
+ .hds-dropdown-toggle-chevron {
50
+ padding-left: 4px;
51
+ }
60
52
  }
61
53
 
62
54
  .hds-dropdown-toggle-icon__wrapper {
63
55
  display: flex;
64
56
  align-items: center;
65
57
  justify-content: center;
66
- width: 32px;
67
- height: 32px;
68
- padding: 1px;
69
58
  border-radius: 3px; // $hds-dropdown-toggle-border-radius - 1px padding - 1px border
70
59
 
71
60
  img {
@@ -76,86 +65,214 @@ $hds-dropdown-toggle-border-radius: 5px;
76
65
  }
77
66
  }
78
67
 
79
- .hds-dropdown-toggle-icon__chevron {
80
- margin-left: 4px;
81
-
82
- @media (prefers-reduced-motion: no-preference) {
83
- transition: transform 0.3s;
68
+ .hds-dropdown-toggle-icon--size-small {
69
+ .hds-dropdown-toggle-icon__wrapper {
70
+ width: 20px;
71
+ height: 20px;
84
72
  }
73
+ }
85
74
 
86
- .hds-dropdown-toggle-icon--is-open & {
87
- transform: rotate(-180deg);
75
+ .hds-dropdown-toggle-icon--size-medium {
76
+ .hds-dropdown-toggle-icon__wrapper {
77
+ width: 32px;
78
+ height: 32px;
88
79
  }
89
80
  }
90
81
 
91
82
  // TOGGLE/BUTTON
92
83
 
93
84
  .hds-dropdown-toggle-button {
94
- box-shadow: none; // we override this to remove the elevation style
85
+ @include hds-button();
95
86
 
96
- .hds-button__icon {
97
- margin-right: -6px; // we apply a negative margin to counter the padding-right of the button and reduce the visual space between the icon and the right border
98
- margin-left: 8px; // this overrides the rule `.hds-button__text + .hds-button__icon`
87
+ &:focus,
88
+ &.mock-focus {
89
+ @include hds-button-state-focus();
90
+ }
99
91
 
100
- @media (prefers-reduced-motion: no-preference) {
101
- transition: transform 0.3s;
92
+ &:disabled,
93
+ &.mock-disabled,
94
+ &:disabled:focus,
95
+ &.mock-disabled:focus,
96
+ &:disabled:hover,
97
+ &.mock-disabled:hover {
98
+ @include hds-button-state-disabled();
99
+
100
+ .hds-dropdown-toggle-button__badge,
101
+ .hds-dropdown-toggle-button__count {
102
+ color: var(--token-color-foreground-primary);
103
+ background-color: var(--token-color-surface-strong);
102
104
  }
103
105
  }
104
106
  }
105
107
 
108
+ @include hds-button-size-classes("hds-dropdown-toggle-button");
106
109
 
107
- .hds-dropdown-toggle-button--is-open {
108
- .hds-button__icon {
109
- transform: rotate(-180deg);
110
- }
110
+ .hds-dropdown-toggle-button--size-small {
111
+ padding-right: 0.375rem;
111
112
  }
112
113
 
114
+ .hds-dropdown-toggle-button--size-medium {
115
+ padding-right: 0.5625rem;
116
+ }
117
+
118
+ .hds-dropdown-toggle-button--color-primary {
119
+ @include hds-button-color-primary();
120
+ }
121
+
122
+ .hds-dropdown-toggle-button--color-secondary {
123
+ @include hds-button-color-secondary();
124
+ }
125
+
126
+ .hds-dropdown-toggle-button--width-full {
127
+ justify-content: space-between;
128
+ width: 100%;
129
+ max-width: 100%;
130
+ }
131
+
132
+ .hds-dropdown-toggle-button__text {
133
+ text-align: left;
134
+ }
135
+
136
+ .hds-dropdown-toggle-button__icon {
137
+ flex: none;
138
+ margin-right: 0.375rem;
139
+ }
140
+
141
+ .hds-dropdown-toggle-button__badge,
142
+ .hds-dropdown-toggle-button__count {
143
+ margin: -3px 0 -3px 6px;
144
+ }
145
+
146
+ // TOGGLE / CHEVRON
147
+
148
+ .hds-dropdown-toggle-chevron {
149
+ margin-left: auto;
150
+ padding-left: 8px;
151
+
152
+ .flight-icon-chevron-down {
153
+ @media (prefers-reduced-motion: no-preference) {
154
+ transition: transform 0.3s;
155
+ }
156
+ }
157
+
158
+ .hds-dropdown-toggle-icon--is-open &,
159
+ .hds-dropdown-toggle-button--is-open & {
160
+ .flight-icon-chevron-down {
161
+ transform: rotate(-180deg);
162
+ }
163
+ }
164
+ }
113
165
 
114
166
  // LIST
115
167
  // UL ELEMENT
116
168
  // GOES INSIDE HDS::DISCLOSURE's :content block
117
169
 
118
- .hds-dropdown-list {
170
+ .hds-dropdown__content {
171
+ display: flex;
172
+ flex-direction: column;
119
173
  width: max-content; // notice: this is important because being in a position absolute means the layout algorithm assigns a width of 0 and this impacts on the flex algorithm of the children (in some cases they don't use the full width)
120
174
  min-width: 200px;
121
175
  max-width: 400px;
122
- margin: 0;
123
- padding: 4px 0;
124
- list-style: none;
125
176
  background-color: var(--token-color-surface-primary);
126
177
  border-radius: 6px;
127
178
  box-shadow: var(--token-surface-high-box-shadow);
128
179
  }
129
180
 
130
- .hds-dropdown-list--fixed-width {
181
+ .hds-dropdown__content--fixed-width {
131
182
  min-width: initial;
132
183
  max-width: initial;
133
184
  }
134
185
 
135
- .hds-dropdown-list--position-right {
186
+ .hds-dropdown__content--position-bottom-right,
187
+ .hds-dropdown__content--position-right {
136
188
  position: absolute;
137
189
  top: calc(100% + 4px);
138
190
  right: 0;
139
- z-index: 2; // https://github.com/hashicorp/design-system/issues/114
191
+ z-index: 2;
140
192
  }
141
193
 
142
- .hds-dropdown-list--position-left {
194
+ .hds-dropdown__content--position-bottom-left,
195
+ .hds-dropdown__content--position-left {
143
196
  position: absolute;
144
197
  top: calc(100% + 4px);
145
198
  left: 0;
146
- z-index: 2; // https://github.com/hashicorp/design-system/issues/114
199
+ z-index: 2;
200
+ }
201
+
202
+ .hds-dropdown__content--position-top-right {
203
+ position: absolute;
204
+ right: 0;
205
+ bottom: calc(100% + 4px);
206
+ z-index: 2;
207
+ }
208
+
209
+ .hds-dropdown__content--position-top-left {
210
+ position: absolute;
211
+ bottom: calc(100% + 4px);
212
+ left: 0;
213
+ z-index: 2;
214
+ }
215
+
216
+
217
+ .hds-dropdown__list {
218
+ flex: 1 1 auto;
219
+ margin: 0;
220
+ padding: 4px 0;
221
+ overflow-y: auto;
222
+ list-style: none;
223
+ overscroll-behavior: contain;
224
+ }
225
+
226
+ .hds-dropdown__header,
227
+ .hds-dropdown__footer {
228
+ position: relative;
229
+ flex: none;
230
+ padding: 0 8px;
231
+
232
+ > .hds-link-standalone {
233
+ width: initial;
234
+ margin: 4px 0;
235
+ padding: 7px 8px; // 7px=8px-1px(accounting for the transparent border)
236
+
237
+ // keep focus ring in sync with the padding
238
+ &::before {
239
+ top: 0;
240
+ bottom: 0;
241
+ }
242
+ }
243
+
244
+ > .hds-button,
245
+ > .hds-form-text-input {
246
+ margin: 8px 0;
247
+ }
248
+
249
+ > .hds-button-set {
250
+ margin: 8px 0;
251
+
252
+ > * + * {
253
+ margin-left: 8px;
254
+ }
255
+ }
147
256
  }
148
257
 
258
+ .hds-dropdown__header--with-divider {
259
+ border-bottom: 1px solid var(--token-color-border-primary);
260
+ }
261
+
262
+ .hds-dropdown__footer--with-divider {
263
+ border-top: 1px solid var(--token-color-border-primary);
264
+ }
149
265
 
150
266
  // LIST > LIST-ITEM
151
267
  // HDS::DROPDOWN::LIST-ITEM
152
268
 
269
+ // HDS::DROPDOWN::LIST-ITEM::COPY-ITEM
153
270
  .hds-dropdown-list-item__copy-item-title {
154
271
  padding: 2px 0 4px;
155
272
  color: var(--token-color-foreground-faint);
156
273
  }
157
274
 
158
- .hds-dropdown-list-item--copy-item {
275
+ .hds-dropdown-list-item--variant-copy-item {
159
276
  width: 100%;
160
277
  padding: 10px 16px 12px;
161
278
 
@@ -213,18 +330,23 @@ $hds-dropdown-toggle-border-radius: 5px;
213
330
  color: var(--token-color-foreground-action);
214
331
  }
215
332
 
216
- .hds-dropdown-list-item--description {
333
+ // HDS::DROPDOWN::LIST-ITEM::DESCRIPTION
334
+
335
+ .hds-dropdown-list-item--variant-description {
217
336
  padding: 2px 16px 4px;
218
337
  color: var(--token-color-foreground-faint);
219
338
  }
220
339
 
221
- .hds-dropdown-list-item--generic {
340
+ // HDS::DROPDOWN::LIST-ITEM::GENERIC
341
+
342
+ .hds-dropdown-list-item--variant-generic {
222
343
  padding-right: 16px;
223
344
  padding-left: 16px;
224
345
  }
225
346
 
226
-
227
- .hds-dropdown-list-item--interactive {
347
+ // HDS::DROPDOWN::LIST-ITEM::INTERACTIVE & HDS::DROPDOWN::LIST-ITEM::CHECKMARK
348
+ .hds-dropdown-list-item--variant-interactive,
349
+ .hds-dropdown-list-item--variant-checkmark {
228
350
  position: relative;
229
351
  min-height: 36px;
230
352
  isolation: isolate; // used to create a new stacking context (needed to have the pseudo element below text/icon but not the parent container)
@@ -243,7 +365,7 @@ $hds-dropdown-toggle-border-radius: 5px;
243
365
  a,
244
366
  button {
245
367
  display: flex;
246
- align-items: center;
368
+ align-items: flex-start;
247
369
  padding: 7px 9px 7px 15px; // notice: we're subtracting 1px because of the transparent border
248
370
  text-decoration: none;
249
371
  border: 1px solid transparent; // because a border for the button is needed for a11y, we apply it to both the button and the link so they have the same height
@@ -294,7 +416,6 @@ $hds-dropdown-toggle-border-radius: 5px;
294
416
 
295
417
  &::after {
296
418
  left: 4px;
297
- background-color: var(--current-background-color);
298
419
  box-shadow: var(--current-focus-ring-box-shadow);
299
420
  }
300
421
  }
@@ -311,7 +432,6 @@ $hds-dropdown-toggle-border-radius: 5px;
311
432
 
312
433
  &::after {
313
434
  left: 4px;
314
- background-color: var(--current-background-color);
315
435
  box-shadow: var(--current-focus-ring-box-shadow);
316
436
  }
317
437
  }
@@ -334,19 +454,17 @@ $hds-dropdown-toggle-border-radius: 5px;
334
454
  &::before {
335
455
  background-color: currentColor;
336
456
  }
337
-
338
- &::after {
339
- background-color: var(--current-background-color);
340
- }
341
457
  }
342
458
  }
343
459
  }
344
460
 
345
461
  .hds-dropdown-list-item__interactive-icon {
462
+ margin-top: 2px;
346
463
  margin-right: 8px;
347
464
  }
348
465
 
349
466
  .hds-dropdown-list-item__interactive-text {
467
+ flex: 1;
350
468
  text-align: left; // the button element was centering text
351
469
  }
352
470
 
@@ -361,7 +479,6 @@ $hds-dropdown-toggle-border-radius: 5px;
361
479
  --current-color-active: var(--token-color-foreground-action-active);
362
480
 
363
481
  &::after {
364
- --current-background-color: var(--token-color-surface-action);
365
482
  --current-focus-ring-box-shadow: var(--token-focus-ring-action-box-shadow);
366
483
  }
367
484
  }
@@ -398,7 +515,9 @@ $hds-dropdown-toggle-border-radius: 5px;
398
515
  }
399
516
  }
400
517
 
401
- .hds-dropdown-list-item--separator {
518
+ // HDS::DROPDOWN::LIST-ITEM::SEPARATOR
519
+
520
+ .hds-dropdown-list-item--variant-separator {
402
521
  position: relative;
403
522
  width: 100%;
404
523
  height: 4px;
@@ -413,8 +532,84 @@ $hds-dropdown-toggle-border-radius: 5px;
413
532
  }
414
533
  }
415
534
 
416
- .hds-dropdown-list-item--title {
535
+ // HDS::DROPDOWN::LIST-ITEM::TITLE
536
+
537
+ .hds-dropdown-list-item--variant-title {
417
538
  padding: 10px 16px 4px;
418
539
  color: var(--token-color-foreground-strong);
419
540
  }
420
541
 
542
+ // HDS::DROPDOWN::LIST-ITEM::CHECKMARK
543
+
544
+ .hds-dropdown-list-item--variant-checkmark-selected {
545
+ .hds-dropdown-list-item__interactive {
546
+ color: var(--token-color-foreground-action);
547
+ }
548
+ }
549
+
550
+ .hds-dropdown-list-item__checkmark {
551
+ display: flex;
552
+ width: 16px;
553
+ height: 20px; // replicating the resulted height of the list item
554
+ margin-left: 8px;
555
+ }
556
+
557
+ .hds-dropdown-list-item__checkmark-icon {
558
+ align-self: center;
559
+ }
560
+
561
+ .hds-dropdown-list-item__interactive[disabled],
562
+ .hds-dropdown-list-item__interactive[disabled]:hover {
563
+ color: var(--token-color-foreground-disabled);
564
+ cursor: not-allowed;
565
+ }
566
+
567
+
568
+ // HDS::DROPDOWN::LIST-ITEM::CHECKBOX & HDS::DROPDOWN::LIST-ITEM::RADIO
569
+
570
+ .hds-dropdown-list-item--variant-checkbox,
571
+ .hds-dropdown-list-item--variant-radio {
572
+ display: flex;
573
+ align-items: self-start;
574
+ padding: 8px 16px;
575
+
576
+ .hds-dropdown-list-item__control {
577
+ flex-shrink: 0;
578
+ margin-top: 2px;
579
+ margin-right: 8px;
580
+
581
+ &[disabled] ~ .hds-dropdown-list-item__label,
582
+ &[disabled] ~ .hds-dropdown-list-item__icon,
583
+ &[disabled] ~ .hds-dropdown-list-item__count {
584
+ color: var(--token-color-foreground-disabled);
585
+ }
586
+ }
587
+
588
+ .hds-dropdown-list-item__label {
589
+ flex-grow: 1;
590
+ color: var(--token-color-foreground-primary);
591
+ }
592
+
593
+ .hds-dropdown-list-item__icon {
594
+ margin-top: 2px;
595
+ margin-right: 4px;
596
+ color: var(--token-color-foreground-primary);
597
+ }
598
+ }
599
+
600
+ // COUNT
601
+ .hds-dropdown-list-item__count {
602
+ margin-left: 8px;
603
+ color: var(--token-color-foreground-faint);
604
+ line-height: 20px; // replicating the resulted height of the list item
605
+ }
606
+
607
+ // BADGE INSIDE CHECKMARK, CHECKBOX OR RADIO
608
+ .hds-dropdown-list-item--variant-checkmark,
609
+ .hds-dropdown-list-item--variant-checkbox,
610
+ .hds-dropdown-list-item--variant-radio {
611
+ // align any `Hds::Badge` within a selectable list item to match baseline
612
+ .hds-badge {
613
+ vertical-align: bottom;
614
+ }
615
+ }