Skip to content

Commit

Permalink
refactor(dropdown): update animations
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Feb 27, 2024
1 parent afd9637 commit 604e0b4
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ export function SelectAccountButton({ onClick, ...props }: SelectAccountButtonPr
return (
<styled.button
type="button"
color="accent.text-primary"
color="ink.text-primary"
userSelect="none"
textStyle="label.03"
_hover={{ color: 'accent.action-primary-hover' }}
_hover={{ color: 'ink.action-primary-hover' }}
data-testid={SendCryptoAssetSelectors.RecipientChooseAccountButton}
fontWeight={500}
onMouseDown={e => preventFocusOfUnderlyingInput(e)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@ import { useNavigate } from 'react-router-dom';
import { useFormikContext } from 'formik';

import { RouteUrls } from '@shared/route-urls';
import type { Entries } from '@shared/utils/type-utils';

import { useRecipientBnsName } from './use-recipient-bns-name';

export const recipientIdentifierTypesMap = { bnsName: 'BNS Name', address: 'Address' } as const;
const recipientIdentifierTypesMap = { address: 'Address', bnsName: 'BNS Name' } as const;

export type RecipientIdentifierType = keyof typeof recipientIdentifierTypesMap;

function makeIteratbleListOfRecipientIdentifierTypes(
recipientTypeMap: typeof recipientIdentifierTypesMap
) {
return (Object.entries(recipientTypeMap) as Entries<typeof recipientTypeMap>).map(
([key, value]) => ({ key, label: value })
);
}
export const recipientIdentifierTypes = makeIteratbleListOfRecipientIdentifierTypes(
recipientIdentifierTypesMap
);

export function useRecipientSelectFields() {
const { setFieldError, setFieldTouched, setFieldValue } = useFormikContext();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import type { Entries } from '@shared/utils/type-utils';
import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';

import { DropdownMenu } from '@app/ui/components/dowpdown-menu/dropdown-menu';
import { Flag } from '@app/ui/components/flag/flag';
import { ChevronDownIcon } from '@app/ui/icons';

import {
type RecipientIdentifierType,
recipientIdentifierTypesMap,
recipientIdentifierTypes,
} from '../recipient-fields/hooks/use-recipient-select-fields';

function makeIteratbleListOfRecipientIdentifierTypes(
recipientTypeMap: typeof recipientIdentifierTypesMap
) {
return (Object.entries(recipientTypeMap) as Entries<typeof recipientTypeMap>).map(
([key, value]) => ({ key, label: value })
);
}
const recipientIdentifierTypes = makeIteratbleListOfRecipientIdentifierTypes(
recipientIdentifierTypesMap
);

interface RecipientIdentifierTypeDropdownProps {
activeRecipientIdentifierType: string;
onSelectRecipientIdentifierType(recipientType: RecipientIdentifierType): void;
Expand All @@ -28,13 +17,15 @@ export function RecipientIdentifierTypeDropdown(props: RecipientIdentifierTypeDr
const { activeRecipientIdentifierType, onSelectRecipientIdentifierType } = props;
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<DropdownMenu.Trigger
data-testid={SendCryptoAssetSelectors.RecipientSelectRecipientTypeDropdown}
>
<Flag
reverse
img={<ChevronDownIcon variant="small" />}
spacing="space.01"
color="accent.text-primary"
_hover={{ color: 'accent.action-primary-hover' }}
color="ink.text-primary"
_hover={{ color: 'ink.action-primary-hover' }}
>
{activeRecipientIdentifierType}
</Flag>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Meta, StoryObj } from '@storybook/react';
import { HStack, styled } from 'leather-styles/jsx';

import { ChevronDownIcon } from '../../icons/chevron-down-icon';
import { PlaceholderIcon } from '../../icons/placeholder-icon';
import { DropdownMenu as Component, DropdownMenuItem } from './dropdown-menu';
import { DropdownMenuItemLayout } from './dropdown-menu-item.layout';
Expand All @@ -21,12 +20,7 @@ export const DropdownMenu: Story = {
render: () => (
<Component.Root>
<Component.Trigger>
<Component.Button>
<HStack gap="space.02" width="100%">
<styled.span textStyle="label.02">Options</styled.span>
<ChevronDownIcon variant="small" />
</HStack>
</Component.Button>
<Component.Button>Button</Component.Button>
</Component.Trigger>
<Component.Portal>
<Component.Content align="start" sideOffset={8}>
Expand All @@ -41,7 +35,6 @@ export const DropdownMenu: Story = {
<styled.span textStyle="label.02">{item.label}</styled.span>
</HStack>
}
contentRight={<PlaceholderIcon />}
/>
</Component.Item>
))}
Expand Down
37 changes: 23 additions & 14 deletions src/app/ui/components/dowpdown-menu/dropdown-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';
import { css } from 'leather-styles/css';
import { type HTMLStyledProps, styled } from 'leather-styles/jsx';

import { ChevronDownIcon } from '@app/ui/icons';

import { Flag } from '../flag/flag';
import { itemBaseStyles, itemInteractiveStyles } from '../item/item-interactive';

export interface DropdownMenuItem {
iconLeft?: ReactNode;
iconRight?: ReactNode;
label: string;
}

const dropdownButtonStyles = css({
bg: 'ink.background-primary',
borderRadius: 'xs',
Expand All @@ -21,31 +23,38 @@ const dropdownButtonStyles = css({
px: 'space.04',
py: 'space.03',
textStyle: 'label.02',
'[data-state=open] &': {
bg: 'ink.component-background-pressed',
},
userSelect: 'none',
'[data-state=open] &': { bg: 'ink.component-background-pressed' },
});
function Button(props: HTMLStyledProps<'button'>) {
return <styled.button className={dropdownButtonStyles} {...props} />;
function Button({ children, ...props }: HTMLStyledProps<'div'>) {
return (
<styled.div className={dropdownButtonStyles} {...props}>
<Flag spacing="space.02" reverse img={<ChevronDownIcon variant="small" />}>
{children}
</Flag>
</styled.div>
);
}

const dropdownTriggerStyles = css({
_focus: { outline: 'none' },
});
const Trigger: typeof RadixDropdownMenu.Trigger = forwardRef((props, ref) => (
<RadixDropdownMenu.Trigger className={dropdownTriggerStyles} ref={ref} {...props} />
));

const dropdownContentStyles = css({
alignItems: 'center',
animationDuration: '400ms',
animationTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)',
'--base-menu-padding': '0px',
bg: 'ink.background-primary',
borderRadius: 'xs',
boxShadow:
'0px 12px 24px 0px rgba(18, 16, 15, 0.08), 0px 4px 8px 0px rgba(18, 16, 15, 0.08), 0px 0px 2px 0px rgba(18, 16, 15, 0.08)',
minWidth: '256px',
p: 'space.02',
willChange: 'transform, opacity',
zIndex: 999,

'&[data-side=bottom]': {
animationName: 'slideUpAndFade',
},
_closed: { animation: 'slideDownAndOut 140ms ease-in-out' },
_open: { animation: 'slideUpAndFade 140ms ease-in-out' },
});
const Content: typeof RadixDropdownMenu.Content = forwardRef((props, ref) => (
<RadixDropdownMenu.Content className={dropdownContentStyles} ref={ref} {...props} />
Expand Down Expand Up @@ -83,9 +92,9 @@ const Separator: typeof RadixDropdownMenu.Separator = forwardRef((props, ref) =>

export const DropdownMenu = {
Root: RadixDropdownMenu.Root,
Trigger: RadixDropdownMenu.Trigger,
Group: RadixDropdownMenu.Group,
Portal: RadixDropdownMenu.Portal,
Trigger,
Button,
Content,
Label,
Expand Down
5 changes: 5 additions & 0 deletions tests/page-object-models/send.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class SendPage {
readonly memoInput: Locator;
readonly previewSendTxButton: Locator;
readonly recipientChooseAccountButton: Locator;
readonly recipientSelectRecipientTypeDropdown: Locator;
readonly recipientSelectFieldAddress: Locator;
readonly recipientSelectFieldBnsName: Locator;
readonly recipientInput: Locator;
Expand Down Expand Up @@ -44,6 +45,10 @@ export class SendPage {
this.recipientChooseAccountButton = page.getByTestId(
SendCryptoAssetSelectors.RecipientChooseAccountButton
);
this.page.getByTestId(SendCryptoAssetSelectors.RecipientSelectFieldAddress);
this.recipientSelectRecipientTypeDropdown = this.page.getByTestId(
SendCryptoAssetSelectors.RecipientSelectRecipientTypeDropdown
);
this.recipientSelectFieldAddress = this.page.getByTestId(
SendCryptoAssetSelectors.RecipientSelectFieldAddress
);
Expand Down
1 change: 1 addition & 0 deletions tests/selectors/send.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export enum SendCryptoAssetSelectors {
MemoFieldInput = 'memo-field-input',
PreviewSendTxBtn = 'preview-send-tx-btn',
RecipientChooseAccountButton = 'recipient-choose-account-button',
RecipientSelectRecipientTypeDropdown = 'recipient-select-field-dropdown-button',
RecipientSelectFieldAddress = 'recipient-select-field-address',
RecipientSelectFieldBnsName = 'recipient-select-field-bnsName',
RecipientFieldInput = 'recipient-field-input',
Expand Down
2 changes: 1 addition & 1 deletion tests/specs/send/send-stx.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ test.describe('send stx', () => {
test('that recipient address matches bns name', async () => {
await sPage.amountInput.fill('.0001');
await sPage.amountInput.blur();
await sPage.recipientSelectFieldAddress.click();
await sPage.recipientSelectRecipientTypeDropdown.click();
await sPage.recipientSelectFieldBnsName.click();
await sPage.recipientInput.fill(TEST_BNS_NAME);
await sPage.recipientInput.blur();
Expand Down
4 changes: 4 additions & 0 deletions theme/keyframes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ import { CssKeyframes } from 'leather-styles/types/system-types';
// ts-unused-exports:disable-next-line
export const keyframes: CssKeyframes = {
...leatherKeyframes,
slideDownAndOut: {
from: { opacity: 1, transform: 'translateY(0)' },
to: { opacity: 0, transform: 'translateY(4px)' },
},
};

0 comments on commit 604e0b4

Please sign in to comment.