feat(ui-refactor 4/4): 表单字段切 bg-field+inset 阴影(替代描边风,宿主/插件组件库统一);流式光标常亮对齐 StreamText
This commit is contained in:
@@ -263,7 +263,7 @@ const CUSTOM_API_OPTIONS: Array<{ value: string; label: string }> = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const customInputCls =
|
const customInputCls =
|
||||||
'w-full rounded-control border border-line-strong bg-surface px-2.5 py-1.5 text-[12px] text-ink outline-none placeholder:text-ink-3 focus:border-ink-3'
|
'w-full rounded-control bg-field shadow-inset-field px-2.5 py-1.5 text-[12px] text-ink outline-none placeholder:text-ink-3'
|
||||||
|
|
||||||
/** 模型设置:搜索/过滤 + @tanstack/react-virtual 虚拟列表(供应商多、模型上千时滚动不卡顿)。
|
/** 模型设置:搜索/过滤 + @tanstack/react-virtual 虚拟列表(供应商多、模型上千时滚动不卡顿)。
|
||||||
* 卡片视觉按行拼装:provider 头行圆角上盖、模型行接左右边框、末行圆角下盖,行尾留组间距。
|
* 卡片视觉按行拼装:provider 头行圆角上盖、模型行接左右边框、末行圆角下盖,行尾留组间距。
|
||||||
@@ -423,7 +423,7 @@ function ModelSettings({
|
|||||||
value={keyValue}
|
value={keyValue}
|
||||||
onChange={(e) => onKeyChange(e.target.value)}
|
onChange={(e) => onKeyChange(e.target.value)}
|
||||||
placeholder="输入 API Key"
|
placeholder="输入 API Key"
|
||||||
className="flex-1 rounded-control border border-line-strong bg-surface px-2.5 py-1.5 font-mono text-[12px] text-ink outline-none focus:border-ink-3"
|
className="flex-1 rounded-control bg-field shadow-inset-field px-2.5 py-1.5 font-mono text-[12px] text-ink outline-none"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -491,7 +491,7 @@ function ModelSettings({
|
|||||||
value={search}
|
value={search}
|
||||||
onChange={(e) => onSearch(e.target.value)}
|
onChange={(e) => onSearch(e.target.value)}
|
||||||
placeholder="搜索模型或提供商"
|
placeholder="搜索模型或提供商"
|
||||||
className="w-full rounded-control border border-line-strong bg-surface py-1.5 pl-8 pr-3 text-[12.5px] text-ink outline-none placeholder:text-ink-3 focus:border-ink-3"
|
className="w-full rounded-control bg-field shadow-inset-field py-1.5 pl-8 pr-3 text-[12.5px] text-ink outline-none placeholder:text-ink-3"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{loading && <span className="text-[11px] text-ink-3">加载中…</span>}
|
{loading && <span className="text-[11px] text-ink-3">加载中…</span>}
|
||||||
@@ -909,7 +909,7 @@ function PluginSettingsForm({
|
|||||||
|
|
||||||
// 注意不要写 w-full:string/number 控件要定宽(w-56/w-28)跟 label 同行,w-full 会把 label 挤成竖排
|
// 注意不要写 w-full:string/number 控件要定宽(w-56/w-28)跟 label 同行,w-full 会把 label 挤成竖排
|
||||||
const inputCls =
|
const inputCls =
|
||||||
'rounded-control border border-line-strong bg-surface px-2.5 py-1.5 text-[12px] text-ink outline-none placeholder:text-ink-3 focus:border-ink-3'
|
'rounded-control bg-field shadow-inset-field px-2.5 py-1.5 text-[12px] text-ink outline-none placeholder:text-ink-3'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
@@ -1023,7 +1023,7 @@ function PluginSettingsForm({
|
|||||||
<select
|
<select
|
||||||
value={typeof value === 'string' ? value : ''}
|
value={typeof value === 'string' ? value : ''}
|
||||||
onChange={(e) => onChange(item.key, e.target.value)}
|
onChange={(e) => onChange(item.key, e.target.value)}
|
||||||
className="w-44 shrink-0 rounded-control border border-line-strong bg-surface px-2 py-1.5 text-[12px] text-ink outline-none focus:border-ink-3"
|
className="w-44 shrink-0 rounded-control bg-field shadow-inset-field px-2 py-1.5 text-[12px] text-ink outline-none"
|
||||||
>
|
>
|
||||||
{!value && <option value="">(未设置)</option>}
|
{!value && <option value="">(未设置)</option>}
|
||||||
{item.options.map((o) => (
|
{item.options.map((o) => (
|
||||||
|
|||||||
@@ -38,20 +38,9 @@ body,
|
|||||||
|
|
||||||
/* ::selection 在 beautifului.css 基座(accent-tint + ink) */
|
/* ::selection 在 beautifului.css 基座(accent-tint + ink) */
|
||||||
|
|
||||||
/* 流式输出光标 */
|
|
||||||
@keyframes caret-blink {
|
|
||||||
0%,
|
|
||||||
60% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
61%,
|
|
||||||
100% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 流式输出光标:以 ::after 附加到流式正文最后一个文本块的最后一行文字之后
|
/* 流式输出光标:以 ::after 附加到流式正文最后一个文本块的最后一行文字之后
|
||||||
(inline 随文,而不是孤零零落在新的一行),结束后随容器 data-streaming 消失 */
|
(inline 随文,而不是孤零零落在新的一行),结束后随容器 data-streaming 消失。
|
||||||
|
对齐 beautifului StreamText:流式期间光标常亮(不闪烁)。 */
|
||||||
.streaming-body[data-streaming='true'] > *:last-child > :is(p, h1, h2, h3, h4, h5, h6):last-child::after,
|
.streaming-body[data-streaming='true'] > *:last-child > :is(p, h1, h2, h3, h4, h5, h6):last-child::after,
|
||||||
.streaming-body[data-streaming='true'] > *:last-child > :is(ul, ol):last-child > li:last-child::after {
|
.streaming-body[data-streaming='true'] > *:last-child > :is(ul, ol):last-child > li:last-child::after {
|
||||||
content: '';
|
content: '';
|
||||||
@@ -62,7 +51,6 @@ body,
|
|||||||
vertical-align: -0.15em;
|
vertical-align: -0.15em;
|
||||||
background: var(--ink);
|
background: var(--ink);
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
animation: caret-blink 0.9s steps(1) infinite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 禁用 textarea 的默认 resize 与滚动条闪烁 */
|
/* 禁用 textarea 的默认 resize 与滚动条闪烁 */
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ export function Input({ className, ...rest }: InputHTMLAttributes<HTMLInputEleme
|
|||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
className={cn(
|
className={cn(
|
||||||
'w-full rounded-control border border-line-strong bg-surface px-2.5 py-1.5 text-[12px] text-ink outline-none placeholder:text-ink-3 disabled:opacity-50',
|
'w-full rounded-control bg-field shadow-inset-field px-2.5 py-1.5 text-[12px] text-ink outline-none placeholder:text-ink-3 disabled:opacity-50',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...rest}
|
{...rest}
|
||||||
@@ -171,7 +171,7 @@ export function Textarea({ className, ...rest }: TextareaHTMLAttributes<HTMLText
|
|||||||
return (
|
return (
|
||||||
<textarea
|
<textarea
|
||||||
className={cn(
|
className={cn(
|
||||||
'w-full resize-y rounded-control border border-line-strong bg-surface px-2.5 py-1.5 text-[12px] leading-4 text-ink outline-none placeholder:text-ink-3 disabled:opacity-50',
|
'w-full resize-y bg-field shadow-inset-field px-2.5 py-1.5 text-[12px] leading-4 text-ink outline-none placeholder:text-ink-3 disabled:opacity-50',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...rest}
|
{...rest}
|
||||||
@@ -188,7 +188,7 @@ export function Select({ options, className, ...rest }: SelectProps): ReactEleme
|
|||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
className={cn(
|
className={cn(
|
||||||
'w-full rounded-control border border-line-strong bg-surface px-2.5 py-1.5 text-[12px] text-ink outline-none disabled:opacity-50',
|
'w-full rounded-control bg-field shadow-inset-field px-2.5 py-1.5 text-[12px] text-ink outline-none disabled:opacity-50',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...rest}
|
{...rest}
|
||||||
|
|||||||
Reference in New Issue
Block a user