Files
xiaoxia-saas/apps/web/src/pages/generate/components/title/TitleStylePanel.tsx
T
xiaoxia 058bfac5c2
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 37s
CI/CD Pipeline / Build Staging API Image (push) Successful in 1m57s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 55s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 3m4s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 3m22s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m32s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m30s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m27s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 3m46s
AI Code Review / AI Code Review (pull_request) Failing after 4m37s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 35s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 36s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 8m22s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 8m53s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 12m0s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m13s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 13m50s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 1m2s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m14s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m17s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 6m58s
CI/CD Pipeline / Unit Tests (push) Successful in 17m29s
CI/CD Pipeline / Integration Tests (push) Successful in 6m27s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 17m13s
CI/CD Pipeline / CI Gate (pull_request) Successful in 5s
CI/CD Pipeline / Production Browser E2E (pull_request) Failing after 520h40m59s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 520h41m0s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 520h41m1s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 520h41m2s
CI/CD Pipeline / CI Gate (push) Failing after 520h41m50s
CI/CD Pipeline / Canary Release to Production (push) Failing after 520h42m2s
CI/CD Pipeline / Deploy Production (push) Failing after 520h42m3s
CI/CD Pipeline / Build Production Web Image (push) Failing after 520h42m4s
CI/CD Pipeline / Build Production API Image (push) Failing after 520h42m4s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 520h49m57s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 520h50m1s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 520h51m56s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 520h54m34s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 520h57m4s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Failing after 520h59m4s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 520h57m6s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 520h59m13s
CI/CD Pipeline / PR Build API Image (push) Failing after 520h59m15s
CI/CD Pipeline / Frontend Lint (push) Failing after 520h59m35s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 520h59m37s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 521h2m9s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 520h59m39s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 520h59m41s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 521h14m55s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 521h14m56s
CI/CD Pipeline / Production Browser E2E (push) Failing after 521h15m58s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 521h15m59s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 521h23m55s
CI/CD Pipeline / PR Build Web Image (push) Failing after 521h33m9s
fix: 字号滑块上限从48提升至128 (#1503)
2026-08-25 22:23:39 +08:00

153 lines
3.9 KiB
TypeScript

/**
* 标题样式设置区
* 位置/字体/字号/样式按钮/预设
*/
import React from "react"
import type { TitleSettings } from "../../types"
import TitlePresetsGrid from "./TitlePresetsGrid"
interface PositionOption {
value: string
label: string
}
interface TitlePresetItem {
key: string
label: string
previewStyle: React.CSSProperties
}
interface TitleStylePanelProps {
settings: TitleSettings
onUpdatePosition: (position: string) => void
onUpdateFont: (font: string) => void
onUpdateSize: (size: number) => void
onToggleBold: () => void
onToggleItalic: () => void
onToggleStroke: () => void
onToggleShadow: () => void
onApplyPreset: (presetKey: string) => void
activePreset: string | null
titlePresets: TitlePresetItem[]
POSITION_OPTIONS: PositionOption[]
FONT_OPTIONS: string[]
}
const TitleStylePanel: React.FC<TitleStylePanelProps> = ({
settings,
onUpdatePosition,
onUpdateFont,
onUpdateSize,
onToggleBold,
onToggleItalic,
onToggleStroke,
onToggleShadow,
onApplyPreset,
activePreset,
titlePresets,
POSITION_OPTIONS,
FONT_OPTIONS,
}) => {
return (
<div className="xx-title-style-section">
<h4 className="xx-section-subtitle">标题样式</h4>
{/* 位置 + 字体 一行 */}
<div className="xx-title-style-row">
<div className="xx-form-field xx-half-field">
<label>位置</label>
<select
className="xx-form-select"
value={settings.position}
onChange={(e) => onUpdatePosition(e.target.value)}
>
{POSITION_OPTIONS.map((opt) => (
<option key={opt.value} value={opt.value}>
{opt.label}
</option>
))}
</select>
</div>
<div className="xx-form-field xx-half-field">
<label>字体</label>
<select
className="xx-form-select"
value={settings.font}
onChange={(e) => onUpdateFont(e.target.value)}
>
{FONT_OPTIONS.map((f) => (
<option key={f} value={f}>
{f}
</option>
))}
</select>
</div>
</div>
{/* 字号滑块 */}
<div className="xx-form-field">
<div className="xx-field-label-row">
<label>字号</label>
<span className="xx-field-value">{settings.size}px</span>
</div>
<input
className="xx-slider"
type="range"
min={12}
max={128}
value={settings.size}
onChange={(e) => onUpdateSize(Number(e.target.value))}
/>
</div>
{/* 预设样式 */}
<div className="xx-form-field">
<label>预设样式</label>
<TitlePresetsGrid
presets={titlePresets}
activePreset={activePreset}
onApply={onApplyPreset}
fontFamily={settings.font}
/>
</div>
{/* 样式按钮:粗体/斜体/描边/阴影 */}
<div className="xx-form-field">
<label>样式</label>
<div className="xx-style-btns">
<button
className={`xx-style-btn ${settings.bold ? "active" : ""}`}
onClick={onToggleBold}
title="粗体"
>
<b>B</b>
</button>
<button
className={`xx-style-btn ${settings.italic ? "active" : ""}`}
onClick={onToggleItalic}
title="斜体"
>
<i>I</i>
</button>
<button
className={`xx-style-btn ${settings.stroke ? "active" : ""}`}
onClick={onToggleStroke}
title="描边"
>
S
</button>
<button
className={`xx-style-btn ${settings.shadow ? "active" : ""}`}
onClick={onToggleShadow}
title="阴影"
>
☁
</button>
</div>
</div>
</div>
)
}
export default TitleStylePanel