-
-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f92ea29
commit 7cadab6
Showing
2 changed files
with
91 additions
and
87 deletions.
There are no files selected for viewing
49 changes: 19 additions & 30 deletions
49
apps/design-system/src/components/DropdownMenu.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,31 @@ | ||
import { DropdownMenu } from '@asyncapi/studio-ui' | ||
import React from 'react'; | ||
import { Meta } from '@storybook/react'; | ||
import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, DropdownMenuItem, DropdownMenuSeparator } from '@asyncapi/studio-ui' | ||
|
||
export default { | ||
const meta: Meta = { | ||
component: DropdownMenu, | ||
parameters: { | ||
layout: 'fullscreen', | ||
backgrounds: { | ||
default: 'dark' | ||
} | ||
}, | ||
} | ||
} | ||
|
||
const items = [ | ||
{ | ||
title: 'Import from URL', | ||
onSelect: () => console.log('Import from URL') | ||
}, | ||
{ | ||
title: 'Import from file', | ||
onSelect: () => console.log('Import from file') | ||
}, | ||
{ | ||
title: 'Import from Base64', | ||
onSelect: () => console.log('Import from Base64') | ||
}, | ||
{ | ||
type: 'separator' | ||
}, | ||
{ | ||
title: 'Generate code/docs', | ||
onSelect: () => console.log('Generate code/docs') | ||
}, | ||
] | ||
export default meta | ||
|
||
|
||
export const Default = { | ||
args: { | ||
trigger: <button className="text-black bg-white rounded mx-3 my-3 px-3">Click me!</button>, | ||
items, | ||
side: 'bottom', | ||
align: 'start' | ||
} | ||
render: () => (<DropdownMenu> | ||
<DropdownMenuTrigger asChild> | ||
<button className="text-black bg-white rounded mx-3 my-3 px-3">Click me!</button> | ||
</DropdownMenuTrigger> | ||
<DropdownMenuContent> | ||
<DropdownMenuItem onSelect={(e) => console.log(e.target)}>Import from URL</DropdownMenuItem> | ||
<DropdownMenuItem onSelect={(e) => console.log(e.target)}>Import from file</DropdownMenuItem> | ||
<DropdownMenuItem onSelect={(e) => console.log(e.target)}>Import from Base64</DropdownMenuItem> | ||
<DropdownMenuSeparator /> | ||
<DropdownMenuItem onSelect={(e) => console.log(e.target)}>Generate code/docs</DropdownMenuItem> | ||
</DropdownMenuContent> | ||
</DropdownMenu>) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,80 @@ | ||
import type { FunctionComponent, ReactNode } from 'react' | ||
import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu' | ||
"use client" | ||
|
||
interface DropdownMenuRegularItem { | ||
type?: 'regular' | ||
title: string | ||
onSelect: () => void | ||
} | ||
import * as React from "react" | ||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" | ||
|
||
interface DropdownMenuSeparatorItem { | ||
type: 'separator' | ||
} | ||
import { cn } from "@asyncapi/studio-utils" | ||
|
||
export type DropdownMenuItem = DropdownMenuRegularItem | DropdownMenuSeparatorItem | ||
const DropdownMenu = DropdownMenuPrimitive.Root | ||
|
||
interface DropdownMenuProps { | ||
trigger: ReactNode | ||
items: DropdownMenuItem[] | ||
side?: 'top' | 'right' | 'bottom' | 'left' | ||
align?: 'start' | 'center' | 'end' | ||
} | ||
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger | ||
|
||
interface DropdownMenuItemComponentProps { | ||
item: DropdownMenuItem | ||
} | ||
const DropdownMenuGroup = DropdownMenuPrimitive.Group | ||
|
||
const DropdownMenuPortal = DropdownMenuPrimitive.Portal | ||
|
||
const DropdownMenuSub = DropdownMenuPrimitive.Sub | ||
|
||
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup | ||
|
||
|
||
const DropdownMenuContent = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.Content>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content> | ||
>(({ className, sideOffset = 5, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.Portal> | ||
<DropdownMenuPrimitive.Content | ||
ref={ref} | ||
sideOffset={sideOffset} | ||
className={cn( | ||
"min-w-[220px] bg-gray-950 rounded-md p-2.5 shadow", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
</DropdownMenuPrimitive.Portal> | ||
)) | ||
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName | ||
|
||
const DropdownMenuItem = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.Item>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & { | ||
inset?: boolean | ||
} | ||
>(({ className, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.Item | ||
ref={ref} | ||
className={cn( | ||
"text-gray-200 text-sm leading-7 px-2.5 cursor-pointer rounded outline-none select-none hover:bg-gray-700 focus:bg-gray-700", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
)) | ||
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName | ||
|
||
|
||
const DropdownMenuSeparator = React.forwardRef< | ||
React.ElementRef<typeof DropdownMenuPrimitive.Separator>, | ||
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator> | ||
>(({ className, ...props }, ref) => ( | ||
<DropdownMenuPrimitive.Separator | ||
ref={ref} | ||
className={cn("w-full h-px bg-gray-700 my-2", className)} | ||
{...props} | ||
/> | ||
)) | ||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName | ||
|
||
const DropdownMenuItemComponent: FunctionComponent<DropdownMenuItemComponentProps> = ({ item }) => { | ||
return ( | ||
item.type === 'separator' ? ( | ||
<RadixDropdownMenu.Separator className="w-full h-px bg-gray-700 my-2" /> | ||
) : ( | ||
<RadixDropdownMenu.Item | ||
className="text-gray-200 text-sm leading-7 px-2.5 cursor-pointer rounded outline-none select-none hover:bg-gray-700 focus:bg-gray-700" | ||
onSelect={item.onSelect} | ||
> | ||
{item.title} | ||
</RadixDropdownMenu.Item> | ||
) | ||
) | ||
} | ||
|
||
export const DropdownMenu: FunctionComponent<DropdownMenuProps> = ({ | ||
trigger, | ||
items, | ||
side, | ||
align, | ||
}) => { | ||
return ( | ||
<RadixDropdownMenu.Root> | ||
<RadixDropdownMenu.Trigger aria-label='Select an Option.' asChild> | ||
{trigger} | ||
</RadixDropdownMenu.Trigger> | ||
<RadixDropdownMenu.Portal> | ||
<RadixDropdownMenu.Content className="min-w-[220px] bg-gray-950 rounded-md p-2.5 shadow" sideOffset={5} side={side} align={align}> | ||
{ | ||
items.map((item, index) => ( | ||
<DropdownMenuItemComponent key={index} item={item} /> | ||
)) | ||
} | ||
<RadixDropdownMenu.Arrow className="fill-gray-950" /> | ||
</RadixDropdownMenu.Content> | ||
</RadixDropdownMenu.Portal> | ||
</RadixDropdownMenu.Root> | ||
) | ||
export { | ||
DropdownMenu, | ||
DropdownMenuTrigger, | ||
DropdownMenuContent, | ||
DropdownMenuItem, | ||
DropdownMenuSeparator, | ||
DropdownMenuGroup, | ||
DropdownMenuPortal, | ||
DropdownMenuSub, | ||
DropdownMenuRadioGroup, | ||
} |