style: format JSX closing brackets for better readability

This commit is contained in:
icarus 2025-09-15 07:05:09 +08:00
parent 8a74356ff5
commit d442c934ee
257 changed files with 1173 additions and 616 deletions

View File

@ -13,15 +13,7 @@
"test": "vitest run",
"test:watch": "vitest"
},
"keywords": [
"ai",
"sdk",
"openai",
"anthropic",
"google",
"cherry-studio",
"vercel-ai-sdk"
],
"keywords": ["ai", "sdk", "openai", "anthropic", "google", "cherry-studio", "vercel-ai-sdk"],
"author": "Cherry Studio",
"license": "MIT",
"repository": {
@ -56,9 +48,7 @@
"engines": {
"node": ">=18.0.0"
},
"files": [
"dist"
],
"files": ["dist"],
"exports": {
".": {
"types": "./dist/index.d.ts",

View File

@ -24,7 +24,6 @@ export const googleToolsPlugin = (config?: ToolConfig) =>
if (!typedParams.tools) {
typedParams.tools = {}
}
// 使用类型安全的方式遍历配置
;(Object.keys(config) as ToolConfigKey[]).forEach((key) => {
if (config[key] && key in toolNameMap && key in google.tools) {

View File

@ -1,26 +1,21 @@
{
"compilerOptions": {
"target": "ES2020",
"allowSyntheticDefaultImports": true,
"declaration": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"noEmitOnError": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
"outDir": "./dist",
"resolveJsonModule": true,
"rootDir": "./src",
"skipLibCheck": true,
"strict": true,
"target": "ES2020"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist"
]
}
"exclude": ["node_modules", "dist"],
"include": ["src/**/*"]
}

View File

@ -3,10 +3,7 @@
"description": "table extension for tiptap forked from tiptap/extension-table",
"version": "3.0.11",
"homepage": "https://cherry-ai.com",
"keywords": [
"tiptap",
"tiptap extension"
],
"keywords": ["tiptap", "tiptap extension"],
"license": "MIT",
"type": "module",
"exports": {
@ -62,10 +59,7 @@
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"src",
"dist"
],
"files": ["src", "dist"],
"devDependencies": {
"@tiptap/core": "^3.2.0",
"@tiptap/pm": "^3.2.0",

View File

@ -1,6 +1,5 @@
.command-list-popover {
/* Base styles are handled inline for theme support */
/* Arrow styles based on placement */
}

View File

@ -25,7 +25,8 @@ const EmojiAvatar = ({
$fontSize={fontSize ?? size * 0.5}
onClick={onClick}
className={className}
style={style}>
style={style}
>
{children}
</StyledEmojiAvatar>
)

View File

@ -25,7 +25,8 @@ const ModelAvatar: FC<Props> = ({ model, size, props, className }) => {
justifyContent: 'center'
}}
{...props}
className={className}>
className={className}
>
{first(model?.name)}
</Avatar>
)

View File

@ -82,21 +82,24 @@ const HtmlArtifactsPopup: React.FC<HtmlArtifactsPopupProps> = ({ open, title, ht
size="small"
type={viewMode === 'split' ? 'primary' : 'default'}
icon={<SquareSplitHorizontal size={14} />}
onClick={() => setViewMode('split')}>
onClick={() => setViewMode('split')}
>
{t('html_artifacts.split')}
</ViewButton>
<ViewButton
size="small"
type={viewMode === 'code' ? 'primary' : 'default'}
icon={<Code size={14} />}
onClick={() => setViewMode('code')}>
onClick={() => setViewMode('code')}
>
{t('html_artifacts.code')}
</ViewButton>
<ViewButton
size="small"
type={viewMode === 'preview' ? 'primary' : 'default'}
icon={<Eye size={14} />}
onClick={() => setViewMode('preview')}>
onClick={() => setViewMode('preview')}
>
{t('html_artifacts.preview')}
</ViewButton>
</ViewControls>
@ -120,7 +123,8 @@ const HtmlArtifactsPopup: React.FC<HtmlArtifactsPopupProps> = ({ open, title, ht
onClick: () => handleCapture('clipboard')
}
]
}}>
}}
>
<Tooltip title={t('html_artifacts.capture.label')} mouseLeaveDelay={0}>
<Button type="text" icon={<Camera size={16} />} className="nodrag" />
</Tooltip>
@ -230,7 +234,8 @@ const HtmlArtifactsPopup: React.FC<HtmlArtifactsPopupProps> = ({ open, title, ht
}}
zIndex={isFullscreen ? 10000 : 1000}
footer={null}
closable={false}>
closable={false}
>
<Container>{renderContent()}</Container>
</StyledModal>
)

View File

@ -295,7 +295,8 @@ export const CodeBlockView: React.FC<Props> = memo(({ children, language, onSave
<SplitViewWrapper
className="split-view-wrapper"
$isSpecialView={showSpecialView && !showSourceView}
$isSplitView={showSpecialView && showSourceView}>
$isSplitView={showSpecialView && showSourceView}
>
{showSpecialView && specialView}
{showSourceView && sourceView}
</SplitViewWrapper>

View File

@ -29,7 +29,8 @@ const CodeToolButton = ({ tool }: CodeToolButtonProps) => {
onClick: child.onClick
}))
}}
trigger={['click']}>
trigger={['click']}
>
{mainTool}
</Dropdown>
)

View File

