优化项目启动器的配置样式

This commit is contained in:
xintaofei
2026-03-27 17:05:06 +08:00
parent 298ecb9ff6
commit c013876bbd
12 changed files with 149 additions and 84 deletions

View File

@@ -12,6 +12,7 @@ import {
SelectValue,
} from "@/components/ui/select"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Separator } from "@/components/ui/separator"
import {
STYLE_OPTIONS,
BASE_COLOR_OPTIONS,
@@ -33,56 +34,43 @@ interface ShadcnConfigPanelProps {
presetCode: string
}
type ConfigI18nKey =
| "config.style"
| "config.baseColor"
| "config.theme"
| "config.chartColor"
| "config.iconLibrary"
| "config.font"
| "config.fontHeading"
| "config.menuAccent"
| "config.menuColor"
| "config.radius"
| "config.template"
const CONFIG_FIELDS: {
key: keyof ShadcnPresetConfig
i18nKey: ConfigI18nKey
function ConfigField({
label,
value,
options,
onChange,
}: {
label: string
value: string
options: { value: string; label: string }[]
}[] = [
{ key: "style", i18nKey: "config.style", options: STYLE_OPTIONS },
{
key: "baseColor",
i18nKey: "config.baseColor",
options: BASE_COLOR_OPTIONS,
},
{ key: "theme", i18nKey: "config.theme", options: THEME_OPTIONS },
{ key: "chartColor", i18nKey: "config.chartColor", options: THEME_OPTIONS },
{
key: "iconLibrary",
i18nKey: "config.iconLibrary",
options: ICON_LIBRARY_OPTIONS,
},
{ key: "font", i18nKey: "config.font", options: FONT_OPTIONS },
{
key: "fontHeading",
i18nKey: "config.fontHeading",
options: FONT_HEADING_OPTIONS,
},
{
key: "menuAccent",
i18nKey: "config.menuAccent",
options: MENU_ACCENT_OPTIONS,
},
{
key: "menuColor",
i18nKey: "config.menuColor",
options: MENU_COLOR_OPTIONS,
},
{ key: "radius", i18nKey: "config.radius", options: RADIUS_OPTIONS },
{ key: "template", i18nKey: "config.template", options: TEMPLATE_OPTIONS },
]
onChange: (v: string) => void
}) {
return (
<div className="space-y-1">
<Label className="text-xs text-muted-foreground">{label}</Label>
<Select value={value} onValueChange={onChange}>
<SelectTrigger className="h-8">
<SelectValue />
</SelectTrigger>
<SelectContent>
{options.map((opt) => (
<SelectItem key={opt.value} value={opt.value}>
{opt.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)
}
function SectionHeader({ children }: { children: React.ReactNode }) {
return (
<h4 className="text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70">
{children}
</h4>
)
}
export function ShadcnConfigPanel({
config,
@@ -92,32 +80,69 @@ export function ShadcnConfigPanel({
const t = useTranslations("ProjectBoot")
const [createOpen, setCreateOpen] = useState(false)
const field = (
key: keyof ShadcnPresetConfig,
i18nKey: string,
options: { value: string; label: string }[]
) => (
<ConfigField
label={t(i18nKey as Parameters<typeof t>[0])}
value={config[key]}
options={options}
onChange={(v) => onConfigChange(key, v)}
/>
)
return (
<div className="flex h-full flex-col">
<ScrollArea className="min-h-0 flex-1 px-4 py-3">
<div className="space-y-3">
{CONFIG_FIELDS.map((field) => (
<div key={field.key} className="space-y-1">
<Label className="text-xs text-muted-foreground">
{t(field.i18nKey)}
</Label>
<Select
value={config[field.key]}
onValueChange={(v) => onConfigChange(field.key, v)}
>
<SelectTrigger className="h-8">
<SelectValue />
</SelectTrigger>
<SelectContent>
{field.options.map((opt) => (
<SelectItem key={opt.value} value={opt.value}>
{opt.label}
</SelectItem>
))}
</SelectContent>
</Select>
<div className="space-y-4">
{/* Style & Template */}
<div className="space-y-2">
<SectionHeader>{t("config.sectionStyle")}</SectionHeader>
<div className="grid grid-cols-2 gap-x-3 gap-y-2">
{field("style", "config.style", STYLE_OPTIONS)}
{field("template", "config.template", TEMPLATE_OPTIONS)}
</div>
</div>
<Separator />
{/* Colors */}
<div className="space-y-2">
<SectionHeader>{t("config.sectionColors")}</SectionHeader>
<div className="space-y-2">
{field("baseColor", "config.baseColor", BASE_COLOR_OPTIONS)}
<div className="grid grid-cols-2 gap-x-3 gap-y-2">
{field("theme", "config.theme", THEME_OPTIONS)}
{field("chartColor", "config.chartColor", THEME_OPTIONS)}
</div>
</div>
</div>
<Separator />
{/* Typography */}
<div className="space-y-2">
<SectionHeader>{t("config.sectionTypography")}</SectionHeader>
<div className="grid grid-cols-2 gap-x-3 gap-y-2">
{field("font", "config.font", FONT_OPTIONS)}
{field("fontHeading", "config.fontHeading", FONT_HEADING_OPTIONS)}
</div>
</div>
<Separator />
{/* Interface */}
<div className="space-y-2">
<SectionHeader>{t("config.sectionInterface")}</SectionHeader>
<div className="grid grid-cols-2 gap-x-3 gap-y-2">
{field("iconLibrary", "config.iconLibrary", ICON_LIBRARY_OPTIONS)}
{field("radius", "config.radius", RADIUS_OPTIONS)}
{field("menuAccent", "config.menuAccent", MENU_ACCENT_OPTIONS)}
{field("menuColor", "config.menuColor", MENU_COLOR_OPTIONS)}
</div>
</div>
))}
</div>
</ScrollArea>

View File

@@ -11,9 +11,9 @@ import {
type ShadcnPresetConfig,
} from "./constants"
const MIN_WIDTH = 280
const MAX_WIDTH = 480
const DEFAULT_WIDTH = 360
const MIN_WIDTH = 260
const MAX_WIDTH = 420
const DEFAULT_WIDTH = 320
export function ShadcnLauncher() {
const [config, setConfig] = useState<ShadcnPresetConfig>(

View File

@@ -1593,7 +1593,11 @@
"menuColor": "لون القائمة",
"radius": "نصف القطر",
"template": "القالب",
"createProject": "إنشاء مشروع"
"createProject": "إنشاء مشروع",
"sectionStyle": "النمط",
"sectionColors": "الألوان",
"sectionTypography": "الخطوط",
"sectionInterface": "الواجهة"
},
"preview": {
"loading": "جاري تحميل المعاينة..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "Menü-Farbe",
"radius": "Radius",
"template": "Vorlage",
"createProject": "Projekt erstellen"
"createProject": "Projekt erstellen",
"sectionStyle": "Stil",
"sectionColors": "Farben",
"sectionTypography": "Typografie",
"sectionInterface": "Oberfläche"
},
"preview": {
"loading": "Vorschau wird geladen..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "Menu Color",
"radius": "Radius",
"template": "Template",
"createProject": "Create Project"
"createProject": "Create Project",
"sectionStyle": "Style",
"sectionColors": "Colors",
"sectionTypography": "Typography",
"sectionInterface": "Interface"
},
"preview": {
"loading": "Loading preview..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "Color del menú",
"radius": "Radio",
"template": "Plantilla",
"createProject": "Crear proyecto"
"createProject": "Crear proyecto",
"sectionStyle": "Estilo",
"sectionColors": "Colores",
"sectionTypography": "Tipografía",
"sectionInterface": "Interfaz"
},
"preview": {
"loading": "Cargando vista previa..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "Couleur du menu",
"radius": "Rayon",
"template": "Modèle",
"createProject": "Créer un projet"
"createProject": "Créer un projet",
"sectionStyle": "Style",
"sectionColors": "Couleurs",
"sectionTypography": "Typographie",
"sectionInterface": "Interface"
},
"preview": {
"loading": "Chargement de l'aperçu..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "メニューカラー",
"radius": "角丸",
"template": "テンプレート",
"createProject": "プロジェクトを作成"
"createProject": "プロジェクトを作成",
"sectionStyle": "スタイル",
"sectionColors": "カラー",
"sectionTypography": "タイポグラフィ",
"sectionInterface": "インターフェース"
},
"preview": {
"loading": "プレビューを読み込み中..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "메뉴 색상",
"radius": "둥글기",
"template": "템플릿",
"createProject": "프로젝트 만들기"
"createProject": "프로젝트 만들기",
"sectionStyle": "스타일",
"sectionColors": "색상",
"sectionTypography": "타이포그래피",
"sectionInterface": "인터페이스"
},
"preview": {
"loading": "미리보기 로딩 중..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "Cor do menu",
"radius": "Raio",
"template": "Modelo",
"createProject": "Criar projeto"
"createProject": "Criar projeto",
"sectionStyle": "Estilo",
"sectionColors": "Cores",
"sectionTypography": "Tipografia",
"sectionInterface": "Interface"
},
"preview": {
"loading": "Carregando visualização..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "菜单颜色",
"radius": "圆角",
"template": "模板",
"createProject": "创建项目"
"createProject": "创建项目",
"sectionStyle": "风格",
"sectionColors": "配色",
"sectionTypography": "排版",
"sectionInterface": "界面"
},
"preview": {
"loading": "加载预览..."

View File

@@ -1593,7 +1593,11 @@
"menuColor": "選單顏色",
"radius": "圓角",
"template": "模板",
"createProject": "建立專案"
"createProject": "建立專案",
"sectionStyle": "風格",
"sectionColors": "配色",
"sectionTypography": "排版",
"sectionInterface": "介面"
},
"preview": {
"loading": "載入預覽..."