Files
waooplus/src/app/[locale]/dev/workspace-redesign/VariantClearBreath.tsx

148 lines
5.4 KiB
TypeScript

'use client'
/**
* 清澈呼吸 — 输入区域
* Apple 风格呼吸光晕 + 下拉标签选项
* 底部排版由 page.tsx 注入
*/
import { useState } from 'react'
import { useTranslations } from 'next-intl'
import { AppIcon } from '@/components/ui/icons'
import { InlineSelector } from './InlineSelector'
import {
STYLE_OPTIONS,
RATIO_OPTIONS,
QUALITY_OPTIONS,
} from './shared'
export default function VariantClearBreath({ children }: { children?: React.ReactNode }) {
const t = useTranslations('workspaceRedesign')
const [selectedStyle, setSelectedStyle] = useState('anime')
const [selectedRatio, setSelectedRatio] = useState('16:9')
const [selectedQuality, setSelectedQuality] = useState('high')
const [inputValue, setInputValue] = useState('')
return (
<div className="min-h-[calc(100vh-120px)] flex flex-col">
{/* 自定义呼吸动画 */}
<style>{`
@keyframes breathe-drift-1 {
0%, 100% {
transform: translate(0, 0) scale(1);
opacity: 0.5;
}
25% {
transform: translate(30px, -20px) scale(1.15);
opacity: 0.7;
}
50% {
transform: translate(-20px, 15px) scale(0.95);
opacity: 0.4;
}
75% {
transform: translate(15px, 25px) scale(1.1);
opacity: 0.65;
}
}
@keyframes breathe-drift-2 {
0%, 100% {
transform: translate(0, 0) scale(1);
opacity: 0.45;
}
30% {
transform: translate(-25px, 20px) scale(1.2);
opacity: 0.7;
}
60% {
transform: translate(20px, -15px) scale(0.9);
opacity: 0.35;
}
80% {
transform: translate(-10px, -25px) scale(1.05);
opacity: 0.6;
}
}
@keyframes breathe-drift-3 {
0%, 100% {
transform: translate(0, 0) scale(1.05);
opacity: 0.4;
}
20% {
transform: translate(20px, 15px) scale(0.9);
opacity: 0.55;
}
45% {
transform: translate(-15px, -20px) scale(1.15);
opacity: 0.7;
}
70% {
transform: translate(10px, -10px) scale(1);
opacity: 0.35;
}
}
`}</style>
<div className="flex flex-col items-center pt-[18vh] pb-12 px-4 max-w-3xl mx-auto w-full">
<div className="mb-6 text-center">
<h1 className="text-3xl font-bold text-[var(--glass-text-primary)] mb-2">
{t('quickActions.title')}
</h1>
<p className="text-sm text-[var(--glass-text-tertiary)]">{t('inputPlaceholder')}</p>
</div>
{/* 呼吸光晕容器 */}
<div className="w-full relative group">
<div
className="absolute -inset-10 rounded-[48px] pointer-events-none"
style={{
background: 'radial-gradient(ellipse 80% 60% at 30% 40%, rgba(6, 182, 212, 0.4), transparent 70%)',
animation: 'breathe-drift-1 8s ease-in-out infinite',
filter: 'blur(30px)',
}}
/>
<div
className="absolute -inset-10 rounded-[48px] pointer-events-none"
style={{
background: 'radial-gradient(ellipse 70% 80% at 70% 60%, rgba(139, 92, 246, 0.35), transparent 70%)',
animation: 'breathe-drift-2 10s ease-in-out infinite',
filter: 'blur(35px)',
}}
/>
<div
className="absolute -inset-12 rounded-[56px] pointer-events-none"
style={{
background: 'radial-gradient(ellipse 60% 50% at 50% 50%, rgba(59, 130, 246, 0.3), transparent 70%)',
animation: 'breathe-drift-3 12s ease-in-out infinite',
filter: 'blur(40px)',
}}
/>
<div className="relative w-full glass-surface-elevated rounded-2xl overflow-hidden">
<textarea
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder={t('inputPlaceholder')}
rows={4}
className="w-full bg-transparent border-none outline-none text-[var(--glass-text-primary)] placeholder:text-[var(--glass-text-tertiary)] text-base resize-none p-5 pb-2"
/>
<div className="flex items-center justify-between gap-2 px-5 pb-4">
<div className="flex items-center gap-2">
<InlineSelector label={t('style')} selectedId={selectedStyle} options={STYLE_OPTIONS} onSelect={setSelectedStyle} renderLabel={(o) => `${o.emoji ?? ''} ${t(o.labelKey)}`} />
<InlineSelector label={t('ratio')} selectedId={selectedRatio} options={RATIO_OPTIONS} onSelect={setSelectedRatio} renderLabel={(o) => t(o.labelKey)} />
<InlineSelector label={t('quality')} selectedId={selectedQuality} options={QUALITY_OPTIONS} onSelect={setSelectedQuality} renderLabel={(o) => t(o.labelKey)} />
</div>
<button className="glass-btn-base glass-btn-primary px-5 py-2 text-sm flex-shrink-0">
{t('startCreation')}
<AppIcon name="arrowRight" className="w-4 h-4" />
</button>
</div>
</div>
</div>
</div>
{/* 底部排版内容 — 由外部注入 */}
{children}
</div>
)
}