导出面板改用平台主题变量
- `Shell` 的米色页面渐变改用 `bg-(image:--platform-body-fill)` - 文案 / 强调 / 描边换成 `--platform-text-strong` / `-base` / `-soft` / `-muted`、`--platform-accent`、`--platform-surface-border` 与 `--platform-surface-hover-border` - 卡片与输入底色换成 `--platform-panel-fill` / `--platform-input-fill` / `--platform-neutral-bg`,冲突卡底换成 `--platform-warm-bg` - 硬编码阴影换成 `--platform-panel-shadow` 与 `--platform-profile-action-shadow` - 小红书品牌红 `#ff2442` 不在 `--platform-*` 调色板里,按原值保留并加注释
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@ import { type Target, TARGET_META } from '../model';
|
||||
export function EmptyTab({ target }: { target: Target }) {
|
||||
return (
|
||||
<div
|
||||
className="grid h-full min-h-0 place-items-center p-6 text-sm text-[#988476]"
|
||||
className="grid h-full min-h-0 place-items-center p-6 text-sm text-(--platform-text-soft)"
|
||||
aria-label={`${TARGET_META[target].label}导出页`}
|
||||
>
|
||||
{`${TARGET_META[target].label}导出页尚未接入`}
|
||||
|
||||
@@ -22,8 +22,8 @@ export function Shell({
|
||||
onClose: () => void;
|
||||
}) {
|
||||
return (
|
||||
<main className="relative flex h-full min-h-0 min-w-0 flex-col overflow-hidden bg-gradient-to-b from-[#fffdf9] via-[#fdf9f5] to-[#f8efe7] text-[#3d1f10]">
|
||||
<header className="flex shrink-0 items-stretch gap-3 border-b border-[#e2cbb8] px-4">
|
||||
<main className="relative flex h-full min-h-0 min-w-0 flex-col overflow-hidden bg-(image:--platform-body-fill) text-(--platform-text-strong)">
|
||||
<header className="flex shrink-0 items-stretch gap-3 border-b border-(--platform-surface-border) px-4">
|
||||
<div className="flex items-center py-2">
|
||||
<strong className="text-base font-semibold">导出到</strong>
|
||||
</div>
|
||||
@@ -35,7 +35,7 @@ export function Shell({
|
||||
type="button"
|
||||
aria-label="关闭导出面板"
|
||||
title="关闭"
|
||||
className="grid size-8 shrink-0 place-items-center rounded-lg border border-[#e2cbb8] bg-[#fffaf5] text-[#6f5848] transition hover:border-[#c7653d] hover:text-[#c7653d]"
|
||||
className="grid size-8 shrink-0 place-items-center rounded-lg border border-(--platform-surface-border) bg-(image:--platform-panel-fill) text-(--platform-text-base) transition hover:border-(--platform-surface-hover-border) hover:text-(--platform-accent)"
|
||||
onClick={onClose}
|
||||
>
|
||||
<X size={16} aria-hidden="true" />
|
||||
|
||||
+4
-2
@@ -18,7 +18,7 @@ export function TargetCard({
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="group flex aspect-square w-full flex-col items-center justify-center gap-4 rounded-3xl border border-[#e2cbb8] bg-[#fffaf5] p-6 text-center shadow-[0_18px_40px_rgba(112,57,30,0.08)] transition hover:-translate-y-0.5 hover:border-[#c7653d] hover:shadow-[0_22px_48px_rgba(112,57,30,0.14)]"
|
||||
className="group flex aspect-square w-full flex-col items-center justify-center gap-4 rounded-3xl border border-(--platform-surface-border) bg-(image:--platform-panel-fill) p-6 text-center shadow-(--platform-panel-shadow) transition hover:-translate-y-0.5 hover:border-(--platform-surface-hover-border) hover:shadow-(--platform-profile-action-shadow)"
|
||||
onClick={() => onOpen(target)}
|
||||
>
|
||||
{/* 图标盒恒为正方形:只许按比例缩放,不许拉成矩形。 */}
|
||||
@@ -29,7 +29,9 @@ export function TargetCard({
|
||||
className="h-full w-full object-contain transition group-hover:scale-105"
|
||||
/>
|
||||
</span>
|
||||
<span className="text-lg font-semibold text-[#3d1f10]">{meta.label}</span>
|
||||
<span className="text-lg font-semibold text-(--platform-text-strong)">
|
||||
{meta.label}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
+2
-2
@@ -33,8 +33,8 @@ export function TargetTabs({
|
||||
aria-current={active ? 'true' : undefined}
|
||||
className={`relative flex min-w-0 items-center justify-center gap-1.5 px-2 pb-2 pt-1 text-xs font-medium transition-colors after:absolute after:inset-x-3 after:bottom-0 after:h-[2px] after:rounded-full after:transition-colors after:content-[''] ${
|
||||
active
|
||||
? 'text-[#c7653d] after:bg-[#c7653d]'
|
||||
: 'text-[#988476] after:bg-transparent hover:text-[#6f5848]'
|
||||
? 'text-(--platform-accent) after:bg-(--platform-accent)'
|
||||
: 'text-(--platform-text-soft) after:bg-transparent hover:text-(--platform-text-base)'
|
||||
}`}
|
||||
onClick={() => onSelect(target)}
|
||||
>
|
||||
|
||||
+6
-3
@@ -12,10 +12,13 @@ import type { ReactNode } from 'react';
|
||||
* 语气 → 类名。用查表而不是嵌套三元:加第四种语气时只加一行,也不用再读一层分支。
|
||||
*/
|
||||
const TONE_CLASS: Record<'primary' | 'ghost' | 'brand', string> = {
|
||||
brand: 'border-[#ff2442] bg-[#ff2442] text-white hover:bg-[#e01e3a]',
|
||||
primary: 'border-[#c7653d] bg-[#c7653d] text-white hover:bg-[#b4562f]',
|
||||
// 小红书红是平台自己的品牌色,不在 `--platform-*` 调色板里,按原值保留。
|
||||
brand:
|
||||
'border-[#ff2442] bg-[#ff2442] text-(--platform-button-primary-text) hover:bg-[#e01e3a]',
|
||||
primary:
|
||||
'border-(--platform-accent) bg-(--platform-accent) text-(--platform-button-primary-text) hover:bg-(--platform-warm-text)',
|
||||
ghost:
|
||||
'border-[#e2cbb8] bg-white/80 text-[#6f5848] hover:border-[#c7653d] hover:text-[#c7653d]',
|
||||
'border-(--platform-surface-border) bg-(--platform-input-fill) text-(--platform-text-base) hover:border-(--platform-surface-hover-border) hover:text-(--platform-accent)',
|
||||
};
|
||||
|
||||
/** 尺寸 → 类名,理由同 [`TONE_CLASS`]。 */
|
||||
|
||||
+3
-3
@@ -12,14 +12,14 @@ export function PublishPane({ tab }: { tab: TaonierTabState }) {
|
||||
const manifest = tab.manifest;
|
||||
if (!manifest) {
|
||||
return (
|
||||
<div className="flex h-full min-h-0 items-center justify-center border-[#e2cbb8] bg-[#fffdf9]/40 p-6 md:border-r">
|
||||
<p className="text-sm text-[#988476]">正在读取项目清单…</p>
|
||||
<div className="flex h-full min-h-0 items-center justify-center border-(--platform-surface-border) bg-(--platform-neutral-bg) p-6 md:border-r">
|
||||
<p className="text-sm text-(--platform-text-soft)">正在读取项目清单…</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className="flex h-full min-h-0 min-w-0 flex-col border-[#e2cbb8] bg-[#fffdf9]/40 md:border-r"
|
||||
className="flex h-full min-h-0 min-w-0 flex-col border-(--platform-surface-border) bg-(--platform-neutral-bg) md:border-r"
|
||||
aria-label="游戏发布表单区"
|
||||
>
|
||||
<GameDistributionPublishFormView
|
||||
|
||||
+3
-3
@@ -28,12 +28,12 @@ export function AdaptPromptDialog({
|
||||
onClose={onDoItMyself}
|
||||
closeOnBackdrop={false}
|
||||
closeOnEscape={false}
|
||||
panelClassName="w-full max-w-md rounded-2xl border border-[#e2cbb8] p-4"
|
||||
panelClassName="w-full max-w-md rounded-2xl border border-(--platform-surface-border) p-4"
|
||||
>
|
||||
<h2 className="text-sm font-semibold text-[#3d1f10]">
|
||||
<h2 className="text-sm font-semibold text-(--platform-text-strong)">
|
||||
这个项目还没有配置好导出
|
||||
</h2>
|
||||
<p className="mt-2 text-xs leading-relaxed text-[#6f5848]">
|
||||
<p className="mt-2 text-xs leading-relaxed text-(--platform-text-base)">
|
||||
要让陶泥儿先在项目里帮你调通一次导出流程(用哪套配置、入口在哪、怎么打包都由它试出来)。
|
||||
调通之后,每次点「打包」就能直接生成代码包。
|
||||
</p>
|
||||
|
||||
+12
-6
@@ -143,27 +143,33 @@ export function ArtifactsPane({
|
||||
/>
|
||||
);
|
||||
} else if (!minitool.readSettled) {
|
||||
formSlot = <p className="text-xs text-[#988476]">正在读取导出信息…</p>;
|
||||
formSlot = (
|
||||
<p className="text-xs text-(--platform-text-soft)">正在读取导出信息…</p>
|
||||
);
|
||||
} else if (!failure) {
|
||||
// 读失败时上面不重复一句话:失败弹窗拿着宿主的现场和下一步。
|
||||
formSlot = (
|
||||
<p className="text-xs text-[#988476]">没能读到导出信息,正在自动重试…</p>
|
||||
<p className="text-xs text-(--platform-text-soft)">
|
||||
没能读到导出信息,正在自动重试…
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex h-full min-h-0 min-w-0 flex-col border-[#e2cbb8] bg-[#fffdf9]/40 md:border-r"
|
||||
className="flex h-full min-h-0 min-w-0 flex-col border-(--platform-surface-border) bg-(--platform-neutral-bg) md:border-r"
|
||||
aria-label="导出内容区"
|
||||
>
|
||||
<div className="flex min-h-0 flex-1 flex-col gap-3 overflow-auto p-3">
|
||||
{formSlot}
|
||||
|
||||
<section
|
||||
className="rounded-2xl border border-[#e2cbb8] bg-[#fffaf5] p-4"
|
||||
className="rounded-2xl border border-(--platform-surface-border) bg-(image:--platform-panel-fill) p-4"
|
||||
aria-label="小工具代码包"
|
||||
>
|
||||
<h3 className="text-sm font-bold text-[#3d1f10]">小工具代码包</h3>
|
||||
<h3 className="text-sm font-bold text-(--platform-text-strong)">
|
||||
小工具代码包
|
||||
</h3>
|
||||
<div className="mt-4 flex flex-col gap-2">
|
||||
{/*
|
||||
「打包」不因为有脚本判据没到位就变灰:有没有脚本是**点下去那一刻**才成立的事实
|
||||
@@ -212,7 +218,7 @@ export function ArtifactsPane({
|
||||
*/}
|
||||
<button
|
||||
type="button"
|
||||
className="cursor-pointer self-center border-0 bg-transparent p-0 text-xs font-semibold text-[#c7653d] underline underline-offset-2 transition-colors hover:text-[#b4562f] active:text-[#3d1f10] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#c7653d]"
|
||||
className="cursor-pointer self-center border-0 bg-transparent p-0 text-xs font-semibold text-(--platform-accent) underline underline-offset-2 transition-colors hover:text-(--platform-warm-text) active:text-(--platform-text-strong) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--platform-accent)"
|
||||
onClick={() => {
|
||||
void openUrl(XHS_PUBLISH_URL).catch((error) => {
|
||||
console.error('[agc] 打开小红书发布页失败', error);
|
||||
|
||||
+13
-9
@@ -41,18 +41,18 @@ export function ConflictCard({
|
||||
<section
|
||||
role="alertdialog"
|
||||
aria-label="导出信息冲突"
|
||||
className="rounded-2xl border border-[#c7653d] bg-[#fff5ef] p-4"
|
||||
className="rounded-2xl border border-(--platform-accent) bg-(--platform-warm-bg) p-4"
|
||||
>
|
||||
<h3 className="text-sm font-semibold text-[#3d1f10]">
|
||||
<h3 className="text-sm font-semibold text-(--platform-text-strong)">
|
||||
这份导出信息被改过
|
||||
</h3>
|
||||
<p className="mt-1 text-xs text-[#6f5848]">
|
||||
<p className="mt-1 text-xs text-(--platform-text-base)">
|
||||
{`下面 ${differing.length} 项两边不一样,各选一个再保存;没列出来的两边一致。`}
|
||||
</p>
|
||||
<div className="mt-3 flex flex-col gap-3">
|
||||
{differing.map((meta) => (
|
||||
<div key={meta.field} className="flex flex-col gap-1">
|
||||
<span className="text-xs font-medium text-[#6f5848]">
|
||||
<span className="text-xs font-medium text-(--platform-text-base)">
|
||||
{meta.label}
|
||||
</span>
|
||||
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
@@ -113,22 +113,26 @@ function Choice({
|
||||
}) {
|
||||
return (
|
||||
<label
|
||||
className={`flex cursor-pointer flex-col gap-0.5 rounded-lg border bg-white px-2 py-1.5 text-xs transition ${
|
||||
selected ? 'border-[#c7653d]' : 'border-[#e2cbb8]'
|
||||
className={`flex cursor-pointer flex-col gap-0.5 rounded-lg border bg-(--platform-input-fill) px-2 py-1.5 text-xs transition ${
|
||||
selected
|
||||
? 'border-(--platform-accent)'
|
||||
: 'border-(--platform-surface-border)'
|
||||
}`}
|
||||
>
|
||||
<span className="flex items-center gap-1 text-[#988476]">
|
||||
<span className="flex items-center gap-1 text-(--platform-text-soft)">
|
||||
<input
|
||||
type="radio"
|
||||
name={name}
|
||||
aria-label={`${label}:${caption}`}
|
||||
checked={selected}
|
||||
className="accent-[#c7653d]"
|
||||
className="accent-(--platform-accent)"
|
||||
onChange={onSelect}
|
||||
/>
|
||||
{caption}
|
||||
</span>
|
||||
<span className="break-all text-[#3d1f10]">{value || '(空)'}</span>
|
||||
<span className="break-all text-(--platform-text-strong)">
|
||||
{value || '(空)'}
|
||||
</span>
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ export function CopyButton({ value, label }: { value: string; label: string }) {
|
||||
className={`inline-flex shrink-0 items-center gap-1 rounded-[10px] border px-2.5 py-1.5 text-xs font-semibold transition disabled:cursor-not-allowed disabled:opacity-45 ${
|
||||
state === 'failed'
|
||||
? 'border-red-300 bg-red-50 text-red-600'
|
||||
: 'border-[#e2cbb8] bg-white/80 text-[#6f5848] hover:border-[#c7653d] hover:text-[#c7653d]'
|
||||
: 'border-(--platform-surface-border) bg-(--platform-input-fill) text-(--platform-text-base) hover:border-(--platform-surface-hover-border) hover:text-(--platform-accent)'
|
||||
}`}
|
||||
onClick={() => {
|
||||
setState('idle');
|
||||
|
||||
+5
-5
@@ -40,23 +40,23 @@ export function DownloadFailureDialog({
|
||||
onClose={onDismiss}
|
||||
closeOnBackdrop={false}
|
||||
closeOnEscape={false}
|
||||
panelClassName="w-full max-w-md rounded-2xl border border-[#e2cbb8] p-4"
|
||||
panelClassName="w-full max-w-md rounded-2xl border border-(--platform-surface-border) p-4"
|
||||
>
|
||||
<p className="text-sm leading-relaxed text-[#3d1f10]">
|
||||
<p className="text-sm leading-relaxed text-(--platform-text-strong)">
|
||||
{failure
|
||||
? `没能把${failure.kind === 'icon' ? '图标' : '代码包'}保存到你选的位置。`
|
||||
: null}
|
||||
</p>
|
||||
{failure ? (
|
||||
<p className="mt-2 text-xs leading-relaxed text-[#6f5848]">
|
||||
<p className="mt-2 text-xs leading-relaxed text-(--platform-text-base)">
|
||||
{failure.reason}
|
||||
</p>
|
||||
) : null}
|
||||
<p className="mt-2 text-xs leading-relaxed text-[#6f5848]">
|
||||
<p className="mt-2 text-xs leading-relaxed text-(--platform-text-base)">
|
||||
也可以让系统在文件管理器里打开它原来的位置,自己复制过去。
|
||||
</p>
|
||||
{revealFailure ? (
|
||||
<p role="status" className="mt-2 text-xs text-[#b4562f]">
|
||||
<p role="status" className="mt-2 text-xs text-(--platform-warm-text)">
|
||||
{revealFailure}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
+2
-2
@@ -57,9 +57,9 @@ export function FailureDialog({
|
||||
onClose={onDismiss}
|
||||
closeOnBackdrop={false}
|
||||
closeOnEscape={false}
|
||||
panelClassName="w-full max-w-md rounded-2xl border border-[#e2cbb8] p-4"
|
||||
panelClassName="w-full max-w-md rounded-2xl border border-(--platform-surface-border) p-4"
|
||||
>
|
||||
<p className="text-sm leading-relaxed text-[#3d1f10]">
|
||||
<p className="text-sm leading-relaxed text-(--platform-text-strong)">
|
||||
{failure ? describeXhsMinitoolFailure(failure) : null}
|
||||
</p>
|
||||
<div className="mt-4 flex flex-wrap justify-end gap-2">
|
||||
|
||||
+23
-10
@@ -41,7 +41,7 @@ export function FormCard({
|
||||
}) {
|
||||
return (
|
||||
<section
|
||||
className="rounded-2xl border border-[#e2cbb8] bg-[#fffaf5] p-4"
|
||||
className="rounded-2xl border border-(--platform-surface-border) bg-(image:--platform-panel-fill) p-4"
|
||||
aria-label="上传到小红书时要填的信息"
|
||||
>
|
||||
{/*
|
||||
@@ -50,7 +50,7 @@ export function FormCard({
|
||||
的自动重读再把值带回来,用户自己打的字先由自动保存落盘。
|
||||
*/}
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<h3 className="text-sm font-bold text-[#3d1f10]">
|
||||
<h3 className="text-sm font-bold text-(--platform-text-strong)">
|
||||
上传到小红书时要填的信息
|
||||
</h3>
|
||||
<PaneButton
|
||||
@@ -101,8 +101,8 @@ export function FormCard({
|
||||
|
||||
/** 表单控件的公共皮:与发布面板的输入同宽、同圆角、同暖色焦点环。 */
|
||||
function fieldInputClass(error: string | null) {
|
||||
return `box-border w-full rounded-[10px] border bg-white/80 px-3 py-2.5 text-sm leading-[1.45] text-[#3d1f10] outline-none transition placeholder:text-[#b9a494] focus-visible:border-[#c7653d] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[#c7653d]/25 ${
|
||||
error ? 'border-[#c7653d]' : 'border-[#e2cbb8]'
|
||||
return `box-border w-full rounded-[10px] border bg-(--platform-input-fill) px-3 py-2.5 text-sm leading-[1.45] text-(--platform-text-strong) outline-none transition placeholder:text-(--platform-text-muted) focus-visible:border-(--platform-accent) focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-(--platform-warm-border) ${
|
||||
error ? 'border-(--platform-accent)' : 'border-(--platform-surface-border)'
|
||||
}`;
|
||||
}
|
||||
|
||||
@@ -134,14 +134,19 @@ function FieldRow({
|
||||
return (
|
||||
<div className="grid gap-1.5">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<label htmlFor={id} className="text-xs font-bold text-[#3d1f10]">
|
||||
<label
|
||||
htmlFor={id}
|
||||
className="text-xs font-bold text-(--platform-text-strong)"
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
<span className="flex items-center gap-2">
|
||||
{maxChars !== undefined ? (
|
||||
<span
|
||||
className={`text-[11px] font-medium tabular-nums ${
|
||||
overLimit ? 'text-[#c7653d]' : 'text-[#988476]'
|
||||
overLimit
|
||||
? 'text-(--platform-accent)'
|
||||
: 'text-(--platform-text-soft)'
|
||||
}`}
|
||||
>
|
||||
{used}/{maxChars}
|
||||
@@ -171,7 +176,10 @@ function FieldRow({
|
||||
/>
|
||||
)}
|
||||
{error ? (
|
||||
<p role="alert" className="text-xs font-medium text-[#c7653d]">
|
||||
<p
|
||||
role="alert"
|
||||
className="text-xs font-medium text-(--platform-accent)"
|
||||
>
|
||||
{error}
|
||||
</p>
|
||||
) : null}
|
||||
@@ -206,13 +214,15 @@ function IconField({
|
||||
|
||||
return (
|
||||
<div className="grid gap-1.5">
|
||||
<span className="text-xs font-bold text-[#3d1f10]">图标</span>
|
||||
<span className="text-xs font-bold text-(--platform-text-strong)">
|
||||
图标
|
||||
</span>
|
||||
<div className="flex items-start gap-3">
|
||||
<IconPreview projectPath={projectPath} relativePath={value} />
|
||||
<div className="grid min-w-0 flex-1 gap-2">
|
||||
{/* 没选图标时不摆一行字:缩略图里的占位符已经说了这件事,右侧直接给唯一那颗按钮。 */}
|
||||
{fileName ? (
|
||||
<p className="truncate text-sm leading-[1.45] text-[#6f5848]">
|
||||
<p className="truncate text-sm leading-[1.45] text-(--platform-text-base)">
|
||||
已选:{fileName}
|
||||
</p>
|
||||
) : null}
|
||||
@@ -241,7 +251,10 @@ function IconField({
|
||||
</div>
|
||||
</div>
|
||||
{error ? (
|
||||
<p role="alert" className="text-xs font-medium text-[#c7653d]">
|
||||
<p
|
||||
role="alert"
|
||||
className="text-xs font-medium text-(--platform-accent)"
|
||||
>
|
||||
{error}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
+4
-2
@@ -69,7 +69,7 @@ export function IconPreview({
|
||||
|
||||
return (
|
||||
<span
|
||||
className="grid size-24 shrink-0 place-items-center overflow-hidden rounded-xl border border-[#e2cbb8] bg-white/80"
|
||||
className="grid size-24 shrink-0 place-items-center overflow-hidden rounded-xl border border-(--platform-surface-border) bg-(--platform-input-fill)"
|
||||
title={
|
||||
failed ? '读不到这张图,用「选择图标」导入一张就能预览' : undefined
|
||||
}
|
||||
@@ -85,7 +85,9 @@ export function IconPreview({
|
||||
) : (
|
||||
<ImageOff
|
||||
size={18}
|
||||
className={failed ? 'text-[#c7653d]' : 'text-[#b9a494]'}
|
||||
className={
|
||||
failed ? 'text-(--platform-accent)' : 'text-(--platform-text-muted)'
|
||||
}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user