@hashicorp/react-components 0.0.0-nightly.b46420c → 0.0.0-nightly.b5f9cca
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/package.json +5 -4
- package/src/components/actions/index.tsx +5 -5
- package/src/components/call-to-action/index.tsx +7 -7
- package/src/components/card/index.test.tsx +1 -1
- package/src/components/card/newsroom-card/index.test.tsx +1 -1
- package/src/components/card/partner-card/index.tsx +3 -3
- package/src/components/card/person-card/index.tsx +1 -1
- package/src/components/card/primitives.tsx +16 -15
- package/src/components/card/resource-card/index.test.tsx +1 -1
- package/src/components/card/resource-card/index.tsx +3 -0
- package/src/components/card/types.ts +2 -2
- package/src/components/card/unified-card/index.spec.tsx +40 -0
- package/src/components/card/unified-card/index.tsx +5 -11
- package/src/components/marketo-form/contexts/FormMetadata.ts +2 -0
- package/src/components/marketo-form/form/index.tsx +4 -2
- package/src/components/marketo-form/partials/fields/checkbox-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/email-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/form-page-url-field/index.tsx +2 -0
- package/src/components/marketo-form/partials/fields/hidden-field/index.tsx +1 -0
- package/src/components/marketo-form/partials/fields/radio-buttons-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/select-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/telephone-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/text-field/index.tsx +1 -1
- package/src/components/marketo-form/partials/fields/textarea-field/index.tsx +1 -1
- package/src/components/marketo-form/types.ts +10 -11
- package/src/components/nav-panel/components/link-list/index.tsx +25 -8
- package/src/components/nav-panel/components/panel/column/index.tsx +17 -2
- package/src/components/nav-panel/components/panel/column/style.module.css +12 -2
- package/src/components/nav-panel/components/panel/root/index.tsx +13 -2
- package/src/components/nav-panel/components/panel/root/style.module.css +19 -4
- package/src/components/nav-panel/components/promo/index.tsx +15 -8
- package/src/components/nav-panel/components/promo/style.module.css +28 -6
- package/src/components/nav-panel/product-panel/index.tsx +104 -27
- package/src/components/nav-panel/product-panel/style.module.css +230 -15
- package/src/components/nav-panel/standard-panel/index.tsx +3 -0
- package/src/components/nav-panel/standard-panel/style.module.css +1 -1
- package/src/components/next-steps/index.tsx +3 -2
- package/src/components/product-badge/index.tsx +1 -1
- package/src/components/subnav/index.tsx +14 -4
- package/src/components/subnav/partials/CtaLinks/github-stars-link/style.module.css +8 -12
- package/src/components/subnav/partials/CtaLinks/index.tsx +9 -8
- package/src/components/subnav/partials/CtaLinks/style.module.css +4 -4
- package/src/components/subnav/partials/DropdownTrigger/index.tsx +2 -2
- package/src/components/subnav/partials/DropdownTrigger/style.module.css +7 -4
- package/src/components/subnav/partials/MenuItemsDefault/index.tsx +29 -8
- package/src/components/subnav/partials/MenuItemsDefault/style.module.css +37 -24
- package/src/components/subnav/partials/MenuItemsOverflow/index.tsx +18 -4
- package/src/components/subnav/partials/MenuItemsOverflow/style.module.css +22 -16
- package/src/components/subnav/partials/TitleLink/index.tsx +5 -3
- package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts +2 -1
- package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-light.ts +2 -1
- package/src/components/subnav/partials/TitleLink/style.module.css +1 -1
- package/src/components/subnav/partials/nav-item-text/style.module.css +2 -4
- package/src/components/subnav/style.module.css +4 -6
- package/src/lib/parse-url/index.test.ts +40 -1
- package/src/lib/parse-url/index.ts +78 -9
- package/src/lib/v/index.ts +4 -5
- package/src/components/consent-manager/README.md +0 -73
- package/src/components/consent-manager/components/banner/banner.module.css +0 -23
- package/src/components/consent-manager/components/banner/banner.test.tsx +0 -31
- package/src/components/consent-manager/components/banner/banner.tsx +0 -73
- package/src/components/consent-manager/components/dialog/dialog.module.css +0 -145
- package/src/components/consent-manager/components/dialog/dialog.test.tsx +0 -194
- package/src/components/consent-manager/components/dialog/dialog.tsx +0 -339
- package/src/components/consent-manager/img/icn_close.tsx +0 -19
- package/src/components/consent-manager/index.test.tsx +0 -334
- package/src/components/consent-manager/index.tsx +0 -186
- package/src/components/consent-manager/loader/README.md +0 -29
- package/src/components/consent-manager/loader/categories.ts +0 -22
- package/src/components/consent-manager/loader/index.tsx +0 -94
- package/src/components/consent-manager/loader/presets/enterprise.ts +0 -12
- package/src/components/consent-manager/loader/presets/oss.ts +0 -10
- package/src/components/consent-manager/loader/services.ts +0 -45
- package/src/components/consent-manager/scripts/custom.tsx +0 -59
- package/src/components/consent-manager/scripts/segment.tsx +0 -87
- package/src/components/consent-manager/style.module.css +0 -9
- package/src/components/consent-manager/types.ts +0 -55
- package/src/components/consent-manager/util/cookies.test.ts +0 -75
- package/src/components/consent-manager/util/cookies.ts +0 -70
- package/src/components/consent-manager/util/integrations.test.ts +0 -115
- package/src/components/consent-manager/util/integrations.ts +0 -110
- package/src/components/subnav/theme.module.css +0 -50
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Copyright (c) HashiCorp, Inc.
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
|
+
'use client'
|
|
5
6
|
|
|
6
7
|
import { useState } from 'react'
|
|
7
8
|
import Badge from '@hashicorp/react-badge'
|
|
@@ -10,7 +11,7 @@ import ExpandableArrow from '@hashicorp/react-expandable-arrow'
|
|
|
10
11
|
import Intro from '../intro'
|
|
11
12
|
import Link from 'next/link'
|
|
12
13
|
import type { NextStepsProps } from './types'
|
|
13
|
-
import
|
|
14
|
+
import { HDSPlusStandaloneLink } from '@hashicorp/react-mds/src/hds-plus/standalone-link'
|
|
14
15
|
import { IconArrowRight16 } from '@hashicorp/flight-icons/svg-react/arrow-right-16'
|
|
15
16
|
import useProductMeta from '@hashicorp/platform-product-meta'
|
|
16
17
|
import s from './style.module.css'
|
|
@@ -69,7 +70,7 @@ export default function NextSteps({
|
|
|
69
70
|
{cta ? (
|
|
70
71
|
<div className={s.cta}>
|
|
71
72
|
<p className={s.ctaCopy}>{cta.copy}</p>
|
|
72
|
-
<
|
|
73
|
+
<HDSPlusStandaloneLink
|
|
73
74
|
href={cta.href}
|
|
74
75
|
text={cta.ctaText}
|
|
75
76
|
icon={
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Products } from '@hashicorp/platform-product-meta'
|
|
7
|
-
import Badge from '@hashicorp/react-
|
|
7
|
+
import Badge from '@hashicorp/react-hds/src/components/badge'
|
|
8
8
|
import { IconDot16 } from '@hashicorp/flight-icons/svg-react/dot-16'
|
|
9
9
|
import s from './style.module.css'
|
|
10
10
|
|
|
@@ -17,8 +17,8 @@ import CtaLinks, { type CtaLinkProps } from './partials/CtaLinks'
|
|
|
17
17
|
import traverse, { isObject } from './helpers/traverse'
|
|
18
18
|
import { areBasePathsMatching } from './helpers/areBasePathsMatching'
|
|
19
19
|
import * as NavigationMenu from '@radix-ui/react-navigation-menu'
|
|
20
|
-
import themeStyles from './theme.module.css'
|
|
21
20
|
import s from './style.module.css'
|
|
21
|
+
import { getLocalizedHref } from '@web/utils/get-localized-href'
|
|
22
22
|
|
|
23
23
|
const productAllowList = {
|
|
24
24
|
consul: 'consul',
|
|
@@ -47,6 +47,7 @@ type SubnavDropdown = {
|
|
|
47
47
|
type MenuItem = SubnavLink | SubnavDropdown | 'divider'
|
|
48
48
|
|
|
49
49
|
export interface SubnavInnerProps {
|
|
50
|
+
locale?: string
|
|
50
51
|
hasOverflow?: boolean
|
|
51
52
|
titleLink: { text: string; url: string }
|
|
52
53
|
product?: Products
|
|
@@ -62,6 +63,7 @@ export interface SubnavInnerProps {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
function SubnavInner({
|
|
66
|
+
locale,
|
|
65
67
|
hasOverflow,
|
|
66
68
|
titleLink,
|
|
67
69
|
product,
|
|
@@ -110,17 +112,20 @@ function SubnavInner({
|
|
|
110
112
|
>
|
|
111
113
|
<NavigationMenu.Link asChild>
|
|
112
114
|
<TitleLink
|
|
115
|
+
locale={locale}
|
|
113
116
|
text={titleLink.text}
|
|
114
|
-
url={titleLink.url}
|
|
117
|
+
url={getLocalizedHref(titleLink.url)}
|
|
115
118
|
product={product}
|
|
116
119
|
theme={theme}
|
|
117
120
|
/>
|
|
118
121
|
</NavigationMenu.Link>
|
|
122
|
+
|
|
119
123
|
{!hasOverflow && (
|
|
120
124
|
<div className={s.subNavRight}>
|
|
121
125
|
<MenuItemsDefault
|
|
122
126
|
menuItems={menuItemsWithActive}
|
|
123
127
|
activatePanel={activatePanel}
|
|
128
|
+
locale={locale}
|
|
124
129
|
/>
|
|
125
130
|
{ctaLinks?.length > 0 && (
|
|
126
131
|
<CtaLinks
|
|
@@ -165,6 +170,10 @@ function Subnav({ className, theme = 'light', ...restProps }: SubnavProps) {
|
|
|
165
170
|
setActivePanel(panel)
|
|
166
171
|
}
|
|
167
172
|
|
|
173
|
+
const ariaLabel = restProps?.titleLink?.text
|
|
174
|
+
? `${restProps.titleLink.text} pages`
|
|
175
|
+
: 'Subnav pages'
|
|
176
|
+
|
|
168
177
|
return (
|
|
169
178
|
<>
|
|
170
179
|
{/**
|
|
@@ -175,11 +184,12 @@ function Subnav({ className, theme = 'light', ...restProps }: SubnavProps) {
|
|
|
175
184
|
<style>{`:root{--subnav-height:${height}px}`}</style>
|
|
176
185
|
<NavigationMenu.Root
|
|
177
186
|
ref={wrapperRef}
|
|
178
|
-
className={classNames(s.root,
|
|
187
|
+
className={classNames(s.root, className, {
|
|
179
188
|
[s.isSticky]: isSticky,
|
|
180
189
|
[s.hasOverflow]: hasOverflow,
|
|
190
|
+
'hdsplus-dark-mode': theme === 'dark',
|
|
181
191
|
})}
|
|
182
|
-
aria-label={
|
|
192
|
+
aria-label={ariaLabel}
|
|
183
193
|
onValueChange={activatePanel}
|
|
184
194
|
value={activePanel}
|
|
185
195
|
delayDuration={0}
|
|
@@ -3,15 +3,13 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* Note: consumes from theme.module.css, as marked */
|
|
7
|
-
|
|
8
6
|
.root {
|
|
9
|
-
--local-scrim-
|
|
10
|
-
--local-divider-color: var(--border-
|
|
7
|
+
--local-scrim-opacity: 0;
|
|
8
|
+
--local-divider-color: var(--token-color-border-primary);
|
|
11
9
|
|
|
12
10
|
position: relative;
|
|
13
|
-
color: var(--
|
|
14
|
-
border: 1px solid var(--local-divider-color);
|
|
11
|
+
color: var(--token-color-foreground-primary);
|
|
12
|
+
border: 1px solid var(--local-divider-color);
|
|
15
13
|
border-radius: 5px;
|
|
16
14
|
background: none;
|
|
17
15
|
transition: background 0.2s, border-color 0.2s;
|
|
@@ -27,17 +25,15 @@
|
|
|
27
25
|
right: -1px;
|
|
28
26
|
bottom: -1px;
|
|
29
27
|
border-radius: 5px;
|
|
30
|
-
transition:
|
|
28
|
+
transition: opacity 0.25s ease;
|
|
29
|
+
opacity: var(--local-scrim-opacity);
|
|
31
30
|
z-index: 0;
|
|
32
|
-
background-color: var(--
|
|
31
|
+
background-color: var(--token-color-foreground-primary);
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
&:hover,
|
|
36
35
|
&:active {
|
|
37
|
-
--local-
|
|
38
|
-
--local-scrim-color: var(
|
|
39
|
-
--gh-stars-scrim-color
|
|
40
|
-
); /* from theme.module.css */
|
|
36
|
+
--local-scrim-opacity: 0.12;
|
|
41
37
|
}
|
|
42
38
|
}
|
|
43
39
|
|
|
@@ -3,19 +3,20 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import {
|
|
7
|
+
HDSPlusButton,
|
|
8
|
+
type HDSPlusButtonProps,
|
|
9
|
+
} from '@hashicorp/react-mds/src/hds-plus/button'
|
|
10
|
+
import FlightIcon from '@hashicorp/react-hds/src/components/flight-icon'
|
|
10
11
|
import type { Products } from '@hashicorp/platform-product-meta'
|
|
11
|
-
import type { ToggleButtonProps } from '@hashicorp/react-
|
|
12
|
-
import * as Dropdown from '@hashicorp/react-
|
|
12
|
+
import type { ToggleButtonProps } from '@hashicorp/react-hds/src/components/dropdown/toggle/button'
|
|
13
|
+
import * as Dropdown from '@hashicorp/react-hds/src/components/dropdown'
|
|
13
14
|
import GithubStarsLink from './github-stars-link'
|
|
14
15
|
import classNames from 'classnames'
|
|
15
16
|
import * as NavigationMenu from '@radix-ui/react-navigation-menu'
|
|
16
17
|
import s from './style.module.css'
|
|
17
18
|
|
|
18
|
-
type CtaLink =
|
|
19
|
+
type CtaLink = HDSPlusButtonProps & { href: string; __typename?: string }
|
|
19
20
|
|
|
20
21
|
type CtaDropdown = {
|
|
21
22
|
__typename?: string
|
|
@@ -83,7 +84,7 @@ function CtaLinks({
|
|
|
83
84
|
const isLastButton = stableIdx === links.length - 1
|
|
84
85
|
|
|
85
86
|
return (
|
|
86
|
-
<
|
|
87
|
+
<HDSPlusButton
|
|
87
88
|
key={href}
|
|
88
89
|
text={text}
|
|
89
90
|
href={href}
|
|
@@ -10,26 +10,26 @@
|
|
|
10
10
|
list-style: none;
|
|
11
11
|
padding: 0 0 0 var(--hdsplus-spacing-05);
|
|
12
12
|
margin: 0;
|
|
13
|
-
gap: 0
|
|
13
|
+
gap: 0 var(--hdsplus-spacing-04);
|
|
14
14
|
@media (--medium-up) {
|
|
15
15
|
gap: 0;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
& > * + * {
|
|
19
19
|
/* Spaces consecutive buttons horizontally on desktop */
|
|
20
|
-
margin-left:
|
|
20
|
+
margin-left: var(--hdsplus-spacing-05);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
&.isInDropdown {
|
|
24
24
|
/* Allows consecutive buttons to wrap */
|
|
25
25
|
flex-wrap: wrap;
|
|
26
26
|
white-space: wrap;
|
|
27
|
-
padding-
|
|
27
|
+
padding-inline: var(--hdsplus-spacing-04);
|
|
28
28
|
|
|
29
29
|
& > * {
|
|
30
30
|
/* Spaces consecutive buttons vertically */
|
|
31
31
|
margin-left: 0;
|
|
32
|
-
margin-top:
|
|
32
|
+
margin-top: var(--hdsplus-spacing-05);
|
|
33
33
|
|
|
34
34
|
&:last-of-type {
|
|
35
35
|
margin-bottom: var(--hdsplus-spacing-04);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import FlightIcon from '@hashicorp/react-
|
|
6
|
+
import FlightIcon from '@hashicorp/react-hds/src/components/flight-icon'
|
|
7
7
|
import NavItemText from '../nav-item-text'
|
|
8
8
|
import * as NavigationMenu from '@radix-ui/react-navigation-menu'
|
|
9
9
|
import s from './style.module.css'
|
|
@@ -27,7 +27,7 @@ function DropdownTrigger(props: DropdownTriggerProps) {
|
|
|
27
27
|
onMouseDown={(e) => e.preventDefault()}
|
|
28
28
|
>
|
|
29
29
|
<NavItemText isActive={isActive} text={text} />
|
|
30
|
-
<FlightIcon name="chevron-down"
|
|
30
|
+
<FlightIcon name="chevron-down" />
|
|
31
31
|
</NavigationMenu.Trigger>
|
|
32
32
|
)
|
|
33
33
|
}
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* Note: consumes from theme.module.css, as marked */
|
|
7
|
-
|
|
8
6
|
.root {
|
|
9
7
|
composes: hds-typography-body-200 from global;
|
|
10
8
|
composes: hds-font-weight-medium from global;
|
|
@@ -26,11 +24,16 @@
|
|
|
26
24
|
width: 12px;
|
|
27
25
|
height: 12px;
|
|
28
26
|
transition: transform 0.3s;
|
|
29
|
-
fill: var(--
|
|
27
|
+
fill: var(--token-color-foreground-primary);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
&:hover {
|
|
33
|
-
background-color: var(--
|
|
31
|
+
background-color: var(--token-color-surface-interactive-hover);
|
|
34
32
|
border-radius: var(--hdsplus-spacing-01);
|
|
35
33
|
}
|
|
34
|
+
|
|
35
|
+
&:focus {
|
|
36
|
+
outline: 2px solid var(--token-color-focus-action-internal);
|
|
37
|
+
outline-style: auto;
|
|
38
|
+
}
|
|
36
39
|
}
|
|
@@ -9,22 +9,30 @@ import NavItemText from '../nav-item-text'
|
|
|
9
9
|
import DropdownTrigger from '../DropdownTrigger'
|
|
10
10
|
import * as NavigationMenu from '@radix-ui/react-navigation-menu'
|
|
11
11
|
import s from './style.module.css'
|
|
12
|
+
import FlightIcon from '@hashicorp/react-hds/src/components/flight-icon'
|
|
13
|
+
import { getLocalizedHref } from '@web/utils/get-localized-href'
|
|
12
14
|
|
|
13
15
|
interface MenuItemsDefaultProps {
|
|
14
16
|
menuItems: (
|
|
15
17
|
| {
|
|
16
18
|
text: string
|
|
17
19
|
url: string
|
|
18
|
-
submenu: {
|
|
20
|
+
submenu: {
|
|
21
|
+
icon: string
|
|
22
|
+
text: string
|
|
23
|
+
url: string
|
|
24
|
+
_isActiveUrl: string
|
|
25
|
+
}[]
|
|
19
26
|
_isActiveUrl: boolean
|
|
20
27
|
}
|
|
21
28
|
| 'divider'
|
|
22
29
|
)[]
|
|
23
30
|
activatePanel: (panel: string) => void
|
|
31
|
+
locale?: string
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
function MenuItemsDefault(props: MenuItemsDefaultProps) {
|
|
27
|
-
const { menuItems, activatePanel } = props
|
|
35
|
+
const { menuItems, activatePanel, locale } = props
|
|
28
36
|
return (
|
|
29
37
|
<NavigationMenu.List className={s.root}>
|
|
30
38
|
{menuItems.map((menuItem, stableIdx) => {
|
|
@@ -41,6 +49,7 @@ function MenuItemsDefault(props: MenuItemsDefaultProps) {
|
|
|
41
49
|
text={text}
|
|
42
50
|
submenu={submenu}
|
|
43
51
|
activatePanel={activatePanel}
|
|
52
|
+
locale={locale}
|
|
44
53
|
/>
|
|
45
54
|
) : (
|
|
46
55
|
<NavLink
|
|
@@ -50,6 +59,7 @@ function MenuItemsDefault(props: MenuItemsDefaultProps) {
|
|
|
50
59
|
text={text}
|
|
51
60
|
url={url}
|
|
52
61
|
isActive={_isActiveUrl}
|
|
62
|
+
locale={locale}
|
|
53
63
|
/>
|
|
54
64
|
)
|
|
55
65
|
})}
|
|
@@ -69,14 +79,19 @@ interface NavLinkProps {
|
|
|
69
79
|
text: string
|
|
70
80
|
url: string
|
|
71
81
|
isActive: boolean
|
|
82
|
+
locale?: string
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
function NavLink(props: NavLinkProps) {
|
|
75
|
-
const { text, url, isActive } = props
|
|
86
|
+
const { text, url, isActive, locale } = props
|
|
76
87
|
return (
|
|
77
88
|
<NavigationMenu.Item className={s.listItem}>
|
|
78
89
|
<NavigationMenu.Link asChild>
|
|
79
|
-
<Link
|
|
90
|
+
<Link
|
|
91
|
+
className={s.navLink}
|
|
92
|
+
href={getLocalizedHref(url, locale)}
|
|
93
|
+
hrefLang={props.locale ? props.locale : undefined}
|
|
94
|
+
>
|
|
80
95
|
<NavItemText isActive={isActive} text={text} />
|
|
81
96
|
</Link>
|
|
82
97
|
</NavigationMenu.Link>
|
|
@@ -86,8 +101,9 @@ function NavLink(props: NavLinkProps) {
|
|
|
86
101
|
|
|
87
102
|
interface NavLinkWithDropdownProps {
|
|
88
103
|
text: string
|
|
89
|
-
submenu: { text: string; url: string; _isActiveUrl: string }[]
|
|
104
|
+
submenu: { icon: string; text: string; url: string; _isActiveUrl: string }[]
|
|
90
105
|
activatePanel: (panel: string) => void
|
|
106
|
+
locale?: string
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
interface NavLinkWithDropdownState {
|
|
@@ -99,7 +115,7 @@ class NavLinkWithDropdown extends React.Component<
|
|
|
99
115
|
NavLinkWithDropdownState
|
|
100
116
|
> {
|
|
101
117
|
render() {
|
|
102
|
-
const { text, submenu, activatePanel } = this.props
|
|
118
|
+
const { text, submenu, activatePanel, locale } = this.props
|
|
103
119
|
const hasActiveChild = submenu.some((s) => s._isActiveUrl)
|
|
104
120
|
|
|
105
121
|
const handleFocusOutside = () => {
|
|
@@ -128,12 +144,17 @@ class NavLinkWithDropdown extends React.Component<
|
|
|
128
144
|
<NavigationMenu.Sub>
|
|
129
145
|
<NavigationMenu.List className={s.dropdownList}>
|
|
130
146
|
{submenu.map((submenuItem, stableIdx) => {
|
|
131
|
-
const { text, url } = submenuItem
|
|
147
|
+
const { icon, text, url } = submenuItem
|
|
132
148
|
return (
|
|
133
149
|
// eslint-disable-next-line react/no-array-index-key
|
|
134
150
|
<NavigationMenu.Item key={stableIdx}>
|
|
135
151
|
<NavigationMenu.Link asChild>
|
|
136
|
-
<Link
|
|
152
|
+
<Link
|
|
153
|
+
className={s.submenuItem}
|
|
154
|
+
href={getLocalizedHref(url, locale)}
|
|
155
|
+
hrefLang={locale ? locale : undefined}
|
|
156
|
+
>
|
|
157
|
+
{icon ? <FlightIcon name={icon} /> : null}
|
|
137
158
|
{text}
|
|
138
159
|
</Link>
|
|
139
160
|
</NavigationMenu.Link>
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* Note: consumes from theme.module.css, as marked */
|
|
7
|
-
|
|
8
6
|
.root {
|
|
9
7
|
display: flex;
|
|
10
8
|
padding: 0 0 0 var(--hdsplus-spacing-08);
|
|
@@ -16,7 +14,6 @@
|
|
|
16
14
|
|
|
17
15
|
.listItem {
|
|
18
16
|
position: relative;
|
|
19
|
-
white-space: nowrap;
|
|
20
17
|
margin: 0;
|
|
21
18
|
padding: 0;
|
|
22
19
|
}
|
|
@@ -31,7 +28,7 @@
|
|
|
31
28
|
white-space: nowrap;
|
|
32
29
|
|
|
33
30
|
&:hover {
|
|
34
|
-
background-color: var(--
|
|
31
|
+
background-color: var(--token-color-surface-interactive-hover);
|
|
35
32
|
border-radius: var(--hdsplus-spacing-01);
|
|
36
33
|
}
|
|
37
34
|
|
|
@@ -42,43 +39,58 @@
|
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
.submenuItem {
|
|
42
|
+
--submenu-item-background-color: transparent;
|
|
43
|
+
|
|
44
|
+
position: relative;
|
|
45
45
|
composes: hds-typography-body-200 from global;
|
|
46
46
|
composes: hds-font-weight-medium from global;
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
color: var(--token-color-foreground-primary);
|
|
48
|
+
display: flex;
|
|
49
|
+
gap: var(--hdsplus-spacing-04);
|
|
50
|
+
padding: var(--hdsplus-spacing-03);
|
|
51
|
+
min-width: 190px;
|
|
52
|
+
align-items: center;
|
|
53
|
+
|
|
54
|
+
&::before {
|
|
55
|
+
content: "";
|
|
56
|
+
position: absolute;
|
|
57
|
+
z-index: -1;
|
|
58
|
+
inset: 2px 0;
|
|
59
|
+
border-radius: var(--hdsplus-spacing-01);
|
|
60
|
+
background-color: var(--submenu-item-background-color);
|
|
61
|
+
}
|
|
49
62
|
|
|
50
63
|
&:hover {
|
|
51
|
-
|
|
64
|
+
--submenu-item-background-color: var(--token-color-surface-interactive-hover);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@media (--large) {
|
|
68
|
+
max-width: 416px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&:focus {
|
|
72
|
+
outline: 2px solid var(--token-color-focus-action-internal);
|
|
73
|
+
outline-style: auto;
|
|
52
74
|
}
|
|
53
75
|
}
|
|
54
76
|
|
|
55
77
|
.submenuModal {
|
|
56
|
-
border-radius:
|
|
57
|
-
|
|
58
|
-
|
|
78
|
+
border-radius: var(--hdsplus-spacing-03);
|
|
79
|
+
border: 1px solid var(--token-color-border-primary);
|
|
80
|
+
box-shadow: var(--token-elevation-high-box-shadow);
|
|
81
|
+
background: var(--token-color-surface-primary);
|
|
59
82
|
z-index: 1;
|
|
60
|
-
display: block;
|
|
61
83
|
position: absolute;
|
|
62
84
|
top: 100%;
|
|
63
|
-
margin:
|
|
64
|
-
padding:
|
|
85
|
+
margin: var(--hdsplus-spacing-03) 0 0 0;
|
|
86
|
+
padding: var(--hdsplus-spacing-04);
|
|
65
87
|
left: 100%;
|
|
66
88
|
transform: translateX(-100%);
|
|
67
89
|
list-style: none;
|
|
68
|
-
|
|
69
|
-
& li {
|
|
70
|
-
& a:hover .text {
|
|
71
|
-
text-decoration: underline;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
& + li {
|
|
75
|
-
margin-top: 6px;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
90
|
}
|
|
79
91
|
|
|
80
92
|
.verticalDivider {
|
|
81
|
-
background: var(--border-
|
|
93
|
+
background: var(--token-color-border-primary);
|
|
82
94
|
height: 1.75rem;
|
|
83
95
|
width: 1px;
|
|
84
96
|
margin: 0 8px;
|
|
@@ -86,6 +98,7 @@
|
|
|
86
98
|
}
|
|
87
99
|
|
|
88
100
|
.dropdownList {
|
|
101
|
+
min-width: max-content;
|
|
89
102
|
list-style: none;
|
|
90
103
|
padding: 0;
|
|
91
104
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import React from 'react'
|
|
7
|
-
import {
|
|
7
|
+
import { vercelSplit } from '../../../../lib/v'
|
|
8
8
|
import Link from 'next/link'
|
|
9
9
|
import type { Products } from '@hashicorp/platform-product-meta'
|
|
10
10
|
import CtaLinks, { type CtaLinkProps } from '../CtaLinks'
|
|
@@ -12,6 +12,8 @@ import DropdownTrigger from '../DropdownTrigger'
|
|
|
12
12
|
import * as NavigationMenu from '@radix-ui/react-navigation-menu'
|
|
13
13
|
import classNames from 'classnames'
|
|
14
14
|
import s from './style.module.css'
|
|
15
|
+
import FlightIcon from '@hashicorp/react-hds/src/components/flight-icon'
|
|
16
|
+
import { getLocalizedHref } from '@web/utils/get-localized-href'
|
|
15
17
|
|
|
16
18
|
interface MenuItemsOverflowProps {
|
|
17
19
|
menuItems: (
|
|
@@ -19,7 +21,7 @@ interface MenuItemsOverflowProps {
|
|
|
19
21
|
| {
|
|
20
22
|
text: string
|
|
21
23
|
url: string
|
|
22
|
-
submenu: { url: string; text: string }[]
|
|
24
|
+
submenu: { icon: string; url: string; text: string }[]
|
|
23
25
|
}
|
|
24
26
|
)[]
|
|
25
27
|
ctaLinks: CtaLinkProps
|
|
@@ -28,6 +30,7 @@ interface MenuItemsOverflowProps {
|
|
|
28
30
|
menuText: string
|
|
29
31
|
constrainWidth?: boolean
|
|
30
32
|
activatePanel: (panel: string) => void
|
|
33
|
+
locale?: string
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
interface MenuItemsOverflowState {
|
|
@@ -47,6 +50,7 @@ class MenuItemsOverflow extends React.Component<
|
|
|
47
50
|
menuText,
|
|
48
51
|
constrainWidth,
|
|
49
52
|
activatePanel,
|
|
53
|
+
locale,
|
|
50
54
|
} = this.props
|
|
51
55
|
|
|
52
56
|
const handleFocusOutside = () => {
|
|
@@ -89,6 +93,8 @@ class MenuItemsOverflow extends React.Component<
|
|
|
89
93
|
key={subStableIdx}
|
|
90
94
|
url={subItem.url}
|
|
91
95
|
text={subItem.text}
|
|
96
|
+
icon={subItem.icon}
|
|
97
|
+
locale={locale}
|
|
92
98
|
/>
|
|
93
99
|
))}
|
|
94
100
|
<hr className={s.divider} />
|
|
@@ -120,15 +126,23 @@ class MenuItemsOverflow extends React.Component<
|
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
interface SubmenuItemProps {
|
|
129
|
+
icon?: string
|
|
123
130
|
url: string
|
|
124
131
|
text: string
|
|
132
|
+
locale?: string
|
|
125
133
|
}
|
|
126
134
|
|
|
127
|
-
function SubmenuItem({ url, text }: SubmenuItemProps) {
|
|
135
|
+
function SubmenuItem({ icon, url, text, locale }: SubmenuItemProps) {
|
|
128
136
|
return (
|
|
129
137
|
<li>
|
|
130
138
|
<NavigationMenu.Link asChild>
|
|
131
|
-
<Link
|
|
139
|
+
<Link
|
|
140
|
+
className={s.submenuItem}
|
|
141
|
+
href={getLocalizedHref(url, locale)}
|
|
142
|
+
title={vercelSplit(text)}
|
|
143
|
+
hrefLang={locale ? locale : undefined}
|
|
144
|
+
>
|
|
145
|
+
{icon ? <FlightIcon name={icon} /> : null}
|
|
132
146
|
{text}
|
|
133
147
|
</Link>
|
|
134
148
|
</NavigationMenu.Link>
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* Note: consumes from theme.module.css, as marked */
|
|
7
|
-
|
|
8
6
|
.root {
|
|
9
7
|
position: relative;
|
|
10
8
|
display: flex;
|
|
@@ -12,14 +10,14 @@
|
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
.dropdown {
|
|
15
|
-
background: var(--
|
|
16
|
-
border-radius:
|
|
13
|
+
background: var(--token-color-surface-primary);
|
|
14
|
+
border-radius: var(--hdsplus-spacing-03);
|
|
17
15
|
box-shadow: var(--token-elevation-high-box-shadow);
|
|
18
|
-
border: 1px solid var(--border-
|
|
16
|
+
border: 1px solid var(--token-color-border-primary);
|
|
19
17
|
margin-top: 8px;
|
|
20
18
|
max-height: calc(100vh - 300%);
|
|
21
19
|
overflow-y: auto;
|
|
22
|
-
padding: var(--hdsplus-spacing-04)
|
|
20
|
+
padding: var(--hdsplus-spacing-04);
|
|
23
21
|
position: absolute;
|
|
24
22
|
right: 0;
|
|
25
23
|
top: 100%;
|
|
@@ -52,27 +50,35 @@
|
|
|
52
50
|
|
|
53
51
|
.submenuTitle {
|
|
54
52
|
composes: g-type-label from global;
|
|
55
|
-
margin:
|
|
56
|
-
color: var(--
|
|
53
|
+
margin: var(--hdsplus-spacing-04) var(--hdsplus-spacing-03) 8px;
|
|
54
|
+
color: var(--token-color-foreground-faint);
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
.divider {
|
|
60
|
-
margin:
|
|
58
|
+
margin: var(--hdsplus-spacing-04) var(--hdsplus-spacing-03);
|
|
61
59
|
border: 0;
|
|
62
60
|
padding: 0;
|
|
63
61
|
height: 1px;
|
|
64
|
-
background: var(--border-
|
|
62
|
+
background: var(--token-color-border-primary);
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
.submenuItem {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
composes: hds-typography-body-300 from global;
|
|
67
|
+
composes: hds-font-weight-semibold from global;
|
|
68
|
+
display: flex;
|
|
69
|
+
gap: var(--hdsplus-spacing-04);
|
|
70
|
+
padding: var(--hdsplus-spacing-02) var(--hdsplus-spacing-03);
|
|
71
|
+
color: var(--token-color-foreground-primary);
|
|
72
|
+
border-radius: var(--hdsplus-spacing-01);
|
|
73
|
+
align-items: center;
|
|
73
74
|
|
|
74
75
|
&:hover {
|
|
75
|
-
|
|
76
|
+
background-color: var(--token-color-surface-interactive-hover);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&:focus {
|
|
80
|
+
outline: 2px solid var(--token-color-focus-action-internal);
|
|
81
|
+
outline-style: auto;
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
|
|
@@ -7,7 +7,7 @@ import { forwardRef } from 'react'
|
|
|
7
7
|
import { camelCase } from 'camel-case'
|
|
8
8
|
import Link from 'next/link'
|
|
9
9
|
import Image from 'next/image'
|
|
10
|
-
import {
|
|
10
|
+
import { vercelSplit } from '../../../../lib/v'
|
|
11
11
|
import classNames from 'classnames'
|
|
12
12
|
import * as CommunityProductLogosOnDark from './mktg-logos/all-community-product-logos_on-dark'
|
|
13
13
|
import * as CommunityProductLogosOnLight from './mktg-logos/all-community-product-logos_on-light'
|
|
@@ -41,6 +41,7 @@ const logoDict = {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
interface TitleLinkProps {
|
|
44
|
+
locale?: string
|
|
44
45
|
text: string
|
|
45
46
|
url: string
|
|
46
47
|
product?: string
|
|
@@ -80,8 +81,8 @@ function getLogo(
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
const TitleLink = forwardRef<HTMLAnchorElement, TitleLinkProps>(
|
|
83
|
-
({ text, url, product, theme }, ref) => {
|
|
84
|
-
const parsedText =
|
|
84
|
+
({ text, url, product, theme, locale }, ref) => {
|
|
85
|
+
const parsedText = vercelSplit(text)
|
|
85
86
|
const Logo = getLogo(parsedText, theme)
|
|
86
87
|
|
|
87
88
|
return (
|
|
@@ -94,6 +95,7 @@ const TitleLink = forwardRef<HTMLAnchorElement, TitleLinkProps>(
|
|
|
94
95
|
href={url}
|
|
95
96
|
title={parsedText}
|
|
96
97
|
ref={ref}
|
|
98
|
+
hrefLang={locale ? locale : undefined}
|
|
97
99
|
>
|
|
98
100
|
{Logo ? (
|
|
99
101
|
<Image
|
package/src/components/subnav/partials/TitleLink/mktg-logos/all-community-product-logos_on-dark.ts
CHANGED
|
@@ -5,5 +5,6 @@ import packer from '@hashicorp/web-mktg-logos/src/packer/packer-community/packer
|
|
|
5
5
|
import terraform from '@hashicorp/web-mktg-logos/src/terraform/terraform-community/terraform-community_on-dark.svg'
|
|
6
6
|
import vagrant from '@hashicorp/web-mktg-logos/src/vagrant/vagrant-community/vagrant-community_on-dark.svg'
|
|
7
7
|
import vault from '@hashicorp/web-mktg-logos/src/vault/vault-community/vault-community_on-dark.svg'
|
|
8
|
+
import waypoint from '@hashicorp/web-mktg-logos/src/waypoint/hashicorp-waypoint-attributed/hashicorp-waypoint_on-dark.svg'
|
|
8
9
|
|
|
9
|
-
export { boundary, consul, nomad, packer, terraform, vagrant, vault }
|
|
10
|
+
export { boundary, consul, nomad, packer, terraform, vagrant, vault, waypoint }
|