Skip to content

Commit

Permalink
rafactor dropdown menu
Browse files Browse the repository at this point in the history
  • Loading branch information
KhudaDad414 committed Jun 3, 2024
1 parent f92ea29 commit 7cadab6
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 87 deletions.
49 changes: 19 additions & 30 deletions apps/design-system/src/components/DropdownMenu.stories.tsx
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>)
}
129 changes: 72 additions & 57 deletions packages/ui/components/DropdownMenu.tsx
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,
}

0 comments on commit 7cadab6

Please sign in to comment.