mirror of
https://github.com/langgenius/dify.git
synced 2026-10-04 13:47:55 +08:00
316 lines
8.3 KiB
TypeScript
316 lines
8.3 KiB
TypeScript
'use client'
|
|
|
|
import type * as React from 'react'
|
|
import type { MenuItemVariant } from '../overlay-shared'
|
|
import type { Placement } from '../placement'
|
|
import { ContextMenu as BaseContextMenu } from '@base-ui/react/context-menu'
|
|
import { cn } from '../cn'
|
|
import { resolveClassName } from '../internals/resolve-class-name'
|
|
import {
|
|
floatingGroupLabelClassName,
|
|
floatingItemIndicatorClassName,
|
|
floatingPopupAnimationClassName,
|
|
floatingSeparatorClassName,
|
|
menuItemClassName,
|
|
menuItemDestructiveClassName,
|
|
menuPopupClassName,
|
|
} from '../overlay-shared'
|
|
import { parsePlacement } from '../placement'
|
|
|
|
const ContextMenu = BaseContextMenu.Root
|
|
const ContextMenuTrigger = BaseContextMenu.Trigger
|
|
const ContextMenuSub = BaseContextMenu.SubmenuRoot
|
|
const ContextMenuGroup = BaseContextMenu.Group
|
|
type ContextMenuProps = BaseContextMenu.Root.Props
|
|
type ContextMenuActions = BaseContextMenu.Root.Actions
|
|
type ContextMenuTriggerProps = BaseContextMenu.Trigger.Props
|
|
type ContextMenuSubProps = BaseContextMenu.SubmenuRoot.Props
|
|
type ContextMenuGroupProps = BaseContextMenu.Group.Props
|
|
type ContextMenuRadioGroupProps<Value = unknown> = Omit<
|
|
BaseContextMenu.RadioGroup.Props,
|
|
'defaultValue' | 'onValueChange' | 'value'
|
|
> & {
|
|
defaultValue?: Value
|
|
onValueChange?: (
|
|
value: Value,
|
|
eventDetails: BaseContextMenu.RadioGroup.ChangeEventDetails,
|
|
) => void
|
|
value?: Value
|
|
}
|
|
type ContextMenuItemVariant = MenuItemVariant
|
|
// Intentionally no public Backdrop export; Base UI handles context-menu modal dismissal internally.
|
|
|
|
function ContextMenuRadioGroup<Value = unknown>(
|
|
props: ContextMenuRadioGroupProps<Value>,
|
|
): React.JSX.Element {
|
|
return <BaseContextMenu.RadioGroup {...props} />
|
|
}
|
|
|
|
type ContextMenuContentProps = Omit<BaseContextMenu.Popup.Props, 'children'> &
|
|
Pick<BaseContextMenu.Positioner.Props, 'sideOffset' | 'alignOffset'> & {
|
|
children: React.ReactNode
|
|
placement?: Placement
|
|
}
|
|
|
|
function ContextMenuContent({
|
|
children,
|
|
placement = 'bottom-start',
|
|
sideOffset = 0,
|
|
alignOffset = 0,
|
|
className,
|
|
...props
|
|
}: ContextMenuContentProps) {
|
|
const { side, align } = parsePlacement(placement)
|
|
|
|
return (
|
|
<BaseContextMenu.Portal>
|
|
<BaseContextMenu.Positioner
|
|
side={side}
|
|
align={align}
|
|
sideOffset={sideOffset}
|
|
alignOffset={alignOffset}
|
|
className="z-50 outline-hidden"
|
|
>
|
|
<BaseContextMenu.Popup
|
|
className={(state) =>
|
|
cn(
|
|
menuPopupClassName,
|
|
floatingPopupAnimationClassName,
|
|
resolveClassName(className, state),
|
|
)
|
|
}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</BaseContextMenu.Popup>
|
|
</BaseContextMenu.Positioner>
|
|
</BaseContextMenu.Portal>
|
|
)
|
|
}
|
|
|
|
type ContextMenuItemProps = BaseContextMenu.Item.Props & {
|
|
variant?: ContextMenuItemVariant
|
|
}
|
|
|
|
function ContextMenuItem({ className, variant = 'default', ...props }: ContextMenuItemProps) {
|
|
return (
|
|
<BaseContextMenu.Item
|
|
data-variant={variant}
|
|
className={(state) =>
|
|
cn(menuItemClassName, menuItemDestructiveClassName, resolveClassName(className, state))
|
|
}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
type ContextMenuLinkItemProps = BaseContextMenu.LinkItem.Props & {
|
|
variant?: ContextMenuItemVariant
|
|
}
|
|
|
|
function ContextMenuLinkItem({
|
|
className,
|
|
variant = 'default',
|
|
closeOnClick = true,
|
|
...props
|
|
}: ContextMenuLinkItemProps) {
|
|
return (
|
|
<BaseContextMenu.LinkItem
|
|
data-variant={variant}
|
|
className={(state) =>
|
|
cn(menuItemClassName, menuItemDestructiveClassName, resolveClassName(className, state))
|
|
}
|
|
closeOnClick={closeOnClick}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
type ContextMenuRadioItemProps<Value = unknown> = Omit<BaseContextMenu.RadioItem.Props, 'value'> & {
|
|
value: Value
|
|
}
|
|
|
|
function ContextMenuRadioItem<Value = unknown>({
|
|
className,
|
|
...props
|
|
}: ContextMenuRadioItemProps<Value>) {
|
|
return (
|
|
<BaseContextMenu.RadioItem
|
|
className={(state) => cn(menuItemClassName, resolveClassName(className, state))}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function ContextMenuCheckboxItem({ className, ...props }: ContextMenuCheckboxItemProps) {
|
|
return (
|
|
<BaseContextMenu.CheckboxItem
|
|
className={(state) => cn(menuItemClassName, resolveClassName(className, state))}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
type ContextMenuCheckboxItemProps = BaseContextMenu.CheckboxItem.Props
|
|
|
|
function ContextMenuCheckboxItemIndicator({
|
|
className,
|
|
...props
|
|
}: ContextMenuCheckboxItemIndicatorProps) {
|
|
return (
|
|
<BaseContextMenu.CheckboxItemIndicator
|
|
className={(state) => cn(floatingItemIndicatorClassName, resolveClassName(className, state))}
|
|
{...props}
|
|
>
|
|
<span aria-hidden className="i-ri-check-line h-4 w-4" />
|
|
</BaseContextMenu.CheckboxItemIndicator>
|
|
)
|
|
}
|
|
|
|
type ContextMenuCheckboxItemIndicatorProps = Omit<
|
|
BaseContextMenu.CheckboxItemIndicator.Props,
|
|
'children'
|
|
>
|
|
|
|
function ContextMenuRadioItemIndicator({
|
|
className,
|
|
...props
|
|
}: ContextMenuRadioItemIndicatorProps) {
|
|
return (
|
|
<BaseContextMenu.RadioItemIndicator
|
|
className={(state) => cn(floatingItemIndicatorClassName, resolveClassName(className, state))}
|
|
{...props}
|
|
>
|
|
<span aria-hidden className="i-ri-check-line h-4 w-4" />
|
|
</BaseContextMenu.RadioItemIndicator>
|
|
)
|
|
}
|
|
|
|
type ContextMenuRadioItemIndicatorProps = Omit<BaseContextMenu.RadioItemIndicator.Props, 'children'>
|
|
|
|
type ContextMenuSubTriggerProps = BaseContextMenu.SubmenuTrigger.Props & {
|
|
variant?: ContextMenuItemVariant
|
|
}
|
|
|
|
function ContextMenuSubTrigger({
|
|
className,
|
|
variant = 'default',
|
|
children,
|
|
...props
|
|
}: ContextMenuSubTriggerProps) {
|
|
return (
|
|
<BaseContextMenu.SubmenuTrigger
|
|
data-variant={variant}
|
|
className={(state) =>
|
|
cn(menuItemClassName, menuItemDestructiveClassName, resolveClassName(className, state))
|
|
}
|
|
{...props}
|
|
>
|
|
{children}
|
|
<span
|
|
aria-hidden
|
|
className="ms-auto i-ri-arrow-right-s-line size-4 shrink-0 text-text-tertiary"
|
|
/>
|
|
</BaseContextMenu.SubmenuTrigger>
|
|
)
|
|
}
|
|
|
|
type ContextMenuSubContentProps = ContextMenuContentProps
|
|
|
|
function ContextMenuSubContent({
|
|
children,
|
|
placement = 'right-start',
|
|
sideOffset = 4,
|
|
alignOffset = 0,
|
|
className,
|
|
...props
|
|
}: ContextMenuSubContentProps) {
|
|
const { side, align } = parsePlacement(placement)
|
|
|
|
return (
|
|
<BaseContextMenu.Portal>
|
|
<BaseContextMenu.Positioner
|
|
side={side}
|
|
align={align}
|
|
sideOffset={sideOffset}
|
|
alignOffset={alignOffset}
|
|
className="z-50 outline-hidden"
|
|
>
|
|
<BaseContextMenu.Popup
|
|
className={(state) =>
|
|
cn(
|
|
menuPopupClassName,
|
|
floatingPopupAnimationClassName,
|
|
resolveClassName(className, state),
|
|
)
|
|
}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</BaseContextMenu.Popup>
|
|
</BaseContextMenu.Positioner>
|
|
</BaseContextMenu.Portal>
|
|
)
|
|
}
|
|
|
|
type ContextMenuGroupLabelProps = BaseContextMenu.GroupLabel.Props
|
|
|
|
function ContextMenuGroupLabel({ className, ...props }: ContextMenuGroupLabelProps) {
|
|
return (
|
|
<BaseContextMenu.GroupLabel
|
|
className={(state) => cn(floatingGroupLabelClassName, resolveClassName(className, state))}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
type ContextMenuSeparatorProps = BaseContextMenu.Separator.Props
|
|
|
|
function ContextMenuSeparator({ className, ...props }: ContextMenuSeparatorProps) {
|
|
return (
|
|
<BaseContextMenu.Separator
|
|
className={(state) => cn(floatingSeparatorClassName, resolveClassName(className, state))}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export {
|
|
ContextMenu,
|
|
ContextMenuCheckboxItem,
|
|
ContextMenuCheckboxItemIndicator,
|
|
ContextMenuContent,
|
|
ContextMenuGroup,
|
|
ContextMenuGroupLabel,
|
|
ContextMenuItem,
|
|
ContextMenuLinkItem,
|
|
ContextMenuRadioGroup,
|
|
ContextMenuRadioItem,
|
|
ContextMenuRadioItemIndicator,
|
|
ContextMenuSeparator,
|
|
ContextMenuSub,
|
|
ContextMenuSubContent,
|
|
ContextMenuSubTrigger,
|
|
ContextMenuTrigger,
|
|
}
|
|
|
|
export type {
|
|
ContextMenuActions,
|
|
ContextMenuCheckboxItemIndicatorProps,
|
|
ContextMenuCheckboxItemProps,
|
|
ContextMenuContentProps,
|
|
ContextMenuGroupLabelProps,
|
|
ContextMenuGroupProps,
|
|
ContextMenuItemProps,
|
|
ContextMenuLinkItemProps,
|
|
ContextMenuProps,
|
|
ContextMenuRadioGroupProps,
|
|
ContextMenuRadioItemIndicatorProps,
|
|
ContextMenuRadioItemProps,
|
|
ContextMenuSeparatorProps,
|
|
ContextMenuSubContentProps,
|
|
ContextMenuSubProps,
|
|
ContextMenuSubTriggerProps,
|
|
ContextMenuTriggerProps,
|
|
}
|