refactor(dify-ui): govern public component APIs (#39806)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
yyh
2026-07-30 10:12:34 +00:00
committed by GitHub
co-authored by autofix-ci[bot]
parent 3aa937def4
commit 563cf2602f
115 changed files with 2378 additions and 975 deletions
@@ -101,12 +101,12 @@ function EnvEditorScope({
}
return (
<Select
<Select<EnvScope>
value={scope}
onValueChange={(nextValue) => {
if (!nextValue) return
onChange?.(nextValue as EnvScope)
onChange?.(nextValue)
}}
>
<SelectTrigger
@@ -117,7 +117,7 @@ function EnvEditorScope({
</SelectTrigger>
<SelectContent placement="bottom-start" popupClassName="min-w-24">
{envScopeOptions.map((option) => (
<SelectItem key={option} value={option} className="h-7 system-xs-regular">
<SelectItem<EnvScope> key={option} value={option} className="h-7 system-xs-regular">
<SelectItemText>{t(($) => $[scopeLabelKeys[option]])}</SelectItemText>
<SelectItemIndicator />
</SelectItem>
@@ -31,7 +31,7 @@ const imageFileExtensions = new Set([
'svg',
'webp',
])
const driveFileIconTypes = new Set<FileTreeIconType>([
const driveFileIconTypes: ReadonlySet<string> = new Set([
'archive',
'code',
'database',
@@ -43,7 +43,11 @@ const driveFileIconTypes = new Set<FileTreeIconType>([
'pdf',
'table',
'text',
])
] satisfies FileTreeIconType[])
function isFileTreeIconType(value: string): value is FileTreeIconType {
return driveFileIconTypes.has(value)
}
function getFileExtension(fileName: string) {
return fileName.split('.').pop()?.toLowerCase() ?? ''
@@ -77,8 +81,7 @@ export function getDriveFileIconType({
if (normalizedFileKind === 'directory') return 'folder'
if (normalizedFileKind && driveFileIconTypes.has(normalizedFileKind as FileTreeIconType))
return normalizedFileKind as FileTreeIconType
if (normalizedFileKind && isFileTreeIconType(normalizedFileKind)) return normalizedFileKind
return getFileIconType(fileName, mimeType)
}
@@ -73,10 +73,11 @@ export function AgentLogSourcePicker({
aria-label={t(($) => $['agentDetail.logs.filters.source.label'])}
className="mt-0 w-fit max-w-full min-w-22"
>
<ComboboxValue placeholder={t(($) => $['agentDetail.logs.filters.source.all'])}>
{(selectedValue: AgentLogSourceResponse[]) => {
if (selectedValue.length === 0)
return t(($) => $['agentDetail.logs.filters.source.all'])
<ComboboxValue<AgentLogSourceResponse, true>
placeholder={t(($) => $['agentDetail.logs.filters.source.all'])}
>
{(selectedValue) => {
if (!selectedValue?.length) return t(($) => $['agentDetail.logs.filters.source.all'])
if (selectedValue.length === 1) return selectedValue[0]!.app_name
return tCommon(($) => $['dynamicSelect.selected'], { count: selectedValue.length })
}}
@@ -117,8 +118,8 @@ export function AgentLogSourcePicker({
<ComboboxGroupLabel className="px-1 pt-2 pb-1">
{getSourceGroupLabel(group, t)}
</ComboboxGroupLabel>
<ComboboxCollection>
{(source: AgentLogSourceResponse) => (
<ComboboxCollection<AgentLogSourceResponse>>
{(source) => (
<ComboboxItem
key={source.id}
value={source}
@@ -220,8 +220,8 @@ export function SourceAppPicker({
{(sourceAppsIsLoading || sourceAppsIsFetchingNextPage) && apps.length === 0 && (
<SourceAppPickerSkeleton />
)}
<ComboboxList className="max-h-none p-0">
{(app: App) => <SourceAppOption key={app.id} app={app} />}
<ComboboxList<App> className="max-h-none p-0">
{(app) => <SourceAppOption key={app.id} app={app} />}
</ComboboxList>
{!(sourceAppsIsLoading || sourceAppsIsFetchingNextPage) && (
<ComboboxEmpty>{t(($) => $['createModal.appSearchEmpty'])}</ComboboxEmpty>
@@ -1,6 +1,6 @@
'use client'
import type { ComponentProps } from 'react'
import type { DropdownMenuContentProps } from '@langgenius/dify-ui/dropdown-menu'
import type { DeploymentActionAppInstance } from './types'
import { cn } from '@langgenius/dify-ui/cn'
import {
@@ -32,8 +32,8 @@ type DeploymentActionsMenuProps = {
appInstance: DeploymentActionAppInstance
className?: string
triggerClassName?: string
placement: ComponentProps<typeof DropdownMenuContent>['placement']
sideOffset?: ComponentProps<typeof DropdownMenuContent>['sideOffset']
placement: DropdownMenuContentProps['placement']
sideOffset?: DropdownMenuContentProps['sideOffset']
}
function DeploymentActionsMenuContent({
@@ -176,8 +176,8 @@ export function AccessSubjectAddButton({
)}
{hasResults ? (
<>
<ComboboxList className="max-h-none p-1">
{(subject: Subject) => (
<ComboboxList<Subject> className="max-h-none p-1">
{(subject) => (
<SubjectItem
key={getSubjectValue(subject)}
subject={subject}
@@ -70,8 +70,8 @@ export const TagSearchContent = ({
)}
</ComboboxInputGroup>
</div>
<ComboboxList className="max-h-58">
{(tag: TagComboboxItem) => {
<ComboboxList<TagComboboxItem> className="max-h-58">
{(tag) => {
if (isCreateTagOption(tag) && canManageTags) {
return (
<Fragment key={tag.id}>
@@ -1,6 +1,5 @@
import type { TagResponse as Tag, TagType } from '@dify/contracts/api/console/tags/types.gen'
import type { ComboboxProps } from '@langgenius/dify-ui/combobox'
import type { ComponentProps } from 'react'
import type { ComboboxContentProps, ComboboxProps } from '@langgenius/dify-ui/combobox'
import type { TagComboboxItem } from './tag-combobox-item'
import { cn } from '@langgenius/dify-ui/cn'
import { Combobox, ComboboxContent, ComboboxTrigger } from '@langgenius/dify-ui/combobox'
@@ -45,7 +44,7 @@ type TagSelectorRootProps = Omit<
| 'children'
>
type TagSelectorContentProps = Pick<
ComponentProps<typeof ComboboxContent>,
ComboboxContentProps,
| 'placement'
| 'sideOffset'
| 'alignOffset'