Skip to content

Commit

Permalink
fix: roll back import of dropdown menu, ref leather-io/issues#64
Browse files Browse the repository at this point in the history
  • Loading branch information
pete-watters committed Jun 19, 2024
1 parent 12dca36 commit b03d6af
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 17 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
"@radix-ui/colors": "3.0.0",
"@radix-ui/react-avatar": "1.0.4",
"@radix-ui/react-dialog": "1.0.5",
"@radix-ui/react-dropdown-menu": "2.0.6",
"@radix-ui/react-tabs": "1.0.4",
"@radix-ui/react-toast": "1.1.5",
"@radix-ui/react-tooltip": "1.0.7",
Expand Down
35 changes: 19 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/app/features/settings/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Flex, Stack, styled } from 'leather-styles/jsx';

import {
Caption,
DropdownMenu,
ExitIcon,
ExpandIcon,
ExternalLinkIcon,
Expand Down Expand Up @@ -36,6 +35,7 @@ import { ThemeDialog } from '@app/features/settings/theme/theme-dialog';
import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks';
import { useHasLedgerKeys, useLedgerDeviceTargetId } from '@app/store/ledger/ledger.selectors';
import { useCurrentNetworkId } from '@app/store/networks/networks.selectors';
import { DropdownMenu } from '@app/ui/components/dropdown-menu/dropdown-menu';

import { openFeedbackDialog } from '../feedback-button/feedback-button';
import { extractDeviceNameFromKnownTargetIds } from '../ledger/utils/generic-ledger-utils';
Expand Down
16 changes: 16 additions & 0 deletions src/app/ui/components/dropdown-menu/dropdown-menu-item.layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ReactNode } from 'react';

import { Flex } from 'leather-styles/jsx';

interface DropdownMenuItemLayoutProps {
contentLeft: ReactNode;
contentRight?: ReactNode;
}
export function DropdownMenuItemLayout({ contentLeft, contentRight }: DropdownMenuItemLayoutProps) {
return (
<Flex alignItems="center" justifyContent="space-between" width="100%">
{contentLeft}
{contentRight}
</Flex>
);
}
47 changes: 47 additions & 0 deletions src/app/ui/components/dropdown-menu/dropdown-menu.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { Meta, StoryObj } from '@storybook/react';
import { HStack, styled } from 'leather-styles/jsx';

import { PlaceholderIcon } from '@leather-wallet/ui';

import { DropdownMenu as Component, DropdownMenuItem } from './dropdown-menu';
import { DropdownMenuItemLayout } from './dropdown-menu-item.layout';

const items: DropdownMenuItem[] = [{ label: 'Label 1' }, { label: 'Label 2' }];

const meta: Meta<typeof Component.Root> = {
component: Component.Root,
tags: ['autodocs'],
title: 'DropdownMenu',
};

export default meta;
type Story = StoryObj<typeof Component.Root>;

export const DropdownMenu: Story = {
render: () => (
<Component.Root>
<Component.Trigger>
<Component.Button>Button</Component.Button>
</Component.Trigger>
<Component.Portal>
<Component.Content align="start" sideOffset={8}>
<Component.Group>
<Component.Label>Label</Component.Label>
{items.map(item => (
<Component.Item key={item.label}>
<DropdownMenuItemLayout
contentLeft={
<HStack gap="space.02" minHeight="24px">
<PlaceholderIcon />
<styled.span textStyle="label.02">{item.label}</styled.span>
</HStack>
}
/>
</Component.Item>
))}
</Component.Group>
</Component.Content>
</Component.Portal>
</Component.Root>
),
};
127 changes: 127 additions & 0 deletions src/app/ui/components/dropdown-menu/dropdown-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { ReactNode, forwardRef } from 'react';

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, Flag, pressableBaseStyles, pressableStyles } from '@leather-wallet/ui';

export interface DropdownMenuItem {
iconLeft?: ReactNode;
iconRight?: ReactNode;
label: string;
}
const dropdownButtonStyles = css({
bg: 'ink.background-primary',
borderRadius: 'xs',
fontWeight: 500,
maxWidth: 'fit-content',
maxHeight: 'fit-content',
px: 'space.04',
py: 'space.03',
textStyle: 'label.02',
userSelect: 'none',
'[data-state=open] &': { bg: 'ink.component-background-pressed' },
});

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 dropdownIconButtonStyles = css({
_hover: { bg: 'ink.component-background-hover' },
_focus: { outline: 'none' },
p: 'space.02',

'&[data-state=open]': { bg: 'ink.component-background-pressed' },
});
const IconButton: typeof RadixDropdownMenu.Trigger = forwardRef((props, ref) => (
<RadixDropdownMenu.Trigger className={dropdownIconButtonStyles} ref={ref} {...props} />
));

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',
'--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)',
p: '0',
willChange: 'transform, opacity',
zIndex: 999,
// _closed: { animation: 'slideDownAndOut 140ms ease-in-out' },
// _open: { animation: 'slideUpAndFade 140ms ease-in-out' },
});
const Content: typeof RadixDropdownMenu.Content = forwardRef(({ className, ...props }, ref) => (
<RadixDropdownMenu.Content
className={`${dropdownContentStyles} ${className}`}
ref={ref}
{...props}
/>
));

const dropdownMenuLabelStyles = css({
color: 'ink.text-subdued',
height: 'auto',
px: 'space.03',
py: 'space.02',
textStyle: 'body.02',
width: '100%',
});
const Label: typeof RadixDropdownMenu.Label = forwardRef((props, ref) => (
<RadixDropdownMenu.Label className={dropdownMenuLabelStyles} ref={ref} {...props} />
));

const dropdownItemStyles = css({ p: 'space.03' });
const Item: typeof RadixDropdownMenu.Item = forwardRef((props, ref) => (
<styled.div className={dropdownItemStyles}>
<RadixDropdownMenu.Item
ref={ref}
className={css(pressableBaseStyles, pressableStyles)}
{...props}
/>
</styled.div>
));

const dropdownMenuSeparatorStyles = css({
bg: 'ink.background-primary',
color: 'ink.border-default',
mx: '0px',
my: 'space.03',
});
const Separator: typeof RadixDropdownMenu.Separator = forwardRef((props, ref) => (
<RadixDropdownMenu.Separator className={dropdownMenuSeparatorStyles} ref={ref} {...props} />
));
const dropdownMenuGroupStyles = css({
p: 'space.02',
});
const Group: typeof RadixDropdownMenu.Group = forwardRef((props, ref) => (
<RadixDropdownMenu.Separator className={dropdownMenuGroupStyles} ref={ref} {...props} />
));

export const DropdownMenu = {
Root: RadixDropdownMenu.Root,
Group,
Portal: RadixDropdownMenu.Portal,
Trigger,
Button,
IconButton,
Content,
Label,
Item,
Separator,
};

0 comments on commit b03d6af

Please sign in to comment.