mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
UX: Multichain: Account Details Fixes (#18999)
* Fix account details editable label * Fix font-weight of the password label * Remove duplicate error * Hide password warning on first screen after bad password, autofocus password field * Fix jest failure * Restore className
This commit is contained in:
parent
dd04913e7e
commit
a5494fc637
@ -24,7 +24,7 @@ describe('Account Details Modal', () => {
|
|||||||
global.platform = { openTab: jest.fn() };
|
global.platform = { openTab: jest.fn() };
|
||||||
|
|
||||||
it('should set account label when changing default account label', () => {
|
it('should set account label when changing default account label', () => {
|
||||||
const { queryByTestId } = renderWithProvider(
|
const { queryByTestId, getByPlaceholderText } = renderWithProvider(
|
||||||
<AccountDetailsModal />,
|
<AccountDetailsModal />,
|
||||||
mockStore,
|
mockStore,
|
||||||
);
|
);
|
||||||
@ -35,7 +35,7 @@ describe('Account Details Modal', () => {
|
|||||||
fireEvent.click(editButton);
|
fireEvent.click(editButton);
|
||||||
expect(queryByTestId('editable-input')).toBeInTheDocument();
|
expect(queryByTestId('editable-input')).toBeInTheDocument();
|
||||||
|
|
||||||
const editableInput = queryByTestId('editable-input');
|
const editableInput = getByPlaceholderText('Account name');
|
||||||
const newAccountLabel = 'New Label';
|
const newAccountLabel = 'New Label';
|
||||||
|
|
||||||
fireEvent.change(editableInput, {
|
fireEvent.change(editableInput, {
|
||||||
|
@ -3,8 +3,8 @@ import { useDispatch, useSelector } from 'react-redux';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {
|
import {
|
||||||
DISPLAY,
|
DISPLAY,
|
||||||
|
FontWeight,
|
||||||
SEVERITIES,
|
SEVERITIES,
|
||||||
TextColor,
|
|
||||||
TextVariant,
|
TextVariant,
|
||||||
} from '../../../helpers/constants/design-system';
|
} from '../../../helpers/constants/design-system';
|
||||||
import {
|
import {
|
||||||
@ -56,19 +56,10 @@ export const AccountDetailsAuthenticate = ({ address, onCancel }) => {
|
|||||||
value={password}
|
value={password}
|
||||||
variant={TextVariant.bodySm}
|
variant={TextVariant.bodySm}
|
||||||
type="password"
|
type="password"
|
||||||
inputProps={{
|
inputProps={{ onKeyPress: handleKeyPress }}
|
||||||
onKeyPress: handleKeyPress,
|
labelProps={{ fontWeight: FontWeight.Medium }}
|
||||||
}}
|
autoFocus
|
||||||
/>
|
/>
|
||||||
{warning ? (
|
|
||||||
<Text
|
|
||||||
marginTop={1}
|
|
||||||
color={TextColor.errorDefault}
|
|
||||||
variant={TextVariant.bodySm}
|
|
||||||
>
|
|
||||||
{warning}
|
|
||||||
</Text>
|
|
||||||
) : null}
|
|
||||||
<BannerAlert marginTop={6} severity={SEVERITIES.DANGER}>
|
<BannerAlert marginTop={6} severity={SEVERITIES.DANGER}>
|
||||||
<Text variant={TextVariant.bodySm}>{t('privateKeyWarning')}</Text>
|
<Text variant={TextVariant.bodySm}>{t('privateKeyWarning')}</Text>
|
||||||
</BannerAlert>
|
</BannerAlert>
|
||||||
|
@ -79,7 +79,10 @@ export const AccountDetails = ({ address }) => {
|
|||||||
<PopoverHeader
|
<PopoverHeader
|
||||||
startAccessory={
|
startAccessory={
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
onClick={() => setAttemptingExport(false)}
|
onClick={() => {
|
||||||
|
dispatch(hideWarning());
|
||||||
|
setAttemptingExport(false);
|
||||||
|
}}
|
||||||
iconName={IconName.ArrowLeft}
|
iconName={IconName.ArrowLeft}
|
||||||
size={Size.SM}
|
size={Size.SM}
|
||||||
/>
|
/>
|
||||||
|
@ -45,7 +45,7 @@ describe('AccountDetails', () => {
|
|||||||
const editButton = screen.getByTestId('editable-label-button');
|
const editButton = screen.getByTestId('editable-label-button');
|
||||||
fireEvent.click(editButton);
|
fireEvent.click(editButton);
|
||||||
|
|
||||||
const editableInput = screen.getByTestId('editable-input');
|
const editableInput = screen.getByPlaceholderText('Account name');
|
||||||
const newAccountLabel = 'New Label';
|
const newAccountLabel = 'New Label';
|
||||||
|
|
||||||
fireEvent.change(editableInput, { target: { value: newAccountLabel } });
|
fireEvent.change(editableInput, { target: { value: newAccountLabel } });
|
||||||
|
@ -1,9 +1,20 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import {
|
||||||
import { Color } from '../../../helpers/constants/design-system';
|
AlignItems,
|
||||||
|
Color,
|
||||||
|
DISPLAY,
|
||||||
|
TextVariant,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
import { getAccountNameErrorMessage } from '../../../helpers/utils/accounts';
|
import { getAccountNameErrorMessage } from '../../../helpers/utils/accounts';
|
||||||
import { ButtonIcon, IconName } from '../../component-library';
|
import {
|
||||||
|
ButtonIcon,
|
||||||
|
FormTextField,
|
||||||
|
IconName,
|
||||||
|
Text,
|
||||||
|
} from '../../component-library';
|
||||||
|
import Box from '../box/box';
|
||||||
|
|
||||||
export default class EditableLabel extends Component {
|
export default class EditableLabel extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -40,40 +51,40 @@ export default class EditableLabel extends Component {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('editable-label', this.props.className)}>
|
<Box
|
||||||
<input
|
className={classnames('editable-label', this.props.className)}
|
||||||
type="text"
|
display={DISPLAY.FLEX}
|
||||||
|
gap={3}
|
||||||
|
>
|
||||||
|
<FormTextField
|
||||||
required
|
required
|
||||||
dir="auto"
|
|
||||||
value={this.state.value}
|
value={this.state.value}
|
||||||
onKeyPress={(event) => {
|
onKeyPress={(event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
this.handleSubmit(isValidAccountName);
|
this.handleSubmit(isValidAccountName);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onChange={(event) => this.setState({ value: event.target.value })}
|
onChange={(event) => {
|
||||||
|
this.setState({ value: event.target.value });
|
||||||
|
}}
|
||||||
data-testid="editable-input"
|
data-testid="editable-input"
|
||||||
className={classnames('large-input', 'editable-label__input', {
|
error={!isValidAccountName}
|
||||||
'editable-label__input--error': !isValidAccountName,
|
helpText={errorMessage}
|
||||||
})}
|
|
||||||
autoFocus
|
autoFocus
|
||||||
|
placeholder={this.context.t('accountName')}
|
||||||
/>
|
/>
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
iconName={IconName.Check}
|
iconName={IconName.Check}
|
||||||
className="editable-label__icon-button"
|
|
||||||
onClick={() => this.handleSubmit(isValidAccountName)}
|
onClick={() => this.handleSubmit(isValidAccountName)}
|
||||||
/>
|
/>
|
||||||
<div className="editable-label__error editable-label__error-amount">
|
</Box>
|
||||||
{errorMessage}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderReadonly() {
|
renderReadonly() {
|
||||||
return (
|
return (
|
||||||
<div className={classnames('editable-label', this.props.className)}>
|
<Box display={DISPLAY.FLEX} alignItems={AlignItems.center} gap={3}>
|
||||||
<div className="editable-label__value">{this.state.value}</div>
|
<Text variant={TextVariant.bodyLgMedium}>{this.state.value}</Text>
|
||||||
<ButtonIcon
|
<ButtonIcon
|
||||||
iconName={IconName.Edit}
|
iconName={IconName.Edit}
|
||||||
ariaLabel={this.context.t('edit')}
|
ariaLabel={this.context.t('edit')}
|
||||||
@ -81,7 +92,7 @@ export default class EditableLabel extends Component {
|
|||||||
onClick={() => this.setState({ isEditing: true })}
|
onClick={() => this.setState({ isEditing: true })}
|
||||||
color={Color.iconDefault}
|
color={Color.iconDefault}
|
||||||
/>
|
/>
|
||||||
</div>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
.editable-label {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
position: relative;
|
|
||||||
flex-flow: wrap;
|
|
||||||
|
|
||||||
&__value {
|
|
||||||
max-width: 250px;
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__input {
|
|
||||||
@include H6;
|
|
||||||
|
|
||||||
color: var(--color-text-default);
|
|
||||||
background-color: var(--color-background-default);
|
|
||||||
width: 250px;
|
|
||||||
text-align: center;
|
|
||||||
border: 1px solid var(--color-border-default);
|
|
||||||
|
|
||||||
&--error {
|
|
||||||
border: 1px solid var(--color-error-default);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__icon-button {
|
|
||||||
margin-left: 10px;
|
|
||||||
left: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__error {
|
|
||||||
@include H7;
|
|
||||||
|
|
||||||
left: 8px;
|
|
||||||
color: var(--color-error-default);
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__error-amount {
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,7 +16,6 @@
|
|||||||
@import 'definition-list/definition-list';
|
@import 'definition-list/definition-list';
|
||||||
@import 'dialog/dialog';
|
@import 'dialog/dialog';
|
||||||
@import 'dropdown/dropdown';
|
@import 'dropdown/dropdown';
|
||||||
@import 'editable-label/index';
|
|
||||||
@import 'error-message/index';
|
@import 'error-message/index';
|
||||||
@import 'icon-border/icon-border';
|
@import 'icon-border/icon-border';
|
||||||
@import 'icon-button/icon-button';
|
@import 'icon-button/icon-button';
|
||||||
|
@ -10,6 +10,8 @@ export function getAccountNameErrorMessage(
|
|||||||
(item) => item.name === newAccountName,
|
(item) => item.name === newAccountName,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isEmptyAccountName = newAccountName === '';
|
||||||
|
|
||||||
const localizedWordForAccount = context
|
const localizedWordForAccount = context
|
||||||
.t('newAccountNumberName')
|
.t('newAccountNumberName')
|
||||||
.replace(' $1', '');
|
.replace(' $1', '');
|
||||||
@ -24,7 +26,7 @@ export function getAccountNameErrorMessage(
|
|||||||
|
|
||||||
const isValidAccountName =
|
const isValidAccountName =
|
||||||
newAccountName === defaultAccountName || // What is written in the text field is the same as the placeholder
|
newAccountName === defaultAccountName || // What is written in the text field is the same as the placeholder
|
||||||
(!isDuplicateAccountName && !isReservedAccountName);
|
(!isDuplicateAccountName && !isReservedAccountName && !isEmptyAccountName);
|
||||||
|
|
||||||
let errorMessage;
|
let errorMessage;
|
||||||
if (isValidAccountName) {
|
if (isValidAccountName) {
|
||||||
@ -33,6 +35,8 @@ export function getAccountNameErrorMessage(
|
|||||||
errorMessage = context.t('accountNameDuplicate');
|
errorMessage = context.t('accountNameDuplicate');
|
||||||
} else if (isReservedAccountName) {
|
} else if (isReservedAccountName) {
|
||||||
errorMessage = context.t('accountNameReserved');
|
errorMessage = context.t('accountNameReserved');
|
||||||
|
} else if (isEmptyAccountName) {
|
||||||
|
errorMessage = context.t('required');
|
||||||
}
|
}
|
||||||
|
|
||||||
return { isValidAccountName, errorMessage };
|
return { isValidAccountName, errorMessage };
|
||||||
|
Loading…
Reference in New Issue
Block a user