Skip to content

Commit 891ec26

Browse files
authored
Feature/config provider (#614)
* bump antd and typescript, and update build tools and components to work with new versions * consolidate ts.config * replace ant-vars.less with ConfigProvider * semantic color variables names for config provider * align css var colors and theme color variables, divide light and dark theme colors * consolidate theme variables * further consolidate theme variables * styled-components.dropdown menu items (#616) * use styled-component to streamline appearance of dropdown menu items * prevent ant from overridding text color during hover/focus on dropdown items * trim unneedd props from baseStyles on dropdown items * restructure colors and theming to provide for styled-components use of themeColors * remove unused nav button drop down item variety * don't open drop downs by default * remove unused imports * make selector more specific and remove !important tag * change focus to focus-visible in selectors and typing for styled-components theme * only export semantic and component colors from theme
1 parent 8cbde6c commit 891ec26

File tree

16 files changed

+1284
-732
lines changed

16 files changed

+1284
-732
lines changed

package-lock.json

Lines changed: 766 additions & 388 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@types/react-plotly.js": "^2.2.4",
4242
"@types/react-router-dom": "^5.1.5",
4343
"@types/sinon": "7.0.6",
44+
"@types/styled-components": "^5.1.34",
4445
"@types/uuid": "^9.0.7",
4546
"@typescript-eslint/eslint-plugin": "^5.42.1",
4647
"@typescript-eslint/parser": "^5.42.1",
@@ -97,8 +98,8 @@
9798
"dependencies": {
9899
"@aics/simularium-viewer": "^3.8.4",
99100
"@ant-design/css-animation": "^1.7.3",
100-
"@ant-design/icons": "^4.0.6",
101-
"antd": "^5.21.6",
101+
"@ant-design/icons": "^4.8.3",
102+
"antd": "^5.22.3",
102103
"axios": "^1.7.4",
103104
"bowser": "^2.11.0",
104105
"classnames": "2.2.5",
@@ -120,6 +121,7 @@
120121
"redux": "4.2.0",
121122
"redux-logic": "^3.0.3",
122123
"reselect": "4.0.0",
124+
"styled-components": "^6.1.13",
123125
"use-debounce": "^9.0.4",
124126
"uuid": "^9.0.1"
125127
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import React from "react";
2+
import { Link, LinkProps } from "react-router-dom";
3+
import styled, { css } from "styled-components";
4+
import { ArrowRight } from "../Icons";
5+
6+
// Dropdown items can be of a few component
7+
// varieties, including buttons, router links, and
8+
// anchor tags. This file unifies their styling,
9+
// and then divides them into three component exports
10+
// for semantically explicit usage in dropdowns.
11+
12+
// Common styles
13+
const baseStyles = css`
14+
font-family: ${(props) => props.theme.typography};
15+
background: none;
16+
border: 2px solid ${({ theme }) => theme.colors.dropdown.background};
17+
border-radius: 3px;
18+
color: ${({ theme }) => theme.colors.dropdown.text};
19+
cursor: pointer;
20+
height: 28px;
21+
padding: 6px;
22+
width: 100%;
23+
min-width: 177px;
24+
font-size: 14px;
25+
26+
&&& {
27+
&:focus-visible,
28+
&:focus-visible:hover {
29+
outline: 1.5px solid ${({ theme }) => theme.colors.dropdown.active};
30+
border: 2px solid ${({ theme }) => theme.colors.dropdown.background};
31+
color: ${({ theme }) => theme.colors.dropdown.activeTextColor};
32+
background-color: ${({ theme }) => theme.colors.dropdown.active};
33+
34+
svg {
35+
fill: ${({ theme }) => theme.colors.dropdown.background};
36+
}
37+
}
38+
39+
&:hover:not(:focus-visible) {
40+
background-color: ${({ theme }) => theme.colors.dropdown.active};
41+
color: ${({ theme }) => theme.colors.dropdown.activeTextColor};
42+
border-color: ${({ theme }) => theme.colors.dropdown.active};
43+
44+
svg {
45+
fill: ${({ theme }) => theme.colors.dropdown.background};
46+
}
47+
}
48+
}
49+
`;
50+
51+
const contentStyles = css`
52+
display: flex;
53+
align-items: center;
54+
gap: 8px;
55+
justify-content: space-between;
56+
color: inherit;
57+
58+
svg {
59+
font-size: 10px;
60+
}
61+
`;
62+
63+
// Styled components
64+
const StyledDropdownButton = styled.button`
65+
${baseStyles}
66+
${contentStyles}
67+
`;
68+
69+
const StyledRouterLink = styled(Link)`
70+
${baseStyles}
71+
${contentStyles}
72+
`;
73+
74+
const StyledExternalLink = styled.a`
75+
${baseStyles}
76+
${contentStyles}
77+
`;
78+
79+
// Typing for the props of each variant
80+
interface BaseDropdownItemProps {
81+
children: React.ReactNode;
82+
onClick?: () => void;
83+
className?: string;
84+
}
85+
86+
interface ButtonProps extends BaseDropdownItemProps {
87+
isSubmenuTrigger?: boolean;
88+
}
89+
90+
interface RouterProps extends BaseDropdownItemProps {
91+
to: LinkProps["to"];
92+
newTab?: boolean;
93+
}
94+
95+
interface AnchorProps extends Omit<BaseDropdownItemProps, "onClick"> {
96+
href: string;
97+
newTab?: boolean;
98+
}
99+
100+
const getNewTabAttributes = (newTab?: boolean) =>
101+
newTab ? { target: "_blank", rel: "noopener noreferrer" } : {};
102+
103+
// Components for use in dropdown menus:
104+
export const DropdownButton: React.FC<ButtonProps> = ({
105+
children,
106+
className,
107+
onClick,
108+
isSubmenuTrigger,
109+
}) => (
110+
<StyledDropdownButton type="button" onClick={onClick} className={className}>
111+
{children}
112+
{isSubmenuTrigger && ArrowRight}
113+
</StyledDropdownButton>
114+
);
115+
116+
export const DropdownRouterLink: React.FC<RouterProps> = ({
117+
children,
118+
className,
119+
to,
120+
newTab,
121+
}) => (
122+
<StyledRouterLink
123+
to={to}
124+
className={className}
125+
{...getNewTabAttributes(newTab)}
126+
>
127+
{children}
128+
</StyledRouterLink>
129+
);
130+
131+
export const DropdownAnchor: React.FC<AnchorProps> = ({
132+
children,
133+
className,
134+
href,
135+
newTab,
136+
}) => (
137+
<StyledExternalLink
138+
href={href}
139+
className={className}
140+
{...getNewTabAttributes(newTab)}
141+
>
142+
{children}
143+
</StyledExternalLink>
144+
);

src/components/CustomDropdown/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ const CustomDropdown: React.FC<CustomDropdownProps> = ({
2727
menu={{ items, theme: "dark", className: styles.menu }}
2828
placement={placement}
2929
disabled={disabled}
30+
dropdownRender={(menu) => (
31+
<div className={styles.menuWrapper}>{menu}</div>
32+
)}
3033
>
3134
<NavButton
3235
titleText={titleText}
Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,18 @@
1-
.menu {
1+
.menu-wrapper {
22
width: fit-content;
33
background-color: var(--dark-theme-dropdown-menu-bg);
44
border-radius: 3px;
5-
padding: 8px;
6-
}
7-
8-
.menu svg {
9-
fill: var(--dark-theme-menu-text-color);
5+
padding: 4px;
106
}
117

12-
.menu :global(.ant-dropdown-menu-item),
13-
.menu :global(.ant-dropdown-menu-submenu) {
14-
border: 2px solid var(--dark-theme-dropdown-menu-item-bg);
15-
border-radius: 4px;
16-
height: 32px;
8+
.menu {
9+
background-color: inherit;
10+
display: flex;
11+
flex-direction: column;
12+
gap: 4px;
1713
}
1814

19-
.menu :global(.ant-dropdown-menu-item) :global(.ant-btn) {
20-
color: var(--dark-theme-dropdown-menu-item-color);
15+
.menu-wrapper .menu :global(.ant-dropdown-menu-submenu-title),
16+
.menu-wrapper .menu :global(.ant-dropdown-menu-item-only-child) {
2117
padding: 0px;
2218
}
23-
24-
.menu :global(.ant-dropdown-menu-item):hover,
25-
.menu :global(.ant-dropdown-menu-submenu):hover {
26-
background-color: var(--dark-theme-dropdown-menu-item-hover-bg);
27-
}
28-
29-
.menu :global(.ant-dropdown-menu-item):hover *,
30-
.menu :global(.ant-dropdown-menu-submenu):hover * {
31-
color: var(--dark-theme-dropdown-menu-item-hover-color);
32-
fill: var(--dark-theme-dropdown-menu-item-hover-color);
33-
}
34-
35-
.menu :global(.ant-dropdown-menu-item):focus-within,
36-
.menu :global(.ant-dropdown-menu-submenu):focus-within {
37-
z-index: 1000;
38-
background-color: var(--dark-theme-dropdown-menu-item-focus-bg);
39-
outline: 1px solid var(--dark-theme-dropdown-menu-item-focus-outline);
40-
}
41-
42-
.menu :global(.ant-dropdown-menu-item) *:focus-visible {
43-
color: var(--dark-theme-dropdown-menu-item-focus-color);
44-
}

src/components/HelpMenu/index.tsx

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from "react";
2-
import { useLocation, Link } from "react-router-dom";
2+
import { useLocation } from "react-router-dom";
33
import { MenuProps } from "antd";
44

55
import { TUTORIAL_PATHNAME } from "../../routes";
@@ -12,24 +12,26 @@ import {
1212
import { ButtonClass } from "../../constants/interfaces";
1313
import { DownArrow } from "../Icons";
1414
import VersionModal from "../VersionModal";
15-
import NavButton from "../NavButton";
1615
import CustomDropdown from "../CustomDropdown";
16+
import {
17+
DropdownAnchor,
18+
DropdownButton,
19+
DropdownRouterLink,
20+
} from "../CustomDropdown/DropdownMenuItems";
1721

1822
const HelpMenu = (): JSX.Element => {
1923
const [modalVisible, setModalVisible] = React.useState(false);
2024

2125
const location = useLocation();
2226
const tutorialLink =
2327
location.pathname === "/viewer" ? (
24-
<Link
25-
to={TUTORIAL_PATHNAME}
26-
target="_blank"
27-
rel="noopener noreferrer"
28-
>
28+
<DropdownRouterLink to={TUTORIAL_PATHNAME} newTab={true}>
2929
Quick start
30-
</Link>
30+
</DropdownRouterLink>
3131
) : (
32-
<Link to={TUTORIAL_PATHNAME}>Quick start</Link>
32+
<DropdownRouterLink to={TUTORIAL_PATHNAME}>
33+
Quick start
34+
</DropdownRouterLink>
3335
);
3436

3537
const items: MenuProps["items"] = [
@@ -40,60 +42,53 @@ const HelpMenu = (): JSX.Element => {
4042
{
4143
key: "forum",
4244
label: (
43-
<a href={FORUM_URL} target="_blank" rel="noopener noreferrer">
45+
<DropdownAnchor href={FORUM_URL} newTab={true}>
4446
Forum
45-
</a>
47+
</DropdownAnchor>
4648
),
4749
},
4850
{
4951
key: "github",
5052
label: (
51-
<a href={GITHUB_URL} target="_blank" rel="noopener noreferrer">
53+
<DropdownAnchor href={GITHUB_URL} newTab={true}>
5254
GitHub
53-
</a>
55+
</DropdownAnchor>
5456
),
5557
},
5658
{
5759
key: "submit-issue",
58-
label: "Submit issue",
60+
label: (
61+
<DropdownButton isSubmenuTrigger={true}>
62+
Submit issue
63+
</DropdownButton>
64+
),
65+
expandIcon: false,
5966
popupOffset: [-0.45, -4],
6067
children: [
6168
{
6269
key: "via-github",
6370
label: (
64-
<a
65-
href={ISSUE_URL}
66-
target="_blank"
67-
rel="noopener noreferrer"
68-
>
71+
<DropdownAnchor href={ISSUE_URL}>
6972
via GitHub (preferred)
70-
</a>
73+
</DropdownAnchor>
7174
),
7275
},
7376
{
7477
key: "via-forum",
7578
label: (
76-
<a
77-
href={FORUM_BUG_REPORT_URL}
78-
target="_blank"
79-
rel="noopener noreferrer"
80-
>
79+
<DropdownAnchor href={FORUM_BUG_REPORT_URL}>
8180
via Forum (for non-GitHub users)
82-
</a>
81+
</DropdownAnchor>
8382
),
8483
},
8584
],
8685
},
8786
{
8887
key: "version",
8988
label: (
90-
<NavButton
91-
titleText={"Version info"}
92-
clickHandler={() => {
93-
setModalVisible(!modalVisible);
94-
}}
95-
buttonType={ButtonClass.DropdownItem}
96-
/>
89+
<DropdownButton onClick={() => setModalVisible(!modalVisible)}>
90+
Version info
91+
</DropdownButton>
9792
),
9893
},
9994
];

src/components/Icons/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
CaretDownFilled,
1919
FullscreenExitOutlined,
2020
FullscreenOutlined,
21+
RightOutlined,
2122
} from "@ant-design/icons";
2223

2324
import PurpleArrowPointingRight from "../../assets/open-arrow.svg";
@@ -57,6 +58,7 @@ export const DownCaret = (
5758
export const FilledCaret = <CaretDownFilled />;
5859
export const FullScreen = <FullscreenOutlined />;
5960
export const ExitFullScreen = <FullscreenExitOutlined />;
61+
export const ArrowRight = <RightOutlined />;
6062

6163
export default {
6264
Play,

0 commit comments

Comments
 (0)