@windstream/react-shared-components 0.1.99 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contentful/index.esm.js +2 -2
- package/dist/contentful/index.esm.js.map +1 -1
- package/dist/contentful/index.js +2 -2
- package/dist/contentful/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/contentful/blocks/breadcrumbs/index.tsx +95 -95
- package/src/contentful/blocks/cards/floating-image-card/index.tsx +2 -2
- package/src/contentful/blocks/find-kinetic/index.tsx +147 -164
- package/src/contentful/blocks/navigation/desktop-link-groups.tsx/index.tsx +139 -139
- package/src/contentful/blocks/navigation/index.tsx +571 -571
- package/src/contentful/blocks/navigation/mobile-link-groups.tsx/index.tsx +82 -82
|
@@ -1,164 +1,147 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { FindKineticProps, ThemeKey } from "./types";
|
|
3
|
-
|
|
4
|
-
import { Link } from "@shared/components/link";
|
|
5
|
-
import { Text } from "@shared/components/text";
|
|
6
|
-
import { NextImage } from "@shared/next";
|
|
7
|
-
|
|
8
|
-
export const FindKinetic: React.FC<FindKineticProps> = ({
|
|
9
|
-
background = "white",
|
|
10
|
-
description,
|
|
11
|
-
enableHeading,
|
|
12
|
-
image,
|
|
13
|
-
list = [],
|
|
14
|
-
localPathPrefix = "/local",
|
|
15
|
-
subTitle,
|
|
16
|
-
title,
|
|
17
|
-
color = "dark",
|
|
18
|
-
maxWidth = true,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
})()}
|
|
149
|
-
</ul>
|
|
150
|
-
</>
|
|
151
|
-
)}
|
|
152
|
-
</div>
|
|
153
|
-
{image && (
|
|
154
|
-
<aside className="hidden md:block xl:flex-shrink-0">
|
|
155
|
-
<NextImage width={472} height={100} src={image} alt="image" />
|
|
156
|
-
</aside>
|
|
157
|
-
)}
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
);
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
export default FindKinetic;
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FindKineticProps, ThemeKey } from "./types";
|
|
3
|
+
|
|
4
|
+
import { Link } from "@shared/components/link";
|
|
5
|
+
import { Text } from "@shared/components/text";
|
|
6
|
+
import { NextImage } from "@shared/next";
|
|
7
|
+
|
|
8
|
+
export const FindKinetic: React.FC<FindKineticProps> = ({
|
|
9
|
+
background = "white",
|
|
10
|
+
description,
|
|
11
|
+
enableHeading,
|
|
12
|
+
image,
|
|
13
|
+
list = [],
|
|
14
|
+
localPathPrefix = "/local",
|
|
15
|
+
subTitle,
|
|
16
|
+
title,
|
|
17
|
+
color = "dark",
|
|
18
|
+
maxWidth = true,
|
|
19
|
+
}) => {
|
|
20
|
+
const bgColorClasses: Record<ThemeKey, string> = {
|
|
21
|
+
blue: "bg-[#07B2E2]",
|
|
22
|
+
green: "bg-[#26B170]",
|
|
23
|
+
yellow: "bg-[#F5FF1E]",
|
|
24
|
+
purple: "bg-[#931D69]",
|
|
25
|
+
white: "bg-white",
|
|
26
|
+
navy: "bg-[#00002D]",
|
|
27
|
+
};
|
|
28
|
+
const normalizedLocalPathPrefix = localPathPrefix
|
|
29
|
+
? `/${localPathPrefix.replace(/^\/+|\/+$/g, "")}`
|
|
30
|
+
: "";
|
|
31
|
+
|
|
32
|
+
const getLocationHref = (code: string) =>
|
|
33
|
+
`${normalizedLocalPathPrefix}/${code.toLowerCase()}`;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
className={`${bgColorClasses[background]} component-container overflow-hidden ${color == "dark" ? "text-text" : "text-white"}`}
|
|
38
|
+
>
|
|
39
|
+
<div
|
|
40
|
+
className={`${maxWidth ? "max-w-120 xl:mx-auto" : ""} mx-5 mb-5 ${image ? "mt-12" : "mt-0 xl:mt-0"} xl:my-20`}
|
|
41
|
+
>
|
|
42
|
+
{title && (
|
|
43
|
+
<Text
|
|
44
|
+
as={enableHeading ? "h1" : "h2"}
|
|
45
|
+
className="heading2 md:heading1 md:text-center"
|
|
46
|
+
>
|
|
47
|
+
{title}
|
|
48
|
+
</Text>
|
|
49
|
+
)}
|
|
50
|
+
{subTitle && (
|
|
51
|
+
<Text
|
|
52
|
+
as={enableHeading ? "h2" : "h3"}
|
|
53
|
+
className="subheading1 mt-4 md:text-center"
|
|
54
|
+
>
|
|
55
|
+
{subTitle}
|
|
56
|
+
</Text>
|
|
57
|
+
)}
|
|
58
|
+
|
|
59
|
+
<div
|
|
60
|
+
className={`mt-8 flex flex-col items-center xl:flex-row ${image ? "xl:mt-16" : "xl:mt-10"} gap-10`}
|
|
61
|
+
>
|
|
62
|
+
<div
|
|
63
|
+
className={`flex flex-col ${image ? "items:center xl:items-start" : "items-center"} gap-10 self-stretch xl:flex-[1_0_0]`}
|
|
64
|
+
>
|
|
65
|
+
{description && (
|
|
66
|
+
<Text as="p" className="body1">
|
|
67
|
+
{description}
|
|
68
|
+
</Text>
|
|
69
|
+
)}
|
|
70
|
+
{list.length > 0 && (
|
|
71
|
+
<>
|
|
72
|
+
<ul className="grid w-full grid-cols-2 gap-x-6 gap-y-5 md:hidden">
|
|
73
|
+
{(() => {
|
|
74
|
+
const sortedList = [...list].sort((a, b) =>
|
|
75
|
+
a.name.localeCompare(b.name)
|
|
76
|
+
);
|
|
77
|
+
const numColumns = 2;
|
|
78
|
+
const numRows = Math.ceil(sortedList.length / numColumns);
|
|
79
|
+
const rearranged = [];
|
|
80
|
+
for (let row = 0; row < numRows; row++) {
|
|
81
|
+
for (let col = 0; col < numColumns; col++) {
|
|
82
|
+
const index = col * numRows + row;
|
|
83
|
+
if (index < sortedList.length) {
|
|
84
|
+
rearranged.push(sortedList[index]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return rearranged.map((item, index: number) => (
|
|
89
|
+
<li key={`item-list-2-${index}`}>
|
|
90
|
+
<Link
|
|
91
|
+
href={getLocationHref(item.code)}
|
|
92
|
+
className="label1"
|
|
93
|
+
>
|
|
94
|
+
{item.name}
|
|
95
|
+
</Link>
|
|
96
|
+
</li>
|
|
97
|
+
));
|
|
98
|
+
})()}
|
|
99
|
+
</ul>
|
|
100
|
+
<ul
|
|
101
|
+
className={`hidden ${image ? "gap-x-6" : "gap-x-20"} gap-y-5 md:grid ${image ? "md:grid-cols-3" : "md:grid-cols-4"}`}
|
|
102
|
+
>
|
|
103
|
+
{(() => {
|
|
104
|
+
const sortedList = [...list].sort((a, b) =>
|
|
105
|
+
a.name.localeCompare(b.name)
|
|
106
|
+
);
|
|
107
|
+
const numColumns = 3;
|
|
108
|
+
const numRows = Math.ceil(sortedList.length / numColumns);
|
|
109
|
+
const rearranged = [];
|
|
110
|
+
for (let row = 0; row < numRows; row++) {
|
|
111
|
+
for (let col = 0; col < numColumns; col++) {
|
|
112
|
+
const index = col * numRows + row;
|
|
113
|
+
if (index < sortedList.length) {
|
|
114
|
+
rearranged.push(sortedList[index]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return rearranged.map((item, index: number) => (
|
|
119
|
+
<li
|
|
120
|
+
key={`item-list-3-${index}`}
|
|
121
|
+
className={`${image ? "" : "w-[172px]"}`}
|
|
122
|
+
>
|
|
123
|
+
<Link
|
|
124
|
+
href={getLocationHref(item.code)}
|
|
125
|
+
className="label1"
|
|
126
|
+
>
|
|
127
|
+
{item.name}
|
|
128
|
+
</Link>
|
|
129
|
+
</li>
|
|
130
|
+
));
|
|
131
|
+
})()}
|
|
132
|
+
</ul>
|
|
133
|
+
</>
|
|
134
|
+
)}
|
|
135
|
+
</div>
|
|
136
|
+
{image && (
|
|
137
|
+
<aside className="hidden md:block">
|
|
138
|
+
<NextImage width={472} height={100} src={image} alt="image" />
|
|
139
|
+
</aside>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export default FindKinetic;
|
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
import React, { CSSProperties } from "react";
|
|
2
|
-
|
|
3
|
-
import { MaterialIcon } from "@shared/components/material-icon";
|
|
4
|
-
import { Text } from "@shared/components/text";
|
|
5
|
-
import { Button } from "@shared/contentful/blocks/button";
|
|
6
|
-
import { ButtonProps as ContentfulButtonProps } from "@shared/contentful/blocks/button/types";
|
|
7
|
-
import { useOutsideClick } from "@shared/hooks/use-outside-click";
|
|
8
|
-
import { cx } from "@shared/utils";
|
|
9
|
-
|
|
10
|
-
type ComponentButtonGroup = {
|
|
11
|
-
anchorId?: string | null;
|
|
12
|
-
title?: string | null;
|
|
13
|
-
items?: { items?: ContentfulButtonProps[] | null } | null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
type Link = ContentfulButtonProps | ComponentButtonGroup;
|
|
17
|
-
|
|
18
|
-
type LinkGroupsProps = {
|
|
19
|
-
link?: Link;
|
|
20
|
-
anchorName: string;
|
|
21
|
-
/**
|
|
22
|
-
* Tailwind text-color class to apply to the top-level link/group
|
|
23
|
-
* label. Lets the parent navbar invert text color (e.g. `text-white`)
|
|
24
|
-
* when rendered on a dark background. Submenu items keep their
|
|
25
|
-
* default `text-text-link` so they remain readable on the white
|
|
26
|
-
* popover background.
|
|
27
|
-
*/
|
|
28
|
-
linkColorClassName?: string;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const isButton = (link: Link): link is ContentfulButtonProps => {
|
|
32
|
-
// If your group never has `href`, this is a simple and effective guard
|
|
33
|
-
return typeof (link as ContentfulButtonProps).href === "string";
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const DesktopLinkGroups: React.FC<LinkGroupsProps> = ({
|
|
37
|
-
link,
|
|
38
|
-
anchorName,
|
|
39
|
-
linkColorClassName,
|
|
40
|
-
}) => {
|
|
41
|
-
const [isOpen, setIsOpen] = React.useState(false);
|
|
42
|
-
|
|
43
|
-
const ref = React.useRef<HTMLDivElement>(null);
|
|
44
|
-
useOutsideClick(ref, () => setIsOpen(false));
|
|
45
|
-
|
|
46
|
-
if (!link) return null;
|
|
47
|
-
|
|
48
|
-
// Single button
|
|
49
|
-
if (isButton(link)) {
|
|
50
|
-
return (
|
|
51
|
-
<Button
|
|
52
|
-
key={`submenu-link-btn-${link.anchorId}`}
|
|
53
|
-
{...link}
|
|
54
|
-
linkClassName={cx(
|
|
55
|
-
"body3 flex items-center h-full",
|
|
56
|
-
linkColorClassName || "text-text"
|
|
57
|
-
)}
|
|
58
|
-
linkVariant="unstyled"
|
|
59
|
-
/>
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Group
|
|
64
|
-
const { anchorId, title, items } = link;
|
|
65
|
-
const subMenu = Array.isArray(items?.items) ? items!.items! : [];
|
|
66
|
-
const fullAnchorName = `--link-anchor-${anchorName}`;
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<div
|
|
70
|
-
className="relative h-full"
|
|
71
|
-
style={{ anchorName: fullAnchorName } as CSSProperties}
|
|
72
|
-
ref={ref}
|
|
73
|
-
>
|
|
74
|
-
<Button
|
|
75
|
-
onClick={() => setIsOpen(prev => !prev)}
|
|
76
|
-
aria-expanded={isOpen}
|
|
77
|
-
buttonClassName={cx(
|
|
78
|
-
"group body3 flex items-center h-full",
|
|
79
|
-
linkColorClassName || "text-text"
|
|
80
|
-
)}
|
|
81
|
-
key={anchorId}
|
|
82
|
-
showButtonAs="unstyled"
|
|
83
|
-
>
|
|
84
|
-
<Text as="span" className="group-hover:underline">
|
|
85
|
-
{title ?? null}
|
|
86
|
-
</Text>
|
|
87
|
-
<MaterialIcon
|
|
88
|
-
weight="200"
|
|
89
|
-
size={24}
|
|
90
|
-
className="group-hover:opacity-50 text-icon-secondary"
|
|
91
|
-
name={isOpen ? "keyboard_arrow_up" : "keyboard_arrow_down"}
|
|
92
|
-
/>
|
|
93
|
-
</Button>
|
|
94
|
-
|
|
95
|
-
<div
|
|
96
|
-
className={cx(
|
|
97
|
-
"shadow-navDrop fixed z-[1001] min-w-44 rounded-input-poppers border border-border bg-bg",
|
|
98
|
-
"transition-[opacity,transform] ease-out",
|
|
99
|
-
isOpen && subMenu.length > 0
|
|
100
|
-
? "pointer-events-auto translate-y-0 opacity-100 duration-75"
|
|
101
|
-
: "pointer-events-none -translate-y-2 opacity-0 duration-0"
|
|
102
|
-
)}
|
|
103
|
-
style={
|
|
104
|
-
{
|
|
105
|
-
positionAnchor: fullAnchorName,
|
|
106
|
-
top: "anchor(bottom)",
|
|
107
|
-
left: "calc((anchor(left) + anchor(right)) / 2)",
|
|
108
|
-
translate: "-50% 0",
|
|
109
|
-
} as CSSProperties
|
|
110
|
-
}
|
|
111
|
-
>
|
|
112
|
-
<ul
|
|
113
|
-
className="flex flex-col gap-2 py-2"
|
|
114
|
-
onClick={event => {
|
|
115
|
-
// Close the popup when a submenu link is clicked.
|
|
116
|
-
// Required for Pages Router where this component persists across
|
|
117
|
-
// client-side navigations and `isOpen` would otherwise stay true.
|
|
118
|
-
const target = event.target as HTMLElement | null;
|
|
119
|
-
if (target?.closest("a")) {
|
|
120
|
-
setIsOpen(false);
|
|
121
|
-
}
|
|
122
|
-
}}
|
|
123
|
-
>
|
|
124
|
-
{subMenu.map((site, index) => {
|
|
125
|
-
return (
|
|
126
|
-
<li key={`submenu-link-${index}`} className="submenu-link type1">
|
|
127
|
-
<Button
|
|
128
|
-
{...site}
|
|
129
|
-
linkVariant="unstyled"
|
|
130
|
-
linkClassName="body3 px-4 hover:bg-bg-surface-hover flex items-center w-full h-11 text-text-link"
|
|
131
|
-
/>
|
|
132
|
-
</li>
|
|
133
|
-
);
|
|
134
|
-
})}
|
|
135
|
-
</ul>
|
|
136
|
-
</div>
|
|
137
|
-
</div>
|
|
138
|
-
);
|
|
139
|
-
};
|
|
1
|
+
import React, { CSSProperties } from "react";
|
|
2
|
+
|
|
3
|
+
import { MaterialIcon } from "@shared/components/material-icon";
|
|
4
|
+
import { Text } from "@shared/components/text";
|
|
5
|
+
import { Button } from "@shared/contentful/blocks/button";
|
|
6
|
+
import { ButtonProps as ContentfulButtonProps } from "@shared/contentful/blocks/button/types";
|
|
7
|
+
import { useOutsideClick } from "@shared/hooks/use-outside-click";
|
|
8
|
+
import { cx } from "@shared/utils";
|
|
9
|
+
|
|
10
|
+
type ComponentButtonGroup = {
|
|
11
|
+
anchorId?: string | null;
|
|
12
|
+
title?: string | null;
|
|
13
|
+
items?: { items?: ContentfulButtonProps[] | null } | null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
type Link = ContentfulButtonProps | ComponentButtonGroup;
|
|
17
|
+
|
|
18
|
+
type LinkGroupsProps = {
|
|
19
|
+
link?: Link;
|
|
20
|
+
anchorName: string;
|
|
21
|
+
/**
|
|
22
|
+
* Tailwind text-color class to apply to the top-level link/group
|
|
23
|
+
* label. Lets the parent navbar invert text color (e.g. `text-white`)
|
|
24
|
+
* when rendered on a dark background. Submenu items keep their
|
|
25
|
+
* default `text-text-link` so they remain readable on the white
|
|
26
|
+
* popover background.
|
|
27
|
+
*/
|
|
28
|
+
linkColorClassName?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const isButton = (link: Link): link is ContentfulButtonProps => {
|
|
32
|
+
// If your group never has `href`, this is a simple and effective guard
|
|
33
|
+
return typeof (link as ContentfulButtonProps).href === "string";
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const DesktopLinkGroups: React.FC<LinkGroupsProps> = ({
|
|
37
|
+
link,
|
|
38
|
+
anchorName,
|
|
39
|
+
linkColorClassName,
|
|
40
|
+
}) => {
|
|
41
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
42
|
+
|
|
43
|
+
const ref = React.useRef<HTMLDivElement>(null);
|
|
44
|
+
useOutsideClick(ref, () => setIsOpen(false));
|
|
45
|
+
|
|
46
|
+
if (!link) return null;
|
|
47
|
+
|
|
48
|
+
// Single button
|
|
49
|
+
if (isButton(link)) {
|
|
50
|
+
return (
|
|
51
|
+
<Button
|
|
52
|
+
key={`submenu-link-btn-${link.anchorId}`}
|
|
53
|
+
{...link}
|
|
54
|
+
linkClassName={cx(
|
|
55
|
+
"body3 flex items-center h-full",
|
|
56
|
+
linkColorClassName || "text-text"
|
|
57
|
+
)}
|
|
58
|
+
linkVariant="unstyled"
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Group
|
|
64
|
+
const { anchorId, title, items } = link;
|
|
65
|
+
const subMenu = Array.isArray(items?.items) ? items!.items! : [];
|
|
66
|
+
const fullAnchorName = `--link-anchor-${anchorName}`;
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
className="relative h-full"
|
|
71
|
+
style={{ anchorName: fullAnchorName } as CSSProperties}
|
|
72
|
+
ref={ref}
|
|
73
|
+
>
|
|
74
|
+
<Button
|
|
75
|
+
onClick={() => setIsOpen(prev => !prev)}
|
|
76
|
+
aria-expanded={isOpen}
|
|
77
|
+
buttonClassName={cx(
|
|
78
|
+
"group body3 flex items-center h-full",
|
|
79
|
+
linkColorClassName || "text-text"
|
|
80
|
+
)}
|
|
81
|
+
key={anchorId}
|
|
82
|
+
showButtonAs="unstyled"
|
|
83
|
+
>
|
|
84
|
+
<Text as="span" className="group-hover:underline">
|
|
85
|
+
{title ?? null}
|
|
86
|
+
</Text>
|
|
87
|
+
<MaterialIcon
|
|
88
|
+
weight="200"
|
|
89
|
+
size={24}
|
|
90
|
+
className="group-hover:opacity-50 text-icon-secondary"
|
|
91
|
+
name={isOpen ? "keyboard_arrow_up" : "keyboard_arrow_down"}
|
|
92
|
+
/>
|
|
93
|
+
</Button>
|
|
94
|
+
|
|
95
|
+
<div
|
|
96
|
+
className={cx(
|
|
97
|
+
"shadow-navDrop fixed z-[1001] min-w-44 rounded-input-poppers border border-border bg-bg",
|
|
98
|
+
"transition-[opacity,transform] ease-out",
|
|
99
|
+
isOpen && subMenu.length > 0
|
|
100
|
+
? "pointer-events-auto translate-y-0 opacity-100 duration-75"
|
|
101
|
+
: "pointer-events-none -translate-y-2 opacity-0 duration-0"
|
|
102
|
+
)}
|
|
103
|
+
style={
|
|
104
|
+
{
|
|
105
|
+
positionAnchor: fullAnchorName,
|
|
106
|
+
top: "anchor(bottom)",
|
|
107
|
+
left: "calc((anchor(left) + anchor(right)) / 2)",
|
|
108
|
+
translate: "-50% 0",
|
|
109
|
+
} as CSSProperties
|
|
110
|
+
}
|
|
111
|
+
>
|
|
112
|
+
<ul
|
|
113
|
+
className="flex flex-col gap-2 py-2"
|
|
114
|
+
onClick={event => {
|
|
115
|
+
// Close the popup when a submenu link is clicked.
|
|
116
|
+
// Required for Pages Router where this component persists across
|
|
117
|
+
// client-side navigations and `isOpen` would otherwise stay true.
|
|
118
|
+
const target = event.target as HTMLElement | null;
|
|
119
|
+
if (target?.closest("a")) {
|
|
120
|
+
setIsOpen(false);
|
|
121
|
+
}
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
{subMenu.map((site, index) => {
|
|
125
|
+
return (
|
|
126
|
+
<li key={`submenu-link-${index}`} className="submenu-link type1">
|
|
127
|
+
<Button
|
|
128
|
+
{...site}
|
|
129
|
+
linkVariant="unstyled"
|
|
130
|
+
linkClassName="body3 px-4 hover:bg-bg-surface-hover flex items-center w-full h-11 text-text-link"
|
|
131
|
+
/>
|
|
132
|
+
</li>
|
|
133
|
+
);
|
|
134
|
+
})}
|
|
135
|
+
</ul>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
};
|