@hashicorp/design-system-components 2.1.0 → 2.2.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 +27 -0
- package/HOW-TO-TEST-A-COMPONENT-IN-CLOUD-UI.md +28 -3
- package/addon/components/hds/app-frame/index.hbs +24 -0
- package/addon/components/hds/app-frame/index.js +52 -0
- package/addon/components/hds/app-frame/parts/footer.hbs +7 -0
- package/addon/components/hds/app-frame/parts/header.hbs +7 -0
- package/addon/components/hds/app-frame/parts/main.hbs +7 -0
- package/addon/components/hds/app-frame/parts/modals.hbs +6 -0
- package/addon/components/hds/app-frame/parts/sidebar.hbs +7 -0
- package/addon/components/hds/application-state/footer.js +5 -0
- package/addon/components/hds/dropdown/index.hbs +2 -2
- package/addon/components/hds/dropdown/index.js +18 -2
- package/addon/components/hds/flyout/footer.hbs +7 -0
- package/addon/components/hds/flyout/index.hbs +1 -0
- package/addon/components/hds/side-nav/base.hbs +14 -0
- package/addon/components/hds/side-nav/{home-link.js → header/home-link.js} +2 -2
- package/addon/components/hds/side-nav/{icon-button.js → header/icon-button.js} +2 -2
- package/addon/components/hds/side-nav/{header.hbs → header/index.hbs} +2 -2
- package/addon/components/hds/side-nav/index.hbs +40 -0
- package/addon/components/hds/side-nav/index.js +107 -0
- package/addon/components/hds/side-nav/list/index.hbs +2 -0
- package/addon/components/hds/side-nav/portal/index.hbs +12 -0
- package/addon/components/hds/side-nav/portal/target.hbs +14 -0
- package/addon/components/hds/side-nav/portal/target.js +156 -0
- package/app/components/hds/{side-nav/wrapper.js → app-frame/index.js} +1 -1
- package/app/components/hds/app-frame/parts/footer.js +6 -0
- package/app/components/hds/app-frame/parts/header.js +6 -0
- package/app/components/hds/{side-nav/icon-button.js → app-frame/parts/main.js} +1 -1
- package/app/components/hds/app-frame/parts/modals.js +6 -0
- package/app/components/hds/app-frame/parts/sidebar.js +6 -0
- package/app/components/hds/{side-nav/home-link.js → flyout/footer.js} +1 -1
- package/app/components/hds/side-nav/base.js +6 -0
- package/app/components/hds/side-nav/header/home-link.js +6 -0
- package/app/components/hds/side-nav/header/icon-button.js +6 -0
- package/app/components/hds/side-nav/index.js +6 -0
- package/app/components/hds/side-nav/portal/index.js +6 -0
- package/app/components/hds/side-nav/portal/target.js +6 -0
- package/app/styles/@hashicorp/design-system-components.scss +1 -0
- package/app/styles/@hashicorp/design-system-power-select-overrides.scss +32 -2
- package/app/styles/components/app-frame.scss +60 -0
- package/app/styles/components/dropdown.scss +11 -0
- package/app/styles/components/flyout.scss +15 -1
- package/app/styles/components/form/textarea.scss +1 -0
- package/app/styles/components/side-nav/a11y-refocus.scss +30 -0
- package/app/styles/components/side-nav/content.scss +156 -0
- package/app/styles/components/side-nav/header.scss +102 -0
- package/app/styles/components/side-nav/index.scss +10 -0
- package/app/styles/components/side-nav/main.scss +202 -0
- package/app/styles/components/side-nav/vars.scss +36 -0
- package/package.json +5 -3
- package/addon/components/hds/side-nav/wrapper.hbs +0 -18
- package/app/styles/components/side-nav.scss +0 -275
- /package/addon/components/hds/side-nav/{home-link.hbs → header/home-link.hbs} +0 -0
- /package/addon/components/hds/side-nav/{icon-button.hbs → header/icon-button.hbs} +0 -0
- /package/app/components/hds/side-nav/{header.js → header/index.js} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
// SIDE-NAV > HEADER
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
@use "../../mixins/focus-ring" as *;
|
|
11
|
+
|
|
12
|
+
@mixin hds-side-nav-icon-button($add-visible-border: false) {
|
|
13
|
+
color: var(--token-side-nav-color-foreground-strong);
|
|
14
|
+
background-color: transparent;
|
|
15
|
+
border: 1px solid transparent;
|
|
16
|
+
border-radius: var(--token-side-nav-body-list-item-border-radius);
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
|
|
19
|
+
@if ($add-visible-border) {
|
|
20
|
+
border-color: var(--token-color-palette-neutral-500);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&:focus,
|
|
24
|
+
&.mock-focus {
|
|
25
|
+
@include hds-focus-ring-with-pseudo-element($top: -1px, $right: -1px, $bottom: -1px, $left: -1px);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&:hover,
|
|
29
|
+
&.mock-hover {
|
|
30
|
+
color: var(--token-side-nav-color-foreground-strong); // to avoid overrides by specificity (eg. `a:hover`)
|
|
31
|
+
background: var(--token-side-nav-color-surface-interactive-hover);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&:active,
|
|
35
|
+
&.mock-active {
|
|
36
|
+
color: var(--token-side-nav-color-foreground-strong); // to avoid overrides by specificity (eg. `a:hover`)
|
|
37
|
+
background: var(--token-side-nav-color-surface-interactive-active);
|
|
38
|
+
|
|
39
|
+
@if ($add-visible-border) {
|
|
40
|
+
border-color: var(--token-color-palette-neutral-400);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// HEADER (LAYOUT WRAPPER)
|
|
46
|
+
|
|
47
|
+
.hds-side-nav-header {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: space-between;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
// LOGO
|
|
55
|
+
|
|
56
|
+
.hds-side-nav-header__logo-container {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex: none;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
width: var(--token-side-nav-header-home-link-logo-size);
|
|
62
|
+
height: var(--token-side-nav-header-home-link-logo-size);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// "home-link"
|
|
66
|
+
|
|
67
|
+
.hds-side-nav__home-link {
|
|
68
|
+
@include hds-side-nav-icon-button();
|
|
69
|
+
display: block;
|
|
70
|
+
width: 100%;
|
|
71
|
+
height: 100%;
|
|
72
|
+
padding: calc(var(--token-side-nav-header-home-link-padding) - 1px); // by design - we take in account the transparent border
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
// ACTIONS
|
|
77
|
+
|
|
78
|
+
.hds-side-nav-header__actions-container {
|
|
79
|
+
display: flex;
|
|
80
|
+
|
|
81
|
+
> * + * { margin-left: var(--token-side-nav-header-actions-spacing); }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// dropdown overrides
|
|
85
|
+
|
|
86
|
+
.hds-side-nav__dropdown { // ⬅︎ add this class name to the `Hds::Dropdown` component to apply the style overrides
|
|
87
|
+
.hds-dropdown-toggle-icon {
|
|
88
|
+
@include hds-side-nav-icon-button($add-visible-border: true);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// generic "icon-button"
|
|
93
|
+
|
|
94
|
+
.hds-side-nav__icon-button {
|
|
95
|
+
@include hds-side-nav-icon-button($add-visible-border: true);
|
|
96
|
+
display: flex;
|
|
97
|
+
align-items: center;
|
|
98
|
+
justify-content: center;
|
|
99
|
+
width: 36px; // same height as the dropdown "toggle"
|
|
100
|
+
height: 36px;
|
|
101
|
+
padding: 5px; // we take in account the transparent border
|
|
102
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
// SIDE-NAV
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
.hds-side-nav {
|
|
11
|
+
position: sticky;
|
|
12
|
+
top: 0;
|
|
13
|
+
z-index: 20; // needs to stay above the main content
|
|
14
|
+
width: var(--hds-app-sidenav-width-fixed); // "default" width used by the `SideNav::Base` subcomponent (that is not responsive)
|
|
15
|
+
height: 100vh;
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
isolation: isolate; // used to create a new stacking context (so we can set the overlay's z-index to -1)
|
|
18
|
+
|
|
19
|
+
// RESPONSIVENESS - This controls the width of the top-level container ("sidebar") in the grid, and impacts the available space for the "main" grid area
|
|
20
|
+
|
|
21
|
+
&.hds-side-nav--is-responsive {
|
|
22
|
+
transition:
|
|
23
|
+
width var(--hds-app-sidenav-animation-duration)
|
|
24
|
+
var(--hds-app-sidenav-animation-easing);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// mobile
|
|
28
|
+
&.hds-side-nav--is-mobile {
|
|
29
|
+
width: var(--hds-app-sidenav-width-minimized);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// desktop
|
|
33
|
+
&.hds-side-nav--is-desktop {
|
|
34
|
+
width: var(--hds-app-sidenav-width-expanded);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
// OVERLAY
|
|
40
|
+
|
|
41
|
+
.hds-side-nav__overlay {
|
|
42
|
+
position: fixed;
|
|
43
|
+
z-index: -1;
|
|
44
|
+
inset: 0;
|
|
45
|
+
background-color: var(--token-color-palette-neutral-700);
|
|
46
|
+
opacity: 0.2;
|
|
47
|
+
transition:
|
|
48
|
+
opacity var(--hds-app-sidenav-animation-duration)
|
|
49
|
+
var(--hds-app-sidenav-animation-easing)
|
|
50
|
+
var(--hds-app-sidenav-animation-delay);
|
|
51
|
+
|
|
52
|
+
// when we're minimized (mobile) we don't want the overlay to be visible/interactive
|
|
53
|
+
.hds-side-nav--is-minimized & {
|
|
54
|
+
opacity: 0;
|
|
55
|
+
pointer-events: none;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// when it's desktop we _never_ want the overlay to be visible
|
|
59
|
+
.hds-side-nav--is-desktop & {
|
|
60
|
+
display: none;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
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
|
+
// RESPONSIVE WRAPPER
|
|
124
|
+
// this container element is used to control the width of the sidebar at different viewports (desktop/mobile) and states (minimized/expanded)
|
|
125
|
+
|
|
126
|
+
.hds-side-nav__wrapper {
|
|
127
|
+
display: flex;
|
|
128
|
+
flex-direction: column;
|
|
129
|
+
height: 100%;
|
|
130
|
+
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
|
+
background: var(--token-side-nav-color-surface-primary);
|
|
132
|
+
|
|
133
|
+
// RESPONSIVENESS - This controls the width of the "sidenav" container, and is independent (bur related) from the parent "sidebar" grid area
|
|
134
|
+
|
|
135
|
+
.hds-side-nav--is-responsive & {
|
|
136
|
+
transition:
|
|
137
|
+
width var(--hds-app-sidenav-animation-duration)
|
|
138
|
+
var(--hds-app-sidenav-animation-easing);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// mobile
|
|
142
|
+
.hds-side-nav--is-mobile.hds-side-nav--is-minimized & {
|
|
143
|
+
width: var(--hds-app-sidenav-width-minimized);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.hds-side-nav--is-mobile.hds-side-nav--is-not-minimized & {
|
|
147
|
+
width: var(--hds-app-sidenav-width-expanded);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// desktop
|
|
151
|
+
.hds-side-nav--is-desktop & {
|
|
152
|
+
width: var(--hds-app-sidenav-width-expanded);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// wrapper's child "containers"
|
|
157
|
+
|
|
158
|
+
.hds-side-nav__wrapper-header {
|
|
159
|
+
padding-top: var(--token-side-nav-wrapper-padding-vertical);
|
|
160
|
+
padding-right: var(--token-side-nav-wrapper-padding-horizontal);
|
|
161
|
+
padding-bottom: 8px; // by design
|
|
162
|
+
padding-left: var(--token-side-nav-wrapper-padding-horizontal);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.hds-side-nav__wrapper-body {
|
|
166
|
+
flex: 1;
|
|
167
|
+
padding:
|
|
168
|
+
var(--token-side-nav-wrapper-padding-vertical)
|
|
169
|
+
var(--token-side-nav-wrapper-padding-horizontal);
|
|
170
|
+
overflow-y: auto;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.hds-side-nav__wrapper-footer {
|
|
174
|
+
padding:
|
|
175
|
+
var(--token-side-nav-wrapper-padding-vertical)
|
|
176
|
+
var(--token-side-nav-wrapper-padding-horizontal);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
// "HIDE-WHEN-MINIMIZED" SPECIAL CLASS
|
|
181
|
+
// this is a special class that is used to control which elements of the sidenav need to be:
|
|
182
|
+
// - hidden (immediately) when the sidenav is "minimized"
|
|
183
|
+
// - shown (transitioning their opacity) when the sidenav is "expanded"
|
|
184
|
+
|
|
185
|
+
.hds-side-nav-hide-when-minimized {
|
|
186
|
+
.hds-side-nav--is-mobile.hds-side-nav--is-minimized & {
|
|
187
|
+
visibility: hidden !important; // we need `!important` here to override the inline style applied to the single panels
|
|
188
|
+
opacity: 0;
|
|
189
|
+
transition: none;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.hds-side-nav--is-mobile.hds-side-nav--is-not-minimized &,
|
|
193
|
+
.hds-side-nav--is-desktop & {
|
|
194
|
+
visibility: visible;
|
|
195
|
+
opacity: 1;
|
|
196
|
+
transition:
|
|
197
|
+
opacity var(--hds-app-sidenav-animation-duration)
|
|
198
|
+
var(--hds-app-sidenav-animation-easing)
|
|
199
|
+
var(--hds-app-sidenav-animation-delay);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) HashiCorp, Inc.
|
|
3
|
+
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
//
|
|
7
|
+
// SIDE-NAV - VARS
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// LOCAL VARIABLES
|
|
12
|
+
// we use `hds-app` as prefix to distinguish them from the normal tokens
|
|
13
|
+
// notice: they may be overwritten at consumer-level side if needed by re-defining the variables in a container element
|
|
14
|
+
|
|
15
|
+
:root {
|
|
16
|
+
// breakpoint
|
|
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
|
+
// widths
|
|
19
|
+
--hds-app-sidenav-width-minimized: 80px;
|
|
20
|
+
--hds-app-sidenav-width-expanded: 280px;
|
|
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
|
+
// animation
|
|
25
|
+
--hds-app-sidenav-animation-duration: 250ms;
|
|
26
|
+
--hds-app-sidenav-animation-delay: var(--hds-app-sidenav-animation-duration);
|
|
27
|
+
--hds-app-sidenav-animation-easing: cubic-bezier(0.65, 0, 0.35, 1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// reduced motion
|
|
31
|
+
|
|
32
|
+
@media (prefers-reduced-motion) {
|
|
33
|
+
:root {
|
|
34
|
+
--hds-app-sidenav-animation-duration: 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hashicorp/design-system-components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Helios Design System Components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hashicorp",
|
|
@@ -38,9 +38,10 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@ember/render-modifiers": "^2.0.5",
|
|
41
|
-
"@hashicorp/design-system-tokens": "^1.4.
|
|
41
|
+
"@hashicorp/design-system-tokens": "^1.4.2",
|
|
42
42
|
"@hashicorp/ember-flight-icons": "^3.0.2",
|
|
43
43
|
"dialog-polyfill": "^0.5.6",
|
|
44
|
+
"ember-a11y-refocus": "^3.0.2",
|
|
44
45
|
"ember-auto-import": "^2.6.0",
|
|
45
46
|
"ember-cached-decorator-polyfill": "^0.1.4",
|
|
46
47
|
"ember-cli-babel": "^7.26.11",
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
"ember-focus-trap": "^1.0.1",
|
|
51
52
|
"ember-keyboard": "^8.1.0",
|
|
52
53
|
"ember-named-blocks-polyfill": "^0.2.5",
|
|
54
|
+
"ember-stargate": "^0.4.3",
|
|
53
55
|
"ember-style-modifier": "^0.8.0",
|
|
54
56
|
"ember-truth-helpers": "^3.0.0",
|
|
55
57
|
"sass": "^1.58.3"
|
|
@@ -61,7 +63,7 @@
|
|
|
61
63
|
"@embroider/test-setup": "^2.0.2",
|
|
62
64
|
"@glimmer/component": "^1.1.2",
|
|
63
65
|
"@glimmer/tracking": "^1.1.2",
|
|
64
|
-
"@percy/cli": "^1.
|
|
66
|
+
"@percy/cli": "^1.24.0",
|
|
65
67
|
"@percy/ember": "^4.2.0",
|
|
66
68
|
"babel-eslint": "^10.1.0",
|
|
67
69
|
"broccoli-asset-rev": "^3.0.0",
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{{!
|
|
2
|
-
Copyright (c) HashiCorp, Inc.
|
|
3
|
-
SPDX-License-Identifier: MPL-2.0
|
|
4
|
-
}}
|
|
5
|
-
|
|
6
|
-
<div class="hds-side-nav__wrapper" ...attributes>
|
|
7
|
-
<div class="hds-side-nav__wrapper-header">
|
|
8
|
-
{{yield to="header"}}
|
|
9
|
-
</div>
|
|
10
|
-
|
|
11
|
-
<div class="hds-side-nav__wrapper-body" aria-label="contents">
|
|
12
|
-
{{yield to="body"}}
|
|
13
|
-
</div>
|
|
14
|
-
|
|
15
|
-
<div class="hds-side-nav__wrapper-footer">
|
|
16
|
-
{{yield to="footer"}}
|
|
17
|
-
</div>
|
|
18
|
-
</div>
|
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) HashiCorp, Inc.
|
|
3
|
-
* SPDX-License-Identifier: MPL-2.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
// SIDE-NAV
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
@use "../mixins/focus-ring" as *;
|
|
11
|
-
|
|
12
|
-
// WIP, naming, etc. will be refined... TODO: Add JSON for color tokens, etc.
|
|
13
|
-
:root {
|
|
14
|
-
// Sizes:
|
|
15
|
-
|
|
16
|
-
// header, body, footer "wrappers":
|
|
17
|
-
--token-side-nav-wrapper-padding-horizontal: 16px;
|
|
18
|
-
--token-side-nav-wrapper-padding-vertical: 16px;
|
|
19
|
-
--token-side-nav-wrapper-header-padding-bottom: 8px;
|
|
20
|
-
|
|
21
|
-
// header content:
|
|
22
|
-
--token-side-nav-header-home-link-padding: 4px;
|
|
23
|
-
--token-side-nav-header-home-link-logo-size: 48px;
|
|
24
|
-
--token-side-nav-header-actions-spacing: 8px;
|
|
25
|
-
|
|
26
|
-
// body content:
|
|
27
|
-
--token-side-nav-body-list-margin-vertical: 16px;
|
|
28
|
-
--token-side-nav-body-list-item-padding-horizontal: 8px;
|
|
29
|
-
--token-side-nav-body-list-item-padding-vertical: 4px;
|
|
30
|
-
--token-side-nav-body-list-item-spacing-vertical: 2px;
|
|
31
|
-
--token-side-nav-body-list-item-content-spacing-horizontal: 8px;
|
|
32
|
-
--token-side-nav-body-list-item-border-radius: 5px;
|
|
33
|
-
|
|
34
|
-
// Colors:
|
|
35
|
-
|
|
36
|
-
// SideNav container:
|
|
37
|
-
--token-side-nav-foreground-primary: #dedfe3;
|
|
38
|
-
--token-side-nav-foreground-primary-strong: #fff;
|
|
39
|
-
--token-side-nav-foreground-faint: #8c909c;
|
|
40
|
-
--token-side-nav-surface-primary: #0c0c0e;
|
|
41
|
-
|
|
42
|
-
// Interactive elements:
|
|
43
|
-
// base:
|
|
44
|
-
--token-side-nav-interactive-surface-hover: #3b3d45;
|
|
45
|
-
--token-side-nav-interactive-surface-active: #656a76;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@mixin hds-side-nav-icon-button($add-visible-border: false) {
|
|
49
|
-
color: var(--token-side-nav-foreground-primary-strong);
|
|
50
|
-
background-color: transparent;
|
|
51
|
-
border: 1px solid transparent;
|
|
52
|
-
border-radius: var(--token-side-nav-body-list-item-border-radius);
|
|
53
|
-
cursor: pointer;
|
|
54
|
-
|
|
55
|
-
@if ($add-visible-border) {
|
|
56
|
-
border-color: var(--token-color-palette-neutral-500);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
&:focus,
|
|
60
|
-
&.mock-focus {
|
|
61
|
-
@include hds-focus-ring-with-pseudo-element($top: -1px, $right: -1px, $bottom: -1px, $left: -1px);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
&:hover,
|
|
65
|
-
&.mock-hover {
|
|
66
|
-
color: var(--token-side-nav-foreground-primary-strong); // to avoid overrides by specificity (eg. `a:hover`)
|
|
67
|
-
background: var(--token-side-nav-interactive-surface-hover);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
&:active,
|
|
71
|
-
&.mock-active {
|
|
72
|
-
color: var(--token-side-nav-foreground-primary-strong); // to avoid overrides by specificity (eg. `a:hover`)
|
|
73
|
-
background: var(--token-side-nav-interactive-surface-active);
|
|
74
|
-
|
|
75
|
-
@if ($add-visible-border) {
|
|
76
|
-
border-color: var(--token-color-palette-neutral-400);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// * SideNav Parent (wrapper) component
|
|
83
|
-
// -------------------------------------------------------------------
|
|
84
|
-
|
|
85
|
-
.hds-side-nav__wrapper {
|
|
86
|
-
display: flex;
|
|
87
|
-
flex-direction: column;
|
|
88
|
-
width: 100%;
|
|
89
|
-
height: 100%;
|
|
90
|
-
color: var(--token-side-nav-foreground-primary); // Default color
|
|
91
|
-
background: var(--token-side-nav-surface-primary);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.hds-side-nav__wrapper-header {
|
|
95
|
-
padding-top: var(--token-side-nav-wrapper-padding-vertical);
|
|
96
|
-
padding-right: var(--token-side-nav-wrapper-padding-horizontal);
|
|
97
|
-
padding-bottom: var(--token-side-nav-wrapper-header-padding-bottom); // by design
|
|
98
|
-
padding-left: var(--token-side-nav-wrapper-padding-horizontal);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.hds-side-nav__wrapper-body {
|
|
102
|
-
flex: 1;
|
|
103
|
-
padding: var(--token-side-nav-wrapper-padding-vertical) var(--token-side-nav-wrapper-padding-horizontal);
|
|
104
|
-
overflow-y: auto;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.hds-side-nav__wrapper-footer {
|
|
108
|
-
padding: var(--token-side-nav-wrapper-padding-vertical) var(--token-side-nav-wrapper-padding-horizontal);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// * Header child elements
|
|
112
|
-
// ---------------------------------------
|
|
113
|
-
|
|
114
|
-
.hds-side-nav-header {
|
|
115
|
-
display: flex;
|
|
116
|
-
align-items: center;
|
|
117
|
-
justify-content: space-between;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.hds-side-nav-header__logo {
|
|
121
|
-
display: block;
|
|
122
|
-
flex: none;
|
|
123
|
-
align-items: center;
|
|
124
|
-
justify-content: center;
|
|
125
|
-
width: var(--token-side-nav-header-home-link-logo-size);
|
|
126
|
-
height: var(--token-side-nav-header-home-link-logo-size);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.hds-side-nav-header__actions {
|
|
130
|
-
display: flex;
|
|
131
|
-
|
|
132
|
-
> * + * { margin-left: var(--token-side-nav-header-actions-spacing); }
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.hds-side-nav__home-link {
|
|
136
|
-
@include hds-side-nav-icon-button();
|
|
137
|
-
display: block;
|
|
138
|
-
width: 100%;
|
|
139
|
-
height: 100%;
|
|
140
|
-
padding: calc(var(--token-side-nav-header-home-link-padding) - 1px); // by design - we take in account the transparent border
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Apply class name to Hds::Dropdown component
|
|
144
|
-
.hds-side-nav__dropdown {
|
|
145
|
-
.hds-dropdown-toggle-icon {
|
|
146
|
-
@include hds-side-nav-icon-button($add-visible-border: true);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.hds-side-nav__icon-button {
|
|
151
|
-
@include hds-side-nav-icon-button($add-visible-border: true);
|
|
152
|
-
display: flex;
|
|
153
|
-
align-items: center;
|
|
154
|
-
justify-content: center;
|
|
155
|
-
width: 36px;
|
|
156
|
-
height: 36px;
|
|
157
|
-
padding: 5px; // we take in account the transparent border
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// * Body child elements
|
|
161
|
-
// ---------------------------------------
|
|
162
|
-
|
|
163
|
-
.hds-side-nav__list-title {
|
|
164
|
-
display: flex;
|
|
165
|
-
align-items: center;
|
|
166
|
-
min-height: 34px;
|
|
167
|
-
margin-top: var(--token-side-nav-body-list-margin-vertical);
|
|
168
|
-
padding: 0 var(--token-side-nav-body-list-item-padding-horizontal);
|
|
169
|
-
color: var(--token-side-nav-foreground-faint);
|
|
170
|
-
|
|
171
|
-
// Remove margin from title at top of all list-items & lists
|
|
172
|
-
.hds-side-nav__list-wrapper:first-child .hds-side-nav__list-item:first-child > & {
|
|
173
|
-
margin-top: 0;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.hds-side-nav__list {
|
|
178
|
-
margin: 0;
|
|
179
|
-
padding: 0;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
.hds-side-nav__list-item {
|
|
183
|
-
list-style-type: none; // Q: Should ul have role="list" added for accessibility?
|
|
184
|
-
|
|
185
|
-
& + & {
|
|
186
|
-
margin-top: var(--token-side-nav-body-list-item-spacing-vertical);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
.hds-side-nav__list-item-link {
|
|
191
|
-
display: flex;
|
|
192
|
-
align-items: center;
|
|
193
|
-
width: 100%;
|
|
194
|
-
min-height: 36px;
|
|
195
|
-
padding: var(--token-side-nav-body-list-item-padding-vertical) var(--token-side-nav-body-list-item-padding-horizontal);
|
|
196
|
-
color: var(--token-side-nav-foreground-primary);
|
|
197
|
-
text-decoration: none;
|
|
198
|
-
background: var(--token-side-nav-surface-primary);
|
|
199
|
-
// "Link" could render as an HTML button element so this overrides the default border style in that case:
|
|
200
|
-
border-color: transparent;
|
|
201
|
-
border-radius: var(--token-side-nav-body-list-item-border-radius);
|
|
202
|
-
|
|
203
|
-
&:focus,
|
|
204
|
-
&.mock-focus {
|
|
205
|
-
@include hds-focus-ring-with-pseudo-element();
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
&:hover,
|
|
209
|
-
&.mock-hover {
|
|
210
|
-
background: var(--token-side-nav-interactive-surface-hover);
|
|
211
|
-
border-color: transparent;
|
|
212
|
-
|
|
213
|
-
.hds-side-nav__list-item-text,
|
|
214
|
-
.hds-side-nav__list-item-icon-leading,
|
|
215
|
-
.hds-side-nav__list-item-icon-trailing {
|
|
216
|
-
color: var(--token-side-nav-foreground-primary-strong);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// notice: this ".active" extra class is used to match the corresponding `active` class assigned automatically
|
|
221
|
-
// by the `<LinkTo>` Ember component (when the link is "current), so that consumers get it for free if they want
|
|
222
|
-
// otherwise they can use the `@isActive` argument to set this visual state directly
|
|
223
|
-
&.active,
|
|
224
|
-
&:active,
|
|
225
|
-
&.mock-active {
|
|
226
|
-
background: var(--token-side-nav-interactive-surface-active);
|
|
227
|
-
|
|
228
|
-
.hds-side-nav__list-item-text,
|
|
229
|
-
.hds-side-nav__list-item-icon-leading,
|
|
230
|
-
.hds-side-nav__list-item-icon-trailing {
|
|
231
|
-
color: var(--token-side-nav-foreground-primary-strong);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.hds-badge,
|
|
235
|
-
.hds-badge-count {
|
|
236
|
-
color: var(--token-color-foreground-primary);
|
|
237
|
-
background: var(--token-color-surface-strong);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
.hds-badge,
|
|
242
|
-
.hds-badge-count {
|
|
243
|
-
margin-left: var(--token-side-nav-body-list-item-content-spacing-horizontal);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// special override for the "back-link" element (no visible active state, by design)
|
|
248
|
-
.hds-side-nav__list-item-link--back-link {
|
|
249
|
-
&:active,
|
|
250
|
-
&.mock-active {
|
|
251
|
-
background: var(--token-side-nav-surface-primary);
|
|
252
|
-
|
|
253
|
-
.hds-side-nav__list-item-text,
|
|
254
|
-
.hds-side-nav__list-item-icon-leading,
|
|
255
|
-
.hds-side-nav__list-item-icon-trailing {
|
|
256
|
-
color: var(--token-side-nav-foreground-primary);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
.hds-side-nav__list-item-text {
|
|
262
|
-
color: var(--token-side-nav-foreground-primary);
|
|
263
|
-
text-align: left;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
.hds-side-nav__list-item-icon-leading {
|
|
267
|
-
flex: none;
|
|
268
|
-
margin-right: var(--token-side-nav-body-list-item-content-spacing-horizontal);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
.hds-side-nav__list-item-icon-trailing {
|
|
272
|
-
flex: none;
|
|
273
|
-
margin-left: auto;
|
|
274
|
-
padding-left: var(--token-side-nav-body-list-item-content-spacing-horizontal);
|
|
275
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|