@hashicorp/design-system-components 2.7.1 → 2.8.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +47 -1
  2. package/HOW-TO-TEST-A-COMPONENT-IN-CLOUD-UI.md +21 -0
  3. package/NEW-COMPONENT-CHECKLIST.md +1 -0
  4. package/addon/components/hds/accordion/index.hbs +8 -0
  5. package/addon/components/hds/accordion/item/button.hbs +16 -0
  6. package/addon/components/hds/accordion/item/button.js +31 -0
  7. package/addon/components/hds/accordion/item/index.hbs +30 -0
  8. package/addon/components/hds/accordion/item/index.js +58 -0
  9. package/addon/components/hds/alert/description.hbs +1 -1
  10. package/addon/components/hds/alert/index.hbs +1 -1
  11. package/addon/components/hds/alert/title.hbs +1 -1
  12. package/addon/components/hds/card/container.js +2 -2
  13. package/addon/components/hds/form/masked-input/base.hbs +34 -0
  14. package/addon/components/hds/form/masked-input/base.js +72 -0
  15. package/addon/components/hds/form/masked-input/field.hbs +30 -0
  16. package/addon/components/hds/form/text-input/base.js +7 -1
  17. package/addon/components/hds/form/text-input/field.hbs +1 -0
  18. package/addon/components/hds/modal/index.js +5 -1
  19. package/addon/components/hds/page-header/index.hbs +1 -1
  20. package/app/components/hds/accordion/index.js +6 -0
  21. package/app/components/hds/accordion/item/button.js +6 -0
  22. package/app/components/hds/accordion/item/index.js +6 -0
  23. package/app/components/hds/form/masked-input/base.js +6 -0
  24. package/app/components/hds/form/masked-input/field.js +6 -0
  25. package/app/styles/@hashicorp/design-system-components.scss +1 -0
  26. package/app/styles/components/accordion.scss +120 -0
  27. package/app/styles/components/alert.scss +0 -15
  28. package/app/styles/components/disclosure-primitive.scss +0 -1
  29. package/app/styles/components/form/index.scss +1 -0
  30. package/app/styles/components/form/masked-input.scss +46 -0
  31. package/app/styles/components/form/text-input.scss +9 -2
  32. package/app/styles/components/form/textarea.scss +2 -2
  33. package/app/styles/components/page-header.scss +17 -1
  34. package/app/styles/components/reveal.scss +2 -0
  35. package/app/styles/components/side-nav/content.scss +2 -2
  36. package/app/styles/components/side-nav/main.scss +13 -0
  37. package/app/styles/mixins/_button.scss +6 -0
  38. package/package.json +7 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # @hashicorp/design-system-components
2
2
 
