@hashicorp/design-system-components 0.12.15 → 1.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 (36) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/NEW-COMPONENT-CHECKLIST.md +1 -0
  3. package/addon/components/hds/button-set/index.hbs +3 -0
  4. package/addon/components/hds/form/checkbox/field.hbs +1 -0
  5. package/addon/components/hds/form/checkbox/group.hbs +5 -1
  6. package/addon/components/hds/form/field/index.hbs +1 -1
  7. package/addon/components/hds/form/field/index.js +11 -3
  8. package/addon/components/hds/form/fieldset/index.hbs +2 -2
  9. package/addon/components/hds/form/fieldset/index.js +7 -3
  10. package/addon/components/hds/form/radio/field.hbs +1 -0
  11. package/addon/components/hds/form/radio/group.hbs +5 -1
  12. package/addon/components/hds/form/select/field.hbs +1 -0
  13. package/addon/components/hds/form/text-input/field.hbs +1 -0
  14. package/addon/components/hds/form/textarea/field.hbs +1 -0
  15. package/addon/components/hds/form/toggle/field.hbs +1 -0
  16. package/addon/components/hds/form/toggle/group.hbs +4 -1
  17. package/addon/components/hds/form/utils/setAriaDescribedBy.js +10 -0
  18. package/addon/components/hds/stepper/step/indicator.hbs +19 -0
  19. package/addon/components/hds/stepper/step/indicator.js +54 -0
  20. package/addon/components/hds/stepper/task/indicator.hbs +3 -0
  21. package/addon/components/hds/stepper/task/indicator.js +69 -0
  22. package/addon/components/hds/tag/index.hbs +26 -0
  23. package/addon/components/hds/tag/index.js +76 -0
  24. package/app/components/hds/button-set/index.js +1 -0
  25. package/app/components/hds/stepper/step/indicator.js +1 -0
  26. package/app/components/hds/stepper/task/indicator.js +1 -0
  27. package/app/components/hds/tag/index.js +1 -0
  28. package/app/styles/@hashicorp/design-system-components.scss +3 -0
  29. package/app/styles/components/button-set.scss +13 -0
  30. package/app/styles/components/form/select.scss +31 -0
  31. package/app/styles/components/stepper/index.scss +2 -0
  32. package/app/styles/components/stepper/step-indicator.scss +180 -0
  33. package/app/styles/components/stepper/task-indicator.scss +70 -0
  34. package/app/styles/components/tag.scss +103 -0
  35. package/package.json +2 -2
  36. package/addon/components/hds/form/utils/getAriaDescribedBy.js +0 -21
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @hashicorp/design-system-components
2
2
 
