-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
keyboard navigation: feature/focus states #589
Changes from 9 commits
d95f5f1
46b0ffd
6d3a4ff
0db3d98
13fb445
23f10a4
a5007c3
ee6cbe4
2c2ba63
5b67b81
6284eee
c2ac2a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React, { ReactNode } from "react"; | ||
import classNames from "classnames"; | ||
import { Dropdown, DropDownProps, MenuProps } from "antd"; | ||
import { ButtonClass } from "../../constants/interfaces"; | ||
import NavButton from "../NavButton"; | ||
|
||
import styles from "./style.css"; | ||
|
||
interface CustomDropdownProps { | ||
items: MenuProps["items"]; | ||
titleText: string; | ||
icon: ReactNode; | ||
buttonType: ButtonClass; | ||
placement?: DropDownProps["placement"]; | ||
disabled?: boolean; | ||
narrow?: boolean; | ||
} | ||
|
||
const CustomDropdown: React.FC<CustomDropdownProps> = ({ | ||
items, | ||
titleText, | ||
icon, | ||
buttonType, | ||
placement, | ||
disabled, | ||
narrow, | ||
}) => { | ||
const menuClassNames = narrow | ||
? classNames(styles.menu, styles.narrow) | ||
: styles.menu; | ||
return ( | ||
<Dropdown | ||
menu={{ items, theme: "dark", className: menuClassNames }} | ||
placement={placement} | ||
disabled={disabled} | ||
> | ||
<NavButton | ||
titleText={titleText} | ||
icon={icon} | ||
buttonType={buttonType} | ||
/> | ||
</Dropdown> | ||
); | ||
}; | ||
|
||
export default CustomDropdown; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
.menu { | ||
width: var(--dropdown-menu-width); | ||
background-color: var(--dark-theme-dropdown-menu-bg); | ||
border-radius: 3px; | ||
padding: 8px; | ||
} | ||
|
||
.menu.narrow { | ||
width: calc(var(--dropdown-menu-width) - 50px); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: This seems a little magic number-y, would it make more sense to either define a narrow width variable or make the width set by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Much better, thank you |
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file replaces the now deleted stylesheets for This was the only style difference between the two to manage for now. |
||
|
||
.menu svg { | ||
fill: var(--dark-theme-menu-text-color); | ||
} | ||
|
||
.menu :global(.ant-dropdown-menu-item), | ||
.menu :global(.ant-dropdown-menu-submenu) { | ||
border: 2px solid var(--dark-theme-dropdown-menu-item-bg); | ||
border-radius: 4px; | ||
height: 32px; | ||
} | ||
|
||
.menu :global(.ant-dropdown-menu-item) :global(.ant-btn) { | ||
color: var(--dark-theme-dropdown-menu-item-color); | ||
padding: 0px; | ||
} | ||
|
||
.menu :global(.ant-dropdown-menu-item):hover, | ||
.menu :global(.ant-dropdown-menu-submenu):hover { | ||
background-color: var(--dark-theme-dropdown-menu-item-hover-bg); | ||
} | ||
|
||
.menu :global(.ant-dropdown-menu-item):hover *, | ||
.menu :global(.ant-dropdown-menu-submenu):hover * { | ||
color: var(--dark-theme-dropdown-menu-item-hover-color); | ||
fill: var(--dark-theme-dropdown-menu-item-hover-color); | ||
} | ||
|
||
.menu :global(.ant-dropdown-menu-item):focus-within, | ||
.menu :global(.ant-dropdown-menu-submenu):focus-within { | ||
z-index: 1000; | ||
background-color: var(--dark-theme-dropdown-menu-item-focus-bg); | ||
outline: 1px solid var(--dark-theme-dropdown-menu-item-focus-outline); | ||
} | ||
|
||
.menu :global(.ant-dropdown-menu-item) *:focus { | ||
color: var(--dark-theme-dropdown-menu-item-focus-color); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import * as React from "react"; | ||
import { useLocation, Link } from "react-router-dom"; | ||
import { Dropdown, MenuProps } from "antd"; | ||
import { MenuProps } from "antd"; | ||
|
||
import { TUTORIAL_PATHNAME } from "../../routes"; | ||
import { | ||
|
@@ -13,8 +13,7 @@ import { ButtonClass } from "../../constants/interfaces"; | |
import { DownArrow } from "../Icons"; | ||
import VersionModal from "../VersionModal"; | ||
import NavButton from "../NavButton"; | ||
|
||
import styles from "./style.css"; | ||
import CustomDropdown from "../CustomDropdown"; | ||
|
||
const HelpMenu = (): JSX.Element => { | ||
const [modalVisible, setModalVisible] = React.useState(false); | ||
|
@@ -57,7 +56,6 @@ const HelpMenu = (): JSX.Element => { | |
{ | ||
key: "submit-issue", | ||
label: "Submit issue", | ||
popupClassName: styles.submenu, | ||
popupOffset: [-0.45, -4], | ||
children: [ | ||
{ | ||
|
@@ -89,26 +87,26 @@ const HelpMenu = (): JSX.Element => { | |
{ | ||
key: "version", | ||
label: ( | ||
<a | ||
onClick={() => { | ||
<NavButton | ||
titleText={"Version info"} | ||
clickHandler={() => { | ||
setModalVisible(!modalVisible); | ||
}} | ||
> | ||
Version info | ||
</a> | ||
buttonType={ButtonClass.DropdownItem} | ||
/> | ||
), | ||
}, | ||
]; | ||
|
||
return ( | ||
<> | ||
<Dropdown menu={{ items, theme: "dark", className: styles.menu }}> | ||
<NavButton | ||
titleText={"Help "} | ||
icon={DownArrow} | ||
buttonType={ButtonClass.Secondary} | ||
/> | ||
</Dropdown> | ||
<CustomDropdown | ||
items={items} | ||
titleText={"Help "} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we just remove that silly space instead. |
||
icon={DownArrow} | ||
buttonType={ButtonClass.Secondary} | ||
narrow={true} | ||
/> | ||
{modalVisible && <VersionModal setModalVisible={setModalVisible} />} | ||
</> | ||
); | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import React, { useState } from "react"; | ||
import { Link, useLocation, useHistory } from "react-router-dom"; | ||
import { ActionCreator } from "redux"; | ||
import { Dropdown, Button, MenuProps } from "antd"; | ||
import { MenuProps } from "antd"; | ||
|
||
import TRAJECTORIES from "../../constants/networked-trajectories"; | ||
import { URL_PARAM_KEY_FILE_NAME } from "../../constants"; | ||
|
@@ -21,8 +21,7 @@ import { VIEWER_PATHNAME } from "../../routes"; | |
import { DownArrow } from "../Icons"; | ||
import FileUploadModal from "../FileUploadModal"; | ||
import NavButton from "../NavButton"; | ||
|
||
import styles from "./style.css"; | ||
import CustomDropdown from "../CustomDropdown"; | ||
|
||
interface LoadFileMenuProps { | ||
isBuffering: boolean; | ||
|
@@ -73,7 +72,6 @@ const LoadFileMenu = ({ | |
{ | ||
key: "from-examples", | ||
label: "Example models", | ||
popupClassName: styles.submenu, | ||
popupOffset: [-0.45, -4], | ||
children: TRAJECTORIES.map((trajectory) => ({ | ||
key: trajectory.id, | ||
|
@@ -94,9 +92,11 @@ const LoadFileMenu = ({ | |
{ | ||
key: "file-upload", | ||
label: ( | ||
<Button type="ghost" onClick={showModal}> | ||
Simularium file | ||
</Button> | ||
<NavButton | ||
titleText={"Simularium file"} | ||
clickHandler={showModal} | ||
buttonType={ButtonClass.DropdownItem} | ||
/> | ||
), | ||
}, | ||
{ | ||
|
@@ -117,18 +117,14 @@ const LoadFileMenu = ({ | |
|
||
return ( | ||
<> | ||
<Dropdown | ||
menu={{ items, theme: "dark", className: styles.menu }} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we lose the dark theming here on the dropdown? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No we don't, although we are overriding most of it anyway. |
||
<CustomDropdown | ||
items={items} | ||
titleText={"Load model"} | ||
icon={DownArrow} | ||
buttonType={ButtonClass.Primary} | ||
placement="bottomRight" | ||
disabled={isDisabled} | ||
> | ||
<NavButton | ||
titleText={"Load model"} | ||
icon={DownArrow} | ||
buttonType={ButtonClass.Primary} | ||
isDisabled={isDisabled} | ||
/> | ||
</Dropdown> | ||
Comment on lines
-120
to
-131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Really like that the NavButton gets collapsed into Dropdown in all the instances here :') |
||
/> | ||
{/* | ||
Conditionally rendering the modal this way instead of as a `visible` prop | ||
forces it to re-render every time it is opened, resetting the form inside. | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,14 +6,18 @@ | |
background-color: var(--dark-theme-action-button-bg); | ||
border: none; | ||
color: var(--dark-theme-action-button-color); | ||
padding: 0px; | ||
padding: 4px 8px; | ||
} | ||
|
||
.nav-button.action-button:global(.ant-btn:hover), | ||
.nav-button.action-button:global(.ant-btn:focus) { | ||
.nav-button.action-button:global(.ant-btn:hover) { | ||
color: var(--dark-theme-action-button-hover-color); | ||
} | ||
|
||
.nav-button.action-button:global(.ant-btn:focus) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider changing the https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI: I updated the lines relevant to this PR , but not every place that |
||
color: var(--dark-theme-action-button-focus-color); | ||
outline: 1px solid var(--dark-theme-primary-button-focus-outline); | ||
} | ||
|
||
.nav-button.action-button:global(.ant-btn).disabled { | ||
color: var(--dark-theme-action-button-disabled-color); | ||
cursor: not-allowed; | ||
|
@@ -26,13 +30,20 @@ | |
color: var(--dark-theme-primary-button-color); | ||
} | ||
|
||
.nav-button.primary-button:global(.ant-btn:hover), | ||
.nav-button.primary-button:global(.ant-btn:focus) { | ||
.nav-button.primary-button:global(.ant-btn:hover) { | ||
color: var(--dark-theme-primary-button-hover-color); | ||
background-color: var(--dark-theme-primary-button-hover-bg); | ||
border-color: var(--dark-theme-primary-button-hover-border); | ||
} | ||
|
||
.nav-button.primary-button:global(.ant-btn:focus) { | ||
color: var(--dark-theme-primary-button-focus-color); | ||
background-color: var(--dark-theme-primary-button-focus-bg); | ||
border-color: var(--dark-theme-primary-button-focus-border); | ||
outline: 1px solid var(--dark-theme-primary-button-focus-outline); | ||
outline-offset: 2px; | ||
} | ||
|
||
.nav-button.primary-button:global(.ant-btn).disabled { | ||
color: var(--dark-theme-primary-button-disabled-color); | ||
background-color: var(--dark-theme-primary-button-disabled-bg); | ||
|
@@ -47,16 +58,28 @@ | |
color: var(--dark-theme-secondary-button-color); | ||
} | ||
|
||
.nav-button.secondary-button:global(.ant-btn:hover), | ||
.nav-button.secondary-button:global(.ant-btn:focus) { | ||
.nav-button.secondary-button:global(.ant-btn:hover) { | ||
color: var(--dark-theme-secondary-button-hover-color); | ||
background-color: var(--dark-theme-secondary-button-hover-bg); | ||
border-color: var(--dark-theme-secondary-button-hover-border); | ||
} | ||
|
||
.nav-button.secondary-button:global(.ant-btn:focus) { | ||
color: var(--dark-theme-secondary-button-focus-color); | ||
background-color: var(--dark-theme-secondary-button-focus-bg); | ||
border-color: var(--dark-theme-secondary-button-focus-border); | ||
outline: 1px solid var(--dark-theme-secondary-button-focus-outline); | ||
outline-offset: 2px; | ||
} | ||
|
||
.nav-button.secondary-button:global(.ant-btn).disabled { | ||
color: var(--dark-theme-secondary-button-disabled-color); | ||
background-color: var(--dark-theme-secondary-button-disabled-bg); | ||
border-color: var(--dark-theme-secondary-button-disabled-border); | ||
cursor: not-allowed; | ||
} | ||
|
||
.nav-button.dropdown-item-button:global(.ant-btn) { | ||
background-color: inherit; | ||
border: inherit; | ||
Comment on lines
+82
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In some cases we were using Using |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like our
CustomModal
andNavButton
this wrapper is mostly to DRY out the code, and will be a vehicle for code for things thatantd
doesn't provide but can be generalized to all dropdowns.