From dfabe4cb28dfa06ecc051453d9884c5040b3ce66 Mon Sep 17 00:00:00 2001 From: yyh <92089059+lyzno1@users.noreply.github.com> Date: Wed, 15 Jul 2026 17:53:59 +0800 Subject: [PATCH] refactor(dify-ui): clarify overlay style semantics (#39016) --- packages/dify-ui/src/alert-dialog/index.tsx | 9 ++-- packages/dify-ui/src/autocomplete/index.tsx | 25 +++++++---- packages/dify-ui/src/combobox/index.tsx | 21 +++++---- packages/dify-ui/src/context-menu/index.tsx | 44 ++++++++++--------- packages/dify-ui/src/dialog/index.tsx | 14 ++---- packages/dify-ui/src/dropdown-menu/index.tsx | 45 +++++++++++--------- packages/dify-ui/src/overlay-shared.ts | 22 +++++----- packages/dify-ui/src/popover/index.tsx | 3 +- packages/dify-ui/src/preview-card/index.tsx | 3 +- packages/dify-ui/src/select/index.tsx | 18 ++++---- 10 files changed, 107 insertions(+), 97 deletions(-) diff --git a/packages/dify-ui/src/alert-dialog/index.tsx b/packages/dify-ui/src/alert-dialog/index.tsx index be9af138a49..d0a3cb1e729 100644 --- a/packages/dify-ui/src/alert-dialog/index.tsx +++ b/packages/dify-ui/src/alert-dialog/index.tsx @@ -5,6 +5,7 @@ import type { ButtonProps } from '../button' import { AlertDialog as BaseAlertDialog } from '@base-ui/react/alert-dialog' import { Button } from '../button' import { cn } from '../cn' +import { modalBackdropClassName, modalPopupAnimationClassName } from '../overlay-shared' export const AlertDialog = BaseAlertDialog.Root export const AlertDialogTrigger = BaseAlertDialog.Trigger @@ -28,16 +29,12 @@ export function AlertDialogContent({ diff --git a/packages/dify-ui/src/autocomplete/index.tsx b/packages/dify-ui/src/autocomplete/index.tsx index e8badea1738..dede962654b 100644 --- a/packages/dify-ui/src/autocomplete/index.tsx +++ b/packages/dify-ui/src/autocomplete/index.tsx @@ -8,10 +8,10 @@ import { cva } from 'class-variance-authority' import { cn } from '../cn' import { textControlCompoundFocusClassName } from '../form-control-shared' import { - overlayIndicatorClassName, - overlayLabelClassName, - overlayPopupAnimationClassName, - overlaySeparatorClassName, + floatingGroupLabelClassName, + floatingItemIndicatorClassName, + floatingPopupAnimationClassName, + floatingSeparatorClassName, } from '../overlay-shared' import { parsePlacement } from '../placement' @@ -276,7 +276,11 @@ export function AutocompleteContent({ {...positionerProps} > {children} @@ -303,12 +307,17 @@ export function AutocompleteItemText({ className, ...props }: AutocompleteItemTe } export function AutocompleteGroupLabel({ className, ...props }: BaseAutocomplete.GroupLabel.Props) { - return + return ( + + ) } export function AutocompleteSeparator({ className, ...props }: BaseAutocomplete.Separator.Props) { return ( - + ) } @@ -339,7 +348,7 @@ export function AutocompleteItemIndicator({ ...props }: React.ComponentProps<'span'>) { return ( - + {children ?? ) diff --git a/packages/dify-ui/src/combobox/index.tsx b/packages/dify-ui/src/combobox/index.tsx index e588c9554f0..7b087d23d3f 100644 --- a/packages/dify-ui/src/combobox/index.tsx +++ b/packages/dify-ui/src/combobox/index.tsx @@ -8,10 +8,10 @@ import { cva } from 'class-variance-authority' import { cn } from '../cn' import { formLabelClassName, textControlCompoundFocusClassName } from '../form-control-shared' import { - overlayIndicatorClassName, - overlayLabelClassName, - overlayPopupAnimationClassName, - overlaySeparatorClassName, + floatingGroupLabelClassName, + floatingItemIndicatorClassName, + floatingPopupAnimationClassName, + floatingSeparatorClassName, } from '../overlay-shared' import { parsePlacement } from '../placement' @@ -320,7 +320,7 @@ export function ComboboxContent({ {...positionerProps} > {children} @@ -352,7 +352,10 @@ export function ComboboxItemIndicator({ ...props }: Omit & { children?: React.ReactNode }) { return ( - + {children ?? ) @@ -363,11 +366,13 @@ export function ComboboxLabel({ className, ...props }: BaseCombobox.Label.Props) } export function ComboboxGroupLabel({ className, ...props }: BaseCombobox.GroupLabel.Props) { - return + return ( + + ) } export function ComboboxSeparator({ className, ...props }: BaseCombobox.Separator.Props) { - return + return } export function ComboboxEmpty({ className, ...props }: BaseCombobox.Empty.Props) { diff --git a/packages/dify-ui/src/context-menu/index.tsx b/packages/dify-ui/src/context-menu/index.tsx index d19cacd7e9a..b07a96b8fd2 100644 --- a/packages/dify-ui/src/context-menu/index.tsx +++ b/packages/dify-ui/src/context-menu/index.tsx @@ -1,18 +1,18 @@ 'use client' import type * as React from 'react' -import type { OverlayItemVariant } from '../overlay-shared' +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 { - overlayDestructiveClassName, - overlayIndicatorClassName, - overlayLabelClassName, - overlayPopupAnimationClassName, - overlayPopupBaseClassName, - overlayRowClassName, - overlaySeparatorClassName, + floatingGroupLabelClassName, + floatingItemIndicatorClassName, + floatingPopupAnimationClassName, + floatingSeparatorClassName, + menuItemClassName, + menuItemDestructiveClassName, + menuPopupClassName, } from '../overlay-shared' import { parsePlacement } from '../placement' @@ -73,7 +73,7 @@ function renderContextMenuPopup({ {...positionerProps} > {children} @@ -106,7 +106,7 @@ export function ContextMenuContent({ } type ContextMenuItemProps = BaseContextMenu.Item.Props & { - variant?: OverlayItemVariant + variant?: MenuItemVariant } export function ContextMenuItem({ @@ -117,14 +117,14 @@ export function ContextMenuItem({ return ( ) } type ContextMenuLinkItemProps = BaseContextMenu.LinkItem.Props & { - variant?: OverlayItemVariant + variant?: MenuItemVariant } export function ContextMenuLinkItem({ @@ -136,7 +136,7 @@ export function ContextMenuLinkItem({ return ( @@ -144,14 +144,14 @@ export function ContextMenuLinkItem({ } export function ContextMenuRadioItem({ className, ...props }: BaseContextMenu.RadioItem.Props) { - return + return } export function ContextMenuCheckboxItem({ className, ...props }: BaseContextMenu.CheckboxItem.Props) { - return + return } export function ContextMenuCheckboxItemIndicator({ @@ -160,7 +160,7 @@ export function ContextMenuCheckboxItemIndicator({ }: Omit) { return ( @@ -174,7 +174,7 @@ export function ContextMenuRadioItemIndicator({ }: Omit) { return ( @@ -183,7 +183,7 @@ export function ContextMenuRadioItemIndicator({ } type ContextMenuSubTriggerProps = BaseContextMenu.SubmenuTrigger.Props & { - variant?: OverlayItemVariant + variant?: MenuItemVariant } export function ContextMenuSubTrigger({ @@ -195,7 +195,7 @@ export function ContextMenuSubTrigger({ return ( {children} @@ -241,11 +241,13 @@ export function ContextMenuSubContent({ } export function ContextMenuLabel({ className, ...props }: BaseContextMenu.GroupLabel.Props) { - return + return ( + + ) } export function ContextMenuSeparator({ className, ...props }: BaseContextMenu.Separator.Props) { return ( - + ) } diff --git a/packages/dify-ui/src/dialog/index.tsx b/packages/dify-ui/src/dialog/index.tsx index 7e1a0d40439..9f1413f0d0d 100644 --- a/packages/dify-ui/src/dialog/index.tsx +++ b/packages/dify-ui/src/dialog/index.tsx @@ -3,6 +3,7 @@ import type * as React from 'react' import { Dialog as BaseDialog } from '@base-ui/react/dialog' import { cn } from '../cn' +import { modalBackdropClassName, modalPopupAnimationClassName } from '../overlay-shared' export const Dialog = BaseDialog.Root export const DialogTrigger = BaseDialog.Trigger @@ -16,16 +17,7 @@ type DialogBackdropProps = Omit & { } export function DialogBackdrop({ className, ...props }: DialogBackdropProps) { - return ( - - ) + return } type DialogViewportProps = Omit & { @@ -45,7 +37,7 @@ export function DialogPopup({ className, ...props }: DialogPopupProps) { + return } export function DropdownMenuRadioItemIndicator({ @@ -33,14 +33,14 @@ export function DropdownMenuRadioItemIndicator({ ...props }: Omit) { return ( - + ) } export function DropdownMenuCheckboxItem({ className, ...props }: Menu.CheckboxItem.Props) { - return + return } export function DropdownMenuCheckboxItemIndicator({ @@ -48,14 +48,17 @@ export function DropdownMenuCheckboxItemIndicator({ ...props }: Omit) { return ( - + ) } export function DropdownMenuLabel({ className, ...props }: Menu.GroupLabel.Props) { - return + return } type DropdownMenuContentProps = { @@ -105,7 +108,7 @@ function renderDropdownMenuPopup({ {...positionerProps} > {children} @@ -138,7 +141,7 @@ export function DropdownMenuContent({ } type DropdownMenuSubTriggerProps = Menu.SubmenuTrigger.Props & { - variant?: OverlayItemVariant + variant?: MenuItemVariant } export function DropdownMenuSubTrigger({ @@ -150,7 +153,7 @@ export function DropdownMenuSubTrigger({ return ( {children} @@ -196,7 +199,7 @@ export function DropdownMenuSubContent({ } type DropdownMenuItemProps = Menu.Item.Props & { - variant?: OverlayItemVariant + variant?: MenuItemVariant } export function DropdownMenuItem({ @@ -207,14 +210,14 @@ export function DropdownMenuItem({ return ( ) } type DropdownMenuLinkItemProps = Menu.LinkItem.Props & { - variant?: OverlayItemVariant + variant?: MenuItemVariant } export function DropdownMenuLinkItem({ @@ -226,7 +229,7 @@ export function DropdownMenuLinkItem({ return ( @@ -234,5 +237,5 @@ export function DropdownMenuLinkItem({ } export function DropdownMenuSeparator({ className, ...props }: Menu.Separator.Props) { - return + return } diff --git a/packages/dify-ui/src/overlay-shared.ts b/packages/dify-ui/src/overlay-shared.ts index 7710ed0a080..fbeeef80e43 100644 --- a/packages/dify-ui/src/overlay-shared.ts +++ b/packages/dify-ui/src/overlay-shared.ts @@ -1,16 +1,18 @@ -export type OverlayItemVariant = 'default' | 'destructive' +export type MenuItemVariant = 'default' | 'destructive' -export const overlayRowClassName = +export const menuItemClassName = 'mx-1 flex h-8 cursor-pointer select-none items-center gap-1 rounded-lg px-2 outline-hidden data-highlighted:bg-state-base-hover data-disabled:cursor-not-allowed data-disabled:opacity-30' -export const overlayDestructiveClassName = +export const menuItemDestructiveClassName = 'data-[variant=destructive]:text-text-destructive data-[variant=destructive]:data-highlighted:bg-state-destructive-hover' -export const overlayIndicatorClassName = 'ms-auto flex shrink-0 items-center text-text-accent' -export const overlayLabelClassName = +export const floatingItemIndicatorClassName = 'ms-auto flex shrink-0 items-center text-text-accent' +export const floatingGroupLabelClassName = 'px-3 pb-0.5 pt-1 text-text-tertiary system-xs-medium-uppercase' -export const overlaySeparatorClassName = 'my-1 h-px bg-divider-subtle' -export const overlayPopupBaseClassName = +export const floatingSeparatorClassName = 'my-1 h-px bg-divider-subtle' +export const menuPopupClassName = 'max-h-(--available-height) overflow-y-auto overflow-x-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur py-1 text-sm text-text-secondary shadow-lg outline-hidden focus:outline-hidden focus-visible:outline-hidden backdrop-blur-[5px]' -export const overlayPopupAnimationClassName = +export const floatingPopupAnimationClassName = 'origin-(--transform-origin) transition-[transform,scale,opacity] data-ending-style:scale-95 data-starting-style:scale-95 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none' -export const overlayBackdropClassName = - 'fixed inset-0 z-50 bg-transparent transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none' +export const modalBackdropClassName = + 'absolute inset-0 z-50 bg-background-overlay transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none' +export const modalPopupAnimationClassName = + 'transition-[transform,scale,opacity] duration-150 data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0 motion-reduce:transition-none' diff --git a/packages/dify-ui/src/popover/index.tsx b/packages/dify-ui/src/popover/index.tsx index c314e92f2c0..514af9c6f55 100644 --- a/packages/dify-ui/src/popover/index.tsx +++ b/packages/dify-ui/src/popover/index.tsx @@ -4,6 +4,7 @@ import type * as React from 'react' import type { Placement } from '../placement' import { Popover as BasePopover } from '@base-ui/react/popover' import { cn } from '../cn' +import { floatingPopupAnimationClassName } from '../overlay-shared' import { parsePlacement } from '../placement' export type { Placement } @@ -55,7 +56,7 @@ export function PopoverContent({ className={cn( 'rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg', 'outline-hidden focus:outline-hidden focus-visible:outline-hidden', - 'origin-(--transform-origin) transition-[transform,scale,opacity] data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0 motion-reduce:transition-none', + floatingPopupAnimationClassName, popupClassName, )} {...popupProps} diff --git a/packages/dify-ui/src/preview-card/index.tsx b/packages/dify-ui/src/preview-card/index.tsx index ec4a4fe92a7..38a5b5aa23e 100644 --- a/packages/dify-ui/src/preview-card/index.tsx +++ b/packages/dify-ui/src/preview-card/index.tsx @@ -4,6 +4,7 @@ import type * as React from 'react' import type { Placement } from '../placement' import { PreviewCard as BasePreviewCard } from '@base-ui/react/preview-card' import { cn } from '../cn' +import { floatingPopupAnimationClassName } from '../overlay-shared' import { parsePlacement } from '../placement' export type { Placement } @@ -65,7 +66,7 @@ export function PreviewCardContent({ + return } export function SelectSeparator({ className, ...props }: BaseSelect.Separator.Props) { - return + return } type SelectContentProps = { @@ -124,7 +125,7 @@ export function SelectContent({ ) { return ( - + )