Skip to content

Commit

Permalink
update: new component PlainTextDropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
aolyang committed Dec 29, 2024
1 parent 0e5bca3 commit 675edac
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 30 deletions.
50 changes: 50 additions & 0 deletions docs/src/components/PlainTextDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { ForwardedRef, ReactNode } from "react"

import useMenuTrigger from "@/hooks/useMenuTrigger"
import { mdiMenuDown } from "@mdi/js"
import { Icon } from "@mdi/react"
import { ButtonBase, ClickAwayListener, Menu, MenuList } from "@mui/material"
import cn from "clsx"
import { forwardRef, useImperativeHandle } from "react"

interface PlainTextSelectProps {
className?: string
Label: ReactNode
children: ReactNode
}

export interface PlainTextDropdownExposed {
close: () => void
}

function PlainTextDropdown(
props: PlainTextSelectProps,
ref: ForwardedRef<PlainTextDropdownExposed>
) {
const { className, Label, children } = props
const { anchor, open, handleClick, handleClose } = useMenuTrigger()

useImperativeHandle(ref, () => ({
close: handleClose
}))
return (
<>
<ButtonBase
className={cn("bar-menu-selector px-1 rounded-[2px]", className)}
onClick={handleClick}
>
{Label}
<Icon path={mdiMenuDown} rotate={open ? 180 : 0} size={1} />
</ButtonBase>
<Menu open={open} anchorEl={anchor}>
<ClickAwayListener onClickAway={handleClose}>
<MenuList>
{children}
</MenuList>
</ClickAwayListener>
</Menu>
</>
)
}

export default forwardRef(PlainTextDropdown)
45 changes: 15 additions & 30 deletions docs/src/components/PlainTextSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,34 @@
import type { ReactNode } from "react"
import type { PlainTextDropdownExposed } from "@/components/PlainTextDropdown"

import useMenuTrigger from "@/hooks/useMenuTrigger"
import { mdiMenuDown } from "@mdi/js"
import { Icon } from "@mdi/react"
import { ButtonBase, ClickAwayListener, Menu, MenuItem, MenuList } from "@mui/material"
import cn from "clsx"
import React, { useState } from "react"
import PlainTextDropdown from "@/components/PlainTextDropdown"
import { MenuItem } from "@mui/material"
import { useRef, useState } from "react"

interface PlainTextSelectProps<T> {
className?: string
items: T[]
renderLabel: (value: T | null) => ReactNode
children: (value: T) => React.ReactNode
children: (value: T) => ReactNode
}

export default function PlainTextSelect<T>(
{ className, items, renderLabel, children }: PlainTextSelectProps<T>
) {
const [value, setValue] = useState<T | null>(null)
const { anchor, open, handleClick, handleClose } = useMenuTrigger()
const dropdownRef = useRef<PlainTextDropdownExposed>(null)
const handleMenuClick = (data: T | null) => {
setValue(data)
handleClose()
dropdownRef.current?.close()
}
return (
<>
<ButtonBase
className={cn("bar-menu-selector px-1 rounded-[2px]", className)}
onClick={handleClick}
>
{renderLabel(value)}
<Icon path={mdiMenuDown} rotate={open ? 180 : 0} size={1} />
</ButtonBase>
<Menu open={open} anchorEl={anchor}>
<ClickAwayListener onClickAway={handleClose}>
<MenuList>
<MenuItem onClick={() => handleMenuClick(null)}>None</MenuItem>
{items.map((item, index) => (
<MenuItem key={index} onClick={() => handleMenuClick(item)}>
{children(item)}
</MenuItem>
))}
</MenuList>
</ClickAwayListener>
</Menu>
</>
<PlainTextDropdown ref={dropdownRef} className={className} Label={renderLabel(value)}>
<MenuItem onClick={() => handleMenuClick(null)}>None</MenuItem>
{items.map((item, index) => (
<MenuItem key={index} onClick={() => handleMenuClick(item)}>
{children(item)}
</MenuItem>
))}
</PlainTextDropdown>
)
}

0 comments on commit 675edac

Please sign in to comment.