Make all UI tabs accessible via keyboard (#9518)

feature/default_network_editable
David Walsh 4 years ago committed by GitHub
parent f5265c24ab
commit cfbcc12398
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      test/e2e/metamask-ui.spec.js
  2. 14
      ui/app/components/app/asset-list-item/asset-list-item.js
  3. 25
      ui/app/components/app/asset-list-item/asset-list-item.scss
  4. 6
      ui/app/components/app/confirm-page-container/confirm-page-container-content/index.scss
  5. 11
      ui/app/components/app/gas-customization/gas-modal-page-container/index.scss
  6. 2
      ui/app/components/app/selected-account/index.scss
  7. 4
      ui/app/components/app/selected-account/selected-account.component.js
  8. 2
      ui/app/components/app/tab-bar/index.scss
  9. 4
      ui/app/components/app/tab-bar/tab-bar.js
  10. 9
      ui/app/components/ui/list-item/index.scss
  11. 4
      ui/app/components/ui/list-item/list-item.component.js
  12. 15
      ui/app/components/ui/tabs/tab/index.scss
  13. 2
      ui/app/components/ui/tabs/tab/tab.component.js
  14. 3
      ui/app/pages/add-token/token-list/index.scss
  15. 8
      ui/app/pages/add-token/token-list/token-list.component.js
  16. 5
      ui/app/pages/home/index.scss

@ -846,7 +846,7 @@ describe('MetaMask', function () {
})
it('displays the contract creation data', async function () {
await driver.clickElement(By.xpath(`//li[contains(text(), 'Data')]`))
await driver.clickElement(By.xpath(`//button[contains(text(), 'Data')]`))
await driver.delay(regularDelayMs)
await driver.findElement(By.xpath(`//div[contains(text(), '127.0.0.1')]`))
@ -860,7 +860,9 @@ describe('MetaMask', function () {
assert.ok(confirmDataText.includes('Bytes:'))
assert.ok(confirmDataText.includes('675'))
await driver.clickElement(By.xpath(`//li[contains(text(), 'Details')]`))
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Details')]`),
)
await driver.delay(regularDelayMs)
})
@ -1055,7 +1057,9 @@ describe('MetaMask', function () {
)
await driver.delay(regularDelayMs)
await driver.clickElement(By.xpath(`//li[contains(text(), 'Advanced')]`))
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Advanced')]`),
)
await driver.delay(tinyDelayMs)
const [gasPriceInput, gasLimitInput] = await driver.findElements(
@ -1098,7 +1102,7 @@ describe('MetaMask', function () {
it('picks the newly created Test token', async function () {
await driver.clickElement(
By.xpath("//li[contains(text(), 'Custom Token')]"),
By.xpath("//button[contains(text(), 'Custom Token')]"),
)
await driver.delay(regularDelayMs)
@ -1165,7 +1169,7 @@ describe('MetaMask', function () {
})
it('displays the token transfer data', async function () {
await driver.clickElement(By.xpath(`//li[contains(text(), 'Data')]`))
await driver.clickElement(By.xpath(`//button[contains(text(), 'Data')]`))
await driver.delay(regularDelayMs)
const functionType = await driver.findElement(
@ -1192,7 +1196,9 @@ describe('MetaMask', function () {
),
)
await driver.clickElement(By.xpath(`//li[contains(text(), 'Details')]`))
await driver.clickElement(
By.xpath(`//button[contains(text(), 'Details')]`),
)
await driver.delay(regularDelayMs)
})

@ -93,10 +93,16 @@ const AssetListItem = ({
className={classnames('asset-list-item', className)}
data-testid={dataTestId}
title={
<>
<h2 className="asset-list-item__token-value">{primary}</h2>
<h2 className="asset-list-item__token-symbol">{tokenSymbol}</h2>
</>
<button
className="asset-list-item__token-button"
onClick={onClick}
title={`${primary} ${tokenSymbol || ''}`}
>
<h2>
<span className="asset-list-item__token-value">{primary}</span>
<span className="asset-list-item__token-symbol">{tokenSymbol}</span>
</h2>
</button>
}
titleIcon={titleIcon}
subtitle={<h3 title={secondary}>{secondary}</h3>}

@ -1,9 +1,24 @@
.asset-list-item {
&__token-value {
padding: 0 5px 0 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
& .list-item__heading {
max-width: 100%;
}
&__token-button {
padding-inline-start: 0;
min-width: 0;
min-height: 0;
text-align: start;
& h2 {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 100%;
}
& span {
padding-right: 5px;
}
}
&__chevron-right {

@ -77,6 +77,12 @@
color: #8c8e94;
text-transform: uppercase;
margin: 0 8px;
& button {
font-size: unset;
color: #8c8e94;
text-transform: uppercase;
}
}
.page-container__footer {

@ -57,6 +57,10 @@
display: none;
}
&__tab {
margin-right: 0;
}
&__tabs {
margin-top: 0;
}
@ -70,9 +74,12 @@
margin-right: 0;
}
&--selected {
& button {
font-size: unset;
}
&.tab--active button {
color: $primary-blue;
border-bottom: 2px solid $primary-blue;
}
}
}

@ -37,6 +37,8 @@
padding: 6px 1px;
border-radius: 10px;
cursor: pointer;
width: 100%;
background-color: unset;
&:hover {
background-color: $Grey-000;

@ -43,7 +43,7 @@ class SelectedAccount extends Component {
this.state.copied ? t('copiedExclamation') : t('copyToClipboard')
}
>
<div
<button
className="selected-account__clickable"
onClick={() => {
this.setState({ copied: true })
@ -60,7 +60,7 @@ class SelectedAccount extends Component {
<div className="selected-account__address">
{shortenAddress(checksummedAddress)}
</div>
</div>
</button>
</Tooltip>
</div>
)

@ -16,6 +16,8 @@
padding: 16px 24px;
opacity: 0.5;
transition: opacity 200ms ease-in-out;
background-color: unset;
text-align: start;
@media screen and (min-width: 576px) {
&:hover {

@ -8,7 +8,7 @@ const TabBar = (props) => {
return (
<div className="tab-bar">
{tabs.map(({ key, content, description }) => (
<div
<button
key={key}
className={classnames('tab-bar__tab pointer', {
'tab-bar__tab--active': isActive(key, content),
@ -22,7 +22,7 @@ const TabBar = (props) => {
</div>
</div>
<div className="tab-bar__tab__caret" />
</div>
</button>
))}
</div>
)

@ -19,7 +19,8 @@
align-items: start;
cursor: pointer;
&:hover {
&:hover,
&:focus-within {
background-color: $Grey-000;
}
@ -44,6 +45,12 @@
display: flex;
align-items: center;
& button {
background: unset;
font-size: unset;
padding-inline-start: 0;
}
&-wrap {
display: inline-block;
margin-left: 8px;

@ -27,7 +27,9 @@ export default function ListItem({
{React.isValidElement(title) ? (
title
) : (
<h2 className="list-item__title">{title}</h2>
<button onClick={onClick}>
<h2 className="list-item__title">{title}</h2>
</button>
)}
{titleIcon && (
<div className="list-item__heading-wrap">{titleIcon}</div>

@ -1,8 +1,15 @@
.tab {
cursor: pointer;
padding: 8px;
min-width: 50px;
text-align: center;
button {
cursor: pointer;
padding: 8px;
min-width: 50px;
text-align: center;
display: block;
width: 100%;
background-color: unset;
font-size: unset;
color: unset;
}
&--active {
color: $black;

@ -25,7 +25,7 @@ const Tab = (props) => {
onClick(tabIndex)
}}
>
{name}
<button>{name}</button>
</li>
)
}

@ -23,7 +23,8 @@
border: 1px solid transparent;
position: relative;
&:hover {
&:hover,
&:focus {
border-color: rgba($malibu-blue, 0.5);
}

@ -37,6 +37,8 @@ export default class InfoBox extends Component {
.map((_, i) => {
const { logo, symbol, name, address } = results[i] || {}
const tokenAlreadyAdded = checkExistingAddresses(address, tokens)
const onClick = () =>
!tokenAlreadyAdded && onToggleToken(results[i])
return (
Boolean(logo || symbol || name) && (
@ -45,10 +47,10 @@ export default class InfoBox extends Component {
'token-list__token--selected': selectedTokens[address],
'token-list__token--disabled': tokenAlreadyAdded,
})}
onClick={() =>
!tokenAlreadyAdded && onToggleToken(results[i])
}
onClick={onClick}
onKeyPress={(event) => event.key === 'Enter' && onClick()}
key={i}
tabIndex="0"
>
<div
className="token-list__token-icon"

@ -31,7 +31,6 @@
flex-grow: 1;
color: $Grey-500;
padding: 16px 8px;
font-weight: 500;
}
@ -39,6 +38,10 @@
color: $Blue-500;
}
&__main-view &__tab button {
padding: 16px 8px;
}
&__connect-status-text {
display: flex;
flex-direction: column;

Loading…
Cancel
Save