@hashicorp/design-system-components 2.12.2 → 2.13.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.
- package/CHANGELOG.md +17 -0
- package/addon/components/hds/app-footer/copyright.hbs +9 -0
- package/addon/components/hds/app-footer/copyright.js +18 -0
- package/addon/components/hds/app-footer/index.hbs +20 -0
- package/addon/components/hds/app-footer/index.js +41 -0
- package/addon/components/hds/app-footer/item.hbs +8 -0
- package/addon/components/hds/app-footer/legal-links.hbs +14 -0
- package/addon/components/hds/app-footer/legal-links.js +66 -0
- package/addon/components/hds/app-footer/link.hbs +22 -0
- package/addon/components/hds/app-footer/status-link.hbs +20 -0
- package/addon/components/hds/app-footer/status-link.js +133 -0
- package/addon/components/hds/side-nav/index.hbs +5 -8
- package/addon/components/hds/side-nav/index.js +22 -11
- package/addon/components/hds/side-nav/toggle-button.hbs +7 -0
- package/app/components/hds/app-footer/copyright.js +6 -0
- package/app/components/hds/app-footer/index.js +6 -0
- package/app/components/hds/app-footer/item.js +6 -0
- package/app/components/hds/app-footer/legal-links.js +6 -0
- package/app/components/hds/app-footer/link.js +6 -0
- package/app/components/hds/app-footer/status-link.js +6 -0
- package/app/components/hds/side-nav/toggle-button.js +6 -0
- package/app/styles/@hashicorp/design-system-components.scss +1 -0
- package/app/styles/components/app-footer.scss +154 -0
- package/app/styles/components/link/standalone.scss +3 -1
- package/app/styles/components/side-nav/header.scss +10 -0
- package/app/styles/components/side-nav/index.scss +1 -0
- package/app/styles/components/side-nav/main.scss +21 -72
- package/app/styles/components/side-nav/toggle-button.scss +106 -0
- package/app/styles/components/side-nav/vars.scss +2 -4
- package/app/styles/components/tag.scss +1 -1
- package/blueprints/hds-component-test/files/tests/acceptance/components/hds/__name__.js +21 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @hashicorp/design-system-components
|
|
2
2
|
|
|
3
|
+
## 2.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1623](https://github.com/hashicorp/design-system/pull/1623) [`2111a5439`](https://github.com/hashicorp/design-system/commit/2111a5439abea2951f12517354db662edd7c9cb9) Thanks [@KristinLBradley](https://github.com/KristinLBradley)! - `AppFooter` - Added new component
|
|
8
|
+
|
|
9
|
+
- [#1630](https://github.com/hashicorp/design-system/pull/1630) [`04da95443`](https://github.com/hashicorp/design-system/commit/04da95443290ee2d03d9bef23787a4ef10577247) Thanks [@alex-ju](https://github.com/alex-ju)! - `SideNav` - add `@isCollapsible` (to control if users can collapse the sidenav on 'desktop' viewports) and `@isMinimized` (to control the default state on 'desktop' viewports) arguments
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#1696](https://github.com/hashicorp/design-system/pull/1696) [`f3f3fb103`](https://github.com/hashicorp/design-system/commit/f3f3fb103a5aa1c6489d011b6820560df4c2ed88) Thanks [@MelSumner](https://github.com/MelSumner)! - `Tag` - Updated padding for dismiss button for WCAG conformance
|
|
14
|
+
|
|
15
|
+
- [#1678](https://github.com/hashicorp/design-system/pull/1678) [`a51976ded`](https://github.com/hashicorp/design-system/commit/a51976ded4f7939fe140a1abade0f98832ccc2d0) Thanks [@alex-ju](https://github.com/alex-ju)! - `Link::Standalone` – increase target size
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [[`04da95443`](https://github.com/hashicorp/design-system/commit/04da95443290ee2d03d9bef23787a4ef10577247)]:
|
|
18
|
+
- @hashicorp/design-system-tokens@1.9.0
|
|
19
|
+
|
|
3
20
|
## 2.12.2
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{{!
|
|
2
|
+
Copyright (c) HashiCorp, Inc.
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
}}
|
|
5
|
+
|
|
6
|
+
<div class="hds-app-footer__copyright" ...attributes>
|
|
7
|
+
<FlightIcon @name="hashicorp" />
|
|
8
|
+
<Hds::Text::Body @tag="span" @size="100">© {{this.year}} HashiCorp</Hds::Text::Body>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
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 HdsAppFooterCopyrightComponent extends Component {
|
|
9
|
+
/**
|
|
10
|
+
* @param year
|
|
11
|
+
* @type {string}
|
|
12
|
+
* @description The copyright year
|
|
13
|
+
* @default The current year (calculated via `Date()`)
|
|
14
|
+
*/
|
|
15
|
+
get year() {
|
|
16
|
+
return this.args.year ?? new Date().getFullYear();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{{!
|
|
2
|
+
Copyright (c) HashiCorp, Inc.
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
}}
|
|
5
|
+
|
|
6
|
+
<div class={{this.classNames}} ...attributes>
|
|
7
|
+
{{yield (hash ExtraBefore=(component "hds/yield"))}}
|
|
8
|
+
<ul class="hds-app-footer__list" aria-label={{this.ariaLabel}}>
|
|
9
|
+
{{yield (hash StatusLink=(component "hds/app-footer/status-link"))}}
|
|
10
|
+
{{yield
|
|
11
|
+
(hash
|
|
12
|
+
Link=(component "hds/app-footer/link")
|
|
13
|
+
LegalLinks=(component "hds/app-footer/legal-links")
|
|
14
|
+
Item=(component "hds/app-footer/item")
|
|
15
|
+
)
|
|
16
|
+
}}
|
|
17
|
+
</ul>
|
|
18
|
+
{{yield (hash ExtraAfter=(component "hds/yield"))}}
|
|
19
|
+
<Hds::AppFooter::Copyright @year={{@copyrightYear}} />
|
|
20
|
+
</div>
|
|
@@ -0,0 +1,41 @@
|
|
|
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 HdsAppFooterIndexComponent extends Component {
|
|
9
|
+
/**
|
|
10
|
+
* @param ariaLabel
|
|
11
|
+
* @type {string}
|
|
12
|
+
* @default 'Footer items'
|
|
13
|
+
*/
|
|
14
|
+
get ariaLabel() {
|
|
15
|
+
return this.args.ariaLabel ?? 'Footer items';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param theme
|
|
20
|
+
* @type {string}
|
|
21
|
+
* @description The component theme
|
|
22
|
+
* @default 'light'
|
|
23
|
+
*/
|
|
24
|
+
get theme() {
|
|
25
|
+
return this.args.theme ?? 'light';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the class names to apply to the component.
|
|
30
|
+
* @method classNames
|
|
31
|
+
* @return {string} The "class" attribute to apply to the component.
|
|
32
|
+
*/
|
|
33
|
+
get classNames() {
|
|
34
|
+
let classes = ['hds-app-footer'];
|
|
35
|
+
|
|
36
|
+
// add a class based on the @theme argument
|
|
37
|
+
classes.push(`hds-app-footer--theme-${this.theme}`);
|
|
38
|
+
|
|
39
|
+
return classes.join(' ');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{{!
|
|
2
|
+
Copyright (c) HashiCorp, Inc.
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
}}
|
|
5
|
+
|
|
6
|
+
<Hds::AppFooter::Item>
|
|
7
|
+
<ul class="hds-app-footer__legal-links" aria-label={{this.ariaLabel}} ...attributes>
|
|
8
|
+
<Hds::AppFooter::Link @href={{this.hrefForSupport}}>Support</Hds::AppFooter::Link>
|
|
9
|
+
<Hds::AppFooter::Link @href={{this.hrefForTerms}}>Terms</Hds::AppFooter::Link>
|
|
10
|
+
<Hds::AppFooter::Link @href={{this.hrefForPrivacy}}>Privacy</Hds::AppFooter::Link>
|
|
11
|
+
<Hds::AppFooter::Link @href={{this.hrefForSecurity}}>Security</Hds::AppFooter::Link>
|
|
12
|
+
<Hds::AppFooter::Link @href={{this.hrefForAccessibility}}>Accessibility</Hds::AppFooter::Link>
|
|
13
|
+
</ul>
|
|
14
|
+
</Hds::AppFooter::Item>
|
|
@@ -0,0 +1,66 @@
|
|
|
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 HdsAppFooterLegalLinksComponent extends Component {
|
|
9
|
+
/**
|
|
10
|
+
* @param ariaLabel
|
|
11
|
+
* @type {string}
|
|
12
|
+
* @default 'Legal links'
|
|
13
|
+
*/
|
|
14
|
+
get ariaLabel() {
|
|
15
|
+
return this.args.ariaLabel ?? 'Legal links';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param hrefForSupport
|
|
20
|
+
* @type {string}
|
|
21
|
+
* @description The href value of the "Support" link
|
|
22
|
+
*/
|
|
23
|
+
get hrefForSupport() {
|
|
24
|
+
return this.args.hrefForSupport ?? 'https://www.hashicorp.com/support';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param hrefForTerms
|
|
29
|
+
* @type {string}
|
|
30
|
+
* @description The href value of the "Terms" link
|
|
31
|
+
*/
|
|
32
|
+
get hrefForTerms() {
|
|
33
|
+
return (
|
|
34
|
+
this.args.hrefForTerms ?? 'https://www.hashicorp.com/terms-of-service'
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param hrefForPrivacy
|
|
40
|
+
* @type {string}
|
|
41
|
+
* @description The href value of the "Privacy" link
|
|
42
|
+
*/
|
|
43
|
+
get hrefForPrivacy() {
|
|
44
|
+
return this.args.hrefForPrivacy ?? 'https://www.hashicorp.com/privacy';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param hrefForSecurity
|
|
49
|
+
* @type {string}
|
|
50
|
+
* @description The href value of the "Security" link
|
|
51
|
+
*/
|
|
52
|
+
get hrefForSecurity() {
|
|
53
|
+
return this.args.hrefForSecurity ?? 'https://www.hashicorp.com/security';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param hrefForAccessibility
|
|
58
|
+
* @type {string}
|
|
59
|
+
* @description The href value of the "Accessibility" link
|
|
60
|
+
*/
|
|
61
|
+
get hrefForAccessibility() {
|
|
62
|
+
return (
|
|
63
|
+
this.args.hrefForAccessibility ?? 'mailto:accessibility@hashicorp.com'
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{{!
|
|
2
|
+
Copyright (c) HashiCorp, Inc.
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
}}
|
|
5
|
+
|
|
6
|
+
<Hds::AppFooter::Item>
|
|
7
|
+
<Hds::Link::Inline
|
|
8
|
+
class="hds-app-footer__link"
|
|
9
|
+
@color="secondary"
|
|
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
|
+
@icon={{@icon}}
|
|
19
|
+
@iconPosition={{@iconPosition}}
|
|
20
|
+
...attributes
|
|
21
|
+
><Hds::Text::Body @tag="span" @size="100">{{yield}}</Hds::Text::Body></Hds::Link::Inline>
|
|
22
|
+
</Hds::AppFooter::Item>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{{!
|
|
2
|
+
Copyright (c) HashiCorp, Inc.
|
|
3
|
+
SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
}}
|
|
5
|
+
|
|
6
|
+
<Hds::AppFooter::Link
|
|
7
|
+
class={{this.classNames}}
|
|
8
|
+
style={{this.itemStyle}}
|
|
9
|
+
@current-when={{@current-when}}
|
|
10
|
+
@models={{hds-link-to-models @model @models}}
|
|
11
|
+
@query={{hds-link-to-query @query}}
|
|
12
|
+
@replace={{@replace}}
|
|
13
|
+
@route={{@route}}
|
|
14
|
+
@isRouteExternal={{@isRouteExternal}}
|
|
15
|
+
@href={{this.href}}
|
|
16
|
+
@isHrefExternal={{@isHrefExternal}}
|
|
17
|
+
@icon={{this.statusIcon}}
|
|
18
|
+
@iconPosition="leading"
|
|
19
|
+
...attributes
|
|
20
|
+
>{{this.text}}</Hds::AppFooter::Link>
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import Component from '@glimmer/component';
|
|
7
|
+
import { htmlSafe } from '@ember/template';
|
|
8
|
+
import { assert } from '@ember/debug';
|
|
9
|
+
|
|
10
|
+
export const STATUSES = {
|
|
11
|
+
operational: {
|
|
12
|
+
text: 'System operational',
|
|
13
|
+
iconName: 'check-circle',
|
|
14
|
+
},
|
|
15
|
+
degraded: {
|
|
16
|
+
text: 'System degraded',
|
|
17
|
+
iconName: 'alert-triangle',
|
|
18
|
+
},
|
|
19
|
+
maintenance: {
|
|
20
|
+
text: 'System maintenance',
|
|
21
|
+
iconName: 'alert-triangle',
|
|
22
|
+
},
|
|
23
|
+
critical: {
|
|
24
|
+
text: 'System critical',
|
|
25
|
+
iconName: 'x-circle',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default class HdsAppFooterStatusLinkComponent extends Component {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(...arguments);
|
|
32
|
+
|
|
33
|
+
assert(
|
|
34
|
+
'Either @status or @text for "Hds::AppFooter::StatusLink" must have a valid value',
|
|
35
|
+
this.args.text !== undefined || this.args.status
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param status
|
|
41
|
+
* @type {string}
|
|
42
|
+
* @description The name of the status which the StatusLink is being set to
|
|
43
|
+
*/
|
|
44
|
+
get status() {
|
|
45
|
+
let status;
|
|
46
|
+
if (this.args.status) {
|
|
47
|
+
status = this.args.status.toLowerCase();
|
|
48
|
+
assert(
|
|
49
|
+
`@status for "Hds::AppFooter" must be one of the following: ${Object.keys(
|
|
50
|
+
STATUSES
|
|
51
|
+
).join(', ')} received: ${this.args.status}`,
|
|
52
|
+
Object.keys(STATUSES).includes(status)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return status;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param statusIcon
|
|
60
|
+
* @type {string}
|
|
61
|
+
* @description The name for the StatusLink icon
|
|
62
|
+
*/
|
|
63
|
+
get statusIcon() {
|
|
64
|
+
if (this.status && !this.args.statusIcon) {
|
|
65
|
+
return STATUSES[this.status].iconName;
|
|
66
|
+
}
|
|
67
|
+
return this.args.statusIcon;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @param statusIconColor
|
|
72
|
+
* @type {string}
|
|
73
|
+
* @description The color for the StatusLink icon
|
|
74
|
+
*/
|
|
75
|
+
get statusIconColor() {
|
|
76
|
+
if (this.status && !this.args.statusIconColor) {
|
|
77
|
+
return STATUSES[this.status].iconColor;
|
|
78
|
+
}
|
|
79
|
+
return this.args.statusIconColor;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get the inline style to apply to the item.
|
|
84
|
+
* @method StatusLink#itemStyle
|
|
85
|
+
* @return {string} The "style" attribute to apply to the item.
|
|
86
|
+
*/
|
|
87
|
+
get itemStyle() {
|
|
88
|
+
if (this.args.statusIconColor) {
|
|
89
|
+
return htmlSafe(
|
|
90
|
+
`--hds-app-footer-status-icon-color: ${this.args.statusIconColor}`
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param text
|
|
99
|
+
* @type {string}
|
|
100
|
+
* @description The text content of the StatusLink
|
|
101
|
+
*/
|
|
102
|
+
get text() {
|
|
103
|
+
if (!this.args.text) {
|
|
104
|
+
return STATUSES[this.status].text;
|
|
105
|
+
}
|
|
106
|
+
return this.args.text;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param href
|
|
111
|
+
* @type {string}
|
|
112
|
+
* @description The href value of the StatusLink
|
|
113
|
+
*/
|
|
114
|
+
get href() {
|
|
115
|
+
return this.args.href ?? 'https://status.hashicorp.com';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Get the class names to apply to the component.
|
|
120
|
+
* @method classNames
|
|
121
|
+
* @return {string} The "class" attribute to apply to the component.
|
|
122
|
+
*/
|
|
123
|
+
get classNames() {
|
|
124
|
+
let classes = ['hds-app-footer__status-link'];
|
|
125
|
+
|
|
126
|
+
// add a class based on the @status argument
|
|
127
|
+
if (this.args.status) {
|
|
128
|
+
classes.push(`hds-app-footer__status-link--${this.status}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return classes.join(' ');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -19,18 +19,15 @@
|
|
|
19
19
|
@navigationText={{@a11yRefocusNavigationText}}
|
|
20
20
|
/>
|
|
21
21
|
{{/if}}
|
|
22
|
-
{{#if this.
|
|
22
|
+
{{#if this.showToggleButton}}
|
|
23
23
|
{{! template-lint-disable no-invalid-interactive}}
|
|
24
24
|
<div class="hds-side-nav__overlay" {{on "click" this.toggleMinimizedStatus}} />
|
|
25
25
|
{{! template-lint-enable no-invalid-interactive}}
|
|
26
|
-
<
|
|
27
|
-
class="hds-side-nav__menu-toggle-button"
|
|
28
|
-
type="button"
|
|
29
|
-
{{on "click" this.toggleMinimizedStatus}}
|
|
26
|
+
<Hds::SideNav::ToggleButton
|
|
30
27
|
aria-label={{this.ariaLabel}}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
@icon={{if this.isMinimized "chevrons-right" "chevrons-left"}}
|
|
29
|
+
{{on "click" this.toggleMinimizedStatus}}
|
|
30
|
+
/>
|
|
34
31
|
{{/if}}
|
|
35
32
|
</:root>
|
|
36
33
|
<:header as |Header|>
|
|
@@ -10,8 +10,9 @@ import { assert } from '@ember/debug';
|
|
|
10
10
|
import { registerDestructor } from '@ember/destroyable';
|
|
11
11
|
|
|
12
12
|
export default class HdsSideNavComponent extends Component {
|
|
13
|
-
@tracked isResponsive = this.args.isResponsive ?? true;
|
|
14
|
-
@tracked isMinimized = this.
|
|
13
|
+
@tracked isResponsive = this.args.isResponsive ?? true; // controls if the component reacts to viewport changes
|
|
14
|
+
@tracked isMinimized = this.args.isMinimized ?? false; // sets the default state on 'desktop' viewports
|
|
15
|
+
@tracked isCollapsible = this.args.isCollapsible ?? false; // controls if users can collapse the sidenav on 'desktop' viewports
|
|
15
16
|
@tracked isAnimating = false;
|
|
16
17
|
@tracked isDesktop = true;
|
|
17
18
|
hasA11yRefocus = this.args.hasA11yRefocus ?? true;
|
|
@@ -39,8 +40,11 @@ export default class HdsSideNavComponent extends Component {
|
|
|
39
40
|
addEventListeners() {
|
|
40
41
|
document.addEventListener('keydown', this.escapePress, true);
|
|
41
42
|
this.desktopMQ.addEventListener('change', this.updateDesktopVariable, true);
|
|
42
|
-
//
|
|
43
|
-
|
|
43
|
+
// if not instantiated as minimized via arguments
|
|
44
|
+
if (!this.args.isMinimized) {
|
|
45
|
+
// set initial state based on viewport
|
|
46
|
+
this.updateDesktopVariable({ matches: this.desktopMQ.matches });
|
|
47
|
+
}
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
removeEventListeners() {
|
|
@@ -56,6 +60,10 @@ export default class HdsSideNavComponent extends Component {
|
|
|
56
60
|
return this.isResponsive && !this.isDesktop && !this.isMinimized;
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
get showToggleButton() {
|
|
64
|
+
return (this.isResponsive && !this.isDesktop) || this.isCollapsible;
|
|
65
|
+
}
|
|
66
|
+
|
|
59
67
|
/**
|
|
60
68
|
* @param ariaLabel
|
|
61
69
|
* @type {string}
|
|
@@ -72,15 +80,15 @@ export default class HdsSideNavComponent extends Component {
|
|
|
72
80
|
let classes = []; // `hds-side-nav` is already set by the "Hds::SideNav::Base" component
|
|
73
81
|
|
|
74
82
|
// add specific class names for the different possible states
|
|
75
|
-
if (this.isDesktop) {
|
|
76
|
-
classes.push('hds-side-nav--is-desktop');
|
|
77
|
-
} else {
|
|
78
|
-
classes.push('hds-side-nav--is-mobile');
|
|
79
|
-
}
|
|
80
83
|
if (this.isResponsive) {
|
|
81
84
|
classes.push('hds-side-nav--is-responsive');
|
|
82
85
|
}
|
|
83
|
-
if (this.
|
|
86
|
+
if (!this.isDesktop && this.isResponsive) {
|
|
87
|
+
classes.push('hds-side-nav--is-mobile');
|
|
88
|
+
} else {
|
|
89
|
+
classes.push('hds-side-nav--is-desktop');
|
|
90
|
+
}
|
|
91
|
+
if (this.isMinimized && this.isResponsive) {
|
|
84
92
|
classes.push('hds-side-nav--is-minimized');
|
|
85
93
|
} else {
|
|
86
94
|
classes.push('hds-side-nav--is-not-minimized');
|
|
@@ -94,7 +102,7 @@ export default class HdsSideNavComponent extends Component {
|
|
|
94
102
|
|
|
95
103
|
@action
|
|
96
104
|
escapePress(event) {
|
|
97
|
-
if (event.key === 'Escape' && !this.isMinimized) {
|
|
105
|
+
if (event.key === 'Escape' && !this.isMinimized && !this.isDesktop) {
|
|
98
106
|
this.isMinimized = true;
|
|
99
107
|
}
|
|
100
108
|
}
|
|
@@ -127,6 +135,9 @@ export default class HdsSideNavComponent extends Component {
|
|
|
127
135
|
updateDesktopVariable(event) {
|
|
128
136
|
this.isDesktop = event.matches;
|
|
129
137
|
|
|
138
|
+
// automatically minimize on narrow viewports (when not in desktop mode)
|
|
139
|
+
this.isMinimized = !this.isDesktop;
|
|
140
|
+
|
|
130
141
|
let { onDesktopViewportChange } = this.args;
|
|
131
142
|
|
|
132
143
|
if (typeof onDesktopViewportChange === 'function') {
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
// app-footer
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
$app-footer-gap: 24px;
|
|
11
|
+
$app-footer-icon-text-gap: 6px;
|
|
12
|
+
|
|
13
|
+
.hds-app-footer {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-wrap: wrap;
|
|
16
|
+
gap: $app-footer-gap;
|
|
17
|
+
justify-content: flex-end;
|
|
18
|
+
padding: 24px;
|
|
19
|
+
color: var(--app-footer-foreground-color);
|
|
20
|
+
border-top: 1px solid var(--app-footer-border-top-color);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// SUB-ELEMENTS
|
|
24
|
+
|
|
25
|
+
// hide list if no children
|
|
26
|
+
.hds-app-footer__list:not(:has(li)) { display: none; }
|
|
27
|
+
|
|
28
|
+
.hds-app-footer__list,
|
|
29
|
+
.hds-app-footer__legal-links {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-wrap: wrap;
|
|
32
|
+
gap: $app-footer-gap;
|
|
33
|
+
align-items: center;
|
|
34
|
+
justify-content: flex-end;
|
|
35
|
+
width: fit-content;
|
|
36
|
+
min-width: 0;
|
|
37
|
+
margin: 0;
|
|
38
|
+
padding: 0;
|
|
39
|
+
list-style-type: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.hds-app-footer__status-link {
|
|
43
|
+
// custom spacing for the status link (internally is using the "AppFooter::Link")
|
|
44
|
+
// Note: we increase specificity because otherwise is overwritten by the order of imports of components scss files
|
|
45
|
+
&.hds-link-inline--icon-leading > .hds-link-inline__icon { margin-right: $app-footer-icon-text-gap; }
|
|
46
|
+
|
|
47
|
+
.flight-icon {
|
|
48
|
+
fill: var(--hds-app-footer-status-icon-color, currentColor);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// preset status types
|
|
53
|
+
.hds-app-footer__status-link--operational {
|
|
54
|
+
.flight-icon { fill: var(--app-footer-status-link-icon-operational-color); }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.hds-app-footer__status-link--degraded {
|
|
58
|
+
.flight-icon { fill: var(--app-footer-status-link-icon-degraded-color); }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.hds-app-footer__status-link--maintenance {
|
|
62
|
+
.flight-icon { fill: var(--app-footer-status-link-icon-maintenance-color); }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.hds-app-footer__status-link--critical {
|
|
66
|
+
.flight-icon { fill: var(--app-footer-status-link-icon-critical-color); }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
.hds-app-footer__link.hds-link-inline--color-secondary,
|
|
71
|
+
.hds-app-footer__status-link {
|
|
72
|
+
// Overriding default colors
|
|
73
|
+
color: var(--app-footer-link-default-color);
|
|
74
|
+
text-align: right;
|
|
75
|
+
|
|
76
|
+
&:hover,
|
|
77
|
+
&.mock-hover {
|
|
78
|
+
color: var(--app-footer-link-hover-color);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&:active,
|
|
82
|
+
&.mock-active {
|
|
83
|
+
color: var(--app-footer-link-active-color);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&:focus,
|
|
87
|
+
&.mock-focus,
|
|
88
|
+
&:focus-visible {
|
|
89
|
+
color: var(--app-footer-link-focus-color);
|
|
90
|
+
outline-color: var(--app-footer-link-focus-outline-color);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.hds-app-footer__list-item {
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.hds-app-footer__copyright {
|
|
100
|
+
display: flex;
|
|
101
|
+
gap: $app-footer-icon-text-gap;
|
|
102
|
+
align-items: center;
|
|
103
|
+
color: var(--app-footer-copyright-text-color);
|
|
104
|
+
|
|
105
|
+
.flight-icon { fill: var(--app-footer-copyright-icon-color); }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// THEMING
|
|
109
|
+
|
|
110
|
+
// Light
|
|
111
|
+
.hds-app-footer--theme-light {
|
|
112
|
+
--app-footer-foreground-color: var(--token-color-foreground-primary);
|
|
113
|
+
--app-footer-border-top-color: var(--token-color-border-primary);
|
|
114
|
+
|
|
115
|
+
// Overriding default Secondary Link colors
|
|
116
|
+
--app-footer-link-default-color: var(--token-color-foreground-faint);
|
|
117
|
+
--app-footer-link-hover-color: var(--token-color-palette-neutral-600);
|
|
118
|
+
--app-footer-link-active-color: var(--token-color-palette-neutral-700);
|
|
119
|
+
--app-footer-link-focus-color: var(--token-color-foreground-faint);
|
|
120
|
+
--app-footer-link-focus-outline-color: var(--token-color-focus-action-internal);
|
|
121
|
+
|
|
122
|
+
// Copyright
|
|
123
|
+
--app-footer-copyright-text-color: var(--token-color-foreground-primary);
|
|
124
|
+
--app-footer-copyright-icon-color: var(--token-color-hashicorp-brand);
|
|
125
|
+
|
|
126
|
+
// StatusLink icon colors
|
|
127
|
+
--app-footer-status-link-icon-operational-color: var(--token-color-foreground-success);
|
|
128
|
+
--app-footer-status-link-icon-degraded-color: var(--token-color-foreground-warning);
|
|
129
|
+
--app-footer-status-link-icon-maintenance-color: var(--token-color-foreground-warning);
|
|
130
|
+
--app-footer-status-link-icon-critical-color: var(--token-color-foreground-critical);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Dark
|
|
134
|
+
.hds-app-footer--theme-dark {
|
|
135
|
+
--app-footer-foreground-color: #b2b6bd;
|
|
136
|
+
--app-footer-border-top-color: #b2b6bd66; // rgba(#b2b6bd, 0.4) - Sass color functions don't work with CSS variables
|
|
137
|
+
|
|
138
|
+
// Overriding default Secondary Link colors
|
|
139
|
+
--app-footer-link-default-color: #b2b6bd;
|
|
140
|
+
--app-footer-link-hover-color: #d5d7db;
|
|
141
|
+
--app-footer-link-active-color: #efeff1;
|
|
142
|
+
--app-footer-link-focus-color: #b2b6bd;
|
|
143
|
+
--app-footer-link-focus-outline-color: #389aff;
|
|
144
|
+
|
|
145
|
+
// Copyright
|
|
146
|
+
--app-footer-copyright-text-color: #b2b6bd;
|
|
147
|
+
--app-footer-copyright-icon-color: #fff;
|
|
148
|
+
|
|
149
|
+
// StatusLink Icon colors
|
|
150
|
+
--app-footer-status-link-icon-operational-color: #009241;
|
|
151
|
+
--app-footer-status-link-icon-degraded-color: #e88c03;
|
|
152
|
+
--app-footer-status-link-icon-maintenance-color: #e88c03;
|
|
153
|
+
--app-footer-status-link-icon-critical-color: #ef3016;
|
|
154
|
+
}
|
|
@@ -21,6 +21,8 @@ $hds-link-standalone-border-width: 1px;
|
|
|
21
21
|
align-items: center;
|
|
22
22
|
justify-content: center;
|
|
23
23
|
width: fit-content;
|
|
24
|
+
padding-top: 4px;
|
|
25
|
+
padding-bottom: 4px;
|
|
24
26
|
font-weight: var(--token-typography-font-weight-regular);
|
|
25
27
|
font-family: var(--token-typography-font-stack-text);
|
|
26
28
|
background-color: transparent; // needs to exist for a11y
|
|
@@ -137,7 +139,7 @@ $hds-link-standalone-focus-shift: 4px;
|
|
|
137
139
|
$shift-extra: $shift + 2px;
|
|
138
140
|
|
|
139
141
|
// notice: this is used not only for the focus, but also to increase the clickable area
|
|
140
|
-
@include hds-focus-ring-with-pseudo-element($
|
|
142
|
+
@include hds-focus-ring-with-pseudo-element($right: -$shift, $left: -$shift, $radius: $hds-link-standalone-focus-border-radius);
|
|
141
143
|
|
|
142
144
|
// we need to override a couple of values for better visual alignment
|
|
143
145
|
&.hds-link-standalone--icon-position-leading::before {
|
|
@@ -60,6 +60,16 @@
|
|
|
60
60
|
justify-content: center;
|
|
61
61
|
width: var(--token-side-nav-header-home-link-logo-size);
|
|
62
62
|
height: var(--token-side-nav-header-home-link-logo-size);
|
|
63
|
+
transition:
|
|
64
|
+
width var(--hds-app-sidenav-animation-duration)
|
|
65
|
+
var(--hds-app-sidenav-animation-easing),
|
|
66
|
+
height var(--hds-app-sidenav-animation-duration)
|
|
67
|
+
var(--hds-app-sidenav-animation-easing);
|
|
68
|
+
|
|
69
|
+
.hds-side-nav--is-minimized & {
|
|
70
|
+
width: var(--token-side-nav-header-home-link-logo-size-minimized);
|
|
71
|
+
height: var(--token-side-nav-header-home-link-logo-size-minimized);
|
|
72
|
+
}
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
// "home-link"
|
|
@@ -31,7 +31,13 @@
|
|
|
31
31
|
|
|
32
32
|
// desktop
|
|
33
33
|
&.hds-side-nav--is-desktop {
|
|
34
|
-
|
|
34
|
+
&.hds-side-nav--is-not-minimized {
|
|
35
|
+
width: var(--hds-app-sidenav-width-expanded);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&.hds-side-nav--is-minimized {
|
|
39
|
+
width: var(--hds-app-sidenav-width-minimized);
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -61,65 +67,6 @@
|
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
// MENU/TOGGLE BUTTON
|
|
66
|
-
|
|
67
|
-
.hds-side-nav__menu-toggle-button {
|
|
68
|
-
position: absolute;
|
|
69
|
-
z-index: 1;
|
|
70
|
-
color: var(--token-color-foreground-high-contrast);
|
|
71
|
-
background: none;
|
|
72
|
-
border: 1px solid transparent;
|
|
73
|
-
cursor: pointer;
|
|
74
|
-
transition-timing-function: var(--hds-app-sidenav-animation-easing);
|
|
75
|
-
transition-duration: var(--hds-app-sidenav-animation-duration);
|
|
76
|
-
transition-property: width, height, padding, border-radius, transform;
|
|
77
|
-
|
|
78
|
-
&:hover {
|
|
79
|
-
background-color: var(--token-color-palette-neutral-600);
|
|
80
|
-
border-color: transparent;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
&:active {
|
|
84
|
-
background-color: var(--token-color-palette-neutral-500);
|
|
85
|
-
border-color: transparent;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
&:focus {
|
|
89
|
-
background-color: var(--token-color-palette-neutral-500);
|
|
90
|
-
border-color: var(--token-color-focus-action-internal);
|
|
91
|
-
outline: 3px solid var(--token-color-focus-action-external);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// by default it's styled as "close" button
|
|
95
|
-
.hds-side-nav--is-mobile & {
|
|
96
|
-
width: 24px;
|
|
97
|
-
height: 24px;
|
|
98
|
-
padding: 1px;
|
|
99
|
-
background-color: var(--token-color-foreground-primary);
|
|
100
|
-
border-radius: 3px;
|
|
101
|
-
transform:
|
|
102
|
-
translateX(calc(var(--hds-app-sidenav-width-expanded) + 8px))
|
|
103
|
-
translateY(24px);
|
|
104
|
-
// z-index: 15; // not needed anymore?
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// when the sidenav is minimized it's styled as "menu" button
|
|
108
|
-
.hds-side-nav--is-mobile.hds-side-nav--is-minimized & {
|
|
109
|
-
width: 36px;
|
|
110
|
-
height: 36px;
|
|
111
|
-
padding: 5px;
|
|
112
|
-
border-radius: 5px;
|
|
113
|
-
transform: translateX(22px) translateY(var(--hds-app-sidenav-menu-button-y-shift));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// when it's desktop we _never_ want to show the menu/toggle button
|
|
117
|
-
.hds-side-nav--is-desktop & {
|
|
118
|
-
display: none;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
70
|
// RESPONSIVE WRAPPER
|
|
124
71
|
// this container element is used to control the width of the sidebar at different viewports (desktop/mobile) and states (minimized/expanded)
|
|
125
72
|
|
|
@@ -129,6 +76,7 @@
|
|
|
129
76
|
height: 100%;
|
|
130
77
|
color: var(--token-side-nav-color-foreground-primary); // we set a default color (in case generic content is added to the header/body/footer of the sidenav)
|
|
131
78
|
background: var(--token-side-nav-color-surface-primary);
|
|
79
|
+
border-right: var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);
|
|
132
80
|
|
|
133
81
|
// RESPONSIVENESS - This controls the width of the "sidenav" container, and is independent (bur related) from the parent "sidebar" grid area
|
|
134
82
|
|
|
@@ -138,17 +86,11 @@
|
|
|
138
86
|
var(--hds-app-sidenav-animation-easing);
|
|
139
87
|
}
|
|
140
88
|
|
|
141
|
-
|
|
142
|
-
.hds-side-nav--is-mobile.hds-side-nav--is-minimized & {
|
|
89
|
+
.hds-side-nav--is-minimized & {
|
|
143
90
|
width: var(--hds-app-sidenav-width-minimized);
|
|
144
91
|
}
|
|
145
92
|
|
|
146
|
-
.hds-side-nav--is-
|
|
147
|
-
width: var(--hds-app-sidenav-width-expanded);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// desktop
|
|
151
|
-
.hds-side-nav--is-desktop & {
|
|
93
|
+
.hds-side-nav--is-not-minimized & {
|
|
152
94
|
width: var(--hds-app-sidenav-width-expanded);
|
|
153
95
|
}
|
|
154
96
|
}
|
|
@@ -160,6 +102,15 @@
|
|
|
160
102
|
padding-right: var(--token-side-nav-wrapper-padding-horizontal);
|
|
161
103
|
padding-bottom: 8px; // by design
|
|
162
104
|
padding-left: var(--token-side-nav-wrapper-padding-horizontal);
|
|
105
|
+
transition:
|
|
106
|
+
padding var(--hds-app-sidenav-animation-duration)
|
|
107
|
+
var(--hds-app-sidenav-animation-easing);
|
|
108
|
+
|
|
109
|
+
.hds-side-nav--is-minimized & {
|
|
110
|
+
padding-top: var(--token-side-nav-wrapper-padding-vertical-minimized);
|
|
111
|
+
padding-right: var(--token-side-nav-wrapper-padding-horizontal-minimized);
|
|
112
|
+
padding-left: var(--token-side-nav-wrapper-padding-horizontal-minimized);
|
|
113
|
+
}
|
|
163
114
|
}
|
|
164
115
|
|
|
165
116
|
.hds-side-nav__wrapper-body {
|
|
@@ -187,10 +138,9 @@
|
|
|
187
138
|
// - shown (transitioning their opacity) when the sidenav is "expanded"
|
|
188
139
|
|
|
189
140
|
.hds-side-nav-hide-when-minimized {
|
|
190
|
-
.hds-side-nav--is-
|
|
141
|
+
.hds-side-nav--is-minimized & {
|
|
191
142
|
visibility: hidden !important; // we need `!important` here to override the inline style applied to the single panels
|
|
192
143
|
opacity: 0;
|
|
193
|
-
transition: none;
|
|
194
144
|
// this is needed because, despite the element having `visibility: hidden`,
|
|
195
145
|
// the child elements ("panels") have their visibility dynamically managed via JS
|
|
196
146
|
// and when they have "visibility: visible" applied, they are not visually visible
|
|
@@ -206,8 +156,7 @@
|
|
|
206
156
|
pointer-events: none;
|
|
207
157
|
}
|
|
208
158
|
|
|
209
|
-
.hds-side-nav--is-
|
|
210
|
-
.hds-side-nav--is-desktop & {
|
|
159
|
+
.hds-side-nav--is-not-minimized & {
|
|
211
160
|
visibility: visible;
|
|
212
161
|
opacity: 1;
|
|
213
162
|
transition:
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
// SIDE-NAV > TOGGLE BUTTON
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
.hds-side-nav__toggle-button {
|
|
12
|
+
position: absolute;
|
|
13
|
+
top: 22px;
|
|
14
|
+
left: calc(var(--token-side-nav-wrapper-border-width) * -1);
|
|
15
|
+
z-index: 1;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: row-reverse;
|
|
18
|
+
align-items: center;
|
|
19
|
+
width: 26px;
|
|
20
|
+
height: 36px;
|
|
21
|
+
padding: 0 4px;
|
|
22
|
+
color: var(--token-color-foreground-high-contrast);
|
|
23
|
+
background: none;
|
|
24
|
+
background-color: var(--token-side-nav-color-surface-primary);
|
|
25
|
+
border: var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);
|
|
26
|
+
border-left-color: transparent;
|
|
27
|
+
border-top-right-radius: var(--token-side-nav-toggle-button-border-radius);
|
|
28
|
+
border-bottom-right-radius: var(--token-side-nav-toggle-button-border-radius);
|
|
29
|
+
transform: translateX(var(--hds-app-sidenav-width-expanded));
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
transition:
|
|
32
|
+
transform var(--hds-app-sidenav-animation-duration)
|
|
33
|
+
var(--hds-app-sidenav-animation-easing),
|
|
34
|
+
width var(--hds-app-sidenav-animation-duration)
|
|
35
|
+
var(--hds-app-sidenav-animation-easing);
|
|
36
|
+
|
|
37
|
+
&::before {
|
|
38
|
+
position: absolute;
|
|
39
|
+
top: calc(var(--token-side-nav-toggle-button-border-radius) * -2);
|
|
40
|
+
left: calc(var(--token-side-nav-wrapper-border-width) * -1);
|
|
41
|
+
box-sizing: border-box;
|
|
42
|
+
width: calc(var(--token-side-nav-toggle-button-border-radius) * 2);
|
|
43
|
+
height: calc(var(--token-side-nav-toggle-button-border-radius) * 2);
|
|
44
|
+
border-bottom: var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);
|
|
45
|
+
border-left: var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);
|
|
46
|
+
border-bottom-left-radius: var(--token-side-nav-toggle-button-border-radius);
|
|
47
|
+
box-shadow: 0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-primary);
|
|
48
|
+
content: "";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&::after {
|
|
52
|
+
position: absolute;
|
|
53
|
+
bottom: calc(var(--token-side-nav-toggle-button-border-radius) * -2);
|
|
54
|
+
left: calc(var(--token-side-nav-wrapper-border-width) * -1);
|
|
55
|
+
box-sizing: border-box;
|
|
56
|
+
width: calc(var(--token-side-nav-toggle-button-border-radius) * 2);
|
|
57
|
+
height: calc(var(--token-side-nav-toggle-button-border-radius) * 2);
|
|
58
|
+
border-top: var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);
|
|
59
|
+
border-left: var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);
|
|
60
|
+
border-top-left-radius: var(--token-side-nav-toggle-button-border-radius);
|
|
61
|
+
box-shadow: 0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-primary);
|
|
62
|
+
content: "";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&:hover,
|
|
66
|
+
&.mock-hover {
|
|
67
|
+
width: 30px;
|
|
68
|
+
background-color: var(--token-side-nav-color-surface-interactive-hover);
|
|
69
|
+
|
|
70
|
+
&::before {
|
|
71
|
+
box-shadow: 0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-interactive-hover);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&::after {
|
|
75
|
+
box-shadow: 0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-interactive-hover);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&:active,
|
|
80
|
+
&.mock-active {
|
|
81
|
+
background-color: var(--token-side-nav-color-surface-interactive-active);
|
|
82
|
+
|
|
83
|
+
&::before {
|
|
84
|
+
box-shadow: 0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-interactive-active);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&::after {
|
|
88
|
+
box-shadow: 0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-interactive-active);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&:focus-visible,
|
|
93
|
+
&.mock-focus {
|
|
94
|
+
border-color: var(--token-color-focus-action-internal);
|
|
95
|
+
outline: 3px solid var(--token-color-focus-action-external);
|
|
96
|
+
|
|
97
|
+
&::before,
|
|
98
|
+
&::after {
|
|
99
|
+
display: none;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.hds-side-nav--is-minimized & {
|
|
104
|
+
transform: translateX(var(--hds-app-sidenav-width-minimized));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -16,13 +16,11 @@
|
|
|
16
16
|
// breakpoint
|
|
17
17
|
--hds-app-desktop-breakpoint: 1088px; // this is used only to read its value via JS and set the `hds-side-nav--is-desktop` class
|
|
18
18
|
// widths
|
|
19
|
-
--hds-app-sidenav-width-minimized:
|
|
19
|
+
--hds-app-sidenav-width-minimized: 48px;
|
|
20
20
|
--hds-app-sidenav-width-expanded: 280px;
|
|
21
21
|
--hds-app-sidenav-width-fixed: var(--hds-app-sidenav-width-expanded);
|
|
22
|
-
// sidebar menu
|
|
23
|
-
--hds-app-sidenav-menu-button-y-shift: 84px;
|
|
24
22
|
// animation
|
|
25
|
-
--hds-app-sidenav-animation-duration:
|
|
23
|
+
--hds-app-sidenav-animation-duration: 200ms;
|
|
26
24
|
--hds-app-sidenav-animation-delay: var(--hds-app-sidenav-animation-duration);
|
|
27
25
|
--hds-app-sidenav-animation-easing: cubic-bezier(0.65, 0, 0.35, 1);
|
|
28
26
|
}
|
|
@@ -29,7 +29,7 @@ $hds-tag-border-radius: 50px;
|
|
|
29
29
|
.hds-tag__dismiss {
|
|
30
30
|
flex: 0 0 auto;
|
|
31
31
|
margin: 0; // reset default button margin
|
|
32
|
-
padding: 6px
|
|
32
|
+
padding: 6px 4px 6px 8px;
|
|
33
33
|
border: none; // reset default button border
|
|
34
34
|
border-radius: inherit;
|
|
35
35
|
border-top-right-radius: 0;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { module, test } from 'qunit';
|
|
7
|
+
import { visit } from '@ember/test-helpers';
|
|
8
|
+
import { setupApplicationTest } from 'dummy/tests/helpers';
|
|
9
|
+
import { a11yAudit } from 'ember-a11y-testing/test-support';
|
|
10
|
+
|
|
11
|
+
module('Acceptance | components/<%= dasherizedModuleName %>', function (hooks) {
|
|
12
|
+
setupApplicationTest(hooks);
|
|
13
|
+
|
|
14
|
+
test('Components/<%= dasherizedModuleName %> page passes automated a11y checks', async function (assert) {
|
|
15
|
+
await visit('/components/<%= dasherizedModuleName %>');
|
|
16
|
+
|
|
17
|
+
await a11yAudit();
|
|
18
|
+
|
|
19
|
+
assert.ok(true, 'a11y automation audit passed');
|
|
20
|
+
});
|
|
21
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hashicorp/design-system-components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Helios Design System Components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hashicorp",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@ember/render-modifiers": "^2.0.5",
|
|
43
43
|
"@ember/test-waiters": "^3.0.2",
|
|
44
|
-
"@hashicorp/design-system-tokens": "^1.
|
|
44
|
+
"@hashicorp/design-system-tokens": "^1.9.0",
|
|
45
45
|
"@hashicorp/ember-flight-icons": "^3.1.3",
|
|
46
46
|
"dialog-polyfill": "^0.5.6",
|
|
47
47
|
"ember-a11y-refocus": "^3.0.2",
|