@hashicorp/design-system-components 1.7.3 → 1.8.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @hashicorp/design-system-components
2
2
 
3
+ ## 1.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1163](https://github.com/hashicorp/design-system/pull/1163) [`992fde13f`](https://github.com/hashicorp/design-system/commit/992fde13f48b925563e85a7253f4c0aaeca50b9d) Thanks [@KristinLBradley](https://github.com/KristinLBradley)! - Add new `SideNav` components
8
+
3
9
  ## 1.7.3
4
10
 
5
11
  ### Patch Changes
@@ -0,0 +1,8 @@
1
+ <div class="hds-side-nav-header" ...attributes>
2
+ <div class="hds-side-nav-header__logo">
3
+ {{yield to="logo"}}
4
+ </div>
5
+ <div class="hds-side-nav-header__actions">
6
+ {{yield to="actions"}}
7
+ </div>
8
+ </div>
@@ -0,0 +1,14 @@
1
+ <Hds::Interactive
2
+ class="hds-side-nav__home-link"
3
+ @current-when={{@current-when}}
4
+ @models={{hds-link-to-models @model @models}}
5
+ @query={{hds-link-to-query @query}}
6
+ @replace={{@replace}}
7
+ @route={{@route}}
8
+ @isRouteExternal={{@isRouteExternal}}
9
+ @href={{@href}}
10
+ @isHrefExternal={{@isHrefExternal}}
11
+ ...attributes
12
+ >
13
+ <FlightIcon @name={{@icon}} @color={{@color}} @stretched={{true}} />
14
+ </Hds::Interactive>
@@ -0,0 +1,15 @@
1
+ <Hds::Interactive
2
+ class="hds-side-nav__icon-button"
3
+ @current-when={{@current-when}}
4
+ @models={{hds-link-to-models @model @models}}
5
+ @query={{hds-link-to-query @query}}
6
+ @replace={{@replace}}
7
+ @route={{@route}}
8
+ @isRouteExternal={{@isRouteExternal}}
9
+ @href={{@href}}
10
+ @isHrefExternal={{@isHrefExternal}}
11
+ ...attributes
12
+ aria-label={{this.ariaLabel}}
13
+ >
14
+ <FlightIcon @name={{@icon}} @color={{@color}} @stretched={{true}} @size="24" />
15
+ </Hds::Interactive>
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright (c) HashiCorp, Inc.
3
+ * SPDX-License-Identifier: MPL-2.0
4
+ */
5
+
6
+ import Component from '@glimmer/component';
7
+ import { assert } from '@ember/debug';
8
+
9
+ export default class HdsSideNavIconButtonComponent extends Component {
10
+ /**
11
+ * @param ariaLabel
12
+ * @type {string}
13
+ * @description The value of `aria-label`
14
+ */
15
+ get ariaLabel() {
16
+ let { ariaLabel } = this.args;
17
+
18
+ assert(
19
+ '@ariaLabel for "Hds::SideNav::IconButton" must have a valid value',
20
+ ariaLabel !== undefined
21
+ );
22
+
23
+ return ariaLabel;
24
+ }
25
+ }
@@ -0,0 +1,19 @@
1
+ <Hds::SideNav::List::Item>
2
+ <Hds::Interactive
3
+ class="hds-side-nav__list-item-link hds-side-nav__list-item-link--back-link"
4
+ @current-when={{@current-when}}
5
+ @models={{hds-link-to-models @model @models}}
6
+ @query={{hds-link-to-query @query}}
7
+ @replace={{@replace}}
8
+ @route={{@route}}
9
+ @isRouteExternal={{@isRouteExternal}}
10
+ @href={{@href}}
11
+ @isHrefExternal={{@isHrefExternal}}
12
+ ...attributes
13
+ >
14
+ <FlightIcon class="hds-side-nav__list-item-icon-leading" @name="chevron-left" />
15
+ <span class="hds-side-nav__list-item-text hds-typography-body-200 hds-font-weight-medium">
16
+ {{@text}}
17
+ </span>
18
+ </Hds::Interactive>
19
+ </Hds::SideNav::List::Item>
@@ -0,0 +1,12 @@
1
+ <nav class="hds-side-nav__list-wrapper" ...attributes>
2
+ <ul class="hds-side-nav__list" role="list">
3
+ {{yield
4
+ (hash
5
+ Item=(component "hds/side-nav/list/item")
6
+ BackLink=(component "hds/side-nav/list/back-link")
7
+ Title=(component "hds/side-nav/list/title")
8
+ Link=(component "hds/side-nav/list/link")
9
+ )
10
+ }}
11
+ </ul>
12
+ </nav>
@@ -0,0 +1,3 @@
1
+ <li class="hds-side-nav__list-item" ...attributes>
2
+ {{yield}}
3
+ </li>
@@ -0,0 +1,43 @@
1
+ <Hds::SideNav::List::Item>
2
+ <Hds::Interactive
3
+ class="hds-side-nav__list-item-link {{if @isActive 'active'}}"
4
+ @current-when={{@current-when}}
5
+ @models={{hds-link-to-models @model @models}}
6
+ @query={{hds-link-to-query @query}}
7
+ @replace={{@replace}}
8
+ @route={{@route}}
9
+ @isRouteExternal={{@isRouteExternal}}
10
+ @href={{@href}}
11
+ @isHrefExternal={{@isHrefExternal}}
12
+ ...attributes
13
+ >
14
+ {{#if @icon}}
15
+ <FlightIcon class="hds-side-nav__list-item-icon-leading" @name={{@icon}} />
16
+ {{/if}}
17
+
18
+ <span class="hds-side-nav__list-item-text hds-typography-body-200 hds-font-weight-medium">
19
+ {{@text}}
20
+ </span>
21
+
22
+ {{#if @count}}
23
+ <Hds::BadgeCount @text={{@count}} @type="inverted" @size="small" />
24
+ {{/if}}
25
+
26
+ {{#if @badge}}
27
+ <Hds::Badge @text={{@badge}} @type="inverted" @size="small" />
28
+ {{/if}}
29
+
30
+ {{yield}}
31
+
32
+ {{#if @hasSubItems}}
33
+ <span class="hds-side-nav__list-item-icon-trailing">
34
+ <FlightIcon @name="chevron-right" @isInlineBlock={{false}} />
35
+ </span>
36
+ {{/if}}
37
+ {{#if @isHrefExternal}}
38
+ <span class="hds-side-nav__list-item-icon-trailing">
39
+ <FlightIcon @name="external-link" @isInlineBlock={{false}} />
40
+ </span>
41
+ {{/if}}
42
+ </Hds::Interactive>
43
+ </Hds::SideNav::List::Item>
@@ -0,0 +1,3 @@
1
+ <Hds::SideNav::List::Item>
2
+ <div class="hds-side-nav__list-title hds-typography-body-100 hds-font-weight-semibold" ...attributes>{{~yield~}}</div>
3
+ </Hds::SideNav::List::Item>
@@ -0,0 +1,13 @@
1
+ <div class="hds-side-nav__wrapper" ...attributes>
2
+ <div class="hds-side-nav__wrapper-header">
3
+ {{yield to="header"}}
4
+ </div>
5
+
6
+ <div class="hds-side-nav__wrapper-body" aria-label="contents">
7
+ {{yield to="body"}}
8
+ </div>
9
+
10
+ <div class="hds-side-nav__wrapper-footer">
11
+ {{yield to="footer"}}
12
+ </div>
13
+ </div>
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/header';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/home-link';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/icon-button';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/list/back-link';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/list/index';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/list/item';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/list/link';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/list/title';
@@ -0,0 +1 @@
1
+ export { default } from '@hashicorp/design-system-components/components/hds/side-nav/wrapper';
@@ -30,6 +30,7 @@
30
30
  @use "../components/link"; // multiple components
31
31
  @use "../components/modal";
32
32
  @use "../components/pagination";
33
+ @use "../components/side-nav";
33
34
  @use "../components/stepper";
34
35
  @use "../components/table";
35
36
  @use "../components/tabs";
@@ -0,0 +1,270 @@
1
+ //
2
+ // SIDE-NAV
3
+ //
4
+
5
+ @use "../mixins/focus-ring" as *;
6
+
7
+ // WIP, naming, etc. will be refined... TODO: Add JSON for color tokens, etc.
8
+ :root {
9
+ // Sizes:
10
+
11
+ // header, body, footer "wrappers":
12
+ --token-side-nav-wrapper-padding-horizontal: 16px;
13
+ --token-side-nav-wrapper-padding-vertical: 16px;
14
+ --token-side-nav-wrapper-header-padding-bottom: 8px;
15
+
16
+ // header content:
17
+ --token-side-nav-header-home-link-padding: 4px;
18
+ --token-side-nav-header-home-link-logo-size: 48px;
19
+ --token-side-nav-header-actions-spacing: 8px;
20
+
21
+ // body content:
22
+ --token-side-nav-body-list-margin-vertical: 16px;
23
+ --token-side-nav-body-list-item-padding-horizontal: 8px;
24
+ --token-side-nav-body-list-item-padding-vertical: 4px;
25
+ --token-side-nav-body-list-item-spacing-vertical: 2px;
26
+ --token-side-nav-body-list-item-content-spacing-horizontal: 8px;
27
+ --token-side-nav-body-list-item-border-radius: 5px;
28
+
29
+ // Colors:
30
+
31
+ // SideNav container:
32
+ --token-side-nav-foreground-primary: #dedfe3;
33
+ --token-side-nav-foreground-primary-strong: #fff;
34
+ --token-side-nav-foreground-faint: #8c909c;
35
+ --token-side-nav-surface-primary: #0c0c0e;
36
+
37
+ // Interactive elements:
38
+ // base:
39
+ --token-side-nav-interactive-surface-hover: #3b3d45;
40
+ --token-side-nav-interactive-surface-active: #656a76;
41
+ }
42
+
43
+ @mixin hds-side-nav-icon-button($add-visible-border: false) {
44
+ color: var(--token-side-nav-foreground-primary-strong);
45
+ background-color: transparent;
46
+ border: 1px solid transparent;
47
+ border-radius: var(--token-side-nav-body-list-item-border-radius);
48
+ cursor: pointer;
49
+
50
+ @if ($add-visible-border) {
51
+ border-color: var(--token-color-palette-neutral-500);
52
+ }
53
+
54
+ &:focus,
55
+ &.mock-focus {
56
+ @include hds-focus-ring-with-pseudo-element($top: -1px, $right: -1px, $bottom: -1px, $left: -1px);
57
+ }
58
+
59
+ &:hover,
60
+ &.mock-hover {
61
+ color: var(--token-side-nav-foreground-primary-strong); // to avoid overrides by specificity (eg. `a:hover`)
62
+ background: var(--token-side-nav-interactive-surface-hover);
63
+ }
64
+
65
+ &:active,
66
+ &.mock-active {
67
+ color: var(--token-side-nav-foreground-primary-strong); // to avoid overrides by specificity (eg. `a:hover`)
68
+ background: var(--token-side-nav-interactive-surface-active);
69
+
70
+ @if ($add-visible-border) {
71
+ border-color: var(--token-color-palette-neutral-400);
72
+ }
73
+ }
74
+ }
75
+
76
+
77
+ // * SideNav Parent (wrapper) component
78
+ // -------------------------------------------------------------------
79
+
80
+ .hds-side-nav__wrapper {
81
+ display: flex;
82
+ flex-direction: column;
83
+ width: 100%;
84
+ height: 100%;
85
+ color: var(--token-side-nav-foreground-primary); // Default color
86
+ background: var(--token-side-nav-surface-primary);
87
+ }
88
+
89
+ .hds-side-nav__wrapper-header {
90
+ padding-top: var(--token-side-nav-wrapper-padding-vertical);
91
+ padding-right: var(--token-side-nav-wrapper-padding-horizontal);
92
+ padding-bottom: var(--token-side-nav-wrapper-header-padding-bottom); // by design
93
+ padding-left: var(--token-side-nav-wrapper-padding-horizontal);
94
+ }
95
+
96
+ .hds-side-nav__wrapper-body {
97
+ flex: 1;
98
+ padding: var(--token-side-nav-wrapper-padding-vertical) var(--token-side-nav-wrapper-padding-horizontal);
99
+ overflow-y: auto;
100
+ }
101
+
102
+ .hds-side-nav__wrapper-footer {
103
+ padding: var(--token-side-nav-wrapper-padding-vertical) var(--token-side-nav-wrapper-padding-horizontal);
104
+ }
105
+
106
+ // * Header child elements
107
+ // ---------------------------------------
108
+
109
+ .hds-side-nav-header {
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: space-between;
113
+ }
114
+
115
+ .hds-side-nav-header__logo {
116
+ display: block;
117
+ flex: none;
118
+ align-items: center;
119
+ justify-content: center;
120
+ width: var(--token-side-nav-header-home-link-logo-size);
121
+ height: var(--token-side-nav-header-home-link-logo-size);
122
+ }
123
+
124
+ .hds-side-nav-header__actions {
125
+ display: flex;
126
+
127
+ > * + * { margin-left: var(--token-side-nav-header-actions-spacing); }
128
+ }
129
+
130
+ .hds-side-nav__home-link {
131
+ @include hds-side-nav-icon-button();
132
+ display: block;
133
+ width: 100%;
134
+ height: 100%;
135
+ padding: calc(var(--token-side-nav-header-home-link-padding) - 1px); // by design - we take in account the transparent border
136
+ }
137
+
138
+ // Apply class name to Hds::Dropdown component
139
+ .hds-side-nav__dropdown {
140
+ .hds-dropdown-toggle-icon {
141
+ @include hds-side-nav-icon-button($add-visible-border: true);
142
+ }
143
+ }
144
+
145
+ .hds-side-nav__icon-button {
146
+ @include hds-side-nav-icon-button($add-visible-border: true);
147
+ display: flex;
148
+ align-items: center;
149
+ justify-content: center;
150
+ width: 36px;
151
+ height: 36px;
152
+ padding: 5px; // we take in account the transparent border
153
+ }
154
+
155
+ // * Body child elements
156
+ // ---------------------------------------
157
+
158
+ .hds-side-nav__list-title {
159
+ display: flex;
160
+ align-items: center;
161
+ min-height: 34px;
162
+ margin-top: var(--token-side-nav-body-list-margin-vertical);
163
+ padding: 0 var(--token-side-nav-body-list-item-padding-horizontal);
164
+ color: var(--token-side-nav-foreground-faint);
165
+
166
+ // Remove margin from title at top of all list-items & lists
167
+ .hds-side-nav__list-wrapper:first-child .hds-side-nav__list-item:first-child > & {
168
+ margin-top: 0;
169
+ }
170
+ }
171
+
172
+ .hds-side-nav__list {
173
+ margin: 0;
174
+ padding: 0;
175
+ }
176
+
177
+ .hds-side-nav__list-item {
178
+ list-style-type: none; // Q: Should ul have role="list" added for accessibility?
179
+
180
+ & + & {
181
+ margin-top: var(--token-side-nav-body-list-item-spacing-vertical);
182
+ }
183
+ }
184
+
185
+ .hds-side-nav__list-item-link {
186
+ display: flex;
187
+ align-items: center;
188
+ width: 100%;
189
+ min-height: 36px;
190
+ padding: var(--token-side-nav-body-list-item-padding-vertical) var(--token-side-nav-body-list-item-padding-horizontal);
191
+ color: var(--token-side-nav-foreground-primary);
192
+ text-decoration: none;
193
+ background: var(--token-side-nav-surface-primary);
194
+ // "Link" could render as an HTML button element so this overrides the default border style in that case:
195
+ border-color: transparent;
196
+ border-radius: var(--token-side-nav-body-list-item-border-radius);
197
+
198
+ &:focus,
199
+ &.mock-focus {
200
+ @include hds-focus-ring-with-pseudo-element();
201
+ }
202
+
203
+ &:hover,
204
+ &.mock-hover {
205
+ background: var(--token-side-nav-interactive-surface-hover);
206
+ border-color: transparent;
207
+
208
+ .hds-side-nav__list-item-text,
209
+ .hds-side-nav__list-item-icon-leading,
210
+ .hds-side-nav__list-item-icon-trailing {
211
+ color: var(--token-side-nav-foreground-primary-strong);
212
+ }
213
+ }
214
+
215
+ // notice: this ".active" extra class is used to match the corresponding `active` class assigned automatically
216
+ // by the `<LinkTo>` Ember component (when the link is "current), so that consumers get it for free if they want
217
+ // otherwise they can use the `@isActive` argument to set this visual state directly
218
+ &.active,
219
+ &:active,
220
+ &.mock-active {
221
+ background: var(--token-side-nav-interactive-surface-active);
222
+
223
+ .hds-side-nav__list-item-text,
224
+ .hds-side-nav__list-item-icon-leading,
225
+ .hds-side-nav__list-item-icon-trailing {
226
+ color: var(--token-side-nav-foreground-primary-strong);
227
+ }
228
+
229
+ .hds-badge,
230
+ .hds-badge-count {
231
+ color: var(--token-color-foreground-primary);
232
+ background: var(--token-color-surface-strong);
233
+ }
234
+ }
235
+
236
+ .hds-badge,
237
+ .hds-badge-count {
238
+ margin-left: var(--token-side-nav-body-list-item-content-spacing-horizontal);
239
+ }
240
+ }
241
+
242
+ // special override for the "back-link" element (no visible active state, by design)
243
+ .hds-side-nav__list-item-link--back-link {
244
+ &:active,
245
+ &.mock-active {
246
+ background: var(--token-side-nav-surface-primary);
247
+
248
+ .hds-side-nav__list-item-text,
249
+ .hds-side-nav__list-item-icon-leading,
250
+ .hds-side-nav__list-item-icon-trailing {
251
+ color: var(--token-side-nav-foreground-primary);
252
+ }
253
+ }
254
+ }
255
+
256
+ .hds-side-nav__list-item-text {
257
+ color: var(--token-side-nav-foreground-primary);
258
+ text-align: left;
259
+ }
260
+
261
+ .hds-side-nav__list-item-icon-leading {
262
+ flex: none;
263
+ margin-right: var(--token-side-nav-body-list-item-content-spacing-horizontal);
264
+ }
265
+
266
+ .hds-side-nav__list-item-icon-trailing {
267
+ flex: none;
268
+ margin-left: auto;
269
+ padding-left: var(--token-side-nav-body-list-item-content-spacing-horizontal);
270
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hashicorp/design-system-components",
3
- "version": "1.7.3",
3
+ "version": "1.8.0",
4
4
  "description": "Helios Design System Components",
5
5
  "keywords": [
6
6
  "hashicorp",