From a1f990584b70c05b1b9e1da8271de5e69e0b47d4 Mon Sep 17 00:00:00 2001 From: yyh <92089059+lyzno1@users.noreply.github.com> Date: Thu, 16 Apr 2026 15:35:04 +0800 Subject: [PATCH] refactor(web): unify Base UI component props to namespace types (#35306) --- .../components/base/ui/alert-dialog/index.tsx | 14 +++++----- web/app/components/base/ui/avatar/index.tsx | 7 ++--- .../components/base/ui/context-menu/index.tsx | 28 +++++++++---------- web/app/components/base/ui/dialog/index.tsx | 8 +++--- .../base/ui/dropdown-menu/index.tsx | 28 +++++++++---------- .../components/base/ui/number-field/index.tsx | 14 +++++----- web/app/components/base/ui/popover/index.tsx | 8 +++--- .../components/base/ui/scroll-area/index.tsx | 14 +++++----- web/app/components/base/ui/select/index.tsx | 22 +++++++-------- web/app/components/base/ui/tooltip/index.tsx | 6 ++-- .../__tests__/index.spec.tsx | 2 +- .../workplace-selector/index.tsx | 2 +- 12 files changed, 76 insertions(+), 77 deletions(-) diff --git a/web/app/components/base/ui/alert-dialog/index.tsx b/web/app/components/base/ui/alert-dialog/index.tsx index e591fed2a3..f277c343fc 100644 --- a/web/app/components/base/ui/alert-dialog/index.tsx +++ b/web/app/components/base/ui/alert-dialog/index.tsx @@ -1,9 +1,9 @@ 'use client' +import type { ComponentPropsWithoutRef, ReactNode } from 'react' import type { ButtonProps } from '@/app/components/base/ui/button' import { AlertDialog as BaseAlertDialog } from '@base-ui/react/alert-dialog' import { cn } from '@langgenius/dify-ui/cn' -import * as React from 'react' import { Button } from '@/app/components/base/ui/button' export const AlertDialog = BaseAlertDialog.Root @@ -12,11 +12,11 @@ export const AlertDialogTitle = BaseAlertDialog.Title export const AlertDialogDescription = BaseAlertDialog.Description type AlertDialogContentProps = { - children: React.ReactNode + children: ReactNode className?: string overlayClassName?: string - popupProps?: Omit, 'children' | 'className'> - backdropProps?: Omit, 'className'> + popupProps?: Omit + backdropProps?: Omit } export function AlertDialogContent({ @@ -50,7 +50,7 @@ export function AlertDialogContent({ ) } -type AlertDialogActionsProps = React.ComponentPropsWithoutRef<'div'> +type AlertDialogActionsProps = ComponentPropsWithoutRef<'div'> export function AlertDialogActions({ className, ...props }: AlertDialogActionsProps) { return ( @@ -62,8 +62,8 @@ export function AlertDialogActions({ className, ...props }: AlertDialogActionsPr } type AlertDialogCancelButtonProps = Omit & { - children: React.ReactNode - closeProps?: Omit, 'children' | 'render'> + children: ReactNode + closeProps?: Omit } export function AlertDialogCancelButton({ diff --git a/web/app/components/base/ui/avatar/index.tsx b/web/app/components/base/ui/avatar/index.tsx index 1587dd2d33..6fca2e87dc 100644 --- a/web/app/components/base/ui/avatar/index.tsx +++ b/web/app/components/base/ui/avatar/index.tsx @@ -1,5 +1,4 @@ import type { ImageLoadingStatus } from '@base-ui/react/avatar' -import type * as React from 'react' import { Avatar as BaseAvatar } from '@base-ui/react/avatar' import { cn } from '@langgenius/dify-ui/cn' @@ -24,7 +23,7 @@ export type AvatarProps = { onLoadingStatusChange?: (status: ImageLoadingStatus) => void } -type AvatarRootProps = React.ComponentPropsWithRef & { +type AvatarRootProps = BaseAvatar.Root.Props & { size?: AvatarSize } @@ -45,7 +44,7 @@ export function AvatarRoot({ ) } -type AvatarFallbackProps = React.ComponentPropsWithRef & { +type AvatarFallbackProps = BaseAvatar.Fallback.Props & { size?: AvatarSize } @@ -66,7 +65,7 @@ export function AvatarFallback({ ) } -type AvatarImageProps = React.ComponentPropsWithRef +type AvatarImageProps = BaseAvatar.Image.Props export function AvatarImage({ className, diff --git a/web/app/components/base/ui/context-menu/index.tsx b/web/app/components/base/ui/context-menu/index.tsx index 4331f095b3..4ff7241b23 100644 --- a/web/app/components/base/ui/context-menu/index.tsx +++ b/web/app/components/base/ui/context-menu/index.tsx @@ -1,9 +1,9 @@ 'use client' +import type { ReactNode } from 'react' import type { Placement } from '@/app/components/base/ui/placement' import { ContextMenu as BaseContextMenu } from '@base-ui/react/context-menu' import { cn } from '@langgenius/dify-ui/cn' -import * as React from 'react' import { overlayBackdropClassName, overlayGroupLabelClassName, @@ -22,18 +22,18 @@ export const ContextMenuGroup = BaseContextMenu.Group export const ContextMenuRadioGroup = BaseContextMenu.RadioGroup type ContextMenuContentProps = { - children: React.ReactNode + children: ReactNode placement?: Placement sideOffset?: number alignOffset?: number className?: string popupClassName?: string positionerProps?: Omit< - React.ComponentPropsWithoutRef, + BaseContextMenu.Positioner.Props, 'children' | 'className' | 'side' | 'align' | 'sideOffset' | 'alignOffset' > popupProps?: Omit< - React.ComponentPropsWithoutRef, + BaseContextMenu.Popup.Props, 'children' | 'className' > } @@ -113,7 +113,7 @@ export function ContextMenuContent({ }) } -type ContextMenuItemProps = React.ComponentPropsWithoutRef & { +type ContextMenuItemProps = BaseContextMenu.Item.Props & { destructive?: boolean } @@ -130,7 +130,7 @@ export function ContextMenuItem({ ) } -type ContextMenuLinkItemProps = React.ComponentPropsWithoutRef & { +type ContextMenuLinkItemProps = BaseContextMenu.LinkItem.Props & { destructive?: boolean } @@ -152,7 +152,7 @@ export function ContextMenuLinkItem({ export function ContextMenuRadioItem({ className, ...props -}: React.ComponentPropsWithoutRef) { +}: BaseContextMenu.RadioItem.Props) { return ( ) { +}: BaseContextMenu.CheckboxItem.Props) { return ( , 'children'>) { +}: Omit) { return ( , 'children'>) { +}: Omit) { return ( & { +type ContextMenuSubTriggerProps = BaseContextMenu.SubmenuTrigger.Props & { destructive?: boolean } @@ -223,7 +223,7 @@ export function ContextMenuSubTrigger({ } type ContextMenuSubContentProps = { - children: React.ReactNode + children: ReactNode placement?: Placement sideOffset?: number alignOffset?: number @@ -258,7 +258,7 @@ export function ContextMenuSubContent({ export function ContextMenuGroupLabel({ className, ...props -}: React.ComponentPropsWithoutRef) { +}: BaseContextMenu.GroupLabel.Props) { return ( ) { +}: BaseContextMenu.Separator.Props) { return ( , 'children'> +type DialogCloseButtonProps = Omit export function DialogCloseButton({ className, @@ -40,10 +40,10 @@ export function DialogCloseButton({ } type DialogContentProps = { - children: React.ReactNode + children: ReactNode className?: string overlayClassName?: string - backdropProps?: React.ComponentPropsWithoutRef + backdropProps?: BaseDialog.Backdrop.Props } export function DialogContent({ diff --git a/web/app/components/base/ui/dropdown-menu/index.tsx b/web/app/components/base/ui/dropdown-menu/index.tsx index ca73e8b003..9046e25ca2 100644 --- a/web/app/components/base/ui/dropdown-menu/index.tsx +++ b/web/app/components/base/ui/dropdown-menu/index.tsx @@ -1,9 +1,9 @@ 'use client' +import type { ReactNode } from 'react' import type { Placement } from '@/app/components/base/ui/placement' import { Menu } from '@base-ui/react/menu' import { cn } from '@langgenius/dify-ui/cn' -import * as React from 'react' import { overlayGroupLabelClassName, overlayIndicatorClassName, @@ -23,7 +23,7 @@ export const DropdownMenuRadioGroup = Menu.RadioGroup export function DropdownMenuRadioItem({ className, ...props -}: React.ComponentPropsWithoutRef) { +}: Menu.RadioItem.Props) { return ( , 'children'>) { +}: Omit) { return ( ) { +}: Menu.CheckboxItem.Props) { return ( , 'children'>) { +}: Omit) { return ( ) { +}: Menu.GroupLabel.Props) { return ( , + Menu.Positioner.Props, 'children' | 'className' | 'side' | 'align' | 'sideOffset' | 'alignOffset' > popupProps?: Omit< - React.ComponentPropsWithoutRef, + Menu.Popup.Props, 'children' | 'className' > } @@ -170,7 +170,7 @@ export function DropdownMenuContent({ }) } -type DropdownMenuSubTriggerProps = React.ComponentPropsWithoutRef & { +type DropdownMenuSubTriggerProps = Menu.SubmenuTrigger.Props & { destructive?: boolean } @@ -192,7 +192,7 @@ export function DropdownMenuSubTrigger({ } type DropdownMenuSubContentProps = { - children: React.ReactNode + children: ReactNode placement?: Placement sideOffset?: number alignOffset?: number @@ -224,7 +224,7 @@ export function DropdownMenuSubContent({ }) } -type DropdownMenuItemProps = React.ComponentPropsWithoutRef & { +type DropdownMenuItemProps = Menu.Item.Props & { destructive?: boolean } @@ -241,7 +241,7 @@ export function DropdownMenuItem({ ) } -type DropdownMenuLinkItemProps = React.ComponentPropsWithoutRef & { +type DropdownMenuLinkItemProps = Menu.LinkItem.Props & { destructive?: boolean } @@ -263,7 +263,7 @@ export function DropdownMenuLinkItem({ export function DropdownMenuSeparator({ className, ...props -}: React.ComponentPropsWithoutRef) { +}: Menu.Separator.Props) { return ( +export type NumberFieldRootProps = BaseNumberField.Root.Props export const numberFieldGroupVariants = cva( [ @@ -32,7 +32,7 @@ export const numberFieldGroupVariants = cva( ) export type NumberFieldSize = NonNullable['size']> -export type NumberFieldGroupProps = React.ComponentPropsWithoutRef & VariantProps +export type NumberFieldGroupProps = BaseNumberField.Group.Props & VariantProps export function NumberFieldGroup({ className, @@ -67,7 +67,7 @@ export const numberFieldInputVariants = cva( }, ) -export type NumberFieldInputProps = Omit, 'size'> & VariantProps +export type NumberFieldInputProps = Omit & VariantProps export function NumberFieldInput({ className, @@ -97,7 +97,7 @@ export const numberFieldUnitVariants = cva( }, ) -export type NumberFieldUnitProps = React.HTMLAttributes & VariantProps +export type NumberFieldUnitProps = HTMLAttributes & VariantProps export function NumberFieldUnit({ className, @@ -116,7 +116,7 @@ const numberFieldControlsVariants = cva( 'flex shrink-0 flex-col items-stretch border-l border-divider-subtle bg-transparent text-text-tertiary', ) -export type NumberFieldControlsProps = React.HTMLAttributes +export type NumberFieldControlsProps = HTMLAttributes export function NumberFieldControls({ className, @@ -185,7 +185,7 @@ type NumberFieldButtonVariantProps = Omit< 'direction' > -export type NumberFieldButtonProps = React.ComponentPropsWithoutRef & NumberFieldButtonVariantProps +export type NumberFieldButtonProps = BaseNumberField.Increment.Props & NumberFieldButtonVariantProps const incrementAriaLabel = 'Increment value' const decrementAriaLabel = 'Decrement value' diff --git a/web/app/components/base/ui/popover/index.tsx b/web/app/components/base/ui/popover/index.tsx index 4383112a4b..dbde17ae21 100644 --- a/web/app/components/base/ui/popover/index.tsx +++ b/web/app/components/base/ui/popover/index.tsx @@ -1,9 +1,9 @@ 'use client' +import type { ReactNode } from 'react' import type { Placement } from '@/app/components/base/ui/placement' import { Popover as BasePopover } from '@base-ui/react/popover' import { cn } from '@langgenius/dify-ui/cn' -import * as React from 'react' import { parsePlacement } from '@/app/components/base/ui/placement' export const Popover = BasePopover.Root @@ -15,18 +15,18 @@ export const PopoverTitle = BasePopover.Title export const PopoverDescription = BasePopover.Description type PopoverContentProps = { - children: React.ReactNode + children: ReactNode placement?: Placement sideOffset?: number alignOffset?: number className?: string popupClassName?: string positionerProps?: Omit< - React.ComponentPropsWithoutRef, + BasePopover.Positioner.Props, 'children' | 'className' | 'side' | 'align' | 'sideOffset' | 'alignOffset' > popupProps?: Omit< - React.ComponentPropsWithoutRef, + BasePopover.Popup.Props, 'children' | 'className' > } diff --git a/web/app/components/base/ui/scroll-area/index.tsx b/web/app/components/base/ui/scroll-area/index.tsx index 242f735054..9a23145039 100644 --- a/web/app/components/base/ui/scroll-area/index.tsx +++ b/web/app/components/base/ui/scroll-area/index.tsx @@ -1,12 +1,12 @@ 'use client' +import type { ReactNode } from 'react' import { ScrollArea as BaseScrollArea } from '@base-ui/react/scroll-area' import { cn } from '@langgenius/dify-ui/cn' -import * as React from 'react' import './scroll-area.css' export const ScrollAreaRoot = BaseScrollArea.Root -type ScrollAreaRootProps = React.ComponentPropsWithRef +type ScrollAreaRootProps = BaseScrollArea.Root.Props export const ScrollAreaContent = BaseScrollArea.Content @@ -17,7 +17,7 @@ type ScrollAreaSlotClassNames = { } type ScrollAreaProps = Omit & { - children: React.ReactNode + children: ReactNode orientation?: 'vertical' | 'horizontal' slotClassNames?: ScrollAreaSlotClassNames label?: string @@ -45,7 +45,7 @@ const scrollAreaViewportClassName = cn( const scrollAreaCornerClassName = 'bg-transparent' -type ScrollAreaViewportProps = React.ComponentPropsWithRef +type ScrollAreaViewportProps = BaseScrollArea.Viewport.Props export function ScrollAreaViewport({ className, @@ -59,7 +59,7 @@ export function ScrollAreaViewport({ ) } -type ScrollAreaScrollbarProps = React.ComponentPropsWithRef +type ScrollAreaScrollbarProps = BaseScrollArea.Scrollbar.Props export function ScrollAreaScrollbar({ className, @@ -74,7 +74,7 @@ export function ScrollAreaScrollbar({ ) } -type ScrollAreaThumbProps = React.ComponentPropsWithRef +type ScrollAreaThumbProps = BaseScrollArea.Thumb.Props export function ScrollAreaThumb({ className, @@ -88,7 +88,7 @@ export function ScrollAreaThumb({ ) } -type ScrollAreaCornerProps = React.ComponentPropsWithRef +type ScrollAreaCornerProps = BaseScrollArea.Corner.Props export function ScrollAreaCorner({ className, diff --git a/web/app/components/base/ui/select/index.tsx b/web/app/components/base/ui/select/index.tsx index 81514a9ad5..80a32fca1e 100644 --- a/web/app/components/base/ui/select/index.tsx +++ b/web/app/components/base/ui/select/index.tsx @@ -1,9 +1,9 @@ 'use client' +import type { ReactNode } from 'react' import type { Placement } from '@/app/components/base/ui/placement' import { Select as BaseSelect } from '@base-ui/react/select' import { cn } from '@langgenius/dify-ui/cn' -import * as React from 'react' import { overlayGroupLabelClassName, overlaySeparatorClassName, @@ -21,7 +21,7 @@ const selectSizeClassName: Record = { large: 'h-9 gap-0.5 rounded-[10px] px-4 py-2 system-md-regular', } -type SelectTriggerProps = React.ComponentPropsWithoutRef & { +type SelectTriggerProps = BaseSelect.Trigger.Props & { size?: 'small' | 'regular' | 'large' } @@ -58,7 +58,7 @@ export function SelectTrigger({ export function SelectGroupLabel({ className, ...props -}: React.ComponentPropsWithoutRef) { +}: BaseSelect.GroupLabel.Props) { return ( ) { +}: BaseSelect.Separator.Props) { return ( , + BaseSelect.Positioner.Props, 'children' | 'className' | 'side' | 'align' | 'sideOffset' | 'alignOffset' > popupProps?: Omit< - React.ComponentPropsWithoutRef, + BaseSelect.Popup.Props, 'children' | 'className' > listProps?: Omit< - React.ComponentPropsWithoutRef, + BaseSelect.List.Props, 'children' | 'className' > } @@ -150,7 +150,7 @@ export function SelectContent({ export function SelectItem({ className, ...props -}: React.ComponentPropsWithoutRef) { +}: BaseSelect.Item.Props) { return ( ) { +}: BaseSelect.ItemText.Props) { return ( , 'children'>) { +}: Omit) { return ( , 'children' | 'className'> +} & Omit export function TooltipContent({ children, diff --git a/web/app/components/header/account-dropdown/workplace-selector/__tests__/index.spec.tsx b/web/app/components/header/account-dropdown/workplace-selector/__tests__/index.spec.tsx index c8224bf10d..338096a9e1 100644 --- a/web/app/components/header/account-dropdown/workplace-selector/__tests__/index.spec.tsx +++ b/web/app/components/header/account-dropdown/workplace-selector/__tests__/index.spec.tsx @@ -163,7 +163,7 @@ describe('WorkplaceSelector', () => { await waitFor(() => { expect(mockNotify).toHaveBeenCalledWith({ type: 'error', - message: 'common.provider.saveFailed', + message: 'common.actionMsg.modifiedUnsuccessfully', }) }) }) diff --git a/web/app/components/header/account-dropdown/workplace-selector/index.tsx b/web/app/components/header/account-dropdown/workplace-selector/index.tsx index aa49075621..a155df48d9 100644 --- a/web/app/components/header/account-dropdown/workplace-selector/index.tsx +++ b/web/app/components/header/account-dropdown/workplace-selector/index.tsx @@ -29,7 +29,7 @@ const WorkplaceSelector = () => { location.assign(`${location.origin}${basePath}`) } catch { - toast.error(t('provider.saveFailed', { ns: 'common' })) + toast.error(t('actionMsg.modifiedUnsuccessfully', { ns: 'common' })) } }