feat(ui-toolkit): increase checkbox and radio clickable area (#4906)
This commit is contained in:
parent
6e7b87d9ef
commit
797db6ee93
@ -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');
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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`);
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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 = ({
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user