From 49b9b6baef3a7244166475f82ea29b3b34576ac4 Mon Sep 17 00:00:00 2001 From: yyh Date: Sun, 19 Apr 2026 16:07:06 +0800 Subject: [PATCH] chore(web): migrate infotip-style tooltips to popover Switch 13 infotip / static-trigger usages of @langgenius/dify-ui/tooltip over to @langgenius/dify-ui/popover with openOnHover, so the descriptive content is reachable on touch and via screen readers. Visual presentation is preserved by setting popupClassName to match the original tooltip styling. Triggers that already own a primary click action (model selector rows, variable chips, online-user avatars, etc.) are intentionally left on Tooltip pending a separate selection-with-preview redesign, since swapping in Popover would have click both fire that action and toggle the popup. Made-with: Cursor --- .../components/app/app-publisher/sections.tsx | 25 ++++++++----- .../config-prompt/advanced-prompt-input.tsx | 26 ++++++++------ .../config-prompt/simple-prompt-input.tsx | 26 ++++++++------ .../app/overview/app-card-sections.tsx | 25 ++++++++----- .../members-page/invited-modal/index.tsx | 18 ++++++---- .../model-parameter-modal/parameter-item.tsx | 18 ++++++---- .../usage-priority-section.tsx | 17 +++++---- .../provider-added-card/quota-panel.tsx | 16 ++++++--- .../system-model-selector/index.tsx | 25 +++++++------ .../layout/__tests__/field-title.spec.tsx | 8 ++--- .../_base/components/layout/field-title.tsx | 19 ++++++---- .../workflow/nodes/_base/node-sections.tsx | 28 +++++++++------ .../llm/components/panel-memory-section.tsx | 34 ++++++++++++------ .../llm/components/panel-output-section.tsx | 35 +++++++++++-------- 14 files changed, 203 insertions(+), 117 deletions(-) diff --git a/web/app/components/app/app-publisher/sections.tsx b/web/app/components/app/app-publisher/sections.tsx index 57522095ae..1ba78dc2b0 100644 --- a/web/app/components/app/app-publisher/sections.tsx +++ b/web/app/components/app/app-publisher/sections.tsx @@ -4,10 +4,10 @@ import type { AppPublisherProps } from './index' import type { PublishWorkflowParams } from '@/types/workflow' import { Button } from '@langgenius/dify-ui/button' import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from '@langgenius/dify-ui/tooltip' + Popover, + PopoverContent, + PopoverTrigger, +} from '@langgenius/dify-ui/popover' import { useTranslation } from 'react-i18next' import Divider from '@/app/components/base/divider' import { CodeBrowser } from '@/app/components/base/icons/src/vender/line/development' @@ -240,12 +240,19 @@ const ActionTooltip = ({ return <>{children} return ( - - {children}} /> - + + {children}} + /> + {tooltip} - - + + ) } diff --git a/web/app/components/app/configuration/config-prompt/advanced-prompt-input.tsx b/web/app/components/app/configuration/config-prompt/advanced-prompt-input.tsx index 5fd394ad45..11bf901d63 100644 --- a/web/app/components/app/configuration/config-prompt/advanced-prompt-input.tsx +++ b/web/app/components/app/configuration/config-prompt/advanced-prompt-input.tsx @@ -4,12 +4,12 @@ import type { ExternalDataTool } from '@/models/common' import type { PromptRole, PromptVariable } from '@/models/debug' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' -import { toast } from '@langgenius/dify-ui/toast' import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from '@langgenius/dify-ui/tooltip' + Popover, + PopoverContent, + PopoverTrigger, +} from '@langgenius/dify-ui/popover' +import { toast } from '@langgenius/dify-ui/toast' import { RiDeleteBinLine, RiErrorWarningFill, @@ -183,18 +183,24 @@ const AdvancedPromptInput: FC = ({
{t('pageTitle.line1', { ns: 'appDebug' })}
- - + )} /> - +
{t('promptTip', { ns: 'appDebug' })}
-
-
+ + )}
diff --git a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx index 2935504f15..511556ee65 100644 --- a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx +++ b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx @@ -4,12 +4,12 @@ import type { ExternalDataTool } from '@/models/common' import type { PromptVariable } from '@/models/debug' import type { GenRes } from '@/service/debug' import { cn } from '@langgenius/dify-ui/cn' -import { toast } from '@langgenius/dify-ui/toast' import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from '@langgenius/dify-ui/tooltip' + Popover, + PopoverContent, + PopoverTrigger, +} from '@langgenius/dify-ui/popover' +import { toast } from '@langgenius/dify-ui/toast' import { useBoolean } from 'ahooks' import { noop } from 'es-toolkit/function' import { produce } from 'immer' @@ -183,18 +183,24 @@ const Prompt: FC = ({
{mode !== AppModeEnum.COMPLETION ? t('chatSubTitle', { ns: 'appDebug' }) : t('completionSubTitle', { ns: 'appDebug' })}
{!readonly && ( - - + )} /> - +
{t('promptTip', { ns: 'appDebug' })}
-
-
+ + )}
diff --git a/web/app/components/app/overview/app-card-sections.tsx b/web/app/components/app/overview/app-card-sections.tsx index 8fef355f34..0d1c1c3cb3 100644 --- a/web/app/components/app/overview/app-card-sections.tsx +++ b/web/app/components/app/overview/app-card-sections.tsx @@ -16,10 +16,10 @@ import { } from '@langgenius/dify-ui/alert-dialog' import { Button } from '@langgenius/dify-ui/button' import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from '@langgenius/dify-ui/tooltip' + Popover, + PopoverContent, + PopoverTrigger, +} from '@langgenius/dify-ui/popover' import { RiArrowRightSLine, RiBookOpenLine, RiBuildingLine, RiEqualizer2Line, RiExternalLinkLine, RiGlobalLine, RiLockLine, RiPaintBrushLine, RiVerifiedBadgeLine, RiWindowLine } from '@remixicon/react' import CopyFeedback from '@/app/components/base/copy-feedback' import Divider from '@/app/components/base/divider' @@ -87,12 +87,19 @@ const MaybeTooltip = ({ return <>{children} return ( - - {children}
} /> - + + {children}
} + /> + {content} - - + + ) } diff --git a/web/app/components/header/account-setting/members-page/invited-modal/index.tsx b/web/app/components/header/account-setting/members-page/invited-modal/index.tsx index 52cc69f726..77ed429be5 100644 --- a/web/app/components/header/account-setting/members-page/invited-modal/index.tsx +++ b/web/app/components/header/account-setting/members-page/invited-modal/index.tsx @@ -1,7 +1,7 @@ import type { InvitationResult } from '@/models/common' import { Button } from '@langgenius/dify-ui/button' import { Dialog, DialogCloseButton, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' -import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { IS_CE_EDITION } from '@/config' @@ -73,8 +73,11 @@ const InvitedModal = ({ { failedInvitationResults.map(item => (
- - + {item.email} @@ -82,10 +85,13 @@ const InvitedModal = ({
)} /> - + {item.message} - - + + ), ) diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx index f7e1962fd7..ba2cd4b072 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx @@ -4,10 +4,10 @@ import type { NodeOutPutVar, } from '@/app/components/workflow/types' import { cn } from '@langgenius/dify-ui/cn' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { Select, SelectContent, SelectItem, SelectItemIndicator, SelectItemText, SelectTrigger, SelectValue } from '@langgenius/dify-ui/select' import { Slider } from '@langgenius/dify-ui/slider' import { Switch } from '@langgenius/dify-ui/switch' -import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import PromptEditor from '@/app/components/base/prompt-editor' @@ -349,18 +349,24 @@ function ParameterItem({ { parameterRule.help && ( - - + )} /> - +
{parameterRule.help[language] || parameterRule.help.en_US}
-
-
+ + ) } diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/usage-priority-section.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/usage-priority-section.tsx index e572ec41af..593d915db3 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/usage-priority-section.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/usage-priority-section.tsx @@ -1,6 +1,6 @@ import type { UsagePriority } from '../use-credential-panel-state' import { cn } from '@langgenius/dify-ui/cn' -import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { useTranslation } from 'react-i18next' import { PreferredProviderTypeEnum } from '../../declarations' @@ -31,8 +31,10 @@ export default function UsagePrioritySection({ value, disabled, onSelect }: Usag {t('modelProvider.card.usagePriority', { ns: 'common' })} - - + @@ -40,10 +42,13 @@ export default function UsagePrioritySection({ value, disabled, onSelect }: Usag )} /> - + {t('modelProvider.card.usagePriorityTip', { ns: 'common' })} - - + +
{options.map(option => ( diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx index 7828dc4635..771a0522b6 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx @@ -3,6 +3,7 @@ import type { ModelProvider } from '../declarations' import type { Plugin } from '@/app/components/plugins/types' import type { ModelProviderQuotaGetPaid } from '@/types/model-provider' import { cn } from '@langgenius/dify-ui/cn' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { useBoolean } from 'ahooks' import * as React from 'react' @@ -99,8 +100,10 @@ const QuotaPanel: FC = ({
{t('modelProvider.quota', { ns: 'common' })} - - + @@ -108,10 +111,13 @@ const QuotaPanel: FC = ({ )} /> - + {tipText} - - + +
diff --git a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx index 9f993260ca..e3066fdccd 100644 --- a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx @@ -10,12 +10,12 @@ import { DialogContent, DialogTitle, } from '@langgenius/dify-ui/dialog' -import { toast } from '@langgenius/dify-ui/toast' import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from '@langgenius/dify-ui/tooltip' + Popover, + PopoverContent, + PopoverTrigger, +} from '@langgenius/dify-ui/popover' +import { toast } from '@langgenius/dify-ui/toast' import { useState } from 'react' import { useTranslation } from 'react-i18next' import { useAppContext } from '@/context/app-context' @@ -138,8 +138,10 @@ const SystemModel: FC = ({ return (
{t(labelKey, { ns: 'common' })} - - + @@ -147,12 +149,15 @@ const SystemModel: FC = ({ )} /> - +
{tipText}
-
-
+ +
) } diff --git a/web/app/components/workflow/nodes/_base/components/layout/__tests__/field-title.spec.tsx b/web/app/components/workflow/nodes/_base/components/layout/__tests__/field-title.spec.tsx index c11b5ecfc8..fe51156964 100644 --- a/web/app/components/workflow/nodes/_base/components/layout/__tests__/field-title.spec.tsx +++ b/web/app/components/workflow/nodes/_base/components/layout/__tests__/field-title.spec.tsx @@ -1,10 +1,10 @@ import { fireEvent, render, screen } from '@testing-library/react' import { FieldTitle } from '../field-title' -vi.mock('@langgenius/dify-ui/tooltip', () => ({ - Tooltip: ({ children }: { children: React.ReactNode }) =>
{children}
, - TooltipTrigger: ({ render }: { render: React.ReactNode }) => <>{render}, - TooltipContent: ({ children }: { children: React.ReactNode }) =>
{children}
, +vi.mock('@langgenius/dify-ui/popover', () => ({ + Popover: ({ children }: { children: React.ReactNode }) =>
{children}
, + PopoverTrigger: ({ render }: { render: React.ReactNode }) => <>{render}, + PopoverContent: ({ children }: { children: React.ReactNode }) =>
{children}
, })) describe('FieldTitle', () => { diff --git a/web/app/components/workflow/nodes/_base/components/layout/field-title.tsx b/web/app/components/workflow/nodes/_base/components/layout/field-title.tsx index ce080fb6dd..fc674790b3 100644 --- a/web/app/components/workflow/nodes/_base/components/layout/field-title.tsx +++ b/web/app/components/workflow/nodes/_base/components/layout/field-title.tsx @@ -1,6 +1,6 @@ import type { ReactNode } from 'react' import { cn } from '@langgenius/dify-ui/cn' -import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { memo, useState, @@ -62,18 +62,25 @@ export const FieldTitle = memo(({ } { tooltip && ( - - + e.stopPropagation()} render={( )} /> - + {tooltip} - - + + ) }
diff --git a/web/app/components/workflow/nodes/_base/node-sections.tsx b/web/app/components/workflow/nodes/_base/node-sections.tsx index a365362123..ec9ee0d2f0 100644 --- a/web/app/components/workflow/nodes/_base/node-sections.tsx +++ b/web/app/components/workflow/nodes/_base/node-sections.tsx @@ -2,7 +2,7 @@ import type { TFunction } from 'i18next' import type { ReactElement } from 'react' import type { IterationNodeType } from '@/app/components/workflow/nodes/iteration/types' import type { NodeProps } from '@/app/components/workflow/types' -import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { BlockEnum, NodeRunningStatus } from '@/app/components/workflow/types' type HeaderMetaProps = { @@ -23,19 +23,27 @@ export const NodeHeaderMeta = ({ return ( <> {data.type === BlockEnum.Iteration && (data as IterationNodeType).is_parallel && ( - - -
- {t('nodes.iteration.parallelModeUpper', { ns: 'workflow' })} -
-
- + + + {t('nodes.iteration.parallelModeUpper', { ns: 'workflow' })} +
+ )} + /> +
{t('nodes.iteration.parallelModeEnableTitle', { ns: 'workflow' })}
{t('nodes.iteration.parallelModeEnableDesc', { ns: 'workflow' })} - - +
+ )} {!!(data._iterationLength && data._iterationIndex && data._runningStatus === NodeRunningStatus.Running) && (
diff --git a/web/app/components/workflow/nodes/llm/components/panel-memory-section.tsx b/web/app/components/workflow/nodes/llm/components/panel-memory-section.tsx index 59b38b41db..d656251c9c 100644 --- a/web/app/components/workflow/nodes/llm/components/panel-memory-section.tsx +++ b/web/app/components/workflow/nodes/llm/components/panel-memory-section.tsx @@ -1,7 +1,7 @@ import type { FC } from 'react' import type { LLMNodeType } from '../types' import type { Memory, Node, NodeOutPutVar } from '@/app/components/workflow/types' -import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import * as React from 'react' import { useTranslation } from 'react-i18next' import MemoryConfig from '@/app/components/workflow/nodes/_base/components/memory-config' @@ -50,18 +50,24 @@ const PanelMemorySection: FC = ({
{t('nodes.common.memories.title', { ns: 'workflow' })}
- - + )} /> - + {t('nodes.common.memories.tip', { ns: 'workflow' })} - - + +
{t('nodes.common.memories.builtIn', { ns: 'workflow' })} @@ -72,18 +78,24 @@ const PanelMemorySection: FC = ({ title={(
user
- - + )} /> - +
{t('nodes.llm.roleDescription.user', { ns: 'workflow' })}
-
-
+ +
)} value={inputs.memory.query_prompt_template || '{{#sys.query#}}'} diff --git a/web/app/components/workflow/nodes/llm/components/panel-output-section.tsx b/web/app/components/workflow/nodes/llm/components/panel-output-section.tsx index bd333b6b1f..ae75d842ae 100644 --- a/web/app/components/workflow/nodes/llm/components/panel-output-section.tsx +++ b/web/app/components/workflow/nodes/llm/components/panel-output-section.tsx @@ -1,8 +1,7 @@ import type { FC } from 'react' import type { LLMNodeType, StructuredOutput } from '../types' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { Switch } from '@langgenius/dify-ui/switch' -import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' -import { RiAlertFill, RiQuestionLine } from '@remixicon/react' import * as React from 'react' import { useTranslation } from 'react-i18next' import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars' @@ -41,35 +40,41 @@ const PanelOutputSection: FC = ({ operations={(
{(!isModelSupportStructuredOutput && !!inputs.structured_output_enabled) && ( - - + - +
+
)} /> - +
{t('structOutput.modelNotSupported', { ns: 'app' })}
{t('structOutput.modelNotSupportedTip', { ns: 'app' })}
-
-
+ + )}
{t('structOutput.structured', { ns: 'app' })}
- - + - +
)} /> - +
{t('structOutput.structuredTip', { ns: 'app' })}
-
- + +