3
+ ## 2.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1516](https://github.com/hashicorp/design-system/pull/1516) [`f2192cad7`](https://github.com/hashicorp/design-system/commit/f2192cad73b6d966bf813f54dcee02e157c76392) Thanks [@didoo](https://github.com/didoo)! - `SideNav` - Fixed issue with links still being interactive (even if visually hidden) when the navigation is "minimized"
8
+
9
+ - [#1518](https://github.com/hashicorp/design-system/pull/1518) [`5fd48e31e`](https://github.com/hashicorp/design-system/commit/5fd48e31ed3241ee19a8226bb28fa04ad79479c5) Thanks [@didoo](https://github.com/didoo)! - `PageHeader` - Fixed overflow of non-breaking text for `title`, `subtitle` and `description` elements
10
+
11
+ - [#1494](https://github.com/hashicorp/design-system/pull/1494) [`169a85b63`](https://github.com/hashicorp/design-system/commit/169a85b6348649bc0e2411f3ab6f6a086eecb692) Thanks [@natmegs](https://github.com/natmegs)! - `Form::TextInput` - Add support for datetime-local type
12
+
13
+ - [#1500](https://github.com/hashicorp/design-system/pull/1500) [`b6c2867a4`](https://github.com/hashicorp/design-system/commit/b6c2867a4b7d1c183e9a17d16208ed12ce1aa43f) Thanks [@didoo](https://github.com/didoo)! - - `SideNav` - updated layout styling for the `SideNav::List::Title` element
14
+
15
+ - [#1520](https://github.com/hashicorp/design-system/pull/1520) [`7f7ec22c3`](https://github.com/hashicorp/design-system/commit/7f7ec22c387ac9df05d05de31e5c2b45d6324777) Thanks [@alex-ju](https://github.com/alex-ju)! - Upgrade `ember-style-modifier` to `3.0.1`
16
+
17
+ - Updated dependencies [[`fd5953633`](https://github.com/hashicorp/design-system/commit/fd595363396c2e6672025ab8f9c3df7d2a3fce53)]:
18
+ - @hashicorp/design-system-tokens@1.7.0
19
+ - @hashicorp/ember-flight-icons@3.0.8
20
+
21
+ ## 2.8.0
22
+
23
+ ### Minor Changes
24
+
25
+ - [#1492](https://github.com/hashicorp/design-system/pull/1492) [`a17e5b2ac`](https://github.com/hashicorp/design-system/commit/a17e5b2acf66493ccbb68a623a3b7ba2fd5ab5a8) Thanks [@KristinLBradley](https://github.com/KristinLBradley)! - `Card` - Updated default value of `@overflow` argument to `"visible"` to address an area of consumer confusion and better support the most common use cases.
26
+
27
+ Technically, this is a breaking change as it will require consumers relying upon the previous `hidden` default value to now manually set the value. The result of not setting the a `"hidden"` value can cause square edges of some images to "stick out" and overlap the rounded corners of the Card itself. We considered this to be a fairly minor, low-impact issue however which would not affect functionality or usability.
28
+
29
+ - [#1452](https://github.com/hashicorp/design-system/pull/1452) [`c277d0366`](https://github.com/hashicorp/design-system/commit/c277d036673cf572c00ebf5b8b35b424c0b057fd) Thanks [@alex-ju](https://github.com/alex-ju)! - `Form::TextInput` - Add loading state on "search" type
30
+
31
+ - [#1468](https://github.com/hashicorp/design-system/pull/1468) [`b0a766ccf`](https://github.com/hashicorp/design-system/commit/b0a766ccf5357dd6f0e8dfb68d8c1ee823e76b50) Thanks [@alex-ju](https://github.com/alex-ju)! - Added `MaskedInput` component for forms
32
+
33
+ - [#1423](https://github.com/hashicorp/design-system/pull/1423) [`5ac340c8c`](https://github.com/hashicorp/design-system/commit/5ac340c8c3a3adab388704067578cf419e2e2f10) Thanks [@KristinLBradley](https://github.com/KristinLBradley)! - Add new `Accordion` component
34
+
35
+ ### Patch Changes
36
+
37
+ - [#1466](https://github.com/hashicorp/design-system/pull/1466) [`cdda7ae8e`](https://github.com/hashicorp/design-system/commit/cdda7ae8eaf553bd32ec9e3944edf08fe352caf4) Thanks [@alex-ju](https://github.com/alex-ju)! - `Hds::PageHeader` – Set position to 'relative'
38
+
39
+ - [#1470](https://github.com/hashicorp/design-system/pull/1470) [`0ea2ccfd0`](https://github.com/hashicorp/design-system/commit/0ea2ccfd0303149014de768c715ebb53dffe6c4c) Thanks [@alex-ju](https://github.com/alex-ju)! - `Hds::Textarea` – Fix border and text color for readonly state
40
+
41
+ - [#1456](https://github.com/hashicorp/design-system/pull/1456) [`b4237e73b`](https://github.com/hashicorp/design-system/commit/b4237e73b3701d94e92556ad0108b8a38bef312d) Thanks [@alex-ju](https://github.com/alex-ju)! - `Hds::Modal` – Prevent `onClose` callback function invocation when `isDismissDisabled` is `true`
42
+
43
+ - [#1469](https://github.com/hashicorp/design-system/pull/1469) [`ef98ed4ed`](https://github.com/hashicorp/design-system/commit/ef98ed4ed188520fd69a0090ab93d7d0c44e634c) Thanks [@didoo](https://github.com/didoo)! - Set the `font-weight` of the `button` mixin explicitly to `regular` instead of relying on inheritance (components using this mixin: `Button`, `Dropdown::ToggleButton` and soon `Accordion`) - No visual difference expected
44
+
45
+ - Updated dependencies [[`b2ec25b39`](https://github.com/hashicorp/design-system/commit/b2ec25b399ba9aad5f8ae0b1f18a1bef9a6543e0)]:
46
+ - @hashicorp/design-system-tokens@1.6.0
47
+ - @hashicorp/ember-flight-icons@3.0.7
48
+
3
49
  ## 2.7.1
4
50
 
5
51
  ### Patch Changes
@@ -16,7 +62,7 @@
16
62
  Upgraded the following dependencies:
17
63
 
18
64
  - `ember-focus-trap` from `1.0.1` to `1.0.2`
19
- - `ember-keyboard"` from `8.1.0` to `8.2.0`
65
+ - `ember-keyboard` from `8.1.0` to `8.2.0`
20
66
  - `ember-truth-helpers` from `3.0.0` to `3.1.1`
21
67
  - `sass` from `1.58.3` to `1.62.1`
22
68
 
@@ -77,3 +77,24 @@ You can override every dependency declared in the engines' `package.json` files
77
77
  Once done run `yarn install` to use the "remote" version of the package, update the `node_modules` and the `yarn.lock` file.
78
78
 
79
79
  **IMPORTANT**: the way in which yarn works in this case is that it resolves in a hash referencing a commit in `yarn.lock`; so if you make changes to the branch, they’re not reflected in the local `node_modules` unless you change the hash manually in the `yarn.lock` to point to another commit, and re-run the `yarn install` command.
80
+
81
+ #### What to do if `yarn start ***` in Cloud UI complains about the different version number
82
+
83
+ There are cases in which the "start" command in Cloud UI will fail with an error similar to this:
84
+ ```
85
+ Missing yarn packages:
86
+ Package: @hashicorp/design-system-components
87
+ * Specified: ^2.7.1
88
+ * Installed: 2.6.0
89
+
90
+ Run `yarn` to install missing dependencies.
91
+ ```
92
+
93
+ Running `yarn install` again will not solve the problem because the issue is with the version of the `@hashicorp/design-system-components` package declared in the `package.json` files in Cloud UI that differs from the one in the overriding package.
94
+
95
+ In this case you have two options:
96
+
97
+ - you can rebase your branch on `main` so that your branch uses the latest version of `@hashicorp/design-system-components` (which is likely the one used in Cloud UI too)
98
+ - if the one in Cloud UI is not the latest, you have to "trick" Cloud UI and replace the existing version with the one used in your branch (use a find & replace in all the `package.json` files)
99
+
100
+ With both options, you will have to re-run the `yarn install` command.
@@ -108,6 +108,7 @@ The engineering checklist has six parts: creating the feature branch, component
108
108
  - [ ] try not to repeat tests (i.e., don't have to test all sizes, all colors, etc.)
109
109
  - [ ] test all accessibility attributes
110
110
  - [ ] test assertions
111
+ - [ ] run the accessibility automation tests (`yarn test:a11y --filter="COMPONENT-NAME"`)
111
112
  - [ ] **documentation**
112
113
  - create component page `ember generate route components/COMPONENT_NAME --dummy`
113
114
  - add link to `templates/index.hbs` page
@@ -0,0 +1,8 @@
1
+ {{!
2
+ Copyright (c) HashiCorp, Inc.
3
+ SPDX-License-Identifier: MPL-2.0
4
+ }}
5
+
6
+ <div class="hds-accordion" ...attributes>
7
+ {{yield (hash Item=(component "hds/accordion/item"))}}
8
+ </div>
@@ -0,0 +1,16 @@
1
+ {{!
2
+ Copyright (c) HashiCorp, Inc.
3
+ SPDX-License-Identifier: MPL-2.0
4
+ ~}}
5
+
6
+ <button
7
+ class={{this.classNames}}
8
+ type="button"
9
+ {{on "click" @onClickToggle}}
10
+ aria-controls={{@contentId}}
11
+ aria-expanded={{if @isOpen "true" "false"}}
12
+ aria-label={{@ariaLabel}}
13
+ ...attributes
14
+ >
15
+ <FlightIcon @name="chevron-down" @size="24" @isInlineBlock={{false}} />
16
+ </button>
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import Component from '@glimmer/component';
7
+
8
+ export default class HdsAccordionItemButtonComponent extends Component {
9
+ /**
10
+ * Get the class names to apply to the component.
11
+ * @method ItemButton#classNames
12
+ * @return {string} The "class" attribute to apply to the component.
13
+ */
14
+ get classNames() {
15
+ let classes = ['hds-accordion-item__button'];
16
+
17
+ // add a class based on the @isOpen argument
18
+ if (this.args.isOpen) {
19
+ classes.push('hds-accordion-item__button--is-open');
20
+ }
21
+
22
+ if (this.args.parentContainsInteractive === false) {
23
+ classes.push(
24
+ 'hds-accordion-item__button--parent-does-not-contain-interactive'
25
+ );
26
+ } else {
27
+ classes.push('hds-accordion-item__button--parent-contains-interactive');
28
+ }
29
+ return classes.join(' ');
30
+ }
31
+ }
@@ -0,0 +1,30 @@
1
+ {{!
2
+ Copyright (c) HashiCorp, Inc.
3
+ SPDX-License-Identifier: MPL-2.0
4
+ ~}}
5
+
6
+ <Hds::DisclosurePrimitive class={{this.classNames}} @isOpen={{@isOpen}} ...attributes>
7
+ <:toggle as |t|>
8
+ <div class="hds-accordion-item__toggle">
9
+ <Hds::Accordion::Item::Button
10
+ @isOpen={{t.isOpen}}
11
+ @onClickToggle={{t.onClickToggle}}
12
+ @contentId={{this.contentId}}
13
+ @ariaLabel={{this.ariaLabel}}
14
+ @parentContainsInteractive={{this.containsInteractive}}
15
+ />
16
+
17
+ <div
18
+ class="hds-accordion-item__toggle-content hds-typography-display-200 hds-foreground-strong hds-font-weight-semibold"
19
+ >
20
+ {{yield to="toggle"}}
21
+ </div>
22
+ </div>
23
+ </:toggle>
24
+
25
+ <:content>
26
+ <div class="hds-accordion-item__content hds-typography-body-200 hds-foreground-primary" id={{this.contentId}}>
27
+ {{yield to="content"}}
28
+ </div>
29
+ </:content>
30
+ </Hds::DisclosurePrimitive>
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import Component from '@glimmer/component';
7
+ import { guidFor } from '@ember/object/internals';
8
+
9
+ export default class HdsAccordionItemIndexComponent extends Component {
10
+ /**
11
+ * Generates a unique ID for the Content
12
+ *
13
+ * @param contentId
14
+ */
15
+ contentId = 'content-' + guidFor(this);
16
+
17
+ /**
18
+ * @param ariaLabel
19
+ * @type {string}
20
+ * @default 'Toggle display'
21
+ */
22
+ get ariaLabel() {
23
+ return this.args.ariaLabel ?? 'Toggle display';
24
+ }
25
+
26
+ /**
27
+ * @param containsInteractive
28
+ * @type {boolean}
29
+ * @default false
30
+ */
31
+ get containsInteractive() {
32
+ return this.args.containsInteractive ?? false;
33
+ }
34
+
35
+ /**
36
+ * Get the class names to apply to the component.
37
+ * @method classNames
38
+ * @return {string} The "class" attribute to apply to the component.
39
+ */
40
+ get classNames() {
41
+ let classes = ['hds-accordion-item'];
42
+
43
+ // add a class based on the @isOpen argument
44
+ if (this.args.isOpen) {
45
+ classes.push('hds-accordion-item--is-open');
46
+ }
47
+
48
+ if (this.containsInteractive) {
49
+ // Entire accordion item including the chevron is interactive:
50
+ classes.push('hds-accordion-item--contains-interactive');
51
+ } else {
52
+ // Only chevron is interactive:
53
+ classes.push('hds-accordion-item--does-not-contain-interactive');
54
+ }
55
+
56
+ return classes.join(' ');
57
+ }
58
+ }
@@ -2,4 +2,4 @@
2
2
  Copyright (c) HashiCorp, Inc.
3
3
  SPDX-License-Identifier: MPL-2.0
4
4
  }}
5
- <div class="hds-alert__description" ...attributes>{{yield}}</div>
5
+ <div class="hds-alert__description hds-font-weight-regular hds-foreground-primary" ...attributes>{{yield}}</div>
@@ -17,7 +17,7 @@
17
17
  {{/if}}
18
18
 
19
19
  <div class="hds-alert__content">
20
- <div class="hds-alert__text">
20
+ <div class="hds-alert__text {{if (eq @type 'compact') 'hds-typography-body-100' 'hds-typography-body-200'}}">
21
21
  {{yield (hash Title=(component "hds/alert/title"))}}
22
22
  {{yield (hash Description=(component "hds/alert/description"))}}
23
23
  </div>
@@ -2,4 +2,4 @@
2
2
  Copyright (c) HashiCorp, Inc.
3
3
  SPDX-License-Identifier: MPL-2.0
4
4
  }}
5
- <div class="hds-alert__title" ...attributes>{{yield}}</div>
5
+ <div class="hds-alert__title hds-font-weight-semibold" ...attributes>{{yield}}</div>
@@ -8,7 +8,7 @@ import { assert } from '@ember/debug';
8
8
 
9
9
  export const DEFAULT_LEVEL = 'base';
10
10
  export const DEFAULT_BACKGROUND = 'neutral-primary';
11
- export const DEFAULT_OVERFLOW = 'hidden';
11
+ export const DEFAULT_OVERFLOW = 'visible';
12
12
  export const LEVELS = ['base', 'mid', 'high'];
13
13
  export const BACKGROUNDS = ['neutral-primary', 'neutral-secondary'];
14
14
  export const OVERFLOWS = ['hidden', 'visible'];
@@ -106,7 +106,7 @@ export default class HdsCardContainerComponent extends Component {
106
106
  *
107
107
  * @param overflow
108
108
  * @type {string}
109
- * @default 'hidden'
109
+ * @default 'visible'
110
110
  */
111
111
  get overflow() {
112
112
  let { overflow = DEFAULT_OVERFLOW } = this.args;
@@ -0,0 +1,34 @@
1
+ {{!
2
+ Copyright (c) HashiCorp, Inc.
3
+ SPDX-License-Identifier: MPL-2.0
4
+ }}
5
+ <div class={{this.classNames}} {{style width=@width}}>
6
+ {{#if @isMultiline}}
7
+ <Hds::Form::Textarea::Base
8
+ class="hds-form-masked-input__control"
9
+ @value={{@value}}
10
+ @isInvalid={{@isInvalid}}
11
+ @height={{@height}}
12
+ id={{this.id}}
13
+ ...attributes
14
+ />
15
+ {{else}}
16
+ <Hds::Form::TextInput::Base
17
+ class="hds-form-masked-input__control"
18
+ @value={{@value}}
19
+ @isInvalid={{@isInvalid}}
20
+ id={{this.id}}
21
+ ...attributes
22
+ />
23
+ {{/if}}
24
+ <button
25
+ class="hds-form-masked-input__toggle-button"
26
+ type="button"
27
+ aria-label={{this.ariaLabel}}
28
+ aria-controls={{this.id}}
29
+ {{on "click" this.onClickToggle}}
30
+ >
31
+ <FlightIcon @name={{if this.isMasked "eye" "eye-off"}} @size="16" @isInlineBlock={{false}} />
32
+ <span class="sr-only" aria-live="polite">{{this.ariaMessageText}}</span>
33
+ </button>
34
+ </div>
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import Component from '@glimmer/component';
7
+ import { tracked } from '@glimmer/tracking';
8
+ import { action } from '@ember/object';
9
+ import { getElementId } from '@hashicorp/design-system-components/utils/hds-get-element-id';
10
+
11
+ export default class HdsFormMaskedInputBaseComponent extends Component {
12
+ @tracked isMasked = this.args.isMasked ?? true;
13
+
14
+ @action
15
+ onClickToggle() {
16
+ this.isMasked = !this.isMasked;
17
+ }
18
+
19
+ /**
20
+ * Calculates the unique ID to assign to the form control
21
+ */
22
+ get id() {
23
+ return getElementId(this);
24
+ }
25
+
26
+ /**
27
+ * @param ariaLabel
28
+ * @type {string}
29
+ * @default 'Show masked content'
30
+ */
31
+ get ariaLabel() {
32
+ if (this.args.ariaLabel) {
33
+ return this.args.ariaLabel;
34
+ } else if (this.isMasked) {
35
+ return 'Show masked content';
36
+ } else {
37
+ return 'Hide masked content';
38
+ }
39
+ }
40
+
41
+ /**
42
+ * @param ariaMessageText
43
+ * @type {string}
44
+ * @default ''
45
+ */
46
+ get ariaMessageText() {
47
+ if (this.args.ariaMessageText) {
48
+ return this.args.ariaMessageText;
49
+ } else if (this.isMasked) {
50
+ return 'Input content is now hidden';
51
+ } else {
52
+ return 'Input content is now visible';
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Get the class names to apply to the component.
58
+ * @method classNames
59
+ * @return {string} The "class" attribute to apply to the component.
60
+ */
61
+ get classNames() {
62
+ let classes = ['hds-form-masked-input'];
63
+
64
+ if (this.isMasked) {
65
+ classes.push(`hds-form-masked-input--is-masked`);
66
+ } else {
67
+ classes.push(`hds-form-masked-input--is-not-masked`);
68
+ }
69
+
70
+ return classes.join(' ');
71
+ }
72
+ }
@@ -0,0 +1,30 @@
1
+ {{!
2
+ Copyright (c) HashiCorp, Inc.
3
+ SPDX-License-Identifier: MPL-2.0
4
+ }}
5
+ <Hds::Form::Field
6
+ @layout="vertical"
7
+ @extraAriaDescribedBy={{@extraAriaDescribedBy}}
8
+ @isRequired={{@isRequired}}
9
+ @isOptional={{@isOptional}}
10
+ @id={{@id}}
11
+ as |F|
12
+ >
13
+ {{! Notice: the order of the elements is not relevant here, because is controlled at "Hds::Form::Field" component level }}
14
+ {{yield (hash Label=F.Label isRequired=F.isRequired isOptional=F.isOptional)}}
15
+ {{yield (hash HelperText=F.HelperText Error=F.Error)}}
16
+ <F.Control>
17
+ <Hds::Form::MaskedInput::Base
18
+ @isMultiline={{@isMultiline}}
19
+ @isMasked={{@isMasked}}
20
+ @value={{@value}}
21
+ @isInvalid={{@isInvalid}}
22
+ @width={{@width}}
23
+ @height={{@height}}
24
+ @id={{F.id}}
25
+ required={{@isRequired}}
26
+ ...attributes
27
+ aria-describedby={{F.ariaDescribedBy}}
28
+ />
29
+ </F.Control>
30
+ </Hds::Form::Field>
@@ -14,9 +14,10 @@ export const TYPES = [
14
14
  'email',
15
15
  'password',
16
16
  'url',
17
- 'search',
18
17
  'date',
19
18
  'time',
19
+ 'datetime-local',
20
+ 'search',
20
21
  ];
21
22
 
22
23
  export default class HdsFormTextInputBaseComponent extends Component {
@@ -56,6 +57,11 @@ export default class HdsFormTextInputBaseComponent extends Component {
56
57
  classes.push(`hds-form-text-input--is-invalid`);
57
58
  }
58
59
 
60
+ // add a class based on the @isLoading argument
61
+ if (this.args.isLoading) {
62
+ classes.push(`hds-form-text-input--is-loading`);
63
+ }
64
+
59
65
  return classes.join(' ');
60
66
  }
61
67
  }
@@ -19,6 +19,7 @@
19
19
  @value={{@value}}
20
20
  @isInvalid={{@isInvalid}}
21
21
  @width={{@width}}
22
+ @isLoading={{@isLoading}}
22
23
  required={{@isRequired}}
23
24
  ...attributes
24
25
  id={{F.id}}
@@ -112,7 +112,11 @@ export default class HdsModalIndexComponent extends Component {
112
112
 
113
113
  // Register "onClose" callback function to be called when a native 'close' event is dispatched
114
114
  this.element.addEventListener('close', () => {
115
- if (this.args.onClose && typeof this.args.onClose === 'function') {
115
+ if (
116
+ !this.isDismissDisabled &&
117
+ this.args.onClose &&
118
+ typeof this.args.onClose === 'function'
119
+ ) {
116
120
  this.args.onClose();
117
121
  }
118
122
 
@@ -8,7 +8,7 @@
8
8
  {{yield (hash IconTile=(component "hds/icon-tile" size="medium"))}}
9
9
  <div class="hds-page-header__main">
10
10
  <div class="hds-page-header__content">
11
- <div class="hds-page-header__title-main">
11
+ <div class="hds-page-header__title-wrapper">
12
12
  {{yield (hash Title=(component "hds/page-header/title"))}}
13
13
  {{yield (hash Badges=(component "hds/page-header/badges"))}}
14
14
  </div>
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ export { default } from '@hashicorp/design-system-components/components/hds/accordion/index';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ export { default } from '@hashicorp/design-system-components/components/hds/accordion/item/button';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ export { default } from '@hashicorp/design-system-components/components/hds/accordion/item/index';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ export { default } from '@hashicorp/design-system-components/components/hds/form/masked-input/base';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ export { default } from '@hashicorp/design-system-components/components/hds/form/masked-input/field';
@@ -12,6 +12,7 @@
12
12
 
13
13
  // Notice: this list can be automatically edited by the Ember blueprint, please don't remove the start/end comments
14
14
  // START COMPONENTS CSS FILES IMPORTS
15
+ @use "../components/accordion";
15
16
  @use "../components/alert";
16
17
  @use "../components/app-frame";
17
18
  @use "../components/application-state";
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ //
7
+ // ACCORDION
8
+ //
9
+
10
+ @use "../mixins/button" as *;
11
+ @use "../mixins/focus-ring" as *;
12
+
13
+ $accordion-item-padding: 16px;
14
+ $accordion-item-border-radius: 6px;
15
+
16
+ // ACCORDION COMPONENT (wrapper)
17
+
18
+ .hds-accordion {
19
+ display: flex;
20
+ flex-direction: column;
21
+ gap: 12px;
22
+ }
23
+
24
+ // ACCORDION ITEM COMPONENT (nested child)
25
+
26
+ .hds-accordion-item {
27
+ background: var(--token-color-surface-primary);
28
+ border-radius: $accordion-item-border-radius;
29
+
30
+ &.hds-accordion-item--does-not-contain-interactive {
31
+ box-shadow: var(--token-surface-mid-box-shadow);
32
+
33
+ &:hover,
34
+ &.mock-hover {
35
+ box-shadow: var(--token-surface-high-box-shadow);
36
+ }
37
+ }
38
+
39
+ &.hds-accordion-item--contains-interactive {
40
+ box-shadow: var(--token-surface-base-box-shadow);
41
+ }
42
+ }
43
+
44
+ // TOGGLE BLOCK
45
+
46
+ .hds-accordion-item__toggle {
47
+ position: relative;
48
+ display: flex;
49
+ gap: 12px;
50
+ align-items: center;
51
+ padding:
52
+ $accordion-item-padding
53
+ $accordion-item-padding
54
+ $accordion-item-padding
55
+ 12px; // by design
56
+ }
57
+
58
+ .hds-accordion-item__button {
59
+ padding: 0;
60
+
61
+ &:hover { cursor: pointer; }
62
+
63
+ // entire toggle area is interactive
64
+ &.hds-accordion-item__button--parent-does-not-contain-interactive {
65
+ @include hds-focus-ring-with-pseudo-element();
66
+ position: static;
67
+ margin: -1px 0;
68
+ color: var(--token-color-foreground-primary);
69
+ background: transparent;
70
+ border: 1px solid transparent;
71
+
72
+ // expand button target to cover entire AccordionItem Toggle block (depending on the `@containsInteractive/@parentContainsInteractive` argument)
73
+ &::after {
74
+ position: absolute;
75
+ display: block;
76
+ border-radius: $accordion-item-border-radius;
77
+ content: "";
78
+ inset: 0;
79
+ }
80
+ }
81
+
82
+ // only chevron button area is interactive
83
+ &.hds-accordion-item__button--parent-contains-interactive {
84
+ @include hds-button();
85
+ width: 24px;
86
+ height: 24px;
87
+
88
+ &:focus,
89
+ &.mock-focus {
90
+ @include hds-button-state-focus();
91
+ }
92
+
93
+ // `hds-button-color-secondary` determines the focus color and needs to be placed after `hds-button-state-focus`
94
+ @include hds-button-color-secondary();
95
+ }
96
+
97
+ // animate chevron icon
98
+ &.hds-accordion-item__button--is-open {
99
+ .flight-icon-chevron-down {
100
+ transform: rotate(-180deg);
101
+ }
102
+ }
103
+
104
+ .flight-icon-chevron-down {
105
+ @media (prefers-reduced-motion: no-preference) {
106
+ transition: transform 0.3s;
107
+ }
108
+ }
109
+ }
110
+
111
+ // Consumer added content that appears next to the chevron button:
112
+ .hds-accordion-item__toggle-content {
113
+ flex: 1;
114
+ }
115
+
116
+ // CONTENT BLOCK
117
+
118
+ .hds-accordion-item__content {
119
+ padding: 4px $accordion-item-padding $accordion-item-padding $accordion-item-padding;
120
+ }
@@ -40,24 +40,9 @@
40
40
  gap: 4px;
41
41
  justify-content: center;
42
42
  color: var(--token-color-foreground-warning-on-surface);
43
- font-size: var(--token-typography-body-200-font-size);
44
- font-family: var(--token-typography-body-200-font-family);
45
- line-height: var(--token-typography-body-200-line-height);
46
-
47
- .hds-alert--type-compact & {
48
- font-size: var(--token-typography-body-100-font-size);
49
- font-family: var(--token-typography-body-100-font-family);
50
- line-height: var(--token-typography-body-100-line-height);
51
- }
52
- }
53
-
54
- .hds-alert__title {
55
- font-weight: var(--token-typography-font-weight-semibold);
56
43
  }
57
44
 
58
45
  .hds-alert__description {
59
- color: var(--token-color-foreground-primary);
60
- font-weight: var(--token-typography-font-weight-regular);
61
46
  word-break: break-word;
62
47
 
63
48
  // we add very basic styling for elements that may be injected via the "description" string
@@ -9,5 +9,4 @@
9
9
 
10
10
  .hds-disclosure-primitive {
11
11
  position: relative;
12
- width: fit-content;
13
12
  }
@@ -15,6 +15,7 @@
15
15
  @use "./group";
16
16
  @use "./indicator";
17
17
  @use "./checkbox";
18
+ @use "./masked-input";
18
19
  @use "./radio";
19
20
  @use "./radio-card";
20
21
  @use "./select";
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ //
7
+ // MASKED-INPUT
8
+ //
9
+
10
+ $hds-form-masked-input-button-size: 24px;
11
+
12
+ .hds-form-masked-input {
13
+ position: relative;
14
+ width: 100%;
15
+
16
+ .hds-form-masked-input__control {
17
+ padding-right: calc(var(--token-form-control-padding) + $hds-form-masked-input-button-size);
18
+ }
19
+ }
20
+
21
+ .hds-form-masked-input--is-masked {
22
+ .hds-form-masked-input__control {
23
+ -webkit-text-security: disc;
24
+ }
25
+ }
26
+
27
+ .hds-form-masked-input--is-not-masked {
28
+ .hds-form-masked-input__control {
29
+ -webkit-text-security: none;
30
+ }
31
+ }
32
+
33
+ // notice: by design, for this button we don't apply a custom style for the focused state
34
+ // but we rely on the standard outlined styling provided by the browser
35
+ .hds-form-masked-input__toggle-button {
36
+ position: absolute;
37
+ top: calc(var(--token-form-control-padding) - var(--token-form-control-border-width));
38
+ right: calc(var(--token-form-control-padding) - var(--token-form-control-border-width));
39
+ width: $hds-form-masked-input-button-size;
40
+ height: $hds-form-masked-input-button-size;
41
+ padding: 2px;
42
+ color: var(--token-color-foreground-primary);
43
+ background-color: transparent;
44
+ border-color: transparent;
45
+ cursor: pointer;
46
+ }
@@ -88,7 +88,8 @@
88
88
  // DATE/TIME
89
89
 
90
90
  &[type="date"],
91
- &[type="time"] {
91
+ &[type="time"],
92
+ &[type="datetime-local"] {
92
93
 
93
94
  // browsers set a specific width for these controls, we want to keep it
94
95
  width: initial;
@@ -108,7 +109,8 @@
108
109
 
109
110
  // we override the default icon with the Flight corresponding one
110
111
  // notice: the original in Chrome has two assets, one for light and one for dark mode, and uses a special syntax, but apparently it doesn't work if used in a stylesheet
111
- &[type="date"] {
112
+ &[type="date"],
113
+ &[type="datetime-local"] {
112
114
  &::-webkit-calendar-picker-indicator {
113
115
  background-image: var(--token-form-text-input-background-image-data-url-date);
114
116
  background-position: center center;
@@ -141,5 +143,10 @@
141
143
  // stylelint-disable-next-line property-no-vendor-prefix
142
144
  -webkit-appearance: none;
143
145
  }
146
+
147
+ // IS LOADING
148
+ &.hds-form-text-input--is-loading {
149
+ background-image: var(--token-form-text-input-background-image-data-url-search-loading);
150
+ }
144
151
  }
145
152
  }
@@ -48,9 +48,9 @@
48
48
  // READONLY
49
49
 
50
50
  &:read-only {
51
- color: var(--token-form-control-disabled-foreground-color);
51
+ color: var(--token-form-control-readonly-foreground-color);
52
52
  background-color: var(--token-form-control-readonly-surface-color);
53
- border-color: var(--token-form-control-disabled-border-color);
53
+ border-color: var(--token-form-control-readonly-border-color);
54
54
  box-shadow: none;
55
55
  }
56
56
 
@@ -8,6 +8,9 @@
8
8
  //
9
9
 
10
10
  .hds-page-header {
11
+ // `container-type: inline-size` creates a new stacking context; to control the position of Page Header content on the z-axis
12
+ // we set this element to `relative` to allow consumers to define the `z-index` value that works in their context
13
+ position: relative;
11
14
  display: flex;
12
15
  flex-direction: column;
13
16
  gap: 16px;
@@ -39,6 +42,7 @@
39
42
  @container (min-width: 768px) {
40
43
  flex-direction: row;
41
44
  justify-content: space-between;
45
+ min-width: 0; // this is important or it will blow beyond the parent flexbox width with long non-breaking names
42
46
  }
43
47
  }
44
48
 
@@ -47,9 +51,11 @@
47
51
  flex-direction: column;
48
52
  flex-grow: 1;
49
53
  gap: 8px;
54
+ min-width: 0; // this is important or it will blow beyond the parent flexbox width with long non-breaking names
55
+ max-width: 100%;
50
56
  }
51
57
 
52
- .hds-page-header__title-main {
58
+ .hds-page-header__title-wrapper {
53
59
  display: flex;
54
60
  flex-direction: row;
55
61
  flex-wrap: wrap;
@@ -57,6 +63,11 @@
57
63
  align-items: center;
58
64
  }
59
65
 
66
+ .hds-page-header__title {
67
+ max-width: 100%;
68
+ overflow-wrap: break-word;
69
+ }
70
+
60
71
  .hds-page-header__badges-wrapper {
61
72
  display: flex;
62
73
  flex-wrap: wrap;
@@ -69,6 +80,11 @@
69
80
  gap: 4px;
70
81
  }
71
82
 
83
+ .hds-page-header__subtitle,
84
+ .hds-page-header__description {
85
+ overflow-wrap: break-word;
86
+ }
87
+
72
88
  .hds-page-header__actions {
73
89
  display: flex;
74
90
  flex-direction: row;
@@ -7,6 +7,8 @@
7
7
  // REVEAL COMPONENT
8
8
  //
9
9
 
10
+ .hds-reveal { width: fit-content; }
11
+
10
12
  .hds-reveal__toggle-button {
11
13
  // overriding some styles of the tertiary button, per design specs
12
14
  min-height: 1.75rem; // 28px, Override default so padding difference will be visible
@@ -34,9 +34,9 @@
34
34
  .hds-side-nav__list-title {
35
35
  display: flex;
36
36
  align-items: center;
37
- min-height: 34px;
37
+ min-height: var(--token-side-nav-body-list-item-height);
38
38
  margin-top: var(--token-side-nav-body-list-margin-vertical);
39
- padding: 0 var(--token-side-nav-body-list-item-padding-horizontal);
39
+ padding: 9px var(--token-side-nav-body-list-item-padding-horizontal); // 8px = (min-height - body-100-line-height) / 2
40
40
  color: var(--token-side-nav-color-foreground-faint);
41
41
 
42
42
  // Remove margin from title at top of all list-items & lists
@@ -191,6 +191,19 @@
191
191
  visibility: hidden !important; // we need `!important` here to override the inline style applied to the single panels
192
192
  opacity: 0;
193
193
  transition: none;
194
+ // this is needed because, despite the element having `visibility: hidden`,
195
+ // the child elements ("panels") have their visibility dynamically managed via JS
196
+ // and when they have "visibility: visible" applied, they are not visually visible
197
+ // (because of the `opacity: 0` of the parent) but the user can still interact with them
198
+ // and click on the links inside the sidenav even if they're not visible at all,
199
+ // so we have to block the interactivity of the whole container
200
+ // for reference see these PRs:
201
+ // - https://github.com/hashicorp/design-system/pull/1338
202
+ // - https://github.com/hashicorp/design-system/pull/1388
203
+ // - https://github.com/hashicorp/design-system/pull/1516
204
+ // and this codepen with a redux of the problem:
205
+ // - https://codepen.io/didoo/pen/mdQKMJW?editors=1100
206
+ pointer-events: none;
194
207
  }
195
208
 
196
209
  .hds-side-nav--is-mobile.hds-side-nav--is-not-minimized &,
@@ -40,6 +40,12 @@ $size-props: (
40
40
  align-items: center;
41
41
  justify-content: center;
42
42
  width: auto;
43
+ // notice: we set the font-weight of the button text to "regular" (on purpose)
44
+ // because of the antialising of the browser that renders the text quite different
45
+ // from what it looks like in Figma, so we prefer to have them visually similar
46
+ // even if they differ in their internal implementation (in Figma the font-weight is medium/500)
47
+ // for more context about this decision: https://hashicorp.atlassian.net/browse/HDS-2099
48
+ font-weight: var(--token-typography-font-weight-regular);
43
49
  font-family: var(--token-typography-font-stack-text);
44
50
  text-decoration: none;
45
51
  border: $hds-button-border-width solid transparent; // We need this to be transparent for a11y
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashicorp/design-system-components",
3
- "version": "2.7.1",
3
+ "version": "2.8.1",
4
4
  "description": "Helios Design System Components",
5
5
  "keywords": [
6
6
  "hashicorp",
@@ -35,12 +35,13 @@
35
35
  "test:ember": "ember test",
36
36
  "test:ember-compatibility": "ember try:each",
37
37
  "test:ember:percy": "percy exec ember test",
38
- "test:a11y": "ENABLE_A11Y_AUDIT=true ember test"
38
+ "test:a11y": "ENABLE_A11Y_AUDIT=true ember test --server",
39
+ "test:a11y-report": "ENABLE_A11Y_MIDDLEWARE_REPORTER=true ember test"
39
40
  },
40
41
  "dependencies": {
41
42
  "@ember/render-modifiers": "^2.0.5",
42
- "@hashicorp/design-system-tokens": "^1.5.0",
43
- "@hashicorp/ember-flight-icons": "^3.0.6",
43
+ "@hashicorp/design-system-tokens": "^1.7.0",
44
+ "@hashicorp/ember-flight-icons": "^3.0.8",
44
45
  "dialog-polyfill": "^0.5.6",
45
46
  "ember-a11y-refocus": "^3.0.2",
46
47
  "ember-auto-import": "^2.6.3",
@@ -53,7 +54,7 @@
53
54
  "ember-keyboard": "^8.2.0",
54
55
  "ember-named-blocks-polyfill": "^0.2.5",
55
56
  "ember-stargate": "^0.4.3",
56
- "ember-style-modifier": "^0.8.0",
57
+ "ember-style-modifier": "^3.0.1",
57
58
  "ember-truth-helpers": "^3.1.1",
58
59
  "sass": "^1.62.1",
59
60
  "tippy.js": "^6.3.7"
@@ -101,7 +102,7 @@
101
102
  "prettier": "^2.8.8",
102
103
  "qunit": "^2.19.4",
103
104
  "qunit-dom": "^2.0.0",
104
- "stylelint": "^14.16.1",
105
+ "stylelint": "^15.10.1",
105
106
  "stylelint-config-rational-order": "^0.1.2",
106
107
  "stylelint-config-standard-scss": "^5.0.0",
107
108
  "webpack": "^5.84.1"