feat(ui-toolkit): increase checkbox and radio clickable area (#4906)

This commit is contained in:
Bartłomiej Głownia 2023-10-04 12:50:02 +02:00 committed by GitHub
parent 6e7b87d9ef
commit 797db6ee93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 131 additions and 119 deletions

View File

@ -40,7 +40,7 @@ context.skip('Node switcher', { tags: '@regression' }, function () {
const errorTypeTxt = 'Error: invalid url';
const nodeErrorTxt = 'fakeUrl is not a valid url.';
cy.getByTestId('node-url-custom').click();
cy.getByTestId('node-url-custom').click({ force: true });
cy.getByTestId(customNodeBtn).within(() => {
cy.get('input').clear().type('fakeUrl');

View File

@ -310,7 +310,9 @@ context(
closeStakingDialog();
navigateTo(navigation.validators);
clickOnValidatorFromList(0);
cy.getByTestId(stakeRemoveStakeRadioButton, txTimeout).click();
cy.getByTestId(stakeRemoveStakeRadioButton, txTimeout).click({
force: true,
});
cy.getByTestId(stakeTokenAmountInputBox).type('-0.1');
cy.contains('Waiting for next epoch to start', epochTimeout);
cy.getByTestId(stakeTokenSubmitButton)
@ -331,7 +333,7 @@ context(
closeStakingDialog();
navigateTo(navigation.validators);
clickOnValidatorFromList(0);
cy.getByTestId(stakeRemoveStakeRadioButton).click();
cy.getByTestId(stakeRemoveStakeRadioButton).click({ force: true });
cy.getByTestId(stakeTokenAmountInputBox).type('4');
cy.contains('Waiting for next epoch to start', epochTimeout);
cy.getByTestId(stakeTokenSubmitButton)

View File

@ -156,7 +156,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
cy.getByTestId('subscription-cell').should('have.text', 'Yes');
});
cy.getByTestId('connect').should('be.disabled');
cy.getByTestId('node-url-custom').click();
cy.getByTestId('node-url-custom').click({ force: true });
cy.get('input').should('exist');
cy.getByTestId('connect').should('be.disabled');
cy.getByTestId('icon-cross').click();

View File

@ -46,7 +46,7 @@ export function stakingValidatorPageAddStake(stake: string) {
export function stakingValidatorPageRemoveStake(stake: string) {
cy.highlight(`Removing a stake of ${stake}`);
cy.get(removeStakeRadioButton, epochTimeout).click();
cy.get(removeStakeRadioButton, epochTimeout).click({ force: true });
cy.get(tokenAmountInputBox).type(stake);
waitForBeginningOfEpoch();
cy.get(tokenSubmitButton)
@ -70,9 +70,13 @@ export function stakingPageAssociateTokens(
cy.highlight(`Associating ${amount} tokens from ${type}`);
cy.get(ethWalletAssociateButton).first().click();
if (type === 'wallet') {
cy.get(associateWalletRadioButton, { timeout: 30000 }).click();
cy.get(associateWalletRadioButton, { timeout: 30000 }).click({
force: true,
});
} else if (type === 'contract') {
cy.get(associateContractRadioButton, { timeout: 30000 }).click();
cy.get(associateContractRadioButton, { timeout: 30000 }).click({
force: true,
});
} else {
cy.highlight(`${type} is not association option`);
}

View File

@ -61,7 +61,7 @@ describe('home', { tags: '@regression' }, () => {
// 0006-NETW-020
cy.getByTestId(nodeHealthTrigger).click();
cy.getByTestId('connect').should('be.disabled');
cy.getByTestId('node-url-custom').click();
cy.getByTestId('node-url-custom').click({ force: true });
cy.getByTestId('connect').should('be.disabled');
cy.get("input[placeholder='https://']")
.focus()

View File

@ -258,21 +258,21 @@ export const TransferForm = ({
)}
</TradingFormGroup>
<div className="mb-4">
<TradingCheckbox
name="include-transfer-fee"
disabled={!transferAmount}
label={
<Tooltip
description={t(
`The fee will be taken from the amount you are transferring.`
)}
>
<div>{t('Include transfer fee')}</div>
</Tooltip>
}
checked={includeFee}
onCheckedChange={() => setIncludeFee(!includeFee)}
/>
<Tooltip
description={t(
`The fee will be taken from the amount you are transferring.`
)}
>
<div>
<TradingCheckbox
name="include-transfer-fee"
disabled={!transferAmount}
label={t('Include transfer fee')}
checked={includeFee}
onCheckedChange={() => setIncludeFee(!includeFee)}
/>
</div>
</Tooltip>
</div>
{transferAmount && fee && (
<TransferFee

View File

@ -494,16 +494,16 @@ const TimeInForce = ({
);
const ReduceOnly = () => (
<Checkbox
name="reduce-only"
checked={true}
disabled={true}
label={
<Tooltip description={<span>{t(REDUCE_ONLY_TOOLTIP)}</span>}>
<>{t('Reduce only')}</>
</Tooltip>
}
/>
<Tooltip description={<span>{t(REDUCE_ONLY_TOOLTIP)}</span>}>
<div>
<Checkbox
name="reduce-only"
checked={true}
disabled={true}
label={t('Reduce only')}
/>
</div>
</Tooltip>
);
const NotionalAndFees = ({

View File

@ -548,62 +548,62 @@ export const DealTicket = ({
name="postOnly"
control={control}
render={({ field }) => (
<Checkbox
name="post-only"
checked={!disablePostOnlyCheckbox && field.value}
disabled={disablePostOnlyCheckbox}
onCheckedChange={(postOnly) => {
field.onChange(postOnly);
setValue('reduceOnly', false);
}}
label={
<Tooltip
description={
<span>
{disablePostOnlyCheckbox
? t(
'"Post only" can not be used on "Fill or Kill" or "Immediate or Cancel" orders.'
)
: t(
'"Post only" will ensure the order is not filled immediately but is placed on the order book as a passive order. When the order is processed it is either stopped (if it would not be filled immediately), or placed in the order book as a passive order until the price taker matches with it.'
)}
</span>
}
>
<span className="text-xs">{t('Post only')}</span>
</Tooltip>
<Tooltip
description={
<span>
{disablePostOnlyCheckbox
? t(
'"Post only" can not be used on "Fill or Kill" or "Immediate or Cancel" orders.'
)
: t(
'"Post only" will ensure the order is not filled immediately but is placed on the order book as a passive order. When the order is processed it is either stopped (if it would not be filled immediately), or placed in the order book as a passive order until the price taker matches with it.'
)}
</span>
}
/>
>
<div>
<Checkbox
name="post-only"
checked={!disablePostOnlyCheckbox && field.value}
disabled={disablePostOnlyCheckbox}
onCheckedChange={(postOnly) => {
field.onChange(postOnly);
setValue('reduceOnly', false);
}}
label={t('Post only')}
/>
</div>
</Tooltip>
)}
/>
<Controller
name="reduceOnly"
control={control}
render={({ field }) => (
<Checkbox
name="reduce-only"
checked={!disableReduceOnlyCheckbox && field.value}
disabled={disableReduceOnlyCheckbox}
onCheckedChange={(reduceOnly) => {
field.onChange(reduceOnly);
setValue('postOnly', false);
}}
label={
<Tooltip
description={
<span>
{disableReduceOnlyCheckbox
? t(
'"Reduce only" can be used only with non-persistent orders, such as "Fill or Kill" or "Immediate or Cancel".'
)
: t(REDUCE_ONLY_TOOLTIP)}
</span>
}
>
<span className="text-xs">{t('Reduce only')}</span>
</Tooltip>
<Tooltip
description={
<span>
{disableReduceOnlyCheckbox
? t(
'"Reduce only" can be used only with non-persistent orders, such as "Fill or Kill" or "Immediate or Cancel".'
)
: t(REDUCE_ONLY_TOOLTIP)}
</span>
}
/>
>
<div>
<Checkbox
name="reduce-only"
checked={!disableReduceOnlyCheckbox && field.value}
disabled={disableReduceOnlyCheckbox}
onCheckedChange={(reduceOnly) => {
field.onChange(reduceOnly);
setValue('postOnly', false);
}}
label={t('Reduce only')}
/>
</div>
</Tooltip>
)}
/>
</div>
@ -614,26 +614,26 @@ export const DealTicket = ({
name="iceberg"
control={control}
render={({ field }) => (
<Checkbox
name="iceberg"
checked={field.value}
onCheckedChange={field.onChange}
disabled={disableIcebergCheckbox}
label={
<Tooltip
description={
<p>
{t(`Trade only a fraction of the order size at once.
<Tooltip
description={
<p>
{t(`Trade only a fraction of the order size at once.
After the peak size of the order has traded, the size is reset. This is repeated until the order is cancelled, expires, or its full volume trades away.
For example, an iceberg order with a size of 1000 and a peak size of 100 will effectively be split into 10 orders with a size of 100 each.
Note that the full volume of the order is not hidden and is still reflected in the order book.`)}
</p>
}
>
<span className="text-xs">{t('Iceberg')}</span>
</Tooltip>
</p>
}
/>
>
<div>
<Checkbox
name="iceberg"
checked={field.value}
onCheckedChange={field.onChange}
disabled={disableIcebergCheckbox}
label={t('Iceberg')}
/>
</div>
</Tooltip>
)}
/>
</div>

View File

@ -4,6 +4,8 @@ import classNames from 'classnames';
import type { ReactNode } from 'react';
type CheckedState = boolean | 'indeterminate';
export const labelClasses =
"relative before:content-[''] before:block before:absolute before:top-1/2 before:left-[0] before:right-[0] before:-translate-y-1/2 before:h-6";
export interface CheckboxProps {
checked?: CheckedState;
label?: ReactNode;
@ -30,7 +32,7 @@ export const Checkbox = ({
);
return (
<div className="flex gap-1">
<label className={`flex gap-1 ${labelClasses}`} htmlFor={name}>
<CheckboxPrimitive.Root
name={name}
id={name}
@ -55,14 +57,13 @@ export const Checkbox = ({
)}
</CheckboxPrimitive.CheckboxIndicator>
</CheckboxPrimitive.Root>
<label
htmlFor={name}
<span
className={classNames('text-sm flex-1', {
'dark:text-neutral-400 text-neutral-600': disabled,
})}
>
{label}
</label>
</div>
</span>
</label>
);
};

View File

@ -2,6 +2,7 @@ import { forwardRef } from 'react';
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { labelClasses } from '../checkbox';
export interface RadioGroupProps {
name?: string;
@ -56,7 +57,7 @@ interface RadioProps {
}
export const Radio = ({ id, value, label, disabled }: RadioProps) => {
const wrapperClasses = classNames('flex items-center gap-2', {
const wrapperClasses = classNames('flex items-center gap-2', labelClasses, {
'opacity-40': disabled,
});
const itemClasses = classNames(
@ -71,7 +72,7 @@ export const Radio = ({ id, value, label, disabled }: RadioProps) => {
'border-black dark:border-white'
);
return (
<div className={wrapperClasses}>
<label className={wrapperClasses} htmlFor={id}>
<RadioGroupPrimitive.Item
value={value}
className={itemClasses}
@ -81,9 +82,7 @@ export const Radio = ({ id, value, label, disabled }: RadioProps) => {
>
<RadioGroupPrimitive.Indicator className={indicatorClasses} />
</RadioGroupPrimitive.Item>
<label htmlFor={id} className={disabled ? '' : 'cursor-pointer'}>
{label}
</label>
</div>
<span className={disabled ? '' : 'cursor-pointer'}>{label}</span>
</label>
);
};

View File

@ -2,6 +2,7 @@ import { VegaIcon, VegaIconNames } from '../icon';
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { labelClasses } from '../checkbox';
type CheckedState = boolean | 'indeterminate';
export interface TradingCheckboxProps {
@ -29,7 +30,10 @@ export const TradingCheckbox = ({
);
return (
<div className="flex gap-1.5 items-center">
<label
htmlFor={name}
className={`flex gap-1.5 items-center ${labelClasses}`}
>
<CheckboxPrimitive.Root
name={name}
id={name}
@ -50,14 +54,13 @@ export const TradingCheckbox = ({
)}
</CheckboxPrimitive.CheckboxIndicator>
</CheckboxPrimitive.Root>
<label
htmlFor={name}
<span
className={classNames('text-xs flex-1', {
'text-vega-clight-200 dark:text-vega-cdark-200': disabled,
})}
>
{label}
</label>
</div>
</span>
</label>
);
};

View File

@ -2,6 +2,7 @@ import { forwardRef } from 'react';
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
import classNames from 'classnames';
import type { ReactNode } from 'react';
import { labelClasses } from '../checkbox';
export interface TradingRadioGroupProps {
name?: string;
@ -59,7 +60,10 @@ interface RadioProps {
}
export const TradingRadio = ({ id, value, label, disabled }: RadioProps) => {
const wrapperClasses = classNames('flex items-center gap-1.5 text-xs');
const wrapperClasses = classNames(
'flex items-center gap-1.5 text-xs',
labelClasses
);
const itemClasses = classNames(
'flex justify-center items-center',
'w-3 h-3 rounded-full border',
@ -74,7 +78,7 @@ export const TradingRadio = ({ id, value, label, disabled }: RadioProps) => {
'border-vega-clight-700 dark:border-vega-cdark-700'
);
return (
<div className={wrapperClasses}>
<label className={wrapperClasses} htmlFor={id}>
<RadioGroupPrimitive.Item
value={value}
className={itemClasses}
@ -84,8 +88,7 @@ export const TradingRadio = ({ id, value, label, disabled }: RadioProps) => {
>
<RadioGroupPrimitive.Indicator className={indicatorClasses} />
</RadioGroupPrimitive.Item>
<label
htmlFor={id}
<span
className={
disabled
? 'text-vega-clight-200 dark:text-vega-cdark-200'
@ -93,7 +96,7 @@ export const TradingRadio = ({ id, value, label, disabled }: RadioProps) => {
}
>
{label}
</label>
</div>
</span>
</label>
);
};