@ -168,14 +168,16 @@ const CodeViewer = ({
maxHeight: expanded ? undefined : maxHeight,
overflowY: expanded ? 'hidden' : 'auto'
} as React.CSSProperties
}>
}
>
<div
className="shiki-list"
style={{
height: `${virtualizer.getTotalSize()}px`,
width: '100%',
position: 'relative'
}}>
}}
>
<div
style={{
position: 'absolute',
@ -183,7 +185,8 @@ const CodeViewer = ({
left: 0,
width: '100%',
transform: `translateY(${virtualItems[0]?.start ?? 0}px)`
}}>
}}
>
{virtualItems.map((virtualItem) => (
<div key={virtualItem.key} data-index={virtualItem.index} ref={virtualizer.measureElement}>
<VirtualizedRow

View File

@ -58,7 +58,8 @@ const CollapsibleSearchBar = ({
expanded: { maxWidth: maxWidth, opacity: 1, transition: { duration: 0.3, ease: 'easeInOut' } },
collapsed: { maxWidth: 0, opacity: 0, transition: { duration: 0.3, ease: 'easeInOut' } }
}}
style={{ overflow: 'hidden', flex: 1 }}>
style={{ overflow: 'hidden', flex: 1 }}
>
<Input
ref={inputRef}
type="text"
@ -91,7 +92,8 @@ const CollapsibleSearchBar = ({
hidden: { opacity: 0, transition: { duration: 0.1, ease: 'easeInOut' } }
}}
style={{ cursor: 'pointer', display: 'flex' }}
onClick={() => setSearchVisible(true)}>
onClick={() => setSearchVisible(true)}
>
<Tooltip title={tooltip} mouseEnterDelay={0.5} mouseLeaveDelay={0}>
{icon}
</Tooltip>

View File

@ -350,7 +350,8 @@ export const ContentSearch = React.forwardRef<ContentSearchRef, Props>(
<Container
ref={containerRef}
style={enableContentSearch ? {} : { display: 'none' }}
$overlayPosition={positionMode === 'absolute' ? 'absolute' : 'static'}>
$overlayPosition={positionMode === 'absolute' ? 'absolute' : 'static'}
>
<NarrowLayout style={{ width: '100%' }}>
<SearchBarContainer $position={positionMode}>
<InputWrapper>

View File

@ -153,7 +153,8 @@ describe('DraggableVirtualList', () => {
onUpdate={() => {}}
className="custom-class"
style={{ border: '1px solid red' }}
itemStyle={{ background: 'blue' }}>
itemStyle={{ background: 'blue' }}
>
{(item) => <div>{item.name}</div>}
</DraggableVirtualList>
)

View File

@ -78,7 +78,8 @@ function DraggableList<T>({
...listStyle,
...provided.draggableProps.style,
marginBottom: 8
}}>
}}
>
{children(item, index)}
</div>
)}

View File

@ -129,7 +129,8 @@ function DraggableVirtualList<T>({
return (
<div
className={`${className} draggable-virtual-list`}
style={{ height: '100%', display: 'flex', flexDirection: 'column', ...style }}>
style={{ height: '100%', display: 'flex', flexDirection: 'column', ...style }}
>
<DragDropContext onDragStart={onDragStart} onDragEnd={_onDragEnd}>
{header}
<Droppable
@ -145,12 +146,14 @@ function DraggableVirtualList<T>({
style={{
...itemStyle,
...provided.draggableProps.style
}}>
}}
>
{item && children(item, rubric.source.index)}
</div>
)
}}
{...droppableProps}>
{...droppableProps}
>
{(provided) => {
// 让 dnd 和虚拟列表共享同一个滚动容器
const setRefs = (el: HTMLDivElement | null) => {
@ -169,14 +172,16 @@ function DraggableVirtualList<T>({
width: '100%',
overflowY: 'auto',
position: 'relative'
}}>
}}
>
<div
className="virtual-list"
style={{
height: `${virtualizer.getTotalSize()}px`,
width: '100%',
position: 'relative'
}}>
}}
>
{virtualizer.getVirtualItems().map((virtualItem) => (
<VirtualRow
key={virtualItem.key}
@ -211,7 +216,8 @@ const VirtualRow = memo(
key={`draggable_${draggableId}`}
draggableId={draggableId}
isDragDisabled={disabled}
index={virtualItem.index}>
index={virtualItem.index}
>
{(provided) => {
const setDragRefs = (el: HTMLElement | null) => {
provided.innerRef(el)
@ -242,7 +248,8 @@ const VirtualRow = memo(
left: 0,
width: '100%',
transform: combinedTransform
}}>
}}
>
<div {...provided.dragHandleProps} className="draggable-content" style={itemStyle}>
{item && children(item, virtualItem.index)}
</div>

View File

@ -46,7 +46,8 @@ export const FreeTrialModelTag: FC<Props> = ({ model, showLabel = true }) => {
color="var(--color-link)"
size={11}
onClick={onNavigateProvider}
style={{ display: 'flex', alignItems: 'center', gap: 2 }}>
style={{ display: 'flex', alignItems: 'center', gap: 2 }}
>
{getProviderLabel(providerId)}
<ArrowUpRight size={12} />
</CustomTag>

View File

@ -69,7 +69,8 @@ export const useHealthStatus = ({ results, showLatency = false }: UseHealthStatu
listStyleType: 'none',
maxWidth: '300px',
wordWrap: 'break-word'
}}>
}}
>
{results.map((result, idx) => {
const statusText = getStatusText(result.status)
const statusColor =

View File

@ -98,7 +98,8 @@ const HorizontalScrollContainer: React.FC<HorizontalScrollContainerProps> = ({
className={className}
$expandable={expandable}
$disableHoverButton={isScrolledToEnd}
onClick={expandable ? handleContainerClick : undefined}>
onClick={expandable ? handleContainerClick : undefined}
>
<ScrollContent ref={scrollRef} $gap={gap} $isExpanded={isExpanded} $expandable={expandable}>
{children}
</ScrollContent>

View File

@ -48,7 +48,8 @@ const BaseFileIcon = ({ size = '1.1em', text = 'SVG', ...props }: BaseFileIconPr
version="1.1"
id="svg4"
xmlns="http://www.w3.org/2000/svg"
{...props}>
{...props}
>
<defs id="defs4" />
<path d="m 14,2 v 4 a 2,2 0 0 0 2,2 h 4" id="path3" />
<path d="M 15,2 H 6 A 2,2 0 0 0 4,4 v 16 a 2,2 0 0 0 2,2 h 12 a 2,2 0 0 0 2,-2 V 7 Z" id="path4" />
@ -58,7 +59,8 @@ const BaseFileIcon = ({ size = '1.1em', text = 'SVG', ...props }: BaseFileIconPr
x="12.478625"
y="17.170216"
id="text4"
transform="scale(0.96196394,1.03954)">
transform="scale(0.96196394,1.03954)"
>
<tspan id="tspan4" x="12.478625" y="17.170216" style={tspanStyle}>
{text}
</tspan>

View File

@ -17,14 +17,16 @@ export function NutstoreIcon(props: React.SVGProps<SVGSVGElement>) {
viewBox="0 0 20 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink">
xmlnsXlink="http://www.w3.org/1999/xlink"
>
<title>线</title>
<g id="线性单坚果" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
<path
d="M10.1590439,0.886175571 C10.1753674,0.890326544 10.291709,0.910777855 10.428428,0.935202765 L10.6388345,0.973279488 C10.7074276,0.985937901 10.77116,0.998048871 10.8200766,1.00807156 C11.2437905,1.09488771 11.6662387,1.21011472 12.1133986,1.37210166 C13.2580363,1.78675499 14.3714894,2.43940777 15.4224927,3.39703693 L15.621,3.584 L15.6351722,3.57092562 C16.53166,2.76294504 17.6751418,2.31986999 18.4291849,2.58060734 L18.5580792,2.63399481 C18.9455012,2.81584984 19.2328582,3.16284846 19.437028,3.61729231 C19.5709871,3.91546021 19.6526725,4.21929758 19.6985752,4.50662941 C19.7148596,4.80478115 19.5904581,5.0358501 19.4098118,5.1582622 C19.3815042,5.17858714 19.3523426,5.19648783 19.3224017,5.21197531 C19.1152073,5.31915066 18.9086763,5.30466603 18.6939183,5.22086872 C18.6620576,5.20843687 18.6328325,5.19564599 18.6006654,5.18105502 C18.4394695,5.11546938 18.2846309,5.06753532 18.1365915,5.04232952 C17.7415971,4.96197402 17.3578102,5.06378907 17.051656,5.32621284 L17.046624,5.33098744 L17.1856424,5.55157847 C18.0964209,7.0577136 18.6880009,8.98631362 18.5914984,10.988329 L18.5672508,11.3423168 C18.518886,12.3590196 18.336046,13.2889191 17.9959883,14.1391815 C17.4227031,15.6418626 16.5311196,16.5912538 15.4105898,16.2529712 L15.278,16.207 C15.204042,16.2889459 15.1247235,16.3618831 15.0410669,16.4278107 L14.9126231,16.5212291 C13.2906651,17.9150353 10.9315401,19.0281897 7.99389616,19.2 L7.17106258,19.2 C3.43360072,19.2 1.02132454,17.63803 0.534391412,16.0333683 L0.513,15.954 L0.504265285,15.9449232 C-0.110228462,15.1972878 0.264421351,10.4760569 2.09599684,6.99794495 L2.22026541,6.76796973 C2.29571954,6.63016882 2.43695112,6.39220857 2.63659846,6.08729923 C2.9688861,5.57981633 3.34471126,5.07232148 3.75709487,4.59788661 C4.2749895,4.0020645 4.81413532,3.50121679 5.3386949,3.15177019 C5.36355777,3.12648036 5.4278064,3.07827062 5.50910569,3.02364741 L5.559,2.991 L5.5530361,2.96941337 C5.48899059,2.69876461 5.47862138,2.4784725 5.54146387,2.2521942 L5.58811106,2.11525813 C5.68308256,1.86409186 5.94349142,1.57994703 6.25873284,1.38755406 C6.58654657,1.18748816 7.23187921,0.95895859 7.69473739,0.883035787 C8.37505518,0.763266442 9.38159553,0.78076773 10.1590439,0.886175571 Z M6.59801776,3.85068129 C6.46732353,3.85068129 6.2240354,3.97828097 6.07844768,4.1001814 C5.59811888,4.42589962 5.12194443,4.87010868 4.65860433,5.40361803 C4.52372819,5.55892011 4.37448327,5.74624534 4.22515758,5.94252901 L4.04684241,6.18089332 C3.57610889,6.82012555 3.16307203,7.45661922 3.27592159,7.33459023 C1.39280393,10.7336939 1.18786427,14.1190682 1.66513528,15.5784041 C1.72944314,15.8645824 2.24255786,16.4352772 2.98506717,16.8902532 C4.03558482,17.5339627 5.43381914,17.9303112 7.15636912,17.9630362 L7.95282724,17.9633776 C10.5671194,17.8104156 12.6011819,16.8513512 14.1270746,15.5866906 L14.2005419,15.5269075 L14.2189125,15.5136158 C14.591184,15.2751975 14.6855045,14.9945722 14.5299888,14.3127204 C14.1480256,12.8500475 13.2023047,10.9705228 11.4802274,8.76564869 C10.6761315,7.73569508 9.84271439,6.77270459 8.9812637,5.88185595 C8.26651717,5.13999817 7.48191474,4.46126051 6.65303256,3.86947602 C6.6343697,3.85523851 6.62003281,3.85068129 6.59801776,3.85068129 Z M8.0520431,2.14478343 C7.34750556,2.24716005 6.81392621,2.48276912 6.75769294,2.58286729 C6.75315545,2.59094425 6.75172186,2.59912409 6.75788522,2.63367631 L6.761,2.653 C6.92447955,2.67441039 7.07755879,2.72514333 7.22081781,2.80306173 L7.36053304,2.88992896 C8.25106173,3.52400396 9.08393795,4.2496146 9.84209216,5.05104835 C10.7498631,5.98954517 11.620838,6.99715009 12.4127624,8.02643665 C14.2357617,10.3660968 15.255676,12.4067536 15.6810213,14.0171728 C15.7810435,14.3986973 15.8140553,14.7531702 15.7838468,15.0855202 L15.779624,15.1139874 L15.7923351,15.1170186 C16.0195271,15.1453183 16.2337261,14.9383655 16.4514,14.5090146 L16.5168229,14.3735502 C16.5998938,14.1934825 16.8522658,13.5389313 16.8131724,13.6336744 L16.800624,13.6629874 L16.8933423,13.4088509 C17.1021765,12.7846983 17.2487406,12.0003637 17.2861365,11.2776414 C17.4525549,9.34169753 16.8847303,7.51332101 15.9618076,5.9792161 C15.8725231,5.8278532 15.7620551,5.66138642 15.6942132,5.57820575 C14.7595226,4.31701776 13.5999579,3.42705248 12.3136888,2.84260842 C11.4827868,2.46507019 10.794487,2.2853603 10.1559862,2.18983638 C9.43796126,2.09113972 8.59553714,2.05880421 8.0520431,2.14478343 Z M16.4823653,4.32067121 L16.364,4.418 L16.393,4.454 L16.5100007,4.3621392 C17.0306065,3.97118443 17.6106194,3.7900296 18.1665334,3.88918284 L18.233,3.904 L18.2063581,3.87419362 C18.1376794,3.79892884 18.0675642,3.72412847 18.0165076,3.68190508 L17.972563,3.65173005 C17.800955,3.56958653 17.0606024,3.86572493 16.4823653,4.32067121 Z"
id="形状结合"
fill="currentColor"
fillRule="nonzero"></path>
fillRule="nonzero"
></path>
</g>
</svg>
</IconSpan>

View File

@ -29,7 +29,8 @@ export function MdiLightbulbOffOutline(props: SVGProps<SVGSVGElement>) {
{/* Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE */}
<path
fill="currentColor"
d="M12 2C9.76 2 7.78 3.05 6.5 4.68l1.43 1.43C8.84 4.84 10.32 4 12 4a5 5 0 0 1 5 5c0 1.68-.84 3.16-2.11 4.06l1.42 1.44C17.94 13.21 19 11.24 19 9a7 7 0 0 0-7-7M3.28 4L2 5.27L5.04 8.3C5 8.53 5 8.76 5 9c0 2.38 1.19 4.47 3 5.74V17a1 1 0 0 0 1 1h5.73l4 4L20 20.72zm3.95 6.5l5.5 5.5H10v-2.42a5 5 0 0 1-2.77-3.08M9 20v1a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-1z"></path>
d="M12 2C9.76 2 7.78 3.05 6.5 4.68l1.43 1.43C8.84 4.84 10.32 4 12 4a5 5 0 0 1 5 5c0 1.68-.84 3.16-2.11 4.06l1.42 1.44C17.94 13.21 19 11.24 19 9a7 7 0 0 0-7-7M3.28 4L2 5.27L5.04 8.3C5 8.53 5 8.76 5 9c0 2.38 1.19 4.47 3 5.74V17a1 1 0 0 0 1 1h5.73l4 4L20 20.72zm3.95 6.5l5.5 5.5H10v-2.42a5 5 0 0 1-2.77-3.08M9 20v1a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-1z"
></path>
</svg>
)
}
@ -40,7 +41,8 @@ export function MdiLightbulbAutoOutline(props: SVGProps<SVGSVGElement>) {
{/* Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE */}
<path
fill="currentColor"
d="M9 2c3.87 0 7 3.13 7 7c0 2.38-1.19 4.47-3 5.74V17c0 .55-.45 1-1 1H6c-.55 0-1-.45-1-1v-2.26C3.19 13.47 2 11.38 2 9c0-3.87 3.13-7 7-7M6 21v-1h6v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1M9 4C6.24 4 4 6.24 4 9c0 2.05 1.23 3.81 3 4.58V16h4v-2.42c1.77-.77 3-2.53 3-4.58c0-2.76-2.24-5-5-5m10 9h-2l-3.2 9h1.9l.7-2h3.2l.7 2h1.9zm-2.15 5.65L18 15l1.15 3.65z"></path>
d="M9 2c3.87 0 7 3.13 7 7c0 2.38-1.19 4.47-3 5.74V17c0 .55-.45 1-1 1H6c-.55 0-1-.45-1-1v-2.26C3.19 13.47 2 11.38 2 9c0-3.87 3.13-7 7-7M6 21v-1h6v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1M9 4C6.24 4 4 6.24 4 9c0 2.05 1.23 3.81 3 4.58V16h4v-2.42c1.77-.77 3-2.53 3-4.58c0-2.76-2.24-5-5-5m10 9h-2l-3.2 9h1.9l.7-2h3.2l.7 2h1.9zm-2.15 5.65L18 15l1.15 3.65z"
></path>
</svg>
)
}
@ -51,7 +53,8 @@ export function MdiLightbulbOn10(props: SVGProps<SVGSVGElement>) {
{/* Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE */}
<path
fill="currentColor"
d="M1 11h3v2H1zm18.1-7.5L17 5.6L18.4 7l2.1-2.1zM11 1h2v3h-2zM4.9 3.5L3.5 4.9L5.6 7L7 5.6zM10 22c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-1h-4zm2-16c-3.3 0-6 2.7-6 6c0 2.2 1.2 4.2 3 5.2V19c0 .6.4 1 1 1h4c.6 0 1-.4 1-1v-1.8c1.8-1 3-3 3-5.2c0-3.3-2.7-6-6-6m1 9.9V17h-2v-1.1c-1.7-.4-3-2-3-3.9c0-2.2 1.8-4 4-4s4 1.8 4 4c0 1.9-1.3 3.4-3 3.9m7-4.9h3v2h-3z"></path>
d="M1 11h3v2H1zm18.1-7.5L17 5.6L18.4 7l2.1-2.1zM11 1h2v3h-2zM4.9 3.5L3.5 4.9L5.6 7L7 5.6zM10 22c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-1h-4zm2-16c-3.3 0-6 2.7-6 6c0 2.2 1.2 4.2 3 5.2V19c0 .6.4 1 1 1h4c.6 0 1-.4 1-1v-1.8c1.8-1 3-3 3-5.2c0-3.3-2.7-6-6-6m1 9.9V17h-2v-1.1c-1.7-.4-3-2-3-3.9c0-2.2 1.8-4 4-4s4 1.8 4 4c0 1.9-1.3 3.4-3 3.9m7-4.9h3v2h-3z"
></path>
</svg>
)
}
@ -74,7 +77,8 @@ export function MdiLightbulbOn50(props: SVGProps<SVGSVGElement>) {
{/* Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE */}
<path
fill="currentColor"
d="M1 11h3v2H1zm9 11c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-1h-4zm3-21h-2v3h2zM4.9 3.5L3.5 4.9L5.6 7L7 5.6zM20 11v2h3v-2zm-.9-7.5L17 5.6L18.4 7l2.1-2.1zM18 12c0 2.2-1.2 4.2-3 5.2V19c0 .6-.4 1-1 1h-4c-.6 0-1-.4-1-1v-1.8c-1.8-1-3-3-3-5.2c0-3.3 2.7-6 6-6s6 2.7 6 6M8 12c0 .35.05.68.14 1h7.72c.09-.32.14-.65.14-1c0-2.21-1.79-4-4-4s-4 1.79-4 4"></path>
d="M1 11h3v2H1zm9 11c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-1h-4zm3-21h-2v3h2zM4.9 3.5L3.5 4.9L5.6 7L7 5.6zM20 11v2h3v-2zm-.9-7.5L17 5.6L18.4 7l2.1-2.1zM18 12c0 2.2-1.2 4.2-3 5.2V19c0 .6-.4 1-1 1h-4c-.6 0-1-.4-1-1v-1.8c-1.8-1-3-3-3-5.2c0-3.3 2.7-6 6-6s6 2.7 6 6M8 12c0 .35.05.68.14 1h7.72c.09-.32.14-.65.14-1c0-2.21-1.79-4-4-4s-4 1.79-4 4"
></path>
</svg>
)
}
@ -96,7 +100,8 @@ export function MdiLightbulbOn90(props: SVGProps<SVGSVGElement>) {
{/* Icon from Material Design Icons by Pictogrammers - https://github.com/Templarian/MaterialDesign/blob/master/LICENSE */}
<path
fill="currentColor"
d="M7 5.6L5.6 7L3.5 4.9l1.4-1.4zM10 22c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-1h-4zm-9-9h3v-2H1zM13 1h-2v3h2zm7 10v2h3v-2zm-.9-7.5L17 5.6L18.4 7l2.1-2.1zM18 12c0 2.2-1.2 4.2-3 5.2V19c0 .6-.4 1-1 1h-4c-.6 0-1-.4-1-1v-1.8c-1.8-1-3-3-3-5.2c0-3.3 2.7-6 6-6s6 2.7 6 6m-6-4c-1 0-1.91.38-2.61 1h5.22C13.91 8.38 13 8 12 8"></path>
d="M7 5.6L5.6 7L3.5 4.9l1.4-1.4zM10 22c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-1h-4zm-9-9h3v-2H1zM13 1h-2v3h2zm7 10v2h3v-2zm-.9-7.5L17 5.6L18.4 7l2.1-2.1zM18 12c0 2.2-1.2 4.2-3 5.2V19c0 .6-.4 1-1 1h-4c-.6 0-1-.4-1-1v-1.8c-1.8-1-3-3-3-5.2c0-3.3 2.7-6 6-6s6 2.7 6 6m-6-4c-1 0-1.91.38-2.61 1h5.22C13.91 8.38 13 8 12 8"
></path>
</svg>
)
}
@ -122,7 +127,8 @@ export function BingLogo(props: SVGProps<SVGSVGElement>) {
height="1em"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
{...props}>
{...props}
>
<path d="M4.842.005a.966.966 0 01.604.142l2.62 1.813c.369.256.492.352.637.496.471.47.752 1.09.797 1.765l.008.847.003 1.441.004 13.002.144-.094 7.015-4.353.015.003.029.01c-.398-.17-.893-.339-1.655-.566l-.484-.146c-.584-.18-.71-.238-.921-.38a2.009 2.009 0 01-.37-.312 2.172 2.172 0 01-.41-.592L11.32 9.063c-.166-.444-.166-.49-.156-.63a.92.92 0 01.806-.864l.094-.01c.044-.005.22.023.29.044l.052.021c.06.026.16.075.313.154l3.63 1.908a6.626 6.626 0 013.292 4.531c.194.99.159 2.037-.102 3.012-.216.805-.639 1.694-1.054 2.213l-.08.099-.047.05c-.01.01-.013.01-.01.002l.043-.074-.072.114c-.011.031-.233.28-.38.425l-.17.161c-.22.202-.431.36-.832.62L13.544 23c-.941.6-1.86.912-2.913.992-.23.018-.854.008-1.074-.017a6.31 6.31 0 01-1.658-.412c-1.854-.738-3.223-2.288-3.705-4.195a8.077 8.077 0 01-.121-.57l-.046-.325a1.123 1.123 0 01-.014-.168l-.006-.029L4 11.617 4.01.866a.981.981 0 01.007-.111.943.943 0 01.825-.75z"></path>
</svg>
)
@ -198,11 +204,13 @@ export function ExaLogo(props: SVGProps<SVGSVGElement>) {
height="1em"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
{...props}>
{...props}
>
<title>Exa</title>
<path
clip-rule="evenodd"
d="M3 0h19v1.791L13.892 12 22 22.209V24H3V0zm9.62 10.348l6.589-8.557H6.03l6.59 8.557zM5.138 3.935v7.17h5.52l-5.52-7.17zm5.52 8.96h-5.52v7.17l5.52-7.17zM6.03 22.21l6.59-8.557 6.589 8.557H6.03z"></path>
d="M3 0h19v1.791L13.892 12 22 22.209V24H3V0zm9.62 10.348l6.589-8.557H6.03l6.59 8.557zM5.138 3.935v7.17h5.52l-5.52-7.17zm5.52 8.96h-5.52v7.17l5.52-7.17zM6.03 22.21l6.59-8.557 6.589 8.557H6.03z"
></path>
</svg>
)
}
@ -260,16 +268,19 @@ export function PoeLogo(props: SVGProps<SVGSVGElement>) {
width="1em"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
{...props}>
{...props}
>
<title>Poe</title>
<path d="M20.708 6.876a1.412 1.412 0 00-1.029-.415h-.006a2.019 2.019 0 01-2.02-2.023A1.415 1.415 0 0016.254 3H4.871A1.412 1.412 0 003.47 4.434a2.026 2.026 0 01-2.025 2.025v.002A1.414 1.414 0 000 7.883v3.642a1.414 1.414 0 001.444 1.42 2.025 2.025 0 012.025 2.02v3.693a.5.5 0 00.89.313l2.051-2.567h9.843a1.412 1.412 0 001.4-1.434v-.002c0-1.12.904-2.025 2.026-2.025a1.412 1.412 0 001.446-1.42V7.88c0-.363-.14-.727-.417-1.005zm-2.42 4.687a2.025 2.025 0 01-2.025 2.005H4.861a2.025 2.025 0 01-2.025-2.005v-3.72A2.026 2.026 0 014.86 5.838h11.4a2.026 2.026 0 012.026 2.005v3.72h.002z"></path>
<path d="M7.413 7.57A1.422 1.422 0 005.99 8.99v1.422a1.422 1.422 0 102.844 0V8.99c0-.784-.636-1.422-1.422-1.422zm6.297 0a1.422 1.422 0 00-1.422 1.421v1.422a1.422 1.422 0 102.844 0V8.99c0-.784-.636-1.422-1.422-1.422z"></path>
<path
d="M7.292 22.643l1.993-2.492h9.844a1.413 1.413 0 001.4-1.434 2.025 2.025 0 012.017-2.027h.01A1.409 1.409 0 0024 15.27v-3.594c0-.344-.113-.68-.324-.951l-.397-.519v4.127a1.415 1.415 0 01-1.444 1.42h-.007a2.026 2.026 0 00-2.018 2.025 1.415 1.415 0 01-1.402 1.436H8.565l-2.169 2.712a.574.574 0 00.896.715v.002z"
fill="url(#lobe-icons-poe-fill-0)"></path>
fill="url(#lobe-icons-poe-fill-0)"
></path>
<path
d="M5.004 19.992l2.12-2.65h9.844a1.414 1.414 0 001.402-1.437c0-1.116.9-2.021 2.014-2.025h.012a1.413 1.413 0 001.443-1.422v-4.13l.52.68c.21.273.324.607.324.95v3.594a1.416 1.416 0 01-1.443 1.42h-.01a2.026 2.026 0 00-2.016 2.026 1.414 1.414 0 01-1.402 1.435H7.97l-1.916 2.4a.671.671 0 01-1.049-.839v-.002z"
fill="url(#lobe-icons-poe-fill-1)"></path>
fill="url(#lobe-icons-poe-fill-1)"
></path>
<defs>
<linearGradient
gradientUnits="userSpaceOnUse"
@ -277,7 +288,8 @@ export function PoeLogo(props: SVGProps<SVGSVGElement>) {
x1="34.01"
x2="1.086"
y1="7.303"
y2="27.715">
y2="27.715"
>
<stop stopColor="#46A6F7"></stop>
<stop offset="1" stop-color="#8364FF"></stop>
</linearGradient>
@ -287,7 +299,8 @@ export function PoeLogo(props: SVGProps<SVGSVGElement>) {
x1="4.915"
x2="24.34"
y1="23.511"
y2="9.464">
y2="9.464"
>
<stop stopColor="#FF44D3"></stop>
<stop offset="1" stop-color="#CF4BFF"></stop>
</linearGradient>

View File

@ -10,11 +10,13 @@ export function SvgSpinners180Ring(props: SVGProps<SVGSVGElement> & { size?: num
height={size}
viewBox="0 0 24 24"
{...svgProps}
className={`animation-rotate ${svgProps.className || ''}`.trim()}>
className={`animation-rotate ${svgProps.className || ''}`.trim()}
>
{/* Icon from SVG Spinners by Utkarsh Verma - https://github.com/n3r4zzurr0/svg-spinners/blob/main/LICENSE */}
<path
fill="currentColor"
d="M12,4a8,8,0,0,1,7.89,6.7A1.53,1.53,0,0,0,21.38,12h0a1.5,1.5,0,0,0,1.48-1.75,11,11,0,0,0-21.72,0A1.5,1.5,0,0,0,2.62,12h0a1.53,1.53,0,0,0,1.49-1.3A8,8,0,0,1,12,4Z"></path>
d="M12,4a8,8,0,0,1,7.89,6.7A1.53,1.53,0,0,0,21.38,12h0a1.5,1.5,0,0,0,1.48-1.75,11,11,0,0,0-21.72,0A1.5,1.5,0,0,0,2.62,12h0a1.53,1.53,0,0,0,1.49-1.3A8,8,0,0,1,12,4Z"
></path>
</svg>
)
}

View File

@ -10,7 +10,8 @@ const UnWrapIcon = (props: React.SVGProps<SVGSVGElement>) => (
strokeWidth={2}
className="unwrap_svg__lucide unwrap_svg__lucide-text unwrap_svg__size-4"
viewBox="0 0 24 24"
{...props}>
{...props}
>
<path d="M17 6.1H3M21 12.1H3M15.1 18H3" />
</svg>
)

View File

@ -12,7 +12,8 @@ const WrapIcon = (props: React.SVGProps<SVGSVGElement>) => (
strokeWidth={2}
className="wrap_svg__lucide wrap_svg__lucide-wrap-text wrap_svg__size-4"
viewBox="0 0 24 24"
{...props}>
{...props}
>
<path d="M3 6h18M3 12h15a3 3 0 1 1 0 6h-4" />
<path d="m16 16-2 2 2 2M3 18h7" />
</svg>

View File

@ -199,7 +199,8 @@ export function LocalBackupManager({ visible, onClose, localBackupDir, restoreMe
type="link"
danger
onClick={() => handleDeleteSingle(record.fileName)}
disabled={deleting || restoring}>
disabled={deleting || restoring}
>
{t('settings.data.local.backup.manager.delete.text')}
</Button>
</>
@ -232,13 +233,15 @@ export function LocalBackupManager({ visible, onClose, localBackupDir, restoreMe
icon={<DeleteOutlined />}
onClick={handleDeleteSelected}
disabled={selectedRowKeys.length === 0 || deleting}
loading={deleting}>
loading={deleting}
>
{t('settings.data.local.backup.manager.delete.selected')} ({selectedRowKeys.length})
</Button>,
<Button key="close" onClick={onClose}>
{t('common.close')}
</Button>
]}>
]}
>
<Table
rowKey="fileName"
columns={columns}

View File

@ -39,7 +39,8 @@ export function LocalBackupModal({
<Button key="submit" type="primary" loading={backuping} onClick={handleBackup}>
{t('common.confirm')}
</Button>
]}>
]}
>
<Input
value={customFileName}
onChange={(e) => setCustomFileName(e.target.value)}

View File

@ -44,7 +44,8 @@ const MarkdownEditor: FC<MarkdownEditorProps> = ({
<PreviewArea className="markdown">
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkCjkFriendly, remarkMath]}
rehypePlugins={[rehypeRaw, rehypeKatex]}>
rehypePlugins={[rehypeRaw, rehypeKatex]}
>
{inputValue || t('settings.provider.notes.markdown_editor_default_value')}
</ReactMarkdown>
</PreviewArea>

View File

@ -99,7 +99,8 @@ const MinAppTabsPool: React.FC = () => {
: { visibility: 'hidden' }
}
data-minapp-tabs-pool
aria-hidden={!shouldShow}>
aria-hidden={!shouldShow}
>
{apps.map((app) => (
<WebviewWrapper key={app.id} $active={app.id === currentMinappId}>
<WebviewContainer

View File

@ -417,7 +417,8 @@ const MinappPopupContainer: React.FC = () => {
root: {
maxWidth: '400px'
}
}}>
}}
>
<TitleText onContextMenu={(e) => handleCopyUrl(e, url ?? appInfo.url)}>{appInfo.name}</TitleText>
</Tooltip>
{appInfo.canOpenExternalLink && (
@ -431,7 +432,8 @@ const MinappPopupContainer: React.FC = () => {
<ButtonsGroup
className={isWin || isLinux ? 'windows' : ''}
style={{ marginRight: isWin || isLinux ? '140px' : 0 }}
isTopNavbar={isTopNavbar}>
isTopNavbar={isTopNavbar}
>
<Tooltip title={t('minapp.popup.goBack')} mouseEnterDelay={0.8} placement="bottom">
<TitleButton onClick={() => handleGoBack(appInfo.id)}>
<ArrowLeftOutlined />
@ -459,7 +461,8 @@ const MinappPopupContainer: React.FC = () => {
: t('minapp.add_to_sidebar')
}
mouseEnterDelay={0.8}
placement="bottom">
placement="bottom"
>
<TitleButton onClick={() => handleTogglePin(appInfo.id)} className={appInfo.isPinned ? 'pinned' : ''}>
<PushpinOutlined style={{ fontSize: 16 }} />
</TitleButton>
@ -472,7 +475,8 @@ const MinappPopupContainer: React.FC = () => {
: t('minapp.popup.open_link_external_off')
}
mouseEnterDelay={0.8}
placement="bottom">
placement="bottom"
>
<TitleButton onClick={handleToggleOpenExternal} className={minappsOpenLinkExternal ? 'open-external' : ''}>
<LinkOutlined />
</TitleButton>
@ -547,7 +551,8 @@ const MinappPopupContainer: React.FC = () => {
body: {
borderTopLeftRadius: '10px'
}
}}>
}}
>
{/* 在所有小程序中显示GoogleLoginTip */}
<GoogleLoginTip isReady={isReady} currentUrl={currentUrl} currentAppId={currentMinappId} />
{!isReady && (

View File

@ -33,7 +33,8 @@ const ModelIdWithTags = ({
</Typography.Text>
}
mouseEnterDelay={0.5}
placement="top">
placement="top"
>
<NameSpan>{model.name}</NameSpan>
</Tooltip>
<ModelTagsWithLabel model={model} size={11} style={{ flexShrink: 0 }} />

View File

@ -36,7 +36,7 @@ export const OGCard = ({ link, show }: Props) => {
const GeneratedGraph = useCallback(() => {
return (
<div className="flex h-36 items-center justify-center bg-accent p-4">
<h2 className="text-2xl font-bold">{metadata['og:title'] || hostname}</h2>
<h2 className="font-bold text-2xl">{metadata['og:title'] || hostname}</h2>
</div>
)
}, [hostname, metadata])
@ -67,7 +67,8 @@ export const OGCard = ({ link, show }: Props) => {
fontSize: '14px',
lineHeight: '1.2',
color: 'var(--color-text)'
}}>
}}
>
{metadata['og:title'] || hostname}
</Title>
</StyledHyperLink>
@ -78,7 +79,8 @@ export const OGCard = ({ link, show }: Props) => {
fontSize: '12px',
lineHeight: '1.2',
color: 'var(--color-text-secondary)'
}}>
}}
>
{metadata['og:description'] || link}
</Paragraph>
</PreviewContent>

View File

@ -316,7 +316,8 @@ const PopupContainer: React.FC<PopupContainerProps> = ({
disabled: vaults.length === 0 || loading || !!error
}}
okText={i18n.t('chat.topics.export.obsidian_btn')}
afterClose={() => setOpen(open)}>
afterClose={() => setOpen(open)}
>
{error && <Alert message={error} type="error" showIcon style={{ marginBottom: 16 }} />}
<Form layout="horizontal" labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} labelAlign="left">
<Form.Item label={i18n.t('chat.topics.export.obsidian_title')}>
@ -333,7 +334,8 @@ const PopupContainer: React.FC<PopupContainerProps> = ({
value={selectedVault}
onChange={handleVaultChange}
placeholder={i18n.t('chat.topics.export.obsidian_vault_placeholder')}
style={{ width: '100%' }}>
style={{ width: '100%' }}
>
{vaults.map((vault) => (
<Option key={vault.name} value={vault.name}>
{vault.name}
@ -363,7 +365,8 @@ const PopupContainer: React.FC<PopupContainerProps> = ({
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
treeDefaultExpandAll={false}
treeNodeFilterProp="title"
treeData={fileTreeData}></TreeSelect>
treeData={fileTreeData}
></TreeSelect>
) : (
<Empty
description={i18n.t('chat.topics.export.obsidian_select_vault_first')}
@ -398,7 +401,8 @@ const PopupContainer: React.FC<PopupContainerProps> = ({
value={state.processingMethod}
onChange={(value) => handleChange('processingMethod', value)}
placeholder={i18n.t('chat.topics.export.obsidian_operate_placeholder')}
allowClear>
allowClear
>
<Option value={ObsidianProcessingMethod.APPEND}>
{i18n.t('chat.topics.export.obsidian_operate_append')}
</Option>

View File

@ -172,7 +172,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
}
}}
closeIcon={null}
footer={null}>
footer={null}
>
<HStack style={{ padding: '0 12px', marginTop: 5 }}>
<Input
prefix={
@ -198,7 +199,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
key={agent.id}
onClick={() => onCreateAssistant(agent)}
className={`agent-item ${agent.id === 'default' ? 'default' : ''} ${index === selectedIndex ? 'keyboard-selected' : ''}`}
onMouseEnter={() => setSelectedIndex(index)}>
onMouseEnter={() => setSelectedIndex(index)}
>
<HStack alignItems="center" gap={5} style={{ overflow: 'hidden', maxWidth: '100%' }}>
<EmojiIcon emoji={agent.emoji || ''} />
<span className="text-nowrap">{agent.name}</span>

View File

@ -127,7 +127,8 @@ const ApiKeyItem: FC<ApiKeyItemProps> = ({
mouseEnterDelay={0.5}
placement="top"
// 确保不留下明文
destroyOnHidden>
destroyOnHidden
>
<span style={{ cursor: 'help' }}>{maskApiKey(keyStatus.key)}</span>
</Tooltip>
@ -154,7 +155,8 @@ const ApiKeyItem: FC<ApiKeyItemProps> = ({
disabled={disabled}
okText={t('common.confirm')}
cancelText={t('common.cancel')}
okButtonProps={{ danger: true }}>
okButtonProps={{ danger: true }}
>
<Tooltip title={t('common.delete')} mouseLeaveDelay={0}>
<Button type="text" icon={<Minus size={16} />} disabled={disabled} />
</Tooltip>

View File

@ -95,7 +95,8 @@ export const ApiKeyList: FC<ApiKeyListProps> = ({ provider, updateProvider, show
size="small"
type="inner"
styles={{ body: { padding: 0 } }}
style={{ marginBottom: '5px', border: '0.5px solid var(--color-border)' }}>
style={{ marginBottom: '5px', border: '0.5px solid var(--color-border)' }}
>
{displayKeys.length === 0 ? (
<Typography.Text type="secondary" style={{ padding: '4px 11px', display: 'block' }}>
{t('error.no_api_key')}
@ -138,7 +139,8 @@ export const ApiKeyList: FC<ApiKeyListProps> = ({ provider, updateProvider, show
onConfirm={removeInvalidKeys}
okText={t('common.confirm')}
cancelText={t('common.cancel')}
okButtonProps={{ danger: true }}>
okButtonProps={{ danger: true }}
>
<Tooltip title={t('settings.provider.remove_invalid_keys')} placement="top" mouseLeaveDelay={0}>
<Button
type="text"
@ -168,7 +170,8 @@ export const ApiKeyList: FC<ApiKeyListProps> = ({ provider, updateProvider, show
onClick={handleAddNew}
icon={<Plus size={16} />}
autoFocus={shouldAutoFocus()}
disabled={isChecking || !!pendingNewKey}>
disabled={isChecking || !!pendingNewKey}
>
{t('common.add')}
</Button>
</Space>

View File

@ -50,7 +50,8 @@ const PopupContainer: React.FC<Props> = ({ providerId, title, resolve, showHealt
transitionName="animation-move-down"
centered
width={600}
footer={null}>
footer={null}
>
{ListComponent}
</Modal>
)

View File

@ -80,7 +80,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
okText={t('backup.confirm.button')}
maskClosable={false}
transitionName="animation-move-down"
centered>
centered
>
{!progressData && <div>{t('backup.content')}</div>}
{progressData && (
<div style={{ textAlign: 'center', padding: '20px 0' }}>

View File

@ -35,7 +35,8 @@ const PopupContainer: React.FC<Props> = ({ content, resolve, ...rest }) => {
afterClose={onClose}
transitionName="animation-move-down"
centered
{...rest}>
{...rest}
>
{content}
</Modal>
)

View File

@ -30,7 +30,8 @@ const PopupContainer: React.FC<Props> = ({ resolve, fs }) => {
afterClose={onClose}
onCancel={onClose}
footer={null}
centered>
centered
>
<NutstorePathSelector fs={fs} onConfirm={resolve} onCancel={onCancel} />
</Modal>
)

View File

@ -67,7 +67,8 @@ const PromptPopupContainer: React.FC<Props> = ({
afterClose={onAfterClose}
afterOpenChange={handleAfterOpenChange}
transitionName="animation-move-down"
centered>
centered
>
<Box mb={8}>{message}</Box>
<Input.TextArea
ref={textAreaRef}

View File

@ -72,7 +72,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
cancelButtonProps={{ disabled: isDisabled }}
maskClosable={false}
transitionName="animation-move-down"
centered>
centered
>
{!progressData && <div>{t('restore.content')}</div>}
{progressData && (
<div style={{ textAlign: 'center', padding: '20px 0' }}>

View File

@ -98,7 +98,8 @@ const PopupContainer: React.FC<Props> = ({
afterOpenChange={handleAfterOpenChange}
maskClosable={false}
keyboard={false}
centered>
centered
>
<EditorContainer>
<RichEditor
ref={editorRef}

View File

@ -303,7 +303,8 @@ const PopupContainer: React.FC<Props> = ({ source, title, resolve }) => {
<Form.Item
label={t('chat.save.knowledge.select.base.title')}
help={!formState.hasValidBase && selectedBaseId ? t('chat.save.knowledge.error.invalid_base') : undefined}
validateStatus={!formState.hasValidBase && selectedBaseId ? 'error' : undefined}>
validateStatus={!formState.hasValidBase && selectedBaseId ? 'error' : undefined}
>
<Select
value={selectedBaseId}
onChange={setSelectedBaseId}
@ -319,18 +320,21 @@ const PopupContainer: React.FC<Props> = ({ source, title, resolve }) => {
isTopicMode
? 'chat.save.topic.knowledge.select.content.label'
: 'chat.save.knowledge.select.content.title'
)}>
)}
>
<Flex gap={8} style={{ flexDirection: 'column' }}>
{contentTypeOptions.map((option) => (
<ContentTypeItem
key={option.type}
align="center"
justify="space-between"
onClick={() => handleContentTypeToggle(option.type)}>
onClick={() => handleContentTypeToggle(option.type)}
>
<Flex align="center" gap={8}>
<CustomTag
color={selectedTypes.includes(option.type) ? TAG_COLORS.SELECTED : TAG_COLORS.UNSELECTED}
size={12}>
size={12}
>
{option.count}
</CustomTag>
<span>{option.label}</span>
@ -397,7 +401,8 @@ const PopupContainer: React.FC<Props> = ({ source, title, resolve }) => {
width={500}
okText={t('common.save')}
cancelText={t('common.cancel')}
okButtonProps={{ loading, disabled: !formState.canSubmit || analysisLoading }}>
okButtonProps={{ loading, disabled: !formState.canSubmit || analysisLoading }}
>
{uiState.type === 'form' ? renderFormContent() : renderEmptyState()}
</Modal>
)

View File

@ -49,7 +49,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
}}
centered
closable={false}
footer={null}>
footer={null}
>
<HistoryPage />
</Modal>
)

View File

@ -374,7 +374,8 @@ const PopupContainer: React.FC<Props> = ({ model, filter: baseFilter, showTagFil
selected: item.isSelected
})}
onClick={() => handleItemClick(item)}
onMouseOver={() => !isFocused && setFocusedItemKey(item.key)}>
onMouseOver={() => !isFocused && setFocusedItemKey(item.key)}
>
<ModelItemLeft>
{item.icon}
{item.name}
@ -388,7 +389,8 @@ const PopupContainer: React.FC<Props> = ({ model, filter: baseFilter, showTagFil
}
}}
data-pinned={item.isPinned}
$isPinned={item.isPinned}>
$isPinned={item.isPinned}
>
<PushpinOutlined />
</PinIconWrapper>
</ModelItem>
@ -418,7 +420,8 @@ const PopupContainer: React.FC<Props> = ({ model, filter: baseFilter, showTagFil
}
}}
closeIcon={null}
footer={null}>
footer={null}
>
{/* 搜索框 */}
<SelectModelSearchBar onSearch={setSearchText} />
<Divider style={{ margin: 0, marginTop: 4, borderBlockStartWidth: 0.5 }} />
@ -440,7 +443,8 @@ const PopupContainer: React.FC<Props> = ({ model, filter: baseFilter, showTagFil
isSticky={isSticky}
scrollPaddingStart={ITEM_HEIGHT} // 留出 sticky header 高度
overscan={5}
scrollerStyle={{ pointerEvents: isMouseOver ? 'auto' : 'none' }}>
scrollerStyle={{ pointerEvents: isMouseOver ? 'auto' : 'none' }}
>
{rowRenderer}
</DynamicVirtualList>
</ListContainer>

View File

@ -36,7 +36,8 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
onCancel={onCancel}
afterClose={onClose}
transitionName="animation-move-down"
centered>
centered
>
<Box mb={8}>Name</Box>
</Modal>
)

View File

@ -135,7 +135,8 @@ const PopupContainer: React.FC<Props> = ({
onCancel={onCancel}
afterClose={onClose}
afterOpenChange={handleAfterOpenChange}
centered>
centered
>
<TextAreaContainer>
<TextArea
ref={textareaRef}
@ -151,7 +152,8 @@ const PopupContainer: React.FC<Props> = ({
<TranslateButton
onClick={handleTranslate}
aria-label="Translate text"
disabled={isTranslating || !textValue.trim()}>
disabled={isTranslating || !textValue.trim()}
>
{isTranslating ? <LoadingOutlined spin /> : <Languages size={16} />}
</TranslateButton>
)}

View File

@ -52,7 +52,8 @@ const PopupContainer: React.FC<Props> = ({ text, title, extension, resolve }) =>
}}
centered
closable={true}
footer={null}>
footer={null}
>
{extension !== undefined ? (
<Editor
editable={false}

View File

@ -85,7 +85,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
} catch (error: any) {
window.toast.error(error.message)
}
}}>
}}
>
{t('settings.general.image_upload')}
</Upload>
</div>
@ -100,7 +101,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
e.stopPropagation()
setEmojiPickerOpen(true)
setDropdownOpen(false)
}}>
}}
>
{t('settings.general.emoji_picker')}
</div>
)
@ -113,7 +115,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
onClick={(e) => {
e.stopPropagation()
handleReset()
}}>
}}
>
{t('settings.general.avatar.reset')}
</div>
)
@ -129,7 +132,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
onCancel={onCancel}
afterClose={onClose}
transitionName="animation-move-down"
centered>
centered
>
<Center mt="30px">
<VStack alignItems="center" gap="10px">
<Dropdown
@ -143,7 +147,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
if (visible) {
setEmojiPickerOpen(false)
}
}}>
}}
>
<Popover
content={<EmojiPicker onEmojiClick={handleEmojiClick} />}
trigger="click"
@ -154,7 +159,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
setDropdownOpen(false)
}
}}
placement="bottom">
placement="bottom"
>
{isEmoji(avatar) ? (
<EmojiAvatar size={80} fontSize={40}>
{avatar}

View File

@ -63,7 +63,8 @@ const SingleFileUploader: React.FC<SingleFileUploaderProps> = ({
logger.error('Upload failed: Invalid file format')
}
}}
onRemove={onRemove}>
onRemove={onRemove}
>
<p className="ant-upload-drag-icon">
<UploadOutlined />
</p>
@ -165,7 +166,8 @@ const VideoPopupContainer: React.FC<Props> = ({ title, resolve }) => {
width={600}
okButtonProps={{ disabled: isOkButtonDisabled }}
okText={t('common.confirm')}
cancelText={t('common.cancel')}>
cancelText={t('common.cancel')}
>
<Space direction="vertical" style={{ width: '100%', gap: '16px' }}>
<SingleFileUploader
uploadType="video"

View File

@ -42,7 +42,8 @@ const GraphvizPreview = ({
enableToolbar={enableToolbar}
ref={ref}
imageRef={containerRef}
source="graphviz">
source="graphviz"
>
<ShadowWhiteContainer ref={containerRef} className="graphviz special-preview" />
</ImagePreviewLayout>
)

View File

@ -129,7 +129,8 @@ const MermaidPreview = ({
enableToolbar={enableToolbar}
ref={ref}
imageRef={containerRef}
source="mermaid">
source="mermaid"
>
<ShadowTransparentContainer ref={containerRef} className="mermaid special-preview" />
</ImagePreviewLayout>
)

View File

@ -128,7 +128,8 @@ const PlantUmlPreview = ({
enableToolbar={enableToolbar}
ref={ref}
imageRef={containerRef}
source="plantuml">
source="plantuml"
>
<ShadowWhiteContainer ref={containerRef} className="plantuml-preview special-preview" />
</ImagePreviewLayout>
)

View File

@ -34,7 +34,8 @@ const SvgPreview = ({ children, enableToolbar = false, className, ref }: SvgPrev
enableToolbar={enableToolbar}
ref={ref}
imageRef={containerRef}
source="svg">
source="svg"
>
{/* 使用透明容器,把背景色完全交给 SVG 自己控制 */}
<ShadowTransparentContainer ref={containerRef} className={className ?? 'svg-preview special-preview'} />
</ImagePreviewLayout>

View File

@ -79,7 +79,8 @@ export const ProviderAvatarPrimitive: React.FC<ProviderAvatarPrimitiveProps> = (
backgroundColor,
color,
...style
}}>
}}
>
{getFirstCharacter(providerName)}
</ProviderLogo>
)

View File

@ -550,7 +550,8 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
onClick={(e) => {
e.stopPropagation()
handleItemAction(item, 'click')
}}>
}}
>
<QuickPanelItemLeft>
<QuickPanelItemIcon>{item.icon}</QuickPanelItemIcon>
<QuickPanelItemLabel>{item.label}</QuickPanelItemLabel>
@ -581,7 +582,8 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
$selectedColorHover={selectedColorHover}
$collapsed={collapsed}
className={ctx.isVisible ? 'visible' : ''}
data-testid="quick-panel">
data-testid="quick-panel"
>
<QuickPanelBody
ref={bodyRef}
onMouseMove={() =>
@ -589,7 +591,8 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
scrollTriggerRef.current = 'initial'
return prev ? prev : true
})
}>
}
>
{!collapsed && (
<DynamicVirtualList
ref={listRef}
@ -599,7 +602,8 @@ export const QuickPanelView: React.FC<Props> = ({ setInputText }) => {
overscan={5}
scrollerStyle={{
pointerEvents: isMouseOver ? 'auto' : 'none'
}}>
}}
>
{rowRenderer}
</DynamicVirtualList>
)}

View File

@ -161,7 +161,8 @@ const CommandListPopover = ({
alignItems: 'center'
}}
onClick={() => selectItem(index)}
onMouseEnter={() => handleItemMouseEnter(index)}>
onMouseEnter={() => handleItemMouseEnter(index)}
>
<div style={{ display: 'flex', alignItems: 'center', gap: '12px', width: '100%' }}>
<div
style={{
@ -171,7 +172,8 @@ const CommandListPopover = ({
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}>
}}
>
<item.icon size={16} />
</div>
<div style={{ flex: 1, minWidth: 0 }}>

View File

@ -23,7 +23,8 @@ export const ToCItem: React.FC<ToCItemProps> = ({ item, onItemClick }) => {
{
'--level': item.level
} as React.CSSProperties
}>
}
>
<a href={`#${item.id}`} onClick={(e) => onItemClick(e, item.id)} data-item-index={item.itemIndex}>
{item.textContent}
</a>

View File

@ -75,7 +75,8 @@ export const ActionMenu: FC<ActionMenuProps> = ({ show, position, items, onClose
boxShadow: '0 6px 16px rgba(0,0,0,0.12)',
overflow: 'hidden',
minWidth
}}>
}}
>
<Menu selectable={false} items={menuItems} onClick={onMenuClick} style={{ border: 'none' }} />
</div>
)

View File

@ -134,7 +134,8 @@ export const ImageUploader: React.FC<ImageUploaderProps> = ({ onImageSelect, vis
showUploadList={false}
beforeUpload={handleFileSelect}
customRequest={() => {}} // Prevent default upload
disabled={loading}>
disabled={loading}
>
{loading ? (
<>
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} />
@ -180,7 +181,8 @@ export const ImageUploader: React.FC<ImageUploaderProps> = ({ onImageSelect, vis
borderRadius: '4px',
color: '#3c4043',
background: '#ffffff'
}}>
}}
>
{t('common.clear')}
</Button>
<Button type="primary" onClick={handleUrlSubmit} disabled={!urlInput.trim()}>
@ -199,7 +201,8 @@ export const ImageUploader: React.FC<ImageUploaderProps> = ({ onImageSelect, vis
onCancel={handleCancel}
footer={null}
width={600}
centered>
centered
>
<Tabs defaultActiveKey="upload" items={tabItems} size="large" />
</Modal>
)

View File

@ -73,7 +73,8 @@ export const TableActionMenu: FC<TableActionMenuProps> = ({ show, position, acti
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
minWidth: '160px',
padding: '4px 0'
}}>
}}
>
{actions.map((action, index) => (
<button
key={index}
@ -99,7 +100,8 @@ export const TableActionMenu: FC<TableActionMenuProps> = ({ show, position, acti
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = 'transparent'
}}>
}}
>
{action.icon && <span>{action.icon}</span>}
<span>{action.label}</span>
</button>

View File

@ -421,13 +421,15 @@ const YamlFrontMatterNodeView: React.FC<NodeViewProps> = ({ node, updateAttribut
if (e.target === e.currentTarget) {
e.preventDefault()
}
}}>
}}
>
<PropertiesContainer
hasContent={hasContent}
onClick={(e) => {
// Prevent node selection when clicking inside properties
e.stopPropagation()
}}>
}}
>
{parsedProperties.map((property) => (
<Dropdown
key={property.key}
@ -437,11 +439,13 @@ const YamlFrontMatterNodeView: React.FC<NodeViewProps> = ({ node, updateAttribut
open={openDropdown === `context-${property.key}`}
onOpenChange={(open) => {
setOpenDropdown(open ? `context-${property.key}` : null)
}}>
}}
>
<PropertyRow
onContextMenu={(e) => {
e.stopPropagation()
}}>
}}
>
<PropertyIcon>{getPropertyIcon(property.type)}</PropertyIcon>
<PropertyName>{property.key}</PropertyName>
{renderPropertyValue(property)}
@ -453,7 +457,8 @@ const YamlFrontMatterNodeView: React.FC<NodeViewProps> = ({ node, updateAttribut
open={openDropdown === `action-${property.key}`}
onOpenChange={(open) => {
setOpenDropdown(open ? `action-${property.key}` : null)
}}>
}}
>
<ActionButton onClick={(e) => e.stopPropagation()} title={t('richEditor.frontMatter.moreActions')}>
<MoreHorizontal size={14} />
</ActionButton>

View File

@ -167,7 +167,8 @@ const DragContextMenu: React.FC<DragContextMenuProps> = ({
$danger={action.danger}
onClick={() => handleMenuItemClick(action)}
disabled={!action.isEnabled(editor, node, position)}
title={action.shortcut ? `${action.label} (${action.shortcut})` : action.label}>
title={action.shortcut ? `${action.label} (${action.shortcut})` : action.label}
>
{action.icon && <MenuItemIcon>{action.icon}</MenuItemIcon>}
<MenuItemLabel>{action.label}</MenuItemLabel>
{action.shortcut && <MenuItemShortcut>{action.shortcut}</MenuItemShortcut>}
@ -193,7 +194,8 @@ const DragContextMenu: React.FC<DragContextMenuProps> = ({
top: menuPosition.y
}}
onKeyDown={handleKeyDown}
tabIndex={-1}>
tabIndex={-1}
>
<EmptyState>No actions available for this block</EmptyState>
</MenuContainer>
)
@ -212,7 +214,8 @@ const DragContextMenu: React.FC<DragContextMenuProps> = ({
}}
onKeyDown={handleKeyDown}
tabIndex={-1}
data-testid="drag-context-menu">
data-testid="drag-context-menu"
>
{GROUP_ORDER.map((group, index) => {
const actions = finalActionsByGroup[group]
const groupElement = renderMenuGroup(group, actions)

View File

@ -52,7 +52,8 @@ const PlaceholderBlock: React.FC<PlaceholderBlockProps> = ({ icon, message, onCl
const target = e.currentTarget as HTMLElement
target.style.borderColor = colors.border
target.style.backgroundColor = colors.background
}}>
}}
>
{icon}
<span style={{ color: '#656d76', fontSize: 14 }}>{message}</span>
</div>

View File

@ -390,7 +390,8 @@ const RichEditor = ({
$isFullWidth={isFullWidth}
$fontFamily={fontFamily}
$fontSize={fontSize}
onKeyDown={onKeyDownEditor}>
onKeyDown={onKeyDownEditor}
>
{showToolbar && (
<Toolbar
editor={editor}

View File

@ -170,7 +170,8 @@ export const Toolbar: React.FC<ToolbarProps> = ({ editor, formattingState, onCom
data-active={isActive}
disabled={isDisabled}
onClick={() => handleCommand(command)}
data-testid={`toolbar-${command}`}>
data-testid={`toolbar-${command}`}
>
<Icon color={isActive ? 'var(--color-primary)' : 'var(--color-text)'} />
</ToolbarButton>
)

View File

@ -238,7 +238,8 @@ export function S3BackupManager({ visible, onClose, s3Config, restoreMethod }: S
type="link"
danger
onClick={() => handleDeleteSingle(record.fileName)}
disabled={deleting || restoring}>
disabled={deleting || restoring}
>
{t('settings.data.s3.manager.delete.label')}
</Button>
</>
@ -271,13 +272,15 @@ export function S3BackupManager({ visible, onClose, s3Config, restoreMethod }: S
icon={<DeleteOutlined />}
onClick={handleDeleteSelected}
disabled={selectedRowKeys.length === 0 || deleting}
loading={deleting}>
loading={deleting}
>
{t('settings.data.s3.manager.delete.selected', { count: selectedRowKeys.length })}
</Button>,
<Button key="close" onClick={onClose}>
{t('settings.data.s3.manager.close')}
</Button>
]}>
]}
>
<Table
rowKey="fileName"
columns={columns}

View File

@ -78,7 +78,8 @@ export function S3BackupModal({
onCancel={handleCancel}
okButtonProps={{ loading: backuping }}
transitionName="animation-move-down"
centered>
centered
>
<Input
value={customFileName}
onChange={(e) => setCustomFileName(e.target.value)}
@ -222,7 +223,8 @@ export function S3RestoreModal({
okButtonProps={{ loading: restoring }}
width={600}
transitionName="animation-move-down"
centered>
centered
>
<div style={{ position: 'relative' }}>
<Select
style={{ width: '100%' }}

View File

@ -52,7 +52,8 @@ const Scrollbar: FC<ScrollbarProps> = ({ ref: passedRef, children, onScroll: ext
{...htmlProps} // Pass other HTML attributes
$isScrolling={isScrolling}
onScroll={combinedOnScroll} // Use the combined handler
ref={passedRef}>
ref={passedRef}
>
{children}
</ScrollBarContainer>
)

View File

@ -134,7 +134,8 @@ const Selector = <V extends string | number>({
trigger={['click']}
placement={placement}
open={open && !disabled}
onOpenChange={handleOpenChange}>
onOpenChange={handleOpenChange}
>
<Label $size={size} $open={open} $disabled={disabled} $isPlaceholder={label === placeholder}>
{label}
<LabelIcon size={size + 3} />

View File

@ -27,7 +27,8 @@ export default function Spinner({ text }: Props) {
repeat: Infinity,
repeatType: 'reverse',
ease: 'easeInOut'
}}>
}}
>
<Search size={16} style={{ color: 'unset' }} />
<span>{text}</span>
</Searching>

View File

@ -206,7 +206,8 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
onClick={(e) => {
e.stopPropagation()
closeTab(tab.id)
}}>
}}
>
<X size={12} />
</CloseButton>
)}
@ -221,7 +222,8 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
<Tooltip
title={t('settings.theme.title') + ': ' + getThemeModeLabel(settedTheme)}
mouseEnterDelay={0.8}
placement="bottom">
placement="bottom"
>
<ThemeButton onClick={toggleTheme}>
{settedTheme === ThemeMode.dark ? (
<Moon size={16} />

View File

@ -42,7 +42,8 @@ const CustomTag: FC<CustomTagProps> = ({
style={{
...(disabled && { cursor: 'not-allowed' }),
...style
}}>
}}
>
{icon && icon} {children}
{closable && (
<CloseIcon

View File

@ -16,7 +16,8 @@ export const ReasoningTag = ({ size, showTooltip, showLabel, ...restProps }: Pro
color="#6372bd"
icon={<i className="iconfont icon-thinking" />}
tooltip={showTooltip ? t('models.type.reasoning') : undefined}
{...restProps}>
{...restProps}
>
{showLabel ? t('models.type.reasoning') : ''}
</CustomTag>
)

View File

@ -17,7 +17,8 @@ export const ToolsCallingTag = ({ size, showTooltip, showLabel, ...restProps }:
color="#f18737"
icon={<ToolOutlined style={{ fontSize: size }} />}
tooltip={showTooltip ? t('models.type.function_calling') : undefined}
{...restProps}>
{...restProps}
>
{showLabel ? t('models.type.function_calling') : ''}
</CustomTag>
)

View File

@ -18,7 +18,8 @@ export const VisionTag = ({ size, showTooltip, showLabel, ...restProps }: Props)
color="#00b96b"
icon={<EyeOutlined style={{ fontSize: size }} />}
tooltip={showTooltip ? t('models.type.vision') : undefined}
{...restProps}>
{...restProps}
>
{showLabel ? t('models.type.vision') : ''}
</CustomTag>
)

View File

@ -18,7 +18,8 @@ export const WebSearchTag = ({ size, showTooltip, showLabel, ...restProps }: Pro
color="#1677ff"
icon={<GlobalOutlined style={{ fontSize: size }} />}
tooltip={showTooltip ? t('models.type.websearch') : undefined}
{...restProps}>
{...restProps}
>
{showLabel ? t('models.type.websearch') : ''}
</CustomTag>
)

View File

@ -11,7 +11,8 @@ export const WarnTag = ({ iconSize: size = 14, message }: Props) => {
return (
<CustomTag
icon={<AlertTriangleIcon size={size} color="var(--color-status-warning)" />}
color="var(--color-status-warning)">
color="var(--color-status-warning)"
>
{message}
</CustomTag>
)

View File

@ -65,7 +65,8 @@ const ThinkingEffect: React.FC<Props> = ({ isThinking, thinkingTimeText, content
transition={{
duration: 0.15,
ease: 'linear'
}}>
}}
>
{messages.map((message, index) => {
if (index < messages.length - 5) return null

View File

@ -67,7 +67,8 @@ const TranslateButton: FC<Props> = ({ text, onTranslated, disabled, style, isLoa
placement="top"
title={t('chat.input.translate', { target_language: getLanguageByLangcode(targetLanguage).label() })}
mouseLeaveDelay={0}
arrow>
arrow
>
<ToolbarButton onClick={handleTranslate} disabled={disabled || isTranslating} style={style} type="text">
{isTranslating ? <LoadingOutlined spin /> : <Languages size={18} />}
</ToolbarButton>

View File

@ -199,13 +199,15 @@ function DynamicVirtualList<T>(props: DynamicVirtualListProps<T>) {
overflow: 'auto',
...(horizontal ? { width: size ?? '100%' } : { height: size ?? '100%' }),
...scrollerStyle
}}>
}}
>
<div
style={{
position: 'relative',
width: horizontal ? `${totalSize}px` : '100%',
height: !horizontal ? `${totalSize}px` : '100%'
}}>
}}
>
{virtualItems.map((virtualItem) => {
const isItemSticky = stickyIndexes.includes(virtualItem.index)
const isItemActiveSticky = isItemSticky && activeStickyIndexRef.current === virtualItem.index

View File

@ -245,7 +245,8 @@ export function WebdavBackupManager({
type="link"
danger
onClick={() => handleDeleteSingle(record.fileName)}
disabled={deleting || restoring}>
disabled={deleting || restoring}
>
{t('settings.data.webdav.backup.manager.delete.text')}
</Button>
</>
@ -278,13 +279,15 @@ export function WebdavBackupManager({
icon={<DeleteOutlined />}
onClick={handleDeleteSelected}
disabled={selectedRowKeys.length === 0 || deleting}
loading={deleting}>
loading={deleting}
>
{t('settings.data.webdav.backup.manager.delete.selected')} ({selectedRowKeys.length})
</Button>,
<Button key="close" onClick={onClose}>
{t('common.close')}
</Button>
]}>
]}
>
<Table
rowKey="fileName"
columns={columns}

View File

@ -76,7 +76,8 @@ export function WebdavBackupModal({
onCancel={handleCancel}
okButtonProps={{ loading: backuping }}
transitionName="animation-move-down"
centered>
centered
>
<Input
value={customFileName}
onChange={(e) => setCustomFileName(e.target.value)}

View File

@ -25,7 +25,8 @@ export const WindowRestoreIcon = ({ size = '1.1em', ...props }: WindowRestoreIco
version="1.1"
id="svg4"
xmlns="http://www.w3.org/2000/svg"
{...props}>
{...props}
>
<defs id="defs1" />
<rect
width="14.165795"
@ -93,7 +94,8 @@ const WindowControls: React.FC = () => {
<Tooltip
title={isMaximized ? t('navbar.window.restore') : t('navbar.window.maximize')}
placement="bottom"
mouseEnterDelay={DEFAULT_DELAY}>
mouseEnterDelay={DEFAULT_DELAY}
>
<ControlButton onClick={handleMaximize} aria-label={isMaximized ? 'Restore' : 'Maximize'}>
{isMaximized ? <WindowRestoreIcon size={14} /> : <Square size={14} />}
</ControlButton>

View File

@ -90,7 +90,8 @@ export const SidebarOpenedMinappTabs: FC = () => {
<Icon
theme={theme}
onClick={() => handleOnClick(app)}
className={`${isActive ? 'opened-active' : ''}`}>
className={`${isActive ? 'opened-active' : ''}`}
>
<MinAppIcon size={20} app={app} style={{ borderRadius: 6 }} sidebar />
</Icon>
</Dropdown>
@ -131,7 +132,8 @@ export const SidebarPinnedApps: FC = () => {
<Icon
theme={theme}
onClick={() => openMinappKeepAlive(app)}
className={`${isActive ? 'active' : ''} ${openedKeepAliveMinapps.some((item) => item.id === app.id) ? 'opened-minapp' : ''}`}>
className={`${isActive ? 'active' : ''} ${openedKeepAliveMinapps.some((item) => item.id === app.id) ? 'opened-minapp' : ''}`}
>
<MinAppIcon size={20} app={app} style={{ borderRadius: 6 }} sidebar />
</Icon>
</Dropdown>

View File

@ -66,7 +66,8 @@ const Sidebar: FC = () => {
<Container
$isFullscreen={isFullscreen}
id="app-sidebar"
style={{ backgroundColor, zIndex: minappShow ? 10000 : 'initial' }}>
style={{ backgroundColor, zIndex: minappShow ? 10000 : 'initial' }}
>
{isEmoji(avatar) ? (
<EmojiAvatar onClick={onEditUser} className="sidebar-avatar" size={31} fontSize={18}>
{avatar}
@ -92,7 +93,8 @@ const Sidebar: FC = () => {
<Tooltip
title={t('settings.theme.title') + ': ' + getThemeModeLabel(settedTheme)}
mouseEnterDelay={0.8}
placement="right">
placement="right"
>
<Icon theme={theme} onClick={toggleTheme}>
{settedTheme === ThemeMode.dark ? (
<Moon size={20} className="icon" />
@ -108,7 +110,8 @@ const Sidebar: FC = () => {
onClick={async () => {
hideMinappPopup()
await to('/settings/provider')
}}>
}}
>
<Icon theme={theme} className={pathname.startsWith('/settings') && !minappShow ? 'active' : ''}>
<Settings size={20} className="icon" />
</Icon>
@ -165,7 +168,8 @@ const MainMenus: FC = () => {
hideMinappPopup()
await modelGenerating()
navigate(path)
}}>
}}
>
<Icon theme={theme} className={isActive}>
{iconMap[icon]}
</Icon>

View File

@ -54,11 +54,13 @@ export function ItemRenderer<T>({
ref={ref}
data-index={index}
className={classNames({ dragOverlay: dragOverlay })}
style={{ ...wrapperStyle }}>
style={{ ...wrapperStyle }}
>
<DraggableItem
className={classNames({ dragging: dragging, dragOverlay: dragOverlay, ghost: ghost })}
{...listeners}
{...props}>
{...props}
>
{renderItem(item, { dragging: !!dragging })}
</DraggableItem>
</ItemWrapper>

View File

@ -178,14 +178,16 @@ function Sortable<T>({
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
onDragCancel={handleDragCancel}
modifiers={modifiers}>
modifiers={modifiers}
>
<SortableContext items={itemIds} strategy={strategy}>
<ListWrapper
className={className}
data-layout={layout}
data-direction={horizontal ? 'horizontal' : 'vertical'}
$gap={gap}
style={listStyle}>
style={listStyle}
>
{items.map((item, index) => (
<SortableItem
key={itemIds[index]}

View File

@ -112,7 +112,8 @@ const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
colorBgMask: _theme === 'dark' ? 'rgba(0,0,0,0.7)' : 'rgba(255,255,255,0.8)',
motionDurationMid: '100ms'
}
}}>
}}
>
{children}
</ConfigProvider>
)

View File

@ -16,7 +16,8 @@ const StyleSheetManager = ({ children }: StyleSheetManagerProps): React.ReactEle
}
// 对于自定义组件,允许所有非特殊属性通过
return prop !== '$' && !prop.startsWith('$')
}}>
}}
>
{children}
</StyledComponentsStyleSheetManager>
)

View File

@ -220,7 +220,8 @@ const AgentsPage: FC = () => {
</Flex>
}
style={{ margin: '0 8px', paddingLeft: 16, paddingRight: 16 }}
onClick={handleGroupClick(group)}></ListItem>
onClick={handleGroupClick(group)}
></ListItem>
))}
</AgentsGroupList>
@ -268,7 +269,8 @@ const AgentsPage: FC = () => {
<Button
type="text"
onClick={handleSearchIconClick}
icon={<Search size={18} color="var(--color-icon)" />}>
icon={<Search size={18} color="var(--color-icon)" />}
>
{t('common.search')}
</Button>
)

View File

@ -170,7 +170,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
okText={t('agents.add.title')}
width={600}
transitionName="animation-move-down"
centered>
centered
>
<Form
ref={formRef}
form={form}
@ -188,7 +189,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
const currentValues = form.getFieldsValue()
setHasUnsavedChanges(currentValues.name?.trim() || currentValues.prompt?.trim() || emoji)
}}>
}}
>
<Form.Item name="name" label="Emoji">
<Popover
content={
@ -200,7 +202,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
/>
}
arrow
trigger="click">
trigger="click"
>
<Button icon={emoji && <span style={{ fontSize: 20 }}>{emoji}</span>}>{t('common.select')}</Button>
</Popover>
</Form.Item>
@ -212,7 +215,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
name="prompt"
label={t('agents.add.prompt.label')}
rules={[{ required: true }]}
style={{ position: 'relative' }}>
style={{ position: 'relative' }}
>
<TextArea placeholder={t('agents.add.prompt.placeholder')} spellCheck={false} rows={10} />
</Form.Item>
<TokenCount>Tokens: {tokenCount}</TokenCount>
@ -234,7 +238,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
<Form.Item
name="knowledge_base_ids"
label={t('agents.add.knowledge_base.label')}
rules={[{ required: false }]}>
rules={[{ required: false }]}
>
<Select
mode="multiple"
allowClear

View File

@ -158,7 +158,8 @@ const AgentCard: FC<Props> = ({ agent, onClick, activegroup, getLocalizedGroupNa
items: menuItems
}}
trigger={['click']}
placement="bottomRight">
placement="bottomRight"
>
<MenuButton
onClick={(e) => {
e.stopPropagation()
@ -189,7 +190,8 @@ const AgentCard: FC<Props> = ({ agent, onClick, activegroup, getLocalizedGroupNa
menu={{
items: menuItems
}}
trigger={['contextMenu']}>
trigger={['contextMenu']}
>
{content}
</Dropdown>
)

View File

@ -106,7 +106,8 @@ const PopupContainer: React.FC<Props> = ({ resolve }) => {
</Flex>
}
transitionName="animation-move-down"
centered>
centered
>
<Form form={form} onFinish={onFinish} layout="vertical">
<Form.Item>
<Radio.Group value={importType} onChange={(e) => setImportType(e.target.value)}>

View File

@ -40,7 +40,8 @@ const PopupContainer: React.FC = () => {
afterClose={onClose}
footer={null}
transitionName="animation-move-down"
centered>
centered
>
<Container>
{agents.length > 0 && (
<DraggableList list={agents} onUpdate={updateAgents}>

View File

@ -235,7 +235,8 @@ const CodeToolsPage: FC = () => {
icon={<Download size={14} />}
onClick={handleInstallBun}
loading={isInstallingBun}
disabled={isInstallingBun}>
disabled={isInstallingBun}
>
{isInstallingBun ? t('code.installing_bun') : t('code.install_bun')}
</Button>
</div>
@ -270,7 +271,8 @@ const CodeToolsPage: FC = () => {
<Link
key={provider.id}
style={{ color: 'var(--color-text)', display: 'flex', alignItems: 'center', gap: 4 }}
to={`/settings/provider?id=${provider.id}`}>
to={`/settings/provider?id=${provider.id}`}
>
<ProviderLogo shape="square" src={getProviderLogo(provider.id)} size={20} />
{getProviderLabel(provider.id)}
<ArrowUpRight size={14} />
@ -281,7 +283,8 @@ const CodeToolsPage: FC = () => {
</div>
}
trigger="hover"
placement="right">
placement="right"
>
<HelpCircle size={14} style={{ color: 'var(--color-text-3)', cursor: 'pointer' }} />
</Popover>
)}
@ -358,7 +361,8 @@ const CodeToolsPage: FC = () => {
onClick={handleLaunch}
loading={isLaunching}
disabled={!canLaunch || !isBunInstalled}
block>
block
>
{isLaunching ? t('code.launching') : t('code.launch.label')}
</Button>
</MainContent>

View File

@ -68,7 +68,8 @@ const FileList: React.FC<FileItemProps> = ({ id, list, files }) => {
},
icon: <ExclamationCircleOutlined style={{ color: 'red' }} />
})
}}>
}}
>
<DeleteIcon size={14} className="lucide-custom" />
</DeleteButton>
</ImageWrapper>
@ -91,7 +92,8 @@ const FileList: React.FC<FileItemProps> = ({ id, list, files }) => {
itemContainerStyle={{
height: '75px',
paddingTop: '12px'
}}>
}}
>
{(item) => (
<FileItem
key={item.key}

View File

@ -119,7 +119,8 @@ const FilesPage: FC = () => {
cancelText={t('common.cancel')}
onConfirm={() => handleDelete(file.id, t)}
placement="left"
icon={<ExclamationCircleOutlined style={{ color: 'red' }} />}>
icon={<ExclamationCircleOutlined style={{ color: 'red' }} />}
>
<Button type="text" danger icon={<DeleteIcon size={14} className="lucide-custom" />} />
</Popconfirm>
{fileType !== 'image' && (
@ -172,7 +173,8 @@ const FilesPage: FC = () => {
setSortField(field as 'created_at' | 'size' | 'name')
setSortOrder('desc')
}
}}>
}}
>
{getFileFieldLabel(field)}
{sortField === field &&
(sortOrder === 'desc' ? <ArrowUpWideNarrow size={12} /> : <ArrowDownNarrowWide size={12} />)}
@ -196,18 +198,21 @@ const FilesPage: FC = () => {
okText={t('common.confirm')}
cancelText={t('common.cancel')}
onConfirm={handleBatchDelete}
icon={<ExclamationCircleOutlined style={{ color: 'red' }} />}>
icon={<ExclamationCircleOutlined style={{ color: 'red' }} />}
>
{t('files.batch_delete')} ({selectedFileIds.length})
</Popconfirm>
)
}
]
}}
trigger={['click']}>
trigger={['click']}
>
<Checkbox
indeterminate={selectedFileIds.length > 0 && selectedFileIds.length < sortedFiles.length}
checked={selectedFileIds.length === sortedFiles.length && sortedFiles.length > 0}
onChange={(e) => handleSelectAll(e.target.checked)}>
onChange={(e) => handleSelectAll(e.target.checked)}
>
{t('files.batch_operation')}
</Checkbox>
</Dropdown.Button>

View File

@ -154,7 +154,8 @@ const SearchResults: FC<Props> = ({ keywords, onMessageClick, onTopicClick, ...p
<Title
level={5}
style={{ color: 'var(--color-primary)', cursor: 'pointer' }}
onClick={() => onTopicClick(topic)}>
onClick={() => onTopicClick(topic)}
>
{topic.name}
</Title>
<div style={{ cursor: 'pointer' }} onClick={() => onMessageClick(message)}>

Some files were not shown because too many files have changed in this diff Show More