refactor: unified cn utils (#29916)

Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
This commit is contained in:
Stephen Zhou
2025-12-19 12:08:34 +08:00
committed by GitHub
parent 80f11471ae
commit a26881cb24
815 changed files with 1064 additions and 1227 deletions

View File

@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
import useSWR from 'swr'
import Link from 'next/link'
import s from './index.module.css'
import classNames from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { fetchAccountIntegrates } from '@/service/common'
const titleClassName = `
@@ -35,7 +35,7 @@ export default function IntegrationsPage() {
{
integrates.map(integrate => (
<div key={integrate.provider} className='mb-2 flex items-center rounded-lg border-[0.5px] border-gray-200 bg-gray-50 px-3 py-2'>
<div className={classNames('mr-3 h-8 w-8 rounded-lg border border-gray-100 bg-white', s[`${integrate.provider}-icon`])} />
<div className={cn('mr-3 h-8 w-8 rounded-lg border border-gray-100 bg-white', s[`${integrate.provider}-icon`])} />
<div className='grow'>
<div className='text-sm font-medium leading-[21px] text-gray-800'>{integrateMap[integrate.provider].name}</div>
<div className='text-xs font-normal leading-[18px] text-gray-500'>{integrateMap[integrate.provider].description}</div>

View File

@@ -1,6 +1,6 @@
import { useState } from 'react'
import { ChevronDownIcon, ChevronRightIcon } from '@heroicons/react/24/outline'
import classNames from '@/utils/classnames'
import { cn } from '@/utils/classnames'
export type IItem = {
key: string
@@ -25,7 +25,7 @@ const Collapse = ({
const toggle = () => setOpen(!open)
return (
<div className={classNames('overflow-hidden rounded-xl bg-background-section-burn', wrapperClassName)}>
<div className={cn('overflow-hidden rounded-xl bg-background-section-burn', wrapperClassName)}>
<div className='flex cursor-pointer items-center justify-between px-3 py-2 text-xs font-medium leading-[18px] text-text-secondary' onClick={toggle}>
{title}
{

View File

@@ -18,7 +18,7 @@ import Loading from '@/app/components/base/loading'
import ProviderCard from '@/app/components/plugins/provider-card'
import List from '@/app/components/plugins/marketplace/list'
import type { Plugin } from '@/app/components/plugins/types'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { getLocaleOnClient } from '@/i18n-config'
import { getMarketplaceUrl } from '@/utils/var'

View File

@@ -11,7 +11,7 @@ import {
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
import { syncDataSourceNotion, updateDataSourceNotionAction } from '@/service/common'
import Toast from '@/app/components/base/toast'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type OperateProps = {
payload: {

View File

@@ -7,7 +7,7 @@ import { DataSourceType } from '../panel/types'
import ConfigFirecrawlModal from './config-firecrawl-modal'
import ConfigWatercrawlModal from './config-watercrawl-modal'
import ConfigJinaReaderModal from './config-jina-reader-modal'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import s from '@/app/components/datasets/create/website/index.module.css'
import { fetchDataSources, removeDataSourceApiKeyBinding } from '@/service/datasets'

View File

@@ -9,7 +9,7 @@ import Indicator from '../../../indicator'
import Operate from '../data-source-notion/operate'
import { DataSourceType } from './types'
import s from './style.module.css'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { noop } from 'lodash-es'
export type ConfigItemType = {

View File

@@ -10,7 +10,7 @@ import s from './style.module.css'
import { DataSourceType } from './types'
import Button from '@/app/components/base/button'
import { DataSourceProvider } from '@/models/common'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type Props = {
type: DataSourceType

View File

@@ -23,7 +23,7 @@ import LanguagePage from './language-page'
import ApiBasedExtensionPage from './api-based-extension-page'
import DataSourcePage from './data-source-page-new'
import ModelProviderPage from './model-provider-page'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import BillingPage from '@/app/components/billing/billing-page'
import CustomPage from '@/app/components/custom/custom-page'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'

View File

@@ -1,5 +1,5 @@
'use client'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Modal from '@/app/components/base/modal'
import Input from '@/app/components/base/input'
import { useTranslation } from 'react-i18next'

View File

@@ -21,7 +21,7 @@ import Button from '@/app/components/base/button'
import UpgradeBtn from '@/app/components/billing/upgrade-btn'
import { NUM_INFINITE } from '@/app/components/billing/config'
import { LanguagesSupported } from '@/i18n-config/language'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Tooltip from '@/app/components/base/tooltip'
import { RiPencilLine } from '@remixicon/react'
import { useGlobalPublicStore } from '@/context/global-public-context'

View File

@@ -7,7 +7,7 @@ import { ReactMultiEmail } from 'react-multi-email'
import { RiErrorWarningFill } from '@remixicon/react'
import RoleSelector from './role-selector'
import s from './index.module.css'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import { inviteMember } from '@/service/common'

View File

@@ -1,5 +1,5 @@
import { useTranslation } from 'react-i18next'
import cn from 'classnames'
import { cn } from '@/utils/classnames'
import React, { useState } from 'react'
import { RiArrowDownSLine } from '@remixicon/react'
import { useProviderContext } from '@/context/provider-context'

View File

@@ -5,7 +5,7 @@ import { useContext } from 'use-context-selector'
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/24/outline'
import { useProviderContext } from '@/context/provider-context'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import type { Member } from '@/models/common'
import { deleteMemberOrCancelInvitation, updateMemberRole } from '@/service/common'
import { ToastContext } from '@/app/components/base/toast'

View File

@@ -5,7 +5,7 @@ import {
RiArrowDownSLine,
} from '@remixicon/react'
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type Props = {
onOperate: () => void

View File

@@ -10,7 +10,7 @@ import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigge
import Avatar from '@/app/components/base/avatar'
import Input from '@/app/components/base/input'
import { fetchMembers } from '@/service/common'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type Props = {
value?: any

View File

@@ -1,7 +1,7 @@
import { Fragment, useCallback, useEffect } from 'react'
import type { ReactNode } from 'react'
import { Dialog, DialogPanel, Transition, TransitionChild } from '@headlessui/react'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { noop } from 'lodash-es'
type DialogProps = {

View File

@@ -19,7 +19,7 @@ import {
} from './hooks'
import InstallFromMarketplace from './install-from-marketplace'
import { useProviderContext } from '@/context/provider-context'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { useGlobalPublicStore } from '@/context/global-public-context'
type Props = {

View File

@@ -17,7 +17,7 @@ import Loading from '@/app/components/base/loading'
import ProviderCard from '@/app/components/plugins/provider-card'
import List from '@/app/components/plugins/marketplace/list'
import type { Plugin } from '@/app/components/plugins/types'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { getLocaleOnClient } from '@/i18n-config'
import { getMarketplaceUrl } from '@/utils/var'

View File

@@ -5,7 +5,7 @@ import {
import { RiAddLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { Authorized } from '@/app/components/header/account-setting/model-provider-page/model-auth'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import type {
Credential,
CustomConfigurationModelFixedFields,

View File

@@ -17,7 +17,7 @@ import type {
ModelProvider,
} from '@/app/components/header/account-setting/model-provider-page/declarations'
import { ModelModalModeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import {
PortalToFollowElem,
PortalToFollowElemContent,

View File

@@ -11,7 +11,7 @@ import {
import Indicator from '@/app/components/header/indicator'
import ActionButton from '@/app/components/base/action-button'
import Tooltip from '@/app/components/base/tooltip'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import type { Credential } from '../../declarations'
import Badge from '@/app/components/base/badge'

View File

@@ -17,7 +17,7 @@ import type {
PortalToFollowElemOptions,
} from '@/app/components/base/portal-to-follow-elem'
import Button from '@/app/components/base/button'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Confirm from '@/app/components/base/confirm'
import type {
ConfigurationMethodEnum,

View File

@@ -6,7 +6,7 @@ import {
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Indicator from '@/app/components/header/indicator'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type ConfigModelProps = {
onClick?: () => void

View File

@@ -18,7 +18,7 @@ import Authorized from './authorized'
import {
useCustomModels,
} from './hooks'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type ManageCustomModelCredentialsProps = {
provider: ModelProvider,

View File

@@ -14,7 +14,7 @@ import type {
ModelProvider,
} from '../declarations'
import { ConfigurationMethodEnum, ModelModalModeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Tooltip from '@/app/components/base/tooltip'
import Badge from '@/app/components/base/badge'

View File

@@ -1,5 +1,5 @@
import type { FC, ReactNode } from 'react'
import classNames from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type ModelBadgeProps = {
className?: string
@@ -10,10 +10,8 @@ const ModelBadge: FC<ModelBadgeProps> = ({
children,
}) => {
return (
<div className={classNames(
'system-2xs-medium-uppercase flex h-[18px] cursor-default items-center rounded-[5px] border border-divider-deep px-1 text-text-tertiary',
className,
)}>
<div className={cn('system-2xs-medium-uppercase flex h-[18px] cursor-default items-center rounded-[5px] border border-divider-deep px-1 text-text-tertiary',
className)}>
{children}
</div>
)

View File

@@ -8,7 +8,7 @@ import { Group } from '@/app/components/base/icons/src/vender/other'
import { OpenaiBlue, OpenaiTeal, OpenaiViolet, OpenaiYellow } from '@/app/components/base/icons/src/public/llm'
import { renderI18nObject } from '@/i18n-config'
import { Theme } from '@/types/app'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import useTheme from '@/hooks/use-theme'
type ModelIconProps = {

View File

@@ -13,7 +13,7 @@ import type {
import { FormTypeEnum } from '../declarations'
import { useLanguage } from '../hooks'
import Input from './Input'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { SimpleSelect } from '@/app/components/base/select'
import Tooltip from '@/app/components/base/tooltip'
import Radio from '@/app/components/base/radio'

View File

@@ -7,7 +7,7 @@ import { useLanguage } from '../hooks'
import type { ModelItem } from '../declarations'
import ModelBadge from '../model-badge'
import FeatureIcon from '../model-selector/feature-icon'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type ModelNameProps = PropsWithChildren<{
modelItem: ModelItem

View File

@@ -21,7 +21,7 @@ import ModelIcon from '../model-icon'
import ModelDisplay from './model-display'
import { InstallPluginButton } from '@/app/components/workflow/nodes/_base/components/install-plugin-button'
import StatusIndicators from './status-indicators'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { useProviderContext } from '@/context/provider-context'
import { RiEqualizer2Line } from '@remixicon/react'
import { useModelInList, usePluginInfo } from '@/service/use-plugins'

View File

@@ -20,7 +20,7 @@ import type { ParameterValue } from './parameter-item'
import Trigger from './trigger'
import type { TriggerProps } from './trigger'
import PresetsParameter from './presets-parameter'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import {
PortalToFollowElem,
PortalToFollowElemContent,

View File

@@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react'
import type { ModelParameterRule } from '../declarations'
import { useLanguage } from '../hooks'
import { isNullOrUndefined } from '../utils'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Switch from '@/app/components/base/switch'
import Tooltip from '@/app/components/base/tooltip'
import Slider from '@/app/components/base/slider'

View File

@@ -8,7 +8,7 @@ import { Brush01 } from '@/app/components/base/icons/src/vender/solid/editor'
import { Scales02 } from '@/app/components/base/icons/src/vender/solid/FinanceAndECommerce'
import { Target04 } from '@/app/components/base/icons/src/vender/solid/general'
import { TONE_LIST } from '@/config'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type PresetsParameterProps = {
onSelect: (toneId: number) => void

View File

@@ -10,7 +10,7 @@ import { MODEL_STATUS_TEXT } from '../declarations'
import { useLanguage } from '../hooks'
import ModelIcon from '../model-icon'
import ModelName from '../model-name'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { useProviderContext } from '@/context/provider-context'
import { SlidersH } from '@/app/components/base/icons/src/vender/line/mediaAndDevices'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'

View File

@@ -4,7 +4,7 @@ import ModelIcon from '../model-icon'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import { useProviderContext } from '@/context/provider-context'
import Tooltip from '@/app/components/base/tooltip'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type ModelTriggerProps = {
modelName: string

View File

@@ -1,7 +1,7 @@
import type { FC } from 'react'
import { RiEqualizer2Line } from '@remixicon/react'
import { CubeOutline } from '@/app/components/base/icons/src/vender/line/shapes'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { useTranslation } from 'react-i18next'
type ModelTriggerProps = {
open: boolean

View File

@@ -12,7 +12,7 @@ import {
RiImageCircleAiLine,
RiVoiceAiFill,
} from '@remixicon/react'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type FeatureIconProps = {
feature: ModelFeatureEnum

View File

@@ -16,7 +16,7 @@ import {
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import classNames from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type ModelSelectorProps = {
defaultModel?: DefaultModel
@@ -70,7 +70,7 @@ const ModelSelector: FC<ModelSelectorProps> = ({
placement='bottom-start'
offset={4}
>
<div className={classNames('relative')}>
<div className={cn('relative')}>
<PortalToFollowElemTrigger
onClick={handleToggle}
className='block'

View File

@@ -13,7 +13,7 @@ import ModelIcon from '../model-icon'
import ModelName from '../model-name'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/line/alertsAndFeedback'
import Tooltip from '@/app/components/base/tooltip'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type ModelTriggerProps = {
open: boolean

View File

@@ -30,7 +30,7 @@ import { Check } from '@/app/components/base/icons/src/vender/line/general'
import { useModalContext } from '@/context/modal-context'
import { useProviderContext } from '@/context/provider-context'
import Tooltip from '@/app/components/base/tooltip'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import FeatureIcon from './feature-icon'
type PopupItemProps = {

View File

@@ -1,7 +1,7 @@
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { PlusCircle } from '@/app/components/base/icons/src/vender/solid/general'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type AddModelButtonProps = {
className?: string

View File

@@ -19,7 +19,7 @@ import Indicator from '@/app/components/header/indicator'
import { changeModelProviderPriority } from '@/service/common'
import { useToastContext } from '@/app/components/base/toast'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { useCredentialStatus } from '@/app/components/header/account-setting/model-provider-page/model-auth/hooks'
import { ConfigProvider } from '@/app/components/header/account-setting/model-provider-page/model-auth'

View File

@@ -24,7 +24,7 @@ import { fetchModelProviderModelList } from '@/service/common'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import { IS_CE_EDITION } from '@/config'
import { useAppContext } from '@/context/app-context'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import {
AddCustomModel,
ManageCustomModelCredentials,

View File

@@ -5,7 +5,7 @@ import type { ModelItem, ModelProvider } from '../declarations'
import { ModelStatusEnum } from '../declarations'
import ModelIcon from '../model-icon'
import ModelName from '../model-name'
import classNames from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import { Balance } from '@/app/components/base/icons/src/vender/line/financeAndECommerce'
import Switch from '@/app/components/base/switch'
import Tooltip from '@/app/components/base/tooltip'
@@ -45,11 +45,9 @@ const ModelListItem = ({ model, provider, isConfigurable, onModifyLoadBalancing
return (
<div
key={`${model.model}-${model.fetch_from}`}
className={classNames(
'group flex h-8 items-center rounded-lg pl-2 pr-2.5',
className={cn('group flex h-8 items-center rounded-lg pl-2 pr-2.5',
isConfigurable && 'hover:bg-components-panel-on-panel-item-bg-hover',
model.deprecated && 'opacity-60',
)}
model.deprecated && 'opacity-60')}
>
<ModelIcon
className='mr-2 shrink-0'

View File

@@ -16,7 +16,7 @@ import type {
import { ConfigurationMethodEnum } from '../declarations'
import Indicator from '../../../indicator'
import CooldownTimer from './cooldown-timer'
import classNames from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Tooltip from '@/app/components/base/tooltip'
import Switch from '@/app/components/base/switch'
import { Balance } from '@/app/components/base/icons/src/vender/line/financeAndECommerce'
@@ -146,12 +146,10 @@ const ModelLoadBalancingConfigs = ({
return (
<>
<div
className={classNames(
'min-h-16 rounded-xl border bg-components-panel-bg transition-colors',
className={cn('min-h-16 rounded-xl border bg-components-panel-bg transition-colors',
(withSwitch || !draftConfig.enabled) ? 'border-components-panel-border' : 'border-util-colors-blue-blue-600',
(withSwitch || draftConfig.enabled) ? 'cursor-default' : 'cursor-pointer',
className,
)}
className)}
onClick={(!withSwitch && !draftConfig.enabled) ? () => toggleModalBalancing(true) : undefined}
>
<div className='flex select-none items-center gap-2 px-[15px] py-3'>
@@ -270,7 +268,7 @@ const ModelLoadBalancingConfigs = ({
<GridMask canvasClassName='!rounded-xl'>
<div className='mt-2 flex h-14 items-center justify-between rounded-xl border-[0.5px] border-components-panel-border px-4 shadow-md'>
<div
className={classNames('text-gradient text-sm font-semibold leading-tight', s.textGradient)}
className={cn('text-gradient text-sm font-semibold leading-tight', s.textGradient)}
>
{t('common.modelProvider.upgradeForLoadBalancing')}
</div>

View File

@@ -15,7 +15,7 @@ import {
import ModelIcon from '../model-icon'
import ModelName from '../model-name'
import ModelLoadBalancingConfigs from './model-load-balancing-configs'
import classNames from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Loading from '@/app/components/base/loading'
@@ -265,10 +265,8 @@ const ModelLoadBalancingModal = ({
<>
<div className='py-2'>
<div
className={classNames(
'min-h-16 rounded-xl border bg-components-panel-bg transition-colors',
draftConfig.enabled ? 'cursor-pointer border-components-panel-border' : 'cursor-default border-util-colors-blue-blue-600',
)}
className={cn('min-h-16 rounded-xl border bg-components-panel-bg transition-colors',
draftConfig.enabled ? 'cursor-pointer border-components-panel-border' : 'cursor-default border-util-colors-blue-blue-600')}
onClick={draftConfig.enabled ? () => toggleModalBalancing(false) : undefined}
>
<div className='flex select-none items-center gap-2 px-[15px] py-3'>

View File

@@ -8,7 +8,7 @@ import {
} from '@remixicon/react'
import { PreferredProviderTypeEnum } from '../declarations'
import Button from '@/app/components/base/button'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
type SelectorProps = {
value?: string

View File

@@ -5,7 +5,7 @@ import { Openai } from '@/app/components/base/icons/src/vender/other'
import { AnthropicDark, AnthropicLight } from '@/app/components/base/icons/src/public/llm'
import { renderI18nObject } from '@/i18n-config'
import { Theme } from '@/types/app'
import cn from '@/utils/classnames'
import { cn } from '@/utils/classnames'
import useTheme from '@/hooks/use-theme'
type ProviderIconProps = {