3
+ ## 1.0.0 🎉
4
+
5
+ ### Major Changes
6
+
7
+ This release signifies the first major release of the HashiCorp Design System. Moving forward we expect to respect [SemVer](https://semver.org/) as we make additional changes to the design system.
8
+
9
+ ### Minor Changes
10
+
11
+ #### Stepper component
12
+
13
+ - [#470](https://github.com/hashicorp/design-system/pull/470) [`96d47264`](https://github.com/hashicorp/design-system/commit/96d4726404664f301df0352a1fdbc4b6b6e9cb88) Thanks [@jorytindall](https://github.com/jorytindall)! - Added Stepper component structure and step/task components
14
+
15
+ #### ButtonSet component
16
+ * [#486](https://github.com/hashicorp/design-system/pull/486) [`3ea2ad55`](https://github.com/hashicorp/design-system/commit/3ea2ad55b2ec9c579e2154ac4bb820f06a231e9f) Thanks [@KristinLBradley](https://github.com/KristinLBradley)! - Add new ButtonSet component to standardize button spacing
17
+
18
+ #### Tag component
19
+ - [#443](https://github.com/hashicorp/design-system/pull/443) [`7756c855`](https://github.com/hashicorp/design-system/commit/7756c8554114564eccb2b08872ceabff02351682) Thanks [@alex-ju](https://github.com/alex-ju) & [@agendelHC](https://github.com/agendelHC)! - Add tag component
20
+
21
+ #### Form controls components
22
+
23
+ - [#447](https://github.com/hashicorp/design-system/pull/447) [`0b1e9855`](https://github.com/hashicorp/design-system/commit/0b1e985586b8f531a6208ea5ce25ac74faa77dda) Thanks [@didoo](https://github.com/didoo)!
24
+
25
+ - Added the form **`TextInput`** controls (`Base`, `Field`)
26
+ - Added the form **`Textarea`** controls (`Base`, `Field`)
27
+ - Added the form **`Select`** controls (`Base`, `Field`)
28
+ - Added the form **`Checkbox`** controls (`Base`, `Field`, `Group`)
29
+ - Added the form **`Radio`** controls (`Base`, `Field`, `Group`)
30
+ - Added the form **`Toggle`** controls (`Base`, `Field`, `Group`)
31
+ - Added the form "base" low-level elements: **`Label`**, **`HelperText`**, **`Error`**, **`Legend`**, **`Field`**, **`Fieldset`**
32
+
33
+ ### Patch Changes
34
+
35
+ - Updated dependencies [[`0b1e9855`](https://github.com/hashicorp/design-system/commit/0b1e985586b8f531a6208ea5ce25ac74faa77dda)]:
36
+ - @hashicorp/design-system-tokens@1.0.0
37
+
3
38
  ## 0.12.15
4
39
 
5
40
  ### Patch Changes
@@ -79,6 +79,7 @@ The engineering checklist has six parts: creating the feature branch, component
79
79
  - [ ] create new component using a blueprint
80
80
  - `ember generate hds-component COMPONENT-NAME`
81
81
  - if it's a child component, then `hds/COMPONENT_NAME/CHILD_NAME`
82
+ - (Note: Many of the below mentioned files will be automatically generated.)
82
83
  - [ ] **component template**
83
84
  - use semantic HTML
84
85
  - the component should have a css class that is the same as the component (e.g. `hds/button` should have a class name of `hds-button` on the component, and additional CSS classes should start with this same class name.
@@ -0,0 +1,3 @@
1
+ <div class="hds-button-set" ...attributes>
2
+ {{yield}}
3
+ </div>
@@ -2,6 +2,7 @@
2
2
  @layout="flag"
3
3
  @contextualClass={{@contextualClass}}
4
4
  @extraAriaDescribedBy={{@extraAriaDescribedBy}}
5
+ @id={{@id}}
5
6
  as |F|
6
7
  >
7
8
  {{! Notice: the order of the elements is not relevant here, because it's controlled at "Hds::Form::Field" component level }}
@@ -13,7 +13,11 @@
13
13
  {{yield
14
14
  (hash
15
15
  Checkbox::Field=(component
16
- "hds/form/checkbox/field" contextualClass="hds-form-group__control-field" isRequired=@isRequired name=@name
16
+ "hds/form/checkbox/field"
17
+ contextualClass="hds-form-group__control-field"
18
+ isRequired=@isRequired
19
+ name=@name
20
+ extraAriaDescribedBy=F.ariaDescribedBy
17
21
  )
18
22
  )
19
23
  }}
@@ -1,4 +1,4 @@
1
- <div class={{this.classNames}} ...attributes>
1
+ <div class={{this.classNames}} {{did-insert this.setAriaDescribedBy}} ...attributes>
2
2
  {{yield
3
3
  (hash
4
4
  Label=(component
@@ -3,18 +3,26 @@ import { tracked } from '@glimmer/tracking';
3
3
  import { assert } from '@ember/debug';
4
4
  import { action } from '@ember/object';
5
5
  import { getElementId } from '../utils/getElementId';
6
- import { getAriaDescribedBy } from '../utils/getAriaDescribedBy';
6
+ import { setAriaDescribedBy } from '../utils/setAriaDescribedBy';
7
+ import { schedule } from '@ember/runloop';
7
8
 
8
9
  export const LAYOUT_TYPES = ['vertical', 'flag'];
9
10
 
10
11
  export default class HdsFormFieldIndexComponent extends Component {
11
- @tracked ariaDescribedBy = getAriaDescribedBy(this);
12
+ @tracked ariaDescribedBy = this.args.extraAriaDescribedBy;
12
13
  @tracked descriptors = [];
13
14
 
14
15
  @action
15
16
  appendDescriptor(element) {
16
17
  this.descriptors.push(element.id);
17
- this.ariaDescribedBy = getAriaDescribedBy(this);
18
+ }
19
+
20
+ @action
21
+ setAriaDescribedBy() {
22
+ // we schedule this afterRender to capture all descriptors registered onInsert
23
+ schedule('afterRender', () => {
24
+ setAriaDescribedBy(this);
25
+ });
18
26
  }
19
27
 
20
28
  /**
@@ -1,4 +1,4 @@
1
- <fieldset class={{this.classNames}} id={{this.id}} ...attributes aria-describedby={{this.ariaDescribedBy}}>
1
+ <fieldset class={{this.classNames}} id={{this.id}} {{did-insert this.setAriaDescribedBy}} ...attributes>
2
2
  {{yield
3
3
  (hash
4
4
  Legend=(component
@@ -17,7 +17,7 @@
17
17
  )
18
18
  }}
19
19
  <div class="hds-form-group__control-fields-wrapper">
20
- {{yield (hash Control=(component "hds/yield"))}}
20
+ {{yield (hash Control=(component "hds/yield") ariaDescribedBy=this.ariaDescribedBy)}}
21
21
  </div>
22
22
  {{yield
23
23
  (hash
@@ -2,16 +2,20 @@ import Component from '@glimmer/component';
2
2
  import { tracked } from '@glimmer/tracking';
3
3
  import { action } from '@ember/object';
4
4
  import { getElementId } from '../utils/getElementId';
5
- import { getAriaDescribedBy } from '../utils/getAriaDescribedBy';
5
+ import { setAriaDescribedBy } from '../utils/setAriaDescribedBy';
6
6
 
7
7
  export default class HdsFormFieldsetIndexComponent extends Component {
8
- @tracked ariaDescribedBy = getAriaDescribedBy(this);
8
+ @tracked ariaDescribedBy = this.args.extraAriaDescribedBy;
9
9
  @tracked descriptors = [];
10
10
 
11
11
  @action
12
12
  appendDescriptor(element) {
13
13
  this.descriptors.push(element.id);
14
- this.ariaDescribedBy = getAriaDescribedBy(this);
14
+ }
15
+
16
+ @action
17
+ setAriaDescribedBy() {
18
+ setAriaDescribedBy(this);
15
19
  }
16
20
 
17
21
  /**
@@ -2,6 +2,7 @@
2
2
  @layout="flag"
3
3
  @contextualClass={{@contextualClass}}
4
4
  @extraAriaDescribedBy={{@extraAriaDescribedBy}}
5
+ @id={{@id}}
5
6
  as |F|
6
7
  >
7
8
  {{! Notice: the order of the elements is not relevant here, because it's controlled at "Hds::Form::Field" component level }}
@@ -13,7 +13,11 @@
13
13
  {{yield
14
14
  (hash
15
15
  Radio::Field=(component
16
- "hds/form/radio/field" contextualClass="hds-form-group__control-field" isRequired=@isRequired name=@name
16
+ "hds/form/radio/field"
17
+ contextualClass="hds-form-group__control-field"
18
+ isRequired=@isRequired
19
+ name=@name
20
+ extraAriaDescribedBy=F.ariaDescribedBy
17
21
  )
18
22
  )
19
23
  }}
@@ -3,6 +3,7 @@
3
3
  @extraAriaDescribedBy={{@extraAriaDescribedBy}}
4
4
  @isRequired={{@isRequired}}
5
5
  @isOptional={{@isOptional}}
6
+ @id={{@id}}
6
7
  as |F|
7
8
  >
8
9
  {{! Notice: the order of the elements is not relevant here, because is controlled at "Hds::Form::Field" component level }}
@@ -3,6 +3,7 @@
3
3
  @extraAriaDescribedBy={{@extraAriaDescribedBy}}
4
4
  @isRequired={{@isRequired}}
5
5
  @isOptional={{@isOptional}}
6
+ @id={{@id}}
6
7
  as |F|
7
8
  >
8
9
  {{! Notice: the order of the elements is not relevant here, because is controlled at "Hds::Form::Field" component level }}
@@ -3,6 +3,7 @@
3
3
  @extraAriaDescribedBy={{@extraAriaDescribedBy}}
4
4
  @isRequired={{@isRequired}}
5
5
  @isOptional={{@isOptional}}
6
+ @id={{@id}}
6
7
  as |F|
7
8
  >
8
9
  {{! Notice: the order of the elements is not relevant here, because is controlled at "Hds::Form::Field" component level }}
@@ -2,6 +2,7 @@
2
2
  @layout="flag"
3
3
  @contextualClass={{@contextualClass}}
4
4
  @extraAriaDescribedBy={{@extraAriaDescribedBy}}
5
+ @id={{@id}}
5
6
  as |F|
6
7
  >
7
8
  {{! Notice: the order of the elements is not relevant here, because is controlled at "Hds::Form::Field" component level }}
@@ -6,7 +6,10 @@
6
6
  {{yield
7
7
  (hash
8
8
  Toggle::Field=(component
9
- "hds/form/toggle/field" contextualClass="hds-form-group__control-field" isRequired=@isRequired
9
+ "hds/form/toggle/field"
10
+ contextualClass="hds-form-group__control-field"
11
+ isRequired=@isRequired
12
+ extraAriaDescribedBy=F.ariaDescribedBy
10
13
  )
11
14
  )
12
15
  }}
@@ -0,0 +1,10 @@
1
+ export function setAriaDescribedBy(element) {
2
+ // append @extraAriaDescribedBy arg, if provided
3
+ if (element.args.extraAriaDescribedBy) {
4
+ element.descriptors.push(element.args.extraAriaDescribedBy);
5
+ }
6
+
7
+ if (element.descriptors.length) {
8
+ element.ariaDescribedBy = element.descriptors.join(' ');
9
+ }
10
+ }
@@ -0,0 +1,19 @@
1
+ <div class={{this.classNames}} ...attributes aria-label={{@status}}>
2
+ <div class="hds-stepper-indicator-step__svg-hexagon">
3
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
4
+ <path
5
+ d="m3.664 6.264 6.99-4.42a2.5 2.5 0 0 1 2.67-.002l7.01 4.422A2.5 2.5 0 0 1 21.5 8.38v7.242a2.5 2.5 0 0 1-1.166 2.115l-7.01 4.422a2.5 2.5 0 0 1-2.67-.002l-6.99-4.42A2.5 2.5 0 0 1 2.5 15.623V8.377a2.5 2.5 0 0 1 1.164-2.113Z"
6
+ stroke-width="1"
7
+ ></path>
8
+ </svg>
9
+ </div>
10
+ <div class="hds-stepper-indicator-step__status">
11
+ {{#if (eq @status "processing")}}
12
+ <FlightIcon class="hds-stepper-indicator-step__icon" @name="loading" @size="16" />
13
+ {{else if (eq @status "complete")}}
14
+ <FlightIcon class="hds-stepper-indicator-step__icon" @name="check" @size="16" />
15
+ {{else}}
16
+ <span class="hds-stepper-indicator-step__text">{{@text}}</span>
17
+ {{/if}}
18
+ </div>
19
+ </div>
@@ -0,0 +1,54 @@
1
+ import Component from '@glimmer/component';
2
+ import { assert } from '@ember/debug';
3
+
4
+ export const DEFAULT_STATUS = 'incomplete';
5
+ export const STATUSES = ['incomplete', 'progress', 'processing', 'complete'];
6
+
7
+ export default class HdsStepperIndicatorStepIndexComponent extends Component {
8
+ /**
9
+ * @param status
10
+ * @type {string}
11
+ * @default "incomplete"
12
+ */
13
+
14
+ get status() {
15
+ let { status = DEFAULT_STATUS } = this.args;
16
+
17
+ assert(
18
+ `@status for "Hds::Stepper::Step::Indicator" must be one of the following: ${STATUSES.join(
19
+ ', '
20
+ )}, received: ${status}`,
21
+ STATUSES.includes(status)
22
+ );
23
+
24
+ return status;
25
+ }
26
+
27
+ /**
28
+ * @param isInteractive
29
+ * @type {boolean}
30
+ * @default false
31
+ */
32
+
33
+ get isInteractive() {
34
+ return this.args.isInteractive || false;
35
+ }
36
+
37
+ /**
38
+ * Get the class names to apply to the component.
39
+ * @method IndicatorStep#classNames
40
+ * @return {string} The "class" attribute to apply to the component.
41
+ */
42
+ get classNames() {
43
+ let classes = ['hds-stepper-indicator-step'];
44
+
45
+ // Based on the @status arg
46
+ classes.push(`hds-stepper-indicator-step--status-${this.status}`);
47
+
48
+ if (this.isInteractive) {
49
+ classes.push(`hds-stepper-indicator-step--is-interactive`);
50
+ }
51
+
52
+ return classes.join(' ');
53
+ }
54
+ }
@@ -0,0 +1,3 @@
1
+ <div class={{this.classNames}} ...attributes aria-label={{@status}}>
2
+ <FlightIcon class="hds-stepper-indicator-task__icon" @name={{this.iconName}} @size="16" />
3
+ </div>
@@ -0,0 +1,69 @@
1
+ import Component from '@glimmer/component';
2
+ import { assert } from '@ember/debug';
3
+
4
+ export const DEFAULT_STATUS = 'incomplete';
5
+ export const STATUSES = ['incomplete', 'progress', 'processing', 'complete'];
6
+ export const MAPPING_STATUS_TO_ICONS = {
7
+ incomplete: 'circle',
8
+ progress: 'circle-half',
9
+ processing: 'loading',
10
+ complete: 'check-circle',
11
+ };
12
+
13
+ export default class HdsStepperIndicatorTaskIndexComponent extends Component {
14
+ /**
15
+ * @param status
16
+ * @type {string}
17
+ * @default "incomplete"
18
+ */
19
+
20
+ get status() {
21
+ let { status = DEFAULT_STATUS } = this.args;
22
+
23
+ assert(
24
+ `@status for "Hds::Stepper::Task::Indicator" must be one of the following: ${STATUSES.join(
25
+ ', '
26
+ )}, received: ${status}`,
27
+ STATUSES.includes(status)
28
+ );
29
+
30
+ return status;
31
+ }
32
+
33
+ /**
34
+ * @param isInteractive
35
+ * @type {boolean}
36
+ * @default false
37
+ */
38
+
39
+ get isInteractive() {
40
+ return this.args.isInteractive || false;
41
+ }
42
+
43
+ /**
44
+ * @param iconName
45
+ * @type {string}
46
+ */
47
+
48
+ get iconName() {
49
+ return MAPPING_STATUS_TO_ICONS[this.status];
50
+ }
51
+
52
+ /**
53
+ * Get the class names to apply to the component.
54
+ * @method IndicatorTask#classNames
55
+ * @return {string} The "class" attribute to apply to the component.
56
+ */
57
+ get classNames() {
58
+ let classes = ['hds-stepper-indicator-task'];
59
+
60
+ // Based on the @status arg
61
+ classes.push(`hds-stepper-indicator-task--status-${this.status}`);
62
+
63
+ if (this.isInteractive) {
64
+ classes.push(`hds-stepper-indicator-task--is-interactive`);
65
+ }
66
+
67
+ return classes.join(' ');
68
+ }
69
+ }
@@ -0,0 +1,26 @@
1
+ <span class={{this.classNames}} ...attributes>
2
+ {{#if this.onDismiss}}
3
+ <button class="hds-tag__dismiss" type="button" aria-label="Dismiss {{this.text}}" {{on "click" this.onDismiss}}>
4
+ <FlightIcon class="hds-tag__dismiss-icon" @name="x" @size="16" @isInlineBlock={{false}} />
5
+ </button>
6
+ {{/if}}
7
+ {{#if (or @href @route)}}
8
+ <Hds::Interactive
9
+ class="hds-tag__link"
10
+ @current-when={{@current-when}}
11
+ @models={{hds-link-to-models @model @models}}
12
+ @query={{hds-link-to-query @query}}
13
+ @replace={{@replace}}
14
+ @route={{@route}}
15
+ @isRouteExternal={{@isRouteExternal}}
16
+ @href={{@href}}
17
+ @isHrefExternal={{@isHrefExternal}}
18
+ >
19
+ {{this.text}}
20
+ </Hds::Interactive>
21
+ {{else}}
22
+ <span class="hds-tag__text">
23
+ {{this.text}}
24
+ </span>
25
+ {{/if}}
26
+ </span>
@@ -0,0 +1,76 @@
1
+ import Component from '@glimmer/component';
2
+ import { assert } from '@ember/debug';
3
+
4
+ export const DEFAULT_COLOR = 'primary';
5
+ export const COLORS = ['primary', 'secondary'];
6
+
7
+ export default class HdsTagIndexComponent extends Component {
8
+ /**
9
+ * @param onDismiss
10
+ * @type {function}
11
+ * @default () => {}
12
+ */
13
+ get onDismiss() {
14
+ let { onDismiss } = this.args;
15
+
16
+ if (typeof onDismiss === 'function') {
17
+ return onDismiss;
18
+ } else {
19
+ return false;
20
+ }
21
+ }
22
+
23
+ /**
24
+ * @param text
25
+ * @type {string}
26
+ * @description The text of the tag. If no text value is defined, an error will be thrown.
27
+ */
28
+ get text() {
29
+ let { text } = this.args;
30
+
31
+ assert('@text for "Hds::Tag" must have a valid value', text !== undefined);
32
+
33
+ return text;
34
+ }
35
+
36
+ /**
37
+ * @param color
38
+ * @type {string}
39
+ * @default primary
40
+ * @description Determines the color of link to be used; acceptable values are `primary` and `secondary`
41
+ */
42
+ get color() {
43
+ if (this.args.href || this.args.route) {
44
+ let { color = DEFAULT_COLOR } = this.args;
45
+ assert(
46
+ `@color for "Hds::Tag" must be one of the following: ${COLORS.join(
47
+ ', '
48
+ )}; received: ${color}`,
49
+ COLORS.includes(color)
50
+ );
51
+ return color;
52
+ } else if (this.args.color) {
53
+ assert(
54
+ '@color can only be applied to "Hds::Tag" along with either @href or @route',
55
+ this.args.href || this.args.route
56
+ );
57
+ }
58
+ return false;
59
+ }
60
+
61
+ /**
62
+ * Get the class names to apply to the component.
63
+ * @method classNames
64
+ * @return {string} The "class" attribute to apply to the component.
65
+ */
66
+ get classNames() {
67
+ let classes = ['hds-tag'];
68
+
69
+ // add a class based on the @color argument
70
+ if (this.color) {
71
+ classes.push(`hds-tag--color-${this.color}`);
72
+ }
73
+
74
+ return classes.join(' ');
75
+ }
76
+ }
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/button-set/index';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/stepper/step/indicator';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/stepper/task/indicator';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/tag/index';
@@ -12,6 +12,7 @@
12
12
  @use "../components/badge-count";
13
13
  @use "../components/breadcrumb";
14
14
  @use "../components/button";
15
+ @use "../components/button-set";
15
16
  @use "../components/card";
16
17
  @use "../components/disclosure";
17
18
  @use "../components/dropdown";
@@ -19,6 +20,8 @@
19
20
  @use "../components/icon-tile";
20
21
  @use "../components/link/inline";
21
22
  @use "../components/link/standalone";
23
+ @use "../components/stepper";
24
+ @use "../components/tag";
22
25
  @use "../components/toast";
23
26
  // END COMPONENT CSS FILES IMPORTS
24
27
 
@@ -0,0 +1,13 @@
1
+ //
2
+ // BUTTON-SET
3
+ //
4
+ // properties within each class are sorted alphabetically
5
+ //
6
+
7
+ .hds-button-set {
8
+ display: flex;
9
+
10
+ > * + * {
11
+ margin-left: 16px;
12
+ }
13
+ }
@@ -67,3 +67,34 @@
67
67
  }
68
68
  }
69
69
  }
70
+
71
+ // MULTIPLE/SIZE
72
+
73
+ .hds-form-select {
74
+ &[multiple],
75
+ &[size]{
76
+ background: none;
77
+
78
+ option {
79
+ border-radius: 3px;
80
+ margin: 2px auto;
81
+
82
+ &:hover {
83
+ color: var(--token-color-foreground-action);
84
+ }
85
+ &:disabled {
86
+ color: var(--token-color-foreground-disabled);
87
+ }
88
+ &:checked {
89
+ color: var(--token-color-foreground-high-contrast);
90
+ background: var(--token-color-palette-blue-200);
91
+ }
92
+ }
93
+
94
+ optgroup {
95
+ color: var(--token-color-foreground-strong);
96
+ font-weight: var(--token-typography-font-weight-semibold);
97
+ font-style: normal; // reset Firefox default
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,2 @@
1
+ @use './step-indicator.scss';
2
+ @use './task-indicator.scss';
@@ -0,0 +1,180 @@
1
+ //
2
+ // STEPPER > INDICATOR > STEP
3
+ //
4
+ // properties within each class are sorted alphabetically
5
+ //
6
+
7
+ $hds-stepper-indicator-step-statuses: ( "incomplete", "progress", "processing", "complete" );
8
+ $hds-stepper-indicator-step-size: 24px;
9
+
10
+ // Base stepper indicator styling
11
+ .hds-stepper-indicator-step {
12
+ height: $hds-stepper-indicator-step-size;
13
+ position: relative;
14
+ width: $hds-stepper-indicator-step-size;
15
+ }
16
+
17
+ .hds-stepper-indicator-step__svg-hexagon {
18
+ filter: drop-shadow(0 1px 1px rgba(101, 106, 118, 0.05));
19
+ height: 100%;
20
+ width: 100%;
21
+ path {
22
+ fill: --status-fill-color;
23
+ stroke: --status-stroke-color;
24
+ }
25
+ }
26
+
27
+ .hds-stepper-indicator-step__status {
28
+ align-items: center;
29
+ display: flex;
30
+ justify-content: center;
31
+ position: absolute;
32
+ top: 0;
33
+ right: 0;
34
+ bottom: 0;
35
+ left: 0;
36
+ }
37
+
38
+ .hds-stepper-indicator-step__icon {
39
+ color: --status-text-color;
40
+ width: 12px;
41
+ height: 12px;
42
+ }
43
+
44
+ .hds-stepper-indicator-step__text {
45
+ color: --status-text-color;
46
+ font-family: var(--token-typography-font-stack-text);
47
+ font-weight: var(--token-typography-font-weight-medium);
48
+ font-size: 0.8125rem;
49
+ overflow: hidden;
50
+ text-align: center;
51
+ user-select: none;
52
+ white-space: nowrap;
53
+ width: 20px;
54
+ }
55
+
56
+ // STATUS
57
+
58
+ // Non-interactive (default)
59
+
60
+ // Non-interactive props that correspond with status
61
+ $non-interactive-props: (
62
+ "incomplete": (
63
+ "text-color": var(--token-color-foreground-strong),
64
+ "fill-color": var(--token-color-surface-faint),
65
+ "stroke-color": var(--token-color-foreground-strong),
66
+ ),
67
+ "progress": (
68
+ "text-color": var(--token-color-foreground-high-contrast),
69
+ "fill-color": var(--token-color-foreground-strong),
70
+ "stroke-color": var(--token-color-foreground-strong),
71
+ ),
72
+ "processing": (
73
+ "text-color": var(--token-color-foreground-high-contrast),
74
+ "fill-color": var(--token-color-foreground-strong),
75
+ "stroke-color": var(--token-color-foreground-strong),
76
+ ),
77
+ "complete": (
78
+ "text-color": var(--token-color-foreground-high-contrast),
79
+ "fill-color": var(--token-color-foreground-strong),
80
+ "stroke-color": var(--token-color-foreground-strong),
81
+ )
82
+ );
83
+
84
+ @each $status in $hds-stepper-indicator-step-statuses {
85
+ // For each status of the non-interactive variant, set the text color, svg fill, and svg stroke colors based on $non-interactive-props
86
+ .hds-stepper-indicator-step--status-#{$status} {
87
+ .hds-stepper-indicator-step__status {
88
+ color: map-get($non-interactive-props, $status, "text-color");
89
+ };
90
+ .hds-stepper-indicator-step__svg-hexagon path {
91
+ fill: map-get($non-interactive-props, $status, "fill-color");
92
+ stroke: map-get($non-interactive-props, $status, "stroke-color");
93
+ }
94
+ }
95
+ }
96
+
97
+ // Interactive
98
+
99
+ // Determine states/status and corresponding styles
100
+ $status-props: (
101
+ "incomplete": (
102
+ "text-color-default": var(--token-color-foreground-primary),
103
+ "fill-color-default": var(--token-color-surface-interactive),
104
+ "stroke-color-default": var(--token-color-border-strong),
105
+ "fill-color-hover": var(--token-color-surface-interactive-hover),
106
+ "fill-color-active": var(--token-color-surface-interactive-active),
107
+ ),
108
+ "progress": (
109
+ "text-color-default": var(--token-color-foreground-high-contrast),
110
+ "fill-color-default": var(--token-color-palette-blue-200),
111
+ "stroke-color-default": var(--token-color-palette-blue-300),
112
+ "fill-color-hover": var(--token-color-palette-blue-300),
113
+ "stroke-color-hover": var(--token-color-palette-blue-400),
114
+ "fill-color-active": var(--token-color-palette-blue-400),
115
+ "stroke-color-active": var(--token-color-palette-blue-400),
116
+ ),
117
+ "processing": (
118
+ "text-color-default": var(--token-color-foreground-high-contrast),
119
+ "fill-color-default": var(--token-color-palette-blue-200),
120
+ "stroke-color-default": var(--token-color-palette-blue-300),
121
+ "fill-color-hover": var(--token-color-palette-blue-300),
122
+ "stroke-color-hover": var(--token-color-palette-blue-400),
123
+ "fill-color-active": var(--token-color-palette-blue-400),
124
+ "stroke-color-active": var(--token-color-palette-blue-400),
125
+ ),
126
+ "complete": (
127
+ "text-color-default": var(--token-color-palette-blue-200),
128
+ "fill-color-default": var(--token-color-palette-blue-50),
129
+ "stroke-color-default": var(--token-color-palette-blue-300),
130
+ "text-color-hover": var(--token-color-palette-blue-300),
131
+ "fill-color-hover": var(--token-color-palette-blue-100),
132
+ "stroke-color-hover": var(--token-color-palette-blue-400),
133
+ "text-color-active": var(--token-color-palette-blue-400),
134
+ "fill-color-active": var(--token-color-palette-blue-100),
135
+ "stroke-color-active": var(--token-color-palette-blue-400),
136
+ )
137
+ );
138
+
139
+ .hds-stepper-indicator-step--is-interactive {
140
+ cursor: pointer;
141
+
142
+ @each $status in $hds-stepper-indicator-step-statuses {
143
+ // For each status set the text, svg fill, and svg stroke color based on $status-props
144
+ &.hds-stepper-indicator-step--status-#{$status} {
145
+ .hds-stepper-indicator-step__status {
146
+ color: map-get($status-props, $status, "text-color-default");
147
+ }
148
+ .hds-stepper-indicator-step__svg-hexagon path {
149
+ fill: map-get($status-props, $status, "fill-color-default");
150
+ stroke: map-get($status-props, $status, "stroke-color-default");
151
+ }
152
+
153
+ &:hover,
154
+ &.mock-hover {
155
+ .hds-stepper-indicator-step__status {
156
+ color: map-get($status-props, $status, "text-color-hover");
157
+ }
158
+ .hds-stepper-indicator-step__svg-hexagon {
159
+ path {
160
+ fill: map-get($status-props, $status, "fill-color-hover");
161
+ stroke: map-get($status-props, $status, "stroke-color-hover");
162
+ };
163
+ }
164
+ }
165
+
166
+ &:active,
167
+ &.mock-active {
168
+ .hds-stepper-indicator-step__status {
169
+ color: map-get($status-props, $status, "text-color-active");
170
+ }
171
+ .hds-stepper-indicator-step__svg-hexagon {
172
+ path {
173
+ fill: map-get($status-props, $status, "fill-color-active");
174
+ stroke: map-get($status-props, $status, "stroke-color-active");
175
+ };
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
@@ -0,0 +1,70 @@
1
+ //
2
+ // STEPPER > INDICATOR > TASK
3
+ //
4
+ // properties within each class are sorted alphabetically
5
+ //
6
+
7
+ $hds-stepper-indicator-task-statuses: ( "incomplete", "progress", "processing", "complete" );
8
+ $hds-stepper-indicator-task-size: 16px;
9
+
10
+ // Determine states and corresponding styles
11
+ $status-props: (
12
+ "incomplete": (
13
+ "color-default": var(--token-color-palette-neutral-300),
14
+ "color-hover": var(--token-color-palette-blue-300),
15
+ "color-active": var(--token-color-palette-blue-400),
16
+ ),
17
+ "progress": (
18
+ "color-default": var(--token-color-palette-blue-200),
19
+ "color-hover": var(--token-color-palette-blue-300),
20
+ "color-active": var(--token-color-palette-blue-400),
21
+ ),
22
+ "processing": (
23
+ "color-default": var(--token-color-palette-blue-200),
24
+ "color-hover": var(--token-color-palette-blue-300),
25
+ "color-active": var(--token-color-palette-blue-400),
26
+ ),
27
+ "complete": (
28
+ "color-default": var(--token-color-palette-green-200),
29
+ "color-hover": var(--token-color-palette-green-300),
30
+ "color-active": var(--token-color-palette-green-400),
31
+ )
32
+ );
33
+
34
+ // Base styling for indicator::task
35
+ .hds-stepper-indicator-task {
36
+ align-items: center;
37
+ color: var(--token-color-foreground-strong);
38
+ display: flex;
39
+ height: $hds-stepper-indicator-task-size;
40
+ justify-content: center;
41
+ position: relative;
42
+ width: $hds-stepper-indicator-task-size;
43
+ }
44
+
45
+ .hds-stepper-indicator-task__icon {
46
+ height: 12px;
47
+ width: 12px;
48
+ }
49
+
50
+ .hds-stepper-indicator-task--is-interactive {
51
+ cursor: pointer;
52
+
53
+ @each $status in $hds-stepper-indicator-task-statuses {
54
+ // For each status set the icon color based on the $status-props
55
+ &.hds-stepper-indicator-task--status-#{$status} {
56
+ color: map-get($status-props, $status, "color-default");
57
+ &:hover,
58
+ &.mock-hover {
59
+ color: map-get($status-props, $status, "color-hover");
60
+ };
61
+ &:active,
62
+ &.mock-active {
63
+ color: map-get($status-props, $status, "color-active");
64
+ };
65
+ }
66
+ }
67
+ }
68
+
69
+
70
+
@@ -0,0 +1,103 @@
1
+ //
2
+ // TAG COMPONENT
3
+ //
4
+ // properties within each class are sorted alphabetically
5
+ //
6
+ //
7
+
8
+ @use "../mixins/focus-ring" as *;
9
+
10
+ // we set a higher value than the line-height (~13px) to accommodate cases where the text wraps
11
+ $hds-tag-border-radius: 50px;
12
+
13
+ .hds-tag {
14
+ align-items: stretch;
15
+ background-color: var(--token-color-surface-interactive);
16
+ border: 1px solid var(--token-color-border-strong);
17
+ border-radius: $hds-tag-border-radius;
18
+ color: var(--token-color-foreground-primary);
19
+ display: inline-flex;
20
+ font-family: var(--token-typography-font-stack-text);
21
+ font-size: 0.8125rem; // 13px
22
+ font-weight: var(--token-typography-font-weight-medium);
23
+ line-height: 1rem; // 16px
24
+ vertical-align: middle;
25
+ }
26
+
27
+ .hds-tag__dismiss {
28
+ flex: 0 0 auto;
29
+ border-radius: inherit;
30
+ border-top-right-radius: 0;
31
+ border-bottom-right-radius: 0;
32
+ border: none; // reset default button border
33
+ margin: 0; // reset default button margin
34
+ padding: 6px 2px 6px 8px;
35
+ }
36
+
37
+ .hds-tag__dismiss-icon {
38
+ color: var(--token-color-foreground-primary);
39
+ height: 12px;
40
+ width: 12px;
41
+ }
42
+
43
+ .hds-tag__text,
44
+ .hds-tag__link {
45
+ border-radius: inherit;
46
+ flex: 1 0 0;
47
+ padding: 3px 10px 5px 10px;
48
+ }
49
+
50
+ .hds-tag__dismiss ~ .hds-tag__text,
51
+ .hds-tag__dismiss ~ .hds-tag__link {
52
+ border-top-left-radius: 0;
53
+ border-bottom-left-radius: 0;
54
+ padding: 3px 8px 5px 6px;
55
+ }
56
+
57
+ // INTERACTIVE ELEMENTS
58
+
59
+ .hds-tag__dismiss,
60
+ .hds-tag__link {
61
+ background-color: var(--token-color-surface-interactive);
62
+ cursor: pointer;
63
+
64
+ &:hover,
65
+ &.mock-hover {
66
+ background-color: var(--token-color-surface-interactive-hover);
67
+ }
68
+
69
+ &:active,
70
+ &.mock-active{
71
+ background-color: var(--token-color-surface-interactive-active);
72
+ }
73
+
74
+ &:focus,
75
+ &.mock-focus {
76
+ @include hds-focus-ring-basic();
77
+ z-index: 1; // ensures focus is not obscured by adjacent elements
78
+ }
79
+ }
80
+
81
+ // COLORS (FOR LINK)
82
+
83
+ .hds-tag--color-primary {
84
+ .hds-tag__link {
85
+ color: var(--token-color-foreground-action);
86
+
87
+ &:hover,
88
+ &.mock-hover {
89
+ color: var(--token-color-foreground-action-hover);
90
+ }
91
+
92
+ &:active,
93
+ &.mock-active{
94
+ color: var(--token-color-foreground-action-active);
95
+ }
96
+ }
97
+ }
98
+
99
+ .hds-tag--color-secondary {
100
+ .hds-tag__link {
101
+ color: var(--token-color-foreground-strong);
102
+ }
103
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashicorp/design-system-components",
3
- "version": "0.12.15",
3
+ "version": "1.0.0",
4
4
  "description": "HashiCorp Design System Components",
5
5
  "keywords": [
6
6
  "hashicorp",
@@ -34,7 +34,7 @@
34
34
  "test:ember:percy": "percy exec ember test"
35
35
  },
36
36
  "dependencies": {
37
- "@hashicorp/design-system-tokens": "^0.8.1",
37
+ "@hashicorp/design-system-tokens": "^1.0.0",
38
38
  "@hashicorp/ember-flight-icons": "^2.0.10",
39
39
  "ember-auto-import": "^2.4.1",
40
40
  "ember-cli-babel": "^7.26.11",
@@ -1,21 +0,0 @@
1
- export function getAriaDescribedBy(element) {
2
- let ariaDescribedBy = [];
3
-
4
- // append descriptor's IDs, if provided
5
- if (element.descriptors) {
6
- element.descriptors.forEach((descriptor) =>
7
- ariaDescribedBy.push(descriptor)
8
- );
9
- }
10
-
11
- // append @extraAriaDescribedBy arg, if provided
12
- if (element.args.extraAriaDescribedBy) {
13
- ariaDescribedBy.push(element.args.extraAriaDescribedBy);
14
- }
15
-
16
- if (ariaDescribedBy.length) {
17
- return ariaDescribedBy.join(' ');
18
- } else {
19
- return null;
20
- }
21